PostgreSQL 9.2 でタイムゾーンのデフォルト値が変わった話

PostgreSQLタイムゾーンをローカル時間に合わせるために、postgresql.conf の timezone の設定を
設定しない(デフォルト)運用にしていた。

今回、PostgreSQL 9.0 → 9.3 にバージョンアップをする際に、タイムゾーンの設定のデフォルト値が変更されていて、大変な目にあったのでメモしておく。

PostgreSQL 9.1 以前

postgresql.conf を以下のように設定すると、PostgreSQLタイムゾーンサーバのタイムゾーンと同じ になる。(timezone はコメントアウト

#timezone = unknown			# actually, defaults to TZ environment
					# setting

当然タイムゾーンが考慮されている。

$ date
Wed Apr  2 15:41:46 JST 2014
$ psql -U postgres -c "select now();" postgres
             now
------------------------------
 2014-04-02 15:42:14.86157+09
(1 row)

あえて Asia/Tokyo とか設定するのはポータブルではないので、タイムゾーンは指定せずに運用していた。

PostgreSQL 9.2 以降

postgresql.conf でタイムゾーンを指定しなかった場合は、PostgreSQLタイムゾーンGMT になるように変更された。

$ date
Wed Apr  2 15:46:11 JST 2014
$ psql -U postgres -c "select now();" postgres
              now
-------------------------------
 2014-04-02 06:46:15.147636+00
(1 row)

これだけだとかなりアグレッシブな変更に見えるが、そこは問題にならないように 9.2 では少し工夫がされている。
具体的には initdb のタイミングで、postgresql.conf の timezone に サーバのタイムゾーン が書き込まれるように変更されたということである。
つまり、普通に PostgreSQL 9.2 以降を単純にインストールをして使う分には、今回のような問題は起こらない。
しかし、Chef などで postgresql.conf を上書きする運用になっている場合には今回の問題を受けるおそれがある。

そのため、今回は postgresql.conf にタイムゾーンを明示的に書くことにした。

timezone = 'Asia/Tokyo'			# actually, defaults to TZ environment
					# setting
データベースにタイムゾーンを設定する方法

データベース単位でタイムゾーンを設定できる方法も用意されている。
以下の SQL を実行する。

ALTER DATABASE your_data_base SET timezone TO 'Asia/Tokyo';

使用できるタイムゾーンの一覧は、以下の SQL で取得できる。

SELECT * FROM pg_timezone_names;

まとめ

PostgreSQL は設定のデフォルト値を強気で変えてくるから気をつけろ!
というか Changelog 読め > 俺