1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「bin/rails db:reset」を安易に実行しない!DBを操作する前はバックアップを必ず取得しようという戒め録

Last updated at Posted at 2025-02-28

はじめに

本番用と開発用のDBをろくに分けずに製作していた、自作アプリのデータベースを間違ってresetしてしまった(しかもバックアップも取っていなかった)ので、再発防止のための戒めと、環境ごとにデータベースを分ける&データベースのバックアップを取得する方法の備忘録です。

使用環境

  • Ruby 3.3.1
  • Rails 7.1.3
  • Fly.io(本番環境)
  • Docker(開発環境)
  • PostgreSQL(データベース)

そもそも、なぜDBのデータ消えちゃったの?

上記の方とほぼ同じでテスト用のDBを作成しようとしている中でエラーが発生し、AIに解決方法を訊いたらbin/rails db:resetのコマンドを提案されました。これを安易に実行してしまったのが原因。

警告もなく「これで成功します!」といつものノリで言われたまま、考えなしに実行したらデータベースのデータが全て消えてしまいました。

よく言われる「AIに提示されたコマンドを意味のわからないまま使ってはいけない」というのはこういうことが起こるからだよな……と今回は身を持って大反省。

AIによく知らないコマンドを提示されたら、わからないまま入力せず必ず調べること。

私の場合は幸いなことに、個人開発の時点で大失敗して反省できたのはラッキーでした。
万が一、会社やチーム開発でこういった自体が起こったときは、すぐに関係者と上司に報告しよう(怖いけど)。

ただ開発したアプリのデータベースが継続的な運用・保守に適していない状態で、特にデータを復元できなくなってしまったことは手痛かったので、今回の反省を踏まえてバックアップを取得できる環境を整えることにしました。

対策その1. 開発環境で入力したデータは開発用DBに登録する

現在、本番環境のデータベース(production)を開発時にも併用している状況なので、開発環境で入力したデータは開発用DB(development)に登録されるように、database.ymlで接続先を環境ごとに分離します。

# database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>
  port: <%= ENV['DB_PORT'] %>
  sslmode: disable #fly.ioのデータベースはsslmodeでないと外部から接続できないため使用

development:
  <<: *default
  database: development環境のデータベース名

test:
  <<: *default
  database: test環境のデータベース名

production:
  <<: *default
  database: production環境のデータベース名
  # もとは「DATABASE_URL」を直接ここに入力していましたが、接続するDBをデータベース名で分離します

開発用とテスト用のDBを作成する

  • DBを作成するためのコマンドを入力する
createdb -U ユーザー名 -h ホスト名 development環境のデータベース名
createdb -U ユーザー名 -h ホスト名 test環境のデータベース名
  • DBをマイグレーションするためのコマンドを入力する(コンテナ内で)
RAILS_ENV=development bin/rails db:migrate
RAILS_ENV=test bin/rails db:migrate

上記の通りに実行してからDockerを再起動すると、本番環境で入力した内容は本番用のDBに、開発環境での入力内容は開発用のDBに登録されるように分離されました。

ついでにRSpecテスト用のDBを作成できました(本来の目的)。

対策その2. DBの操作前は必ずバックアップを取得する

DBを操作するようなことがある場合、作業前にdumpファイルを取得しておくと安心。
ベテランの方ほど、こういった万が一の事故防止を徹底しているようです。見習います。

pg_dump

PostgresSQLデータベースをバックアップするユーティリティ。
PostgresSQLのバックアップについては他にも方法がいくつかありますが、今回はこちらを使いました。

pg_dump -U ユーザー名 -h ホスト名 -d バックアップを取得するデータベース名 -f backup.sql

上記を入力後、求められるデータベースのパスワードを打ち込めば、backup.sqlファイルが生成されます。

backup.sqlファイルは再度コマンドを入力すると上書きされるので、別々に残したい場合は下記のようにタイムスタンプを付けると良さげです。
念のために、日次で取得しておくことも大切。

-f backup_$(date +"%Y%m%d%H%M%S").sql

DBファイルは機密情報の塊なので、.gitignoreに記述してGitHubのリモートリポジトリに公開されないように設定しておきましょう。

# .gitignore
backup.sql

バックアップファイルのデータをリストアしたい時は、下記のように入力します。

psql -U ユーザー名 -h ホスト名 -d リストア先のデータベース名 -f backup.sql

あとがき

本番環境のデータを抹消した上に復元もできなくなってしまったという大失敗ですが、おかげで就職前にデータベース周りを再勉強できたこと、何よりも「AIの言うことを鵜呑みにする」典型的失敗パターンを経験できたのは良かったのかなと思います。

もっと酷ければプログラムが壊れてしまったりアプリ全体が動かなくなったりするようなので、AIが堂々と提示してくるコマンドは必ずどんなコマンドかよく調べて理解してから使おうね……という、とても今更な学びと戒めでした。

最後までご覧いただき、ありがとうございました!

参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?