🛢️

Heroku Postgres Hobby-dev を最新バージョンにアップデートする

2021/12/23に公開

これは、Heroku Advent Calendar 2021 ゆかちゃんの誕生日を zenn.dev で試してみようのコーナーです。
ゆかちゃん! 33歳の誕生日おめでとう!!! 来年もPerfumeをよろしくね☆(ゝω・)vキャピ


さて、Heroku。安心・安全に楽しく無料プランをお使いの方が非常にたくさんいるかと実感しています。わたし自身も無料のプランには多くお世話になっています。

そんな中。無料プランではたまに厄介な出来事が起こることも事実。一時的に作ったアプリや開発環境、テスト環境でも継続して利用することはよくあることです。

そんなとき、Heroku Postgres のバージョンを上げたいときってありませんか? はい、私は今し方ありました。他のネタ作るために準備をしていたら、バージョンを上げずにいられない状況になりました。しかしながら、heroku pg:upgrade によるバージョンアップは "Hobby-dev" には対応していません。

しかし、先人のえらい人は言いましたpg:copy を使え、と。


毎年前置きが長くてごめんなさい、ということで pg:copy を使って Heroku Postgres:Hobby-dev のバージョンをアップグレードする方法です。

流れは次の通り

  1. 新しい Heroku Postgres:Hobby-dev を作る
  2. 古いデータベースから新しい方へ、データをコピーする
  3. 新しいデータベースを pg:promote する
  4. 古いデータベースを削除する

事前にメンテナンスモードにしておいた方が良いですね。安全です。開発用とか、テスト環境とか自分しか使っていないならお構いなしです。とっとと行きましょう。

1. 新しい Heroku Postgres:Hobby-dev を作る

GUI からでもいいですが、CLI が得意なみなさまは CLI でちゃちゃっと作りましょう。

HEROKU-APP-NAME : 今ご利用中の Heroku App名に置き換えてください

$ heroku addons:create heroku-postgresql:hobby-dev -a HEROKU-APP-NAME
Creating heroku-postgresql:hobby-dev on ⬢ HEROKU-APP-NAME... free
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-xxxxxx-18432 as HEROKU_POSTGRESQL_YELLOW_URL
Use heroku addons:docs heroku-postgresql to view documentation

はい、作成できました。ここで HEROKU_POSTGRESQL_YELLOW_URL は重要です。基本的に色の名前がつきます。YELLOW ではない他の色の場合もあります。心してかかりましょう。

はい、ここで pg:info を使って、データベースの状況を確認しておきましょう。古いデータベースが 12.9 で新しく作った方が 13.5 となっていますね。新しいデータベースが準備できたようです。

$ heroku pg:info -a HEROKU-APP-NAME
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            12.9
Created:               2020-05-31 01:44 UTC
Data Size:             8.5 MB/1.00 GB (In compliance)
Tables:                4
Rows:                  12/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-xxxx-64365

=== HEROKU_POSTGRESQL_YELLOW_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            13.5
Created:               2021-12-22 09:02 UTC
Data Size:             8.3 MB/1.00 GB (In compliance)
Tables:                4
Rows:                  13/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-xxxxx-18432

2. 古いデータベースから新しい方へ、データをコピーする

ここで pg:copy が必要となります。古い方から、新しい方へ。書き方がこんな感じです。

heroku pg:copy <A = 古いDBのあるHeroku App名>::<B = DATABASEのURL> <C = 新しいDBのDATABASE URL> -a <D = 新しいDBのあるHeroku App名>

このとき、
A = D: HEROKU-APP-NAME
B: DATABASE_URL (今使っているものが異なるURLのケースもありますが基本これ)
C: HEROKU_POSTGRESQL_YELLOW_URL (さっき作った時に重要だといったあれ)

となりますので、つぎのようにコマンドを実行しましょう。

