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