PostgreSQLのバキュームにてハマる

Posted by @kachina_t on Mon, Jan 10, 2011
In Development
Tags development

案件によって、色々なRDBを使うのだけど、今回はPostgreSQLのおはなし。

[postgres@devsrv ~]$ psql -l
Password for user postgres:
        List of databases
    Name    |  Owner   | Encoding
------------+----------+----------
 foo_db     | foo      | UTF8
 bar_db     | bar      | UTF8
 postgres   | postgres | UTF8
 template0  | postgres | UTF8
 template1  | postgres | UTF8
(5 rows)

定期的にvacuumをしなくちゃいけないってのは知ってたので
サービスで使っているデータベース『foo_db』と『bar_db』に対しては
日次処理でvacuumを実行していたのだけど

運用から3年弱で、予期せぬエラーが

WARNING:  database "postgres" must be vacuumed within 9183172 transactions
HINT:  To avoid a database shutdown, execute a full-database VACUUM in "postgres".

無知でした『postgres』データベースに対してもvacuumが必要な様です。
このメッセージが出ちゃったら、以下の手順でしか復旧できないようで...

手順1.PostgreSQLサービスの再起動

[root@devsrv ~]# /etc/init.d/postgresql restart

手順2.フルバキュームの実施

[postgres@devsrv ~]$ psql -U postgres postgres
Password for user postgres:
Welcome to psql 8.1.15 (server 8.1.5), the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

postgres=# vacuum full;

要約すると、データベース×トランザクション毎に『xid』と言われる
ユニークキーが採番されるのだけど、この『xid』は10億から始り、20億より以下であることが求められています。
vacuumを実行することで、採番された『xid』を『FrozenXID』に再割り当てし『xid』を初期化します。

先に記したエラーメッセージは、postgresデータベースの『xid』が枯渇してしまい
残りが1000万を切りましたよってことです。

なので、あと1000万トランザクションを使いきるまでに
対象となっている『postgres』データベースに対して、vacuumを実行する必要があります。

まあ、大抵のサービスではミドルウェアのバージョンアップ、インフラの拡張等で移行すると思うので
この障害に出くわすことはあまりないと思うのだが
こんなこともあるから、気をつけなきゃだめだよってことで。