$ heroku pg:copy HEROKU-APP-NAME::DATABASE_URL HEROKU_POSTGRESQL_YELLOW_URL -a HEROKU-APP-NAME
 ▸    WARNING: Destructive action
 ▸    This command will remove all data from YELLOW
 ▸    Data from DATABASE will then be transferred to YELLOW
 ▸    To proceed, type HEROKU-APP-NAME or re-run this command with --confirm HEROKU-APP-NAME

> HEROKU-APP-NAME
Starting copy of DATABASE to YELLOW... done
Copying... done

--confirm つけてもいいですし、このように HEROKU-APP-NAME を手打ちしても良いです。これでデータのコピーが完了です。

3. 新しいデータベースを pg:promote する

今のままでも使えますが、アプリ側で **HEROKU_POSTGRESQL_YELLOW_URL** を参照するようにしないといけなく、煩わしいだけです。そこで、新しく入れたデータベースをプロモーションして DATABASE_URL で使えるようにします。これが pg:promote です。

$ heroku pg:promote HEROKU_POSTGRESQL_YELLOW_URL -a HEROKU-APP-NAME
Ensuring an alternate alias for existing DATABASE_URL... HEROKU_POSTGRESQL_YELLOW_URL
Promoting postgresql-xxxxx-18432 to DATABASE_URL on ⬢ HEROKU-APP-NAME... done

どのようになったか pg:info で確認しましょう。新しい HEROKU_POSTGRESQL_YELLOW_URL 側に DATABASE_URL が付与されましたね。新しいデータベースを利用する、という状況になれたと言うことです。

さて、古い方は、というと。HEROKU_POSTGRESQL_ROSE_URL が割り当てられました。古い方へは、この URL を使ってアクセスできます。

$ heroku pg:info -a HEROKU-APP-NAME
=== HEROKU_POSTGRESQL_YELLOW_URL, DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            13.5
Created:               2021-12-22 09:02 UTC
Data Size:             8.4 MB/1.00 GB (In compliance)
Tables:                4
Rows:                  13/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-xxxxx-18432

=== HEROKU_POSTGRESQL_ROSE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            12.9
Created:               2020-05-31 01:44 UTC
Data Size:             8.5 MB/1.00 GB (In compliance)
Tables:                4
Rows:                  12/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-xxxx-64365

4. 古いデータベースを削除する

とは言え、もう古い方のデータベースはいりません。削除しましょう。addons:destroy です。これもアプリ名の確認があります。--confirm を使って自動化も可能ですね。

$ heroku addons:destroy HEROKU_POSTGRESQL_ROSE_URL -a HEROKU-APP-NAME
 ▸    WARNING: Destructive Action
 ▸    This command will affect the app HEROKU-APP-NAME
 ▸    To proceed, type HEROKU-APP-NAME or re-run this command with --confirm HEROKU-APP-NAME

> HEROKU-APP-NAME
Destroying postgresql-deep-67374 on ⬢ HEROKU-APP-NAME... done

さて、このままだと、新しいデータベースに二つのURL名が付与されていて、ちょっとうっとうしいです。稼働には影響ありませんが、DATABASE_URLだけにしておくことがスマートでしょう。いらない URL は addons:detach で削除できます。

$ heroku addons:detach HEROKU_POSTGRESQL_YELLOW_URL -a HEROKU-APP-NAME
Detaching HEROKU_POSTGRESQL_YELLOW to postgresql-xxxxxx-18432 from ⬢ HEROKU-APP-NAME... done
Unsetting HEROKU_POSTGRESQL_YELLOW config vars and restarting ⬢ HEROKU-APP-NAME... done, v37

ということで、最終形です。こうなりました。

$ heroku pg:info -a HEROKU-APP-NAME
=== HEROKU_POSTGRESQL_YELLOW_URL, DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           1/20
PG Version:            13.5
Created:               2021-12-22 09:02 UTC
Data Size:             8.4 MB/1.00 GB (In compliance)
Tables:                4
Rows:                  13/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-xxxxx-18432

やったぜ(๑•̀ㅂ•́)و✧

Discussion