何ヶ月か前にあるちょっとしたPhoenixアプリのコードを更新した時にうっかり本番データベースの状態を考慮せずに
スキーマとマイグレーションを変更してしまいました。その結果、本番データベースとスキーマとマイグレーションの間に不整合が発生し、マイグレーションやロールバックができなくなりました。
練習用プロジェクトなのでデータベースを一旦削除して最初から作り直すのが一番早いと思い、そうすることにしました。
Gigalixirのデータベースを削除した際に気がついた点をメモします。
環境
- macOS 14.2.1 23C71 arm64
- MacBookPro 18,1
- gigalixir 1.9.3
- elixir 1.15.4
- erlang 26.0.2
- phoenix 1.7.10
- postgrex 0.17.4
- phoenix_ecto 4.4.3
gigalixir
本記事はGigalixirにデプロイしたことがある人を対象にしていますが、まだの方もわかりやすい公式ドキュメントやQiita記事が多数ありますので是非とも挑戦してみてください!
Gigalixir is a fully-featured, production-stable platform-as-a-service built just for Elixir that saves you money and unlocks the full power of Elixir and Phoenix without forcing you to build production infrastructure or deal with maintenance and operations. For more information, see https://www.gigalixir.com.
Gigalixir は、Elixir 専用に構築された、フル機能で安定した運用が可能なサービスとしてのプラットフォームであり、運用インフラストラクチャの構築やメンテナンスや運用の負担を強いることなく、コストを節約し、Elixir と Phoenix の能力を最大限に活用できます。 詳細については、https://www.gigalixir.com を参照してください。
データベースを削除する方法
ふた通りのやり方があるようです。どちらともやり方は簡単です。
- ターミナルから (CUI; 文字ユーザーインターフェイス)
- Gigalixirのウエブアプリから (GUI; 画像/図形ユーザーインターフェイス)
データベースを削除するため、保存されているデータなどはすべて削除されます。
ターミナルから
cd path/to/my_phoenix_app
# データベースの情報を印字し、IDを取得
gigalixir pg
# データベースを削除
gigalixir pg:destroy -a <アプリ名> -d <データベースのID>
# 再度データベースの情報を印字し、データベースが削除されたことを確認
gigalixir pg
Gigalixirのウエブアプリから
- [Database]タブをクリック
- [DESTROY]ボタンをクリック
- 確認のためにデータベース ID を入力
- [DELETE]ボタンをクリック
データベースを再度生成
cd path/to/my_phoenix_app
# 無料プランのデータベースを生成
gigalixir pg:create --free
# データベースが生成されたか確認
gigalixir pg
これであとはいつも通り普通にマイグレーションしたらいいのかなと思ったら、エラーが出ました。
マイグレーションがうまくいかない
cd path/to/my_phoenix_app
# マイグレーションを実行
gigalixir ps:migrate
でっかいエラーなので見た目が怖いですが、よくみてみると親切に色んな手がかりを残してくれています。
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2928ms.
This means requests are coming in and your connection pool cannot serve them fast enough. You can address this by:
- Ensuring your database is available and that you can connect to it
- Tracking down slow queries and making sure they are running fast enough
- Increasing the pool_size (although this increases resource consumption)
- Allowing requests to wait longer by increasing :queue_target and :queue_interval
特にコードも設定も変えていないので、一つ目の「データベースの存在、接続」である可能性が高いと思われます。
DATABASE_URLを確認
データベースの設定よくみたらDATABASE_URL
が正しく設定されていませんでした。
cd path/to/my_phoenix_app
# 現在の設定を確認
gigalixir config
# データベースの情報を取得
gigalixir pg
DATABASE_URL
の値を正しいものに変更します。
# DATABASE_URLの値を変更
my_database_url="postgresql://xxxx-user:pw-xxxx@postgres-free-tier-v2020.gigalixir.com:5432/xxxx"
gigalixir config:set DATABASE_URL="$my_database_url"
# データベースの情報が変更されたか確認
gigalixir pg
おまけ:DATABASE_URL
の値だけを取り出す
ついでにDATABASE_URL
の値だけを取り出すスクリプトを考えてみました。
jq
があれば一発です。
gigalixir config | jq '.DATABASE_URL'
# "postgresql://89296796-ad8c-..."
grepの-o, --only-matching
オプションを活用してこう言うやり方ができるそうです。
gigalixir config | grep -o '"DATABASE_URL": "[^"]*' | grep -o '[^"]*$'
# postgresql://89296796-ad8c-...
URLの形式が決まっている感じなので、固定のところは正規表現の中で明示してもいいのかもしれません。
gigalixir config |
grep -o 'postgresql://[a-z0-9-]*:[a-z0-9-]*@[a-z0-9-]*.gigalixir.com:5432/[a-z0-9-]*'
# postgresql://89296796-ad8c-...
こんなことに時間をかけるより切取・貼付をした方が早いですが、勉強になります。きっとどこかで役に立つと信じています。
最後に一言
本記事は 闘魂 Elixir #66 の成果です。ありがとうございます。