状況
日次でデータベースよりデータを抽出してファイルに書き出すバッチファイルを動かしていた。
ある日、出力結果を確認してみたところ、空っぽになっていた。
環境等
- Linux 4.14.13-200.fc26.x86_64
- PostgreSQL 9.6.6
状況調査
出力ファイルの確認
空っぽ。
出力ファイルの元となるビュー、テーブルのデータ確認
ビューを確認すると、空っぽ。
ビューの元となるテーブルを参照すると、データは存在するように見える。
PostgreSQLのログ確認
[2018-02-27 08:25:19 JST][11420][][] ERROR: トランザクション3960637355のステータスにアクセスできませんでした
[2018-02-27 08:25:19 JST][11420][][] 詳細: ファイル"pg_clog/0EC1"をオープンできませんでした: No such file or directory。
[2018-02-27 08:25:19 JST][11420][][] コンテキスト: テーブル"hoge.public.sometable"の自動解析
[2018-02-27 08:26:19 JST][11437][][] ERROR: トランザクション3960637355のステータスにアクセスできませんでした
[2018-02-27 08:26:19 JST][11437][][] 詳細: ファイル"pg_clog/0EC1"をオープンできませんでした: No such file or directory。
[2018-02-27 08:26:19 JST][11437][][] コンテキスト: テーブル"hoge.public.sometable"の自動解析
[2018-02-27 08:27:19 JST][11445][][] ERROR: トランザクション3960637355のステータスにアクセスできませんでした
[2018-02-27 08:27:19 JST][11445][][] 詳細: ファイル"pg_clog/0EC1"をオープンできませんでした: No such file or directory。
ふぁっ?!
pg_clog/0EC1
が無いとおっしゃる
念のため確認
$ sudo su - postgres
-bash-4.4$ cd /var/lib/pgsql/data/pg_clog
-bash-4.4$ ll
合計 4392
-rw-------. 1 postgres postgres 262144 12月 21 11:03 0000
-rw------- 1 postgres postgres 262144 12月 21 13:08 0001
-rw------- 1 postgres postgres 262144 12月 21 21:28 0002
-rw------- 1 postgres postgres 262144 12月 22 19:59 0003
-rw------- 1 postgres postgres 262144 12月 23 18:34 0004
-rw------- 1 postgres postgres 262144 12月 24 16:49 0005
-rw------- 1 postgres postgres 262144 12月 25 08:59 0006
-rw------- 1 postgres postgres 262144 1月 9 20:40 0007
-rw------- 1 postgres postgres 262144 1月 10 13:55 0008
-rw------- 1 postgres postgres 262144 1月 12 10:06 0009
-rw------- 1 postgres postgres 262144 1月 13 12:21 000A
-rw------- 1 postgres postgres 262144 1月 15 01:52 000B
-rw------- 1 postgres postgres 262144 1月 15 11:57 000C
-rw------- 1 postgres postgres 262144 1月 16 00:37 000D
-rw------- 1 postgres postgres 262144 1月 17 01:28 000E
-rw------- 1 postgres postgres 262144 1月 18 02:08 000F
-rw------- 1 postgres postgres 262144 2月 20 01:43 0010
-bash-4.4$
確かに無い。
対応
実際にやってみたこと
pg_ctlgのバックアップ
早急にPostgreSQLを止めて、pg_ctlg
ディレクトリのバックアップを取得する。
$ sudo systemctl stop postgresql.service
$ sudo su - postgres
-bash-4.4$ cd /var/lib/pgsql/data
-bash-4.4$ cp -r pg_ctlg pg_ctlg.bk
-bash-4.4$
空のカタログファイルの手動作成
ブロックサイズを合わせる必要があるようなので
dd
コマンドを用いて指定サイズ(256k)でゼロ埋めされたファイルを作る
$ sudo su - postgres
-bash-4.4$ dd if=/dev/zero of=/var/lib/pgsql/data/pg_clog/0EC1 bs=256k count=1
データベースを起動し、VACUUM
を実行する
念のため
$ sudo systemctl start postgresql.service
$ sudo su - postgres
-bash-4.4$ vacuumdb -a -v F
公式ドキュメントによると、 vacuumdbはPostgreSQLの問い合わせオプティマイザが使用する内部的な統計情報も生成します。
とあるので、カタログファイルを再生成してくれないかなーと期待を込めて
動作確認
ビューの元となるテーブルを参照すると、今まで通りデータは存在するように見える。
クライアントより、テーブルのソートを行ったところ、メモリをアロケートできない旨のエラーが表示された。
なんじゃらほい _(┐「ε:)_
(具体的なエラーメッセージは失念)
しかし、この状態で十分ほど放置していたら直った。謎い。
所感
どうして直ったのか分からないので、大変モヤモヤする結果となった。