Postgresのアップグレードでロケールが一致しない場合ってありますよね。
旧DBでは「en_GB.UTF-8」だったのに、新DBでは「jp_GB.UTF-8」で、新DBに合わせたい時。
そんな時の対処法をご説明致します。
本記事ではPostgres9.6からPostgres10へのアップグレードを元に説明させて頂きます。
このブログは現役のエンジニア(プログラマー歴が約12年)の僕(よしたか)が2019年12月後半から日々更新しております。
もしもアフィリエイトは会員登録後も無料です!
今すぐ会員登録してアフィリエイトを始めよう!
pg_upgradeコマンドでロケールが一致しない例
「pg_upgrade」コマンドでPostgresのアップグレードを行う場合、
$ /usr/pgsql-10/bin/pg_upgrade --old-bindir=/usr/pgsql-9.6/bin --new-bindir=/usr/pgsql-10/bin --old-datadir=/var/lib/pgsql/9.6/data --new-datadir=/var/lib/pgsql/10/data --jobs=6 --check
整合性チェックを実行しています。
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for invalid "unknown" user columns ok
Checking for hash indexes ok
データベース"postgres"の lc_collate 値が一致しません:旧 "en_GB.UTF-8"、新 "ja_JP.UTF-8"
失敗しました、終了しています
$ psql
こんな感じで「--check」オプションを付けると、移行可能かのみ確認する事が出来ますが、上記のようにロケールのエラーが出る場合があります。
旧DBと新DBのロケールの確認
実際に旧DBと新DBのロケールを確認してみると、
postgres=# select name,setting,context from pg_settings where name like 'lc%';
name | setting | context
-------------+-------------+-----------
lc_collate | en_GB.UTF-8 | internal
lc_ctype | en_GB.UTF-8 | internal
lc_messages | en_GB.UTF-8 | superuser
lc_monetary | en_GB.UTF-8 | user
lc_numeric | en_GB.UTF-8 | user
lc_time | en_GB.UTF-8 | user
(6 行)
postgres=#
postgres=# select name,setting,context from pg_settings where name like 'lc%';
name | setting | context
-------------+-------------+-----------
lc_collate | jp_GB.UTF-8 | internal
lc_ctype | jp_GB.UTF-8 | internal
lc_messages | jp_GB.UTF-8 | superuser
lc_monetary | jp_GB.UTF-8 | user
lc_numeric | jp_GB.UTF-8 | user
lc_time | jp_GB.UTF-8 | user
(6 行)
postgres=#
このように確かに違ってますね。
既存DBのロケールを新DBのロケールに合わせる
では実際に既存DBのロケールを新DBのロケールに合わせてみましょう。
// 事前バックアップ
$ pg_dumpall > backup.sql
// 既存ディレクトリをバックアップ
$ mv /var/lib/pgsql/9.6 /var/lib/pgsql/9.6_org
// initdbでロケールを指定してデータベースを再作成
$ initdb --locale=ja_JP.UTF-8 -D /var/lib/pgsql/9.6/data
// 事前バックアップからデータ復元
$ psql -f backup.sql postgres
// 後はPostgresを起動してロケールの確認
このような感じで、ロケールの変更にはinitdbを行う必要があります。
後は改めて「pg_upgrade」コマンドを使ってアップグレードを行えばOKかと。
1回バックアップを取って、再度データベースを作って…と手間がかかるかもしれませんが、一番確実な方法かなと思います。
まとめ
いかがだったでしょうか。
こういった場面になっても混乱せず、1つ1つ対処していきたいですね。
今日はさくっとここまでとなります!