PostgreSQL 9.2 でタイムゾーンのデフォルト値が変わった話
PostgreSQL 9.1 から 9.2 にバージョンアップすると postgresql.conf に timezone の設定を書かなかった場合のデフォルトが「ローカルタイムゾーン」から「GMT」に変わってて命を落とした…
2014-03-31 18:36:12 via web
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 読め > 俺