TECH BLOG
技術ブログ
  • 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」を別の表記に変更することでエラーを解消できます。
具体的には

  1. タイムゾーン名に変更する
  2. 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 などについても解説をしたかったのですが、長くなりそうですので次回以降の記事で解説できればと思います。

CATEGORY

ARCHIVE

PostgreSQLに関するご相談は
株式会社インサイトまで
お気軽にお問い合わせください。

CONTACT