動いているデータベースの中にしかない構造
このサービスがすることは、すべてバージョン管理の中にある。少なくともコードは。動いている先のデータベースは 32 の表で、そのうち 15 はリポジトリのどこにも定義がない — CREATE TABLE もなければ、スキーマのファイルもなく、何もない。サーバーを失えば、コードはそっくり戻ってくるが、データの形はコードがたまたま何を要求するかから組み直すほかない。
これらの数字は、動いているデータベースを 736 ファイル・5,671,710 文字のリポジトリと突き合わせて出したものだ。見積もりではない。
構造の半分はこうして消える
ずさんさではない。だからこそ書き留める値打ちがある。一つ一つの手順は、どれも理にかなっていた。
いまのコードより前に作られた表は、書き留められたことがない。当時はただそこにあったからだ。以後に足された表は移行スクリプトで入り、それらはリポジトリにある — 17 の定義はそこから来ている。あとから足された列は、一行の ALTER TABLE を端末で打って入った。一秒で終わる変更のためにスクリプトを書くより、打つほうが速かったからだ。
いちばん厄介なのは索引である。索引は何かが遅いときに、遅いその場で足され、その場で直る。あとには何も残らない。見直すものもなく、忘れても落ちるものがない。ここにある三十二の二次索引のうち十一は、まさにそれで生まれ、どこにも記録がない。
カウンターそのものが入っている表、166,438 行あるそれも、定義のない十五のうちの一つだ。
本当に壊れるのはどこか
ほとんど壊れない — ある一点までは。データベースをダンプから戻すときである。
ダンプは構造も運ぶので、素直に戻すぶんには問題ない。危ないのは、表を戻すのではなく作り直す道すじだ。別の機械への引っ越し、選んだ表だけの取り込み、スクリプトからの再作成。データは戻り、索引は黙って戻らない。何も失敗しない。問い合わせは正しい答えを返す。ただ時間がかかるようになるだけで、原因は見えない。その索引が何だったかの唯一の記録は、もうそれを持っていない機械の上にあるからだ。
これこそ名前をつけておくべき壊れ方である。欠けた索引はエラーを出さない。遅い正しい答えを出す。これを捕まえる試験はない。試験は通ってしまうからだ。
それまでのあいだ何をするか
正直なところ、これは直っていない。構造は今日、リポジトリにない。あるのは修正より小さく、何もないよりはましなものだ。
壊す操作の前には必ずダンプを取り、ウェブの公開場所の外に置く。実際に一度は行った復元 — 済んだつもりではなく。そして復元のたびに確かめる短い一覧、動いているデータベースにしかないと分かっている索引の一覧。機械には「どんな索引を持っているか」と尋ねられるし、その答えは前回のものと比べられる。
一般化した話は、データベースにとどまらない。システムの一部が動いている系の中にしかないなら、それは控えがあるのではなく、人質を取られているのだ。どんな設備についても問う値打ちがあるのは「バックアップはあるか」ではなく「この機械が消えたら、リポジトリから組み直せないものは何か」である。ここでの答えは十五の表と十一の索引で、それを知るのに午後が一つかかった。