-
2025-03-30 PostgreSQLPostgreSQL パラメータ
“invalid value for parameter “recovery_target_time”エラーについて
recovery_target_time に指定した値が不正となる
PostgreSQL で PITR を行う際に、リカバリしたい時点を recovery_target_time に指定します。
このとき、recovery_target_time に指定したタイムスタンプが不正であると「invalid value for parameter "recovery_target_time"」というエラーが発生します。
PostgreSQL 17.2 で出力されるエラーメッセージの例を下記に記載します。
$ pg_ctl start -D data_001
waiting for server to start....2025-02-17 06:51:36.168 GMT [45931] LOG: invalid value for parameter "recovery_target_time": "2025-02-16 10:00:00 JST"
2025-02-17 06:51:36.168 UTC [45931] FATAL: configuration file "/home/postgres/data_001/postgresql.conf" contains errors
stopped waiting
上記の例では、recovery_target_time に「2025-02-16 10:00:00 JST」という値を設定したのですが、これが不正な値といわれています。
recovery_target_time にはタイムスタンプを設定します。
タイムスタンプについては、公式ドキュメントに説明がありますので、そちらを参照してください。
【 PostgreSQL 16.4文書 - 8.5.1.3. タイムスタンプ - 】
https://www.postgresql.jp/docs/16/datatype-datetime.html#DATATYPE-DATETIME-INPUT-TIME-STAMPS
recovery_target_time に設定した「2025-02-16 10:00:00 JST」という値は、タイムスタンプとして問題ないように見えます。が、どこが問題かと言いますと末尾の「JST」の部分がエラーの原因となります。
例えば、同じタイムゾーンの略語である「UTC」などを指定した場合には、エラーなく起動します。
この「JST」や「UTC」は、タイムゾーンの略語や略称に該当します。この「JST」を PostgreSQL が解釈できなかったためエラーとなっています。
ソースコードからインストールした PostgreSQL の timezone
PostgreSQL が解釈できるタイムゾーン名は、share/timezone ディレクトリの配下にあるファイル名と同名のものとなっています。
ソースコードからインストールした PostgreSQL 17.2 の share/timezone は下記となっていました。
$ ls share/timezone
Africa Arctic Australia CET Cuba Eire Etc GB GMT+0 Greenwich Iceland Israel JST MET MST7MDT NZ-CHAT Portugal ROC Turkey US W-SU
America Asia Brazil Chile EET EST Europe GB-Eire GMT-0 Hongkong Indian Jamaica Kwajalein Mexico Navajo Pacific PRC ROK UCT UTC Zulu
Antarctica Atlantic Canada CST6CDT Egypt EST5EDT Factory GMT GMT0 HST Iran Japan Libya MST NZ Poland PST8PDT Singapore Universal WET
上記のとおり、timezone に JST が含まれていないため、「2025-02-16 10:00:00 JST」 という値はタイムスタンプとして不正と扱われます。
エラーとなる原因を確認できました。では、どうすれば解決できるのかということになりますが、一番単純な方法としては「JST」を別の表記に変更することでエラーを解消できます。
具体的には
- タイムゾーン名に変更する
- UTCオフセット(+09)に変更する
の 2 つの方法があります。
タイムゾーン名に変更する場合は「2025-02-16 10:00:00 Asia/Tokyo」となります。
UTCオフセット(+09)に変更する場合は「2025-02-16 10:00:00+09」となります。
ちなみに、ソースコードからインストールした PostgreSQL 17 では「JST」は解釈されませんが、パッケージからインストールした PostgreSQL 17 では「JST」は正しく解釈されます。
パッケージからインストールした PostgreSQL の timezone
パッケージからインストールした PostgreSQL 17 の timezone ディレクトリを確認します。
$ ls /usr/pgsql-17/share/timezone
ls: cannot access '/usr/pgsql-17/share/timezone': No such file or directory
パッケージからインストールした PostgreSQL 17 のディレクトリ配下には timezone ディレクトリがありませんでした。
なぜ timezone ディレクトリがなくても問題ないかというと、インストール時の configure に --with-system-tzdata オプションが指定されているためです。
pg_config で configure のオプションを確認した結果が下記となります。
$ /usr/pgsql-17/bin/pg_config | grep -oE -- "--with-system-tzdata=[^ ]+"
--with-system-tzdata=/usr/share/zoneinfo'
--with-system-tzdata オプションに /usr/share/zoneinfo というディレクトリが指定されています。
この /usr/share/zoneinfo は Linux でのタイムゾーンが格納されているディレクトリとなります。
つまり、ソースコードからインストールした場合には、PostgreSQL 独自のタイムゾーンデータが利用され、パッケージからのインストールした場合には、システムのタイムゾーンデータが利用されるという仕組みになっています。
システムのタイムゾーンデータに JST が含まれているため、パッケージからインストールした場合には「2025-02-16 10:00:00 JST」 が不正なタイムスタンプとなりません。
--with-system-tzdata オプションについての詳細は、公式ドキュメントを参照してください。
【 PostgreSQL 16.4文書 - 17.3. AutoconfとMakeによる構築とインストール - 】
https://www.postgresql.jp/document/16/html/install-make.html#CONFIGURE-OPTION-WITH-SYSTEM-TZDATA
まとめ
以上が recovery_target_time に指定するタイムスタンプに JST を指定した場合に発生するエラーの解説と対応方法となります。
ちなみに、recovery_target_time に限らず、SET TIMEZONE などでも同様のエラーが発生します。
今回のエラーと合わせて、タイムスタンプに指定できるフォーマットや、pg_timezone_names などについても解説をしたかったのですが、長くなりそうですので次回以降の記事で解説できればと思います。