COLUMN
CMSのデータ移行|記事は全部移ったのに、次の1件が保存できなかった
データベースを丸ごと新しいサーバーへ移して、画面の表示はすべて正常だった。
それなのに、移行後に初めて記事を1件保存しようとした瞬間、「Duplicate entry '0'」というエラーで保存できなかった。
原因は、移行の途中で全テーブルから主キーと連番(AUTO_INCREMENT)の設定が抜け落ちていたことだった。
今年の夏、自社の製品サイトのデモ環境とお客様向けページの移行で、私たちはこの種類のつまずきを3回続けて経験した。
どれも「見た目は正常」なまま起きていた。
CMSのデータ移行で、記事や画像を運ぶことと同じくらい大事なのは、データの「器」の形まで運べているかどうかだと思う。
この記事では、実際に起きた3つの事故と、いま移行のたびに確かめている項目をまとめておく。
CMSのデータ移行で運ぶのは、記事の中身だけではない
CMSの移行というと、記事の本文や画像を新しいサイトへ写す作業を思い浮かべる人が多いと思う。
実際の中身は、もう少し層が分かれている。
ひとつは記事・ページ・画像といったコンテンツそのもの。
もうひとつは、そのコンテンツを入れているデータベースの構造で、どの列が主キーか、新しい行に何番を振るか、文字コードは何か、といった決まりごとだ。
最後に、公開日時や公開状態、URLの対応表のような、画面に出ないけれど動作を左右する設定がある。
移行後の確認で多くの人が見るのは、最初の層だけだ。
ページを開いて、文章と画像がきちんと出ていれば「移った」と判断する。
ただ、二つ目と三つ目の層が壊れていても、既存のページは普通に表示される。
壊れていることが分かるのは、誰かが新しい記事を書こうとしたときや、公開予約の時刻が来たときだ。
つまり移行の不具合は、移行作業が終わって担当者の手を離れたあとに表に出てくることが多い。
事故1:記事は全部移ったのに、次の1件が保存できなかった
最初の事故は、製品サイトに置いているデモ環境を本番サーバーへ移したときに起きた。
手元の環境からデータベースを書き出し、管理ツールの画面からインポートした。
件数を数え、トップページや記事ページを開いて、表示に問題がないことを確かめた。
ここまでは何の違和感もなかった。
異変が出たのは、移行後に初めて新しいデータを保存しようとしたときだった。
新しい行には本来、データベースが自動で「最後の番号+1」を振る。
その仕組みがテーブルから消えていたため、番号が空のまま「0」として入ろうとし、2件目の保存で重複エラーになった。
調べると、全テーブルの主キーと自動採番の設定が、インポートの途中で落ちていた。
データの中身は1行も欠けていないのに、器の形だけが変わっていたことになる。
復旧には、テーブルごとに主キーの有無を調べ、無いものにだけ設定を付け直すスクリプトを作った。
何度流しても同じ結果になるように書いたので、途中で止まっても安心してやり直せた。
それ以来、データベースを丸ごと移すときは、構造まで含めて書き出せる専用のコマンドでダンプを取り、画面からのインポートは使わないことにしている。
事故2:ファイル名を確かめずに、古いデータベースを入れてしまった
二つ目は、その数日後のやり直しの作業で起きた。
正しいダンプを入れ直したつもりが、実際に入れたのは名前のよく似た、ひとつ前の世代のデータベースだった。
入れた直後から、デモ環境のすべてのページがサーバーエラー(500)になった。
新しいほうは89テーブル、取り違えた古いほうは81テーブルで、プログラムが必要とする8つのテーブルが丸ごと足りなかった。
このときは画面が全部止まったので、すぐに気づけたのは不幸中の幸いだった。
ただ、テーブル数がもう少し近ければ、一部の機能だけが静かに動かない状態で公開されていたかもしれない。
いまは、入れる前にダンプのファイル名と移行先のデータベース名を声に出すつもりで突き合わせ、入れたあとにはテーブル数を数えて、元の環境と同じ数かを確かめている。
手間は1分もかからない。
事故3:新しく作ったページが2つとも「0番」になっていた
三つ目は、お客様向けの業種別ページを本番に追加したときのことだ。
固定ページを1つ足すだけの作業で、番号はデータベースに任せて登録した。
ところが本番のデータベースは、過去の復元作業の影響で、ページのテーブルの自動採番が効かない状態のままだった。
結果として、新しいページの番号が「0」で入り、気づいたときには同じ0番のページが2件できていた。
画面上はどちらのページも表示されていたので、ここでも見た目だけでは分からなかった。
番号を振り直し、主キーと自動採番を付け直して落ち着いた。
この件のあと、本番へ直接データを足すときは「いまの最大の番号+1」を自分で計算して明示的に入れる決まりにした。
データベースの自動採番を信じないのは少し窮屈だが、移行や復元を何度か経たデータベースでは、そのほうが確実だと思う。
見た目では気づけない、データ移行の小さな落とし穴
主キーのほかにも、表示確認では見逃しやすい落とし穴がいくつかあった。
ひとつは改行コードだ。
このCMSは本文の一部を、文字数を記録した形式でデータベースに保存している。
移行の途中で改行が「LF」から「CRLF」に変わると、1行ごとに1バイトずつ長さがずれ、その記事の本文が丸ごと読めなくなる。
以前、ファイルを経由させただけでこれが起きて、記事が空白になったことがある。
もうひとつは、移行用のSQLを分割して流すときの区切り方だ。
「セミコロンと改行」を文の終わりとみなす簡単な分割をすると、本文中の記号を置き換えた表記(不等号なら末尾がセミコロンで終わる形)がたまたま行末に来たところで、文が途中で切れてしまう。
三つ目は公開日時で、移行元とサーバーの時刻設定がずれていると、公開日時が未来になった記事はページを開いても見つからない扱いになる。
どれも、移行した直後のトップページを眺めているだけでは見えてこない。
データ移行で、私たちがいま必ず確かめている7項目
3回の事故を経て、いまは移行のたびに次の7つを確認している。
1つ目は、テーブルの数と、主なテーブルごとの行数が移行前と一致していること。
2つ目は、移すデータベースの名前と、ダンプのファイル名が対応していること。
3つ目は、主キーと自動採番の設定が全テーブルに残っていること。
4つ目は、移行後に新しい記事を1件、実際に保存してみること。
5つ目は、改行や文字数の情報を含む本文が壊れていないかを、記事を数件開いて確かめること。
6つ目は、公開日時と公開状態が移行前と同じになっていること。
7つ目は、移す前の状態にいつでも戻せるバックアップがあること。
この中で、いちばん効き目があるのは4つ目だと思う。
新しく1件保存して、それを消すだけの作業で、器の形が壊れていないかが一度に分かる。
実際、事故1と事故3は、どちらもこの確認を移行の直後にやっていれば、その場で見つかっていた。
お客様のサイトの移行をお手伝いするときも、最後に必ず「では1件、新しく書いてみましょう」と一緒に試すようにしている。
移行を外部の制作会社に任せる場合も、この7項目はそのまま確認の依頼に使える。
専門的な知識がなくても、「新しい記事を1件保存できるか」「テーブルの数は合っているか」を聞くだけで、移行の質はかなり見えてくる。
コンテナでは、管理画面からデータベースのバックアップを取って戻せる機能を標準で用意しているので、移行の前後で状態を残しておくところまでは担当者の手元で完結できる。
WordPressなど他のCMSから移る場合の進め方は、移行の案内ページにもまとめている。