今日は先日遭遇してしまった
「Herokuで過去のマイグレーションファイルを誤って反映されとる…orz」
という状況での修正反映&データ復旧の手順をまとめてみます。
ま、普通に開発してればあまりないシチュエーションですが…(・_・)
技術的に難しくはないもののHeroku独自の仕様もあったりしますので、
もしもやらかしちゃった方がいたら参考にしてみて下さい。
- そもそもやりたいこと
- バックアップ&リストアの前提条件
- Herokuのメンテナンスモード機能をONにする
- バックアップを作成する
- アプリ名等の確認
- DBを削除する
- 修正したマイグレーションファイルをデプロイする
- Herokuアプリ(web dyno)の再起動
- マイグレーションファイルの反映
- 再度Herokuアプリ(web dyno)の再起動
- バックアップからリストアする
- Herokuのメンテナンスモード機能をOFFにする
- 動作確認
- まとめ
そもそもやりたいこと
通常マイグレーションファイルを追加して対応するが、
どうしても反映済のバグってる過去のマイグレーションファイルの内容を変更したい。
そこで今回は現在のDBのデータを退避させて、修正後に戻す作業を行う。
バックアップ&リストアの前提条件
- pg(PostgreSQL)のアドオンを使用していること
- 正しいデータがデプロイ環境のDBに存在していること
※そもそも間違ったDB内容のデータが投入されているのであれば、復旧用のrake task等でデータを整形してから対応するか、マイグレーションファイルにデフォルト値を記載する等の対応が必要になるでしょう…。
※下記手順をローカル開発環境、またはStaging(テスト環境)で実施してからProduction(本番環境)で行ったほうが良いでしょう。
Herokuのメンテナンスモード機能をONにする
ユーザ操作によるDB更新を抑止します。
DBの矛盾が発生しないようにHerokuの機能でメンテナンスモードでユーザーのアクセスを制限しましょう。
Settings
の下にある Maintenance Mode
から可能です。
コマンドでは
$ heroku maintenance:on --app sushi
で出来るようです。
Maintenance Mode | Heroku Dev Center
バックアップを作成する
無料でも手動バックアップの作成&リストアは可能です。
まず『利用している』DBのアドオンの詳細ページに行きましょう。
(複数DBが存在する場合もあるので注意)
そして Durability
タブ下の Create Manual Backup
を実施します。
コマンドでは
$ heroku pg:backups:capture --app [アプリ名]
で出来ます。
Heroku PGBackups | Heroku Dev Center
なお、実施前に取得したバックアップからの復元方法などを公式で軽く見ておくと良いでしょう。
不安な方や既に運用しているサービスに関しては復旧テストもしておいても良いでしょう。
Heroku PGBackups | Heroku Dev Center
アプリ名等の確認
Durability
タブのページで、それぞれDB名(DATABASE_URL)・アプリ名・Backupバージョン名が確認できるので控えておきましょう。
DBを削除する
DBの権限の問題からHerokuではRailsからのDROP操作が出来ません。
つまり heroku run rails db:migrate:reset
等は行なえません。
そこで、pgのアドオン用の命令で直接DBを削除してしまいます。
$ heroku pg:reset [DB名] --app [アプリ名]
例:
$ heroku pg:reset postgresql-xxxxxxxxxxx-99999 --app sushi
マイグレーションの状態確認でDBとスキーマが空であることを確認しましょう。
$ heroku run rails db:migrate:status --app sushi Running rails db:migrate:status on ⬢ sushi... up, run.4506 (Hobby) Schema migrations table does not exist yet.
空っぽになっていたら次回 rails db:migrate
すれば、
マイグレーションファイルを全部実行してスキーマファイルを作成しなおせます。
修正したマイグレーションファイルをデプロイする
ローカルからHerokuへデプロイするという運用の方はpushしてデプロイしましょう。
$ git push production master
Herokuアプリ(web dyno)の再起動
ここで再起動しないと前のアプリの情報も含んでしまい、
前の誤った情報を含むマイグレーションファイルの構成で反映される可能性があります。
※これを行っていなかったがために1回ちゃんと反映されていなかったので気をつけるべし
$ heroku restart -r production
マイグレーションファイルの反映
$ heroku run rails db:migrate --app [アプリ名]
動作確認
$ heroku run rails db:migrate:status --app [アプリ名]
全て反映されてUPになっていればOK
再度Herokuアプリ(web dyno)の再起動
DB構成が変わっているので、念の為アプリを再起動しておいたほうが良いと思われる。
$ heroku restart --app sushi
バックアップからリストアする
メンテナンスモードにしてから取得したバックアップデータをリストアしましょう。
$ heroku pg:backups:restore [Backupバージョン名] [DB名] --app [アプリ名]
例:
$ heroku pg:backups:restore b008 postgresql-dimensional-92915 --app warm-plateau-1361
Heroku PGBackups | Heroku Dev Center
Herokuのメンテナンスモード機能をOFFにする
これを忘れてたらずっとメンテナンスモードなので使えるように戻しましょう。
動作確認
対象のアプリのDBでリストアされて以前と同様に使えることを確認しましょう。
正しくリストアしたデータにアクセス出来ていればOKです!
以上!
まとめ
普通に開発していればあまりないと思いますが、誤ったmigrationファイルをコミットしちゃった!とか、
あろうことかHerokuにデプロイまでしちゃった!という時の復旧方法でした。
自分がミスって無くても複数人で開発してたら、レビューですり抜けちゃうというのは全然ありえますしね!
もし困ったときには思い出して役立てて頂ければ幸いです!