オールアバウトTech Blog

株式会社オールアバウトのエンジニアブログです。

【新卒週間2019】新卒1年目 業務で起こした私の事故紹介

f:id:allabout-techblog:20190320090105p:plain

今年も例年に引き続き、オールアバウトの新卒1年目エンジニアが投稿する企画「テックブログ新卒週間2019」を開催します。

第1弾はオールアバウトの広告配信を担うグループに所属しております@cflated0528からお送りします。
普段の業務では広告配信結果を可視化するアプリの開発を主に行っております。
本日は入社一年目である私の事故紹介(誤字に非ず)をしたいと思います。

事故1:作業を二週間巻き戻した話

こちら、まだ入社して半年も経っていない頃、自身が開発に参加したアプリでの話となります。
まず、こちらの失敗について書きたいと思います。

事故発生の流れ

私の所属部署では主に広告配信に関する業務を行っております。
広告配信といえば、近年様々なニュースで騒がれています。
オールアバウトでも事業として広告を配信しており、配信時には何の広告を何処のページでどれくらい配信していたか、配信実績を社内の複数のデータベースに分けて残しています。
それらデータベースには定義書が整備されているのですが、一つのデータベースだけでも以下のように数百テーブルあります。
いくつかのテーブルには似たようなデータが入っていたり中々に複雑です。

f:id:allabout-techblog:20190314135048p:plain
あるDB定義書のテーブル一覧の一部(390行)

上述したとおり私は広告配信結果を可視化するアプリを作成しております。
そのアプリの作成時、このデータベースから必要なデータを取得し表示用データの作成を行いました。
その際、過去に利用されていたSQL等を参考にデータ出力を試みました。
私としてはコードを見て、理解したつもりでデータ出力を行っていたのですが、最終的に作成したほぼすべてのクエリにミスがありました。
出力する必要があるデータ量が多く、私が担当した部分がアプリケーションの根幹部分だったことなどから作成に2週間弱かかっており、その時間の作業が巻き戻りました。

失敗から学んだこと

このあと上司が全てのSQLを書き直し、今ではアプリケーションは元気に動いています。
この失敗で学んだことは

  • 分からなかったら分かっている人に相談
  • 問題が大きくなりすぎない状況づくりが必要 ということです。

上述しましたが、過去に利用されていたSQLなどを見て私はデータベースの構造を一人で理解しようとしました。
その結果、データベースの構造をわかったつもりになり、データを作成し失敗をしました。
今回の場合、データの内容を理解している方が近くにいたため、その方に相談していれば自身の間違いに気がつけたと思います。
分からなければ自分一人で悩まず、時間がかかりすぎる前に相談することが重要だと感じます。

また、そもそも2週間分の作業に対して上司にほとんど確認を取らなかったことも問題でした。
作業を分けてこまめにレビューをうけていれば作成の初期段階で気がつき被害は最小限に抑えられていました。
自身が初めて行うような作業の場合は作業を細かく分けて都度確認すること、いっその事モブプロのように一緒に作るでもいいと思います。
とにかく問題が大きくなりすぎない状況を作り作業を進めていくことが大切だと学びました。

事故2:本番データベースのデータを吹き飛ばした

こちらは、タイトルからして不穏さしか感じられませんが、実際に私が起こした事故となります。
どのように今回のことが起こったのか、どう解決したのか、そこから考えたことを書きたいと思います。

事故発生の流れ

オールアバウトのアプリケーションの開発・リリースのフローを簡単に書きますと

  1. 開発環境で開発を行う。
  2. 開発内容のプルリクを上げレビューを受ける。
  3. ステージング環境(検証環境)で本番リリース前にテストを行う。
  4. 問題がなければ本番環境へリリースを行う。

というようになっております。
こちらの事故は私が開発していた、一日一回レポート用の表示データを出力する日次バッチプログラムの開発時、改修レビューが完了し、ステージング環境でテストを行う際に引き起こされました。

オールアバウトのステージング環境のデータは自動同期などは行われておりません。
ステージング環境のデータを更新したい場合、手動で本番環境からデータをダンプしステージング環境にインポートしていました。
何度も行っている作業で慣れもあり、確認が疎かになっていたこともあるのだと思います。
ステージング環境からデータをダンプし本番環境に書き込みました。
書き込み開始数秒後に気がついたものの既に遅く…本番データは上書きされていました。

事故の解決

データ上書後、頭が真っ白になりました。
幸いにして、日次実行バッチ用のデータベースであり、更新も朝に一度だけ別のデータベースから送られてくるだけであるため、動いているサービスには影響はありませんでした。
その後、復元作業を行いました。
オールアバウトではGCP(Google Cloud Platform)をメインで利用しており、SREグループがその管理を行っております。GCP上にあるデータベースもその例に漏れません。
本番データベースはCloud SQLの機能で毎日バックアップが取られており、当日の朝も更新前のデータが残っていました。 そこから当日のデータを復旧し、朝に更新データを送ってくる別のデータベースでデータの再生成および再送信を行っていただきました。
社内システム構造、他者からの手助けなどのおかげで1時間程度で全データの復旧を完了させることができました。

失敗から学んだこと

今回の事故を起こしていくつか考えたことがあります。
まず、失敗した要因は一体何だったのかです。
考えると以下のようなことが要因にあったかと思います。

  • 今触っているデータベースが本番だと分かりづらかったこと。
    • テーブルの更新作業はSQLクライアント(Sequel Pro)を用いて行っていた。
    • あまり設定を行っておらず、以下の画像の様な表示になっており、自身が何に対して操作を行っているか注意しなければ分からなかった。 f:id:allabout-techblog:20190314140021p:plain
  • 作業への馴れで確認が疎かになっていたこと。
    • 上記の問題がある上で操作への馴れから確認を怠った。
  • 書き込み権限付きで本番データを触っていたこと。
    • エクスポート作業であるのだから、そもそもそんな権限はいらない。
  • ステージングに手作業で毎回データを入れる必要があること。
    • 人的ミスが発生しうるフローになっている。

以上のような要因があった上で、上述した行動をとってしまった、とれてしまったために今回の事故につながってしまったと考えます。 それらへの対策を考えると以下の対応が取れるかと思います。

  • 触っているデータベースが一目で危険であるかどうかを認識できるようにする。
    • 現在は以下のようにして一目で自分が危険なデータを触っていることが分かるよう視覚化した。 f:id:allabout-techblog:20190314140124p:plain
  • 指差喚呼などの確認フローを辿ること。
  • 必要がないときはRead Onlyユーザで操作を行う。
  • ステージング環境作成の自動化。
    • 今回のデータベースであれば本番データを日次で自動で同期しておくなど。

現在では、4つ目の対策については設計や実装にかかる工数の関係上行ってはいませんが、それ以外の対策は実施し、再度同じ失敗を繰り返さないように気をつけています。

また、今回の事故から、万が一起こってしまった場合に備えることも重要であると感じました。
今回、本番環境のデータを上書きしてしまい、過去のデータを全て再集計する必要があるのではないか、その場合はその日中にリカバリ作業が終わらないのではないかと想像しました。
しかし、SREや他のメンバーの事前の対策もあり復元作業自体は想定よりも非常に軽いものでした。
今回は私が手動でデータを吹き飛ばしましたが、システムトラブルで消えたり停止することもあると思います。
事故が起こるまで原因はわかりませんが、もし起こってしまったときのために起こりうる問題を想像すること、起こった時にシステムをどのように動かすか、どのように復旧をするか、今回は他者が段取りを整えてくれていましたが、事前に考えなければいけないものだったと感じさせられました。

さらには、言い出せる環境づくりも普段から心がけて置くべきだと感じました。
今回の事故を起こした際、誰にも言わずに問題を隠蔽する考えは正直言って脳裏をよぎりました。
黙っていれば誰がやったのか発覚しないのではないか、自分ひとりで復旧ができるんじゃないかなど、正直なところ自身の失敗を言い出すことに、叱責を受けることに恐怖を感じました。
そんな時に言い出せる環境を作っておくこと、問題解決時に助けになってくれると相手に思ってもらえる状況を作らなければ被害は広がっていくことかと思います。

おわりに

きちんと確認することなど、運用として事故が起こらないように気をつけることは非常に大事です。
ただ、それでも馴れがでれば不注意、確認不足などからふとした瞬間に事故を起こるものだとは思います。
そんなときのためにシステム的にも事故が起こらない仕組み作りや、いざ起こったときの対策を考えることで安全なシステムを構築できるように頑張ろうと思います。