こんにちは、技術推進部の佐藤です。
4 月ということもあり、社会人デビューをされた方たちを目にする機会が増えました。
「自分が若かった頃はこんなにしっかりしていたかな」などと懐かしんでいたら、ふと以前在籍していた会社で血の気が引くような失敗をしたことを思い出しました。
今回はそのお話をいたします。
ただ、その失敗から得た対策のおかげで、今まで 10 年以上もの間に一度も同じような失敗を起こしていません。
これからデータベースを触る方、今まで触っていても失敗したことがない方はご参考になれば幸いです。
何が起こったのか
背景
昔在籍していた会社でのことですが、オンプレにある自社ウェブアプリケーションを AWS 環境( EC2 + RDS )に移設するプロジェクトがありました。
その中で、私はデータベース( PostgreSQL )を RDS に移行する部分を担当しておりました。
基本的には既存データベースから dump ファイルを取得し、RDS へ流し込むだけの作業ですが、唯一のオーダーとして「文字コードは cp932 から UTF-8 に変えたい」というものがありました。
当時の私はこのオーダーを実現できるよう、RDS の設定変更や文字コードを変換しては dump ファイルを流し込み、文字化けしては DROP DATABASE を行う、という作業を繰り返していました。
事件
そんな繰り返し作業の最中に、うっかり事件を起こしてしまったのです。
作業中、ターミナルソフトを複数ウィンドウで起動し、それぞれで本番環境と開発環境を開いていました。
それぞれの設定を見比べつつ、開発環境ではそのまま DROP DATABASE を発行していました。
作業にも慣れて慢心していたのでしょう、あろうことかターミナルを間違えて本番環境に対して DROP DATABASE を発行してしまいました。
始めは全く気づかなかったのですが、後ろの席のサポートセンターの方たちが何やらざわめき立ちました。
何が起こっているのかを把握するため耳を立てつつ、作業を続けておりました。
どうやら本番環境で何か不具合が起こっていると聞こえ、データを確認しようとデータベースに接続しようとしたところエラーが返ってきました。
今でもこの時のことを思い出すと胃が痛くなります。
(以下は再現画像です)
どう対処したか
初動
まずはサポートセンターの方々へ「データベースを落としてしまった」旨を報告しました。
その後、お昼を食べに外出していた上司へ架電し、現在の状態を報告した上で dump ファイルをリストアするよう指示を受けました。
その後
リストア自体はすぐに完了したものの、当日 0:00 時点の dump であったため 0:00 から 12:30 ごろまでのデータが欠落しています。
取り急ぎ前日分まで復旧した旨をサポートセンターの方々へ報告していると、上司が帰社してきました。
すぐに上司と共に影響範囲を調査し、ユーザー向けのお知らせを作成しサポートセンターへ展開しました。
サポートセンターからは、そのお知らせをユーザーが見える場所(コーポレートサイト等)に公開していただき、問い合わせを受けた際にも同じ内容を案内していただきました。
収束
全ユーザーの 1 割ほどが影響を受けたので、その方達には個別に連絡を取り、オペレーションを再度行っていただきました。
完全に元通りという訳にはいきませんでしたが、サポートセンターへのお問い合わせは徐々に減っていき、当日内でなんとか収束いたしました。
その後はお詫び文を作成、掲載し終了となりました。
学びとその後の対策
このようなインシデントに直面することで、そもそもインシデントを「防止する仕組み」と「起こった場合の対策」の両方を考えておくことが大事だと学びました。
また、今でこそ当然のことと思いますが、エンジニアが行う作業はどんな小さなことでも多くのユーザーに影響を及ぼすことを体感しました。
その影響を収束させるためにはより一層のコストがかかることも身をもって知りました。
あの不安や焦燥感、作業量の多さを考えると、普段から「防止する仕組み」は徹底しておいて損はないかと思います。
そして、もし万が一失敗を起こしてしまった際には、焦りながらも復旧できるような「起こった場合の対策」の手順を考えておくと安心感が得られます。
あまりスマートではありませんが、私が今でも行っている「防止する仕組み」と、当時行った「起こった場合の対策」をお伝えしたいと思います。
防止する仕組み
1. ターミナルソフトは本番環境が一目で分かるようにしておく
この事件以降、ターミナルの見た目が自由に変更しやすい RLogin を使うようにしました。
以下のように「本番環境は白背景」にし、一目でわかるようにしています。
なお、RLogin では以下のように設定することで接続先ごとに背景色を変更することができます。
参考までに、iterm2 (macOS) での設定内容も記載いたします。
私は基本的には有りもののテーマを使いますので、Solarized Light を使っています。
上記のように設定しておくと、以下の右側のように背景色が変わります。
(左側は開発環境であり、Solarized Dark を使用しております)
なお、iterm2 では Advanced にて以下のような設定をすることで、ターミナル内に指定の文字列が表示されたら Profile を自動で切り替えることができます。
接続先のホスト名ごとに切り換えるために使用しています。
2. 指差し確認と声出し、そして他者の立ち会い
本番環境で何かしらコマンドを実行する場合、Enter キーを押下する前に必ず指差し確認をします。
その際に実行する内容を声に出すことで、本当に実行してよいのかを自問自答します。
加えて、他者に立ち会っていただき画面共有することで、実行する内容をダブルチェックしています。
最初は指差し確認や声出しは少し恥ずかしく感じるかもしれませんが、これくらいでインシデントを防げるなら安いものです。
3. 読み取り専用ユーザーを作成しておく
そもそも本番環境のデータベースに影響を与えられないようなユーザーを作成し、そのユーザーで操作していればこのようなことは起きません。
各データベースやその中にあるテーブルの owner からも外してしまえば、DROP DATABASE や DROP TABLE を発行することができません。
作り方は以下の通りです。
CREATE USER read_only_test WITH PASSWORD 'your_password'; -- read_only_test という名前のユーザーを新規作成 GRANT CONNECT ON DATABASE database_name TO read_only_test; -- データベースへのアクセスを許可 GRANT USAGE ON SCHEMA public TO read_only_test; -- デフォルトで存在する publi スキーマへのアクセスを許可 GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only_test; -- public スキーマ内の全テーブルへ `SELECT のみ` 許可
一番最後の GRANT 文が大事です。
上記手順で作成すれば、 owner でも無く SELECT 文しか発行できないユーザーとなります。
この状態なら DROP DATABASE を実行できませんし、
DROP TABLE や UPDATE 文も実行できません。
起こった場合の対策
バックアップを取っておく
大前提として、DB を操作するようなことがある場合、作業前に dump ファイルを取得しておくべきです。
さらに、念のために crontab などで日次の dump ファイルを取得しておくことも大切です。
以下のようなコマンドを crontab で回すようにしました。
pg_dump -c --if-exists -U ${user_name} -h ${host_name}$ -d ${db_name}$ -n ${schema_name} > /path/to/file.dump
また、各データベースにあるポイントインタイムリカバリを使用できるよう準備をしておくと、インシデントが起こる直前までロールフォワードできるので安心です。
PostgreSQL では WAL ログというファイルを常に出力し、有事の際にはそのファイルを適用することで実現できます。
( MySQL ではバイナリログ (binlog) と呼ばれるファイルです)
設定内容の詳細は割愛いたしますが、「 PostgreSQL PITR 設定」等と Google 検索をしていただければ、参考になるサイトは多く出てくるかと思います。
なお、WAL ログを出力するだけでなく、その適用方法もきちんと手順化しておくことも大事です。
最後に
「防ぐ努力」に記載した内容は今でも実施しており、そのおかげでこれまで本番環境でのヒューマンエラーは一度も起こしていません。
泥臭くはありますが、インフラエンジニアの方とこのお話しをするととても共感していただけます。
ベテランほど徹底している印象ですので、本番環境で作業することがある方は是非ともお試しいただきたいです。
なお、スパイダープラスでは私がジョインする以前からバックアップはきちんと取得しております。
大量の工事写真や図面、検査情報などお客様の業務を支える大切なデータを万が一にも失わないよう備えております。
専門のチームが支えておりますので、ご安心いただければと思います。
スパイダープラスでは仲間を募集中です。
スパイダープラスにちょっと興味が出てきたなという方がいらっしゃったらお気軽にご連絡ください。最後までご覧くださり、ありがとうございます。