エラー
無効なタイムスタンプを含むタプルを削除しようとしています
DELETE FROM comments WHERE date > '1 Jan 9999' OR date < '1 Jan 2000' OR date_found > '1 Jan 9999' OR date_found < '1 Jan 2000';
で終わる
ERROR: attempted to delete invisible tuple
2009年には、OPで修正されたまったく同じエラーメッセージについて議論するメーリングリストがありますが、彼がそれをどのようにしたのか、またはこのエラーにつながったのかについての説明はありません。
Googleでヒットがなく、PostgreSQLの知識が限られているため、私は無力です。
腐敗の原因
OSカーネルがパニックになったときに、おそらくスワップが配置されている/ dev / md1を再構築しているときに、Debian 8で実行しているPostgreSQL 9.5.5サーバー(メモリ制限の上限を除くすべてのデフォルト設定)を実行しました。それ以前は、PostgreSQLは400GBのログファイルでほとんどすべてのディスク領域を使い果たしました。OSは二度と起動しなかったので、ディスクチェックは問題ありませんでした。念のため、LiveCDから起動し、各ブロックデバイスをイメージにバックアップしました。/ dev / md2から/ディレクトリを正常に再構築しました。fsckはクリーンなファイルシステムを示し、PGDATAフォルダーを外部HDDにバックアップしました。
回復を試みるためにしたこと
mdデバイスをフォーマットし、新鮮なpostgresql-9.5とともにOSを再インストールした後、PostgreSQLサーバーを停止し、PGDATAフォルダーをpostgresユーザーに移動してchownし、サーバーを起動しました。
すぐに私が始めてきたようにpg_dumpall
、それはで死にました
Error message from server: ERROR: timestamp out of range
私は自然に問題のタプルを削除しようとしましたが、同じinvisible tuple
エラーが何度も何度も発生するだけです。
試したこと
まず、ページの破損が原因でDELETEクエリが失敗したため、次の設定を行いました。
zero_damaged_pages = on
ignore_system_indexes = on
enable_indexscan = off
enable_bitmapscan = off
enable_indexonlyscan = off
今、私は同じクエリを再度実行すると、サーバーが同じページを何度もゼロ設定することに気付きました。
invalid page in block 92800 of relation base/16385/16443; zeroing out page
私は未定義の順序で以下を試しました:
pg_resetxlog -D $PGDATA
エラーやメッセージなしで仕事をした- pkey制約を含むすべてのインデックスを削除しました
CREATE TABLE aaa AS (SELECT * FROM comments);
リードにSegmentation fault
上heap_deform_tuple (tuple=tuple@entry=0x7f0d1be29b08, tupleDesc=tupleDesc@entry=0x7f0d1a35abe0, values=values@entry=0x7ffd57a5beb0, isnull=isnull@entry=0x7ffd57a65af0 "\001\001")
再現性があり、〜9GBのコアダンプが残ります。SELECT COUNT(*) from comments;
VACUUM comments;
完了することができますが、他のテーブルでは同じトリックは機能しません。SELECT COUNT(*) from photos;
そしてVACUUM photos;
今では死ぬERROR: MultiXactId 302740528 has not been created yet -- apparent wraparound
-これはすべてのテーブルに出没し、他のエラーはもうポップアップしません。
考え
DBは、(多くので打たなっていたが、おそらく複製)を書き込んDBをやっていたON CONFLICT
句VACUUM
私はそれがとのトラブルを引き起こしているということで残っているものであると信じて、カーネルパニックが発生したときnonexistent MultiXactIds
とinvisible tuple
- データは2年以上にわたってクローラーで収集されましたが、一部を失っても大丈夫です
- 今、バックアップを行います
- テーブル間にトリガーもトリガーもありませんでした
現在のpg_controldataの出力は次のとおりです。
pg_control version number: 942
Catalog version number: 201510051
Database system identifier: 6330224129664261958
Database cluster state: in production
pg_control last modified: Thu 08 Dec 2016 01:06:22 AM EET
Latest checkpoint location: 1562/8F9F8A8
Prior checkpoint location: 1562/8F7F460
Latest checkpoint's REDO location: 1562/8F9F8A8
Latest checkpoint's REDO WAL file: 000000010000156200000008
Latest checkpoint's TimeLineID: 1
Latest checkpoint's PrevTimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0/40781255
Latest checkpoint's NextOID: 67798231
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 615
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 0
Latest checkpoint's oldestMultiXid: 1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:0
Latest checkpoint's newestCommitTsXid:0
Time of latest checkpoint: Thu 08 Dec 2016 01:06:22 AM EET
Fake LSN counter for unlogged rels: 0/1
Minimum recovery ending location: 0/0
Min recovery ending loc's timeline: 0
Backup start location: 0/0
Backup end location: 0/0
End-of-backup record required: no
wal_level setting: minimal
wal_log_hints setting: off
max_connections setting: 100
max_worker_processes setting: 8
max_prepared_xacts setting: 0
max_locks_per_xact setting: 64
track_commit_timestamp setting: off
Maximum data alignment: 8
Database block size: 8192
Blocks per segment of large relation: 131072
WAL block size: 8192
Bytes per WAL segment: 16777216
Maximum length of identifiers: 64
Maximum columns in an index: 32
Maximum size of a TOAST chunk: 1996
Size of a large-object chunk: 2048
Date/time type storage: 64-bit integers
Float4 argument passing: by value
Float8 argument passing: by value
Data page checksum version: 0
更新
- (2016年12月9日)存在しないMultiXactIdsについて読んでいると、クラッシュの時点でデータベースに運用負荷がかかっていなかったことを思い出しましたが、手動
VACUUM
要求を処理していました。ディスクに残っているスペースが3%しかないことに気付いた後、ウェブサーバーとクローラーをオフラインにしました。/var/log
大きなファイルをチェックする必要がありましたが、誤ってPostgreSQLを非難しVACUUM FULL
、デバイスに残されたスペースがわずかであるために中止されたことがわかりました。それで、私は普通のVACUUMを始めて、それを残しました。 - (2016年12月14日)PostgreSQLソースの9.5ブランチをGithubからダウンロードし、heapam.cおよびmultixact.cのブロックをコメント化し、これらのエラーがスローされないことを期待してコンパイルしました。しかし、APTで使用していたものと同じフラグを使用してサーバーを構成する必要があったため、サーバーは起動しませんでした。約47のフラグがあり、それぞれに非自明な名前の依存関係が必要だったため、私はその考えをあきらめました。
(2016年12月16日)関連するページをゼロにすることで、無効なタイムスタンプを持つタプルを削除する方法を見つけました。最初に次のオプションを設定します
psql
:\set FETCH_COUNT 1 \pset pager off
それから私はします
SELECT ctid, * FROM comments;
。そのようにしてctid
、クエリが終了する前に、悪いタプルを吐き出します。その後、そのページをゼロで埋めます。dd if=/dev/zero of=/var/lib/postgresql/9.5/main/base/16385/16443 bs=8K seek=92803 count=1 conv=notrunc
しかし、この方法でゼロにされた各ページは前のページを壊し、結果としてページ16442
に無効なタイムスタンプを持つタプルができます。ここで私が間違っていることはわかりません。(2016年12月16日)
pg_dump -Fc --table photos vw > photos.bak
1.3GB(おそらく800GBのうち)が書き込まれた後、セグメンテーションエラーが発生します。サーバーログは次のとおりです。2016-12-16 18:48:05 EET [19337-2] LOG: server process (PID 29088) was terminated by signal 11: Segmentation fault 2016-12-16 18:48:05 EET [19337-3] DETAIL: Failed process was running: COPY public.photos (id, owner_id, width, height, text, date, link, thumb, album_id, time_found, user_id, lat, long) TO stdout; 2016-12-16 18:48:05 EET [19337-4] LOG: terminating any other active server processes 2016-12-16 18:48:05 EET [19342-2] WARNING: terminating connection because of crash of another server process 2016-12-16 18:48:05 EET [19342-3] DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. 2016-12-16 18:48:05 EET [19342-4] HINT: In a moment you should be able to reconnect to the database and repeat your command. 2016-12-16 18:48:05 EET [19337-5] LOG: all server processes terminated; reinitializing 2016-12-16 18:48:06 EET [29135-1] LOG: database system was interrupted; last known up at 2016-12-14 22:58:59 EET 2016-12-16 18:48:07 EET [29135-2] LOG: database system was not properly shut down; automatic recovery in progress 2016-12-16 18:48:07 EET [29135-3] LOG: invalid record length at 1562/A302F878 2016-12-16 18:48:07 EET [29135-4] LOG: redo is not required 2016-12-16 18:48:07 EET [29135-5] LOG: MultiXact member wraparound protections are now enabled 2016-12-16 18:48:07 EET [19337-6] LOG: database system is ready to accept connections 2016-12-16 18:48:07 EET [29139-1] LOG: autovacuum launcher started
ここに短いスタックトレースがあります:
#0 pglz_decompress (source=source@entry=0x7fbfb6b99b13 "32;00/0ag4d/Jnz\027QI\003Jh3A.jpg", slen=<optimized out>, dest=dest@entry=0x7fbf74a0b044 "", rawsize=926905132) #1 0x00007fc1bf120c12 in toast_decompress_datum (attr=0x7fbfb6b99b0b) #2 0x00007fc1bf423c83 in text_to_cstring (t=0x7fbfb6b99b0b)
私はそれを回避する方法がわかりません。
(2016年12月29日)
SELECT * FROM tablename LIMIT 10000 OFFSET 0
オフセットをインクリメントし、デッドタプルの周りを絞り込むユーティリティを作成しました。タプル以外のローカルマシンでデータを正常に複製しました(唯一のものを願っています)。手動で破損しました。サーバーが再起動する場合も待機することになっています。ただし、RAIDに十分なスペースが残っていなかっslowdisk
たため、8TB HDDにテーブルスペースを作成しました。私がしようとするとCREATE DATABASE vwslow WITH TABLESPACE slowdisk
、エラーが発生しません:2016-12-29 02:34:13 EET [29983-1] LOG: request to flush past end of generated WAL; request 950412DE/114D59, currpos 1562/A3030C70 2016-12-29 02:34:13 EET [29983-2] CONTEXT: writing block 58368001 of relation base/16385/16473 2016-12-29 02:34:13 EET [29983-3] ERROR: xlog flush request 950412DE/114D59 is not satisfied --- flushed only to 1562/A3030C70 2016-12-29 02:34:13 EET [29983-4] CONTEXT: writing block 58368001 of relation base/16385/16473 2016-12-29 02:34:13 EET [30005-44212] postgres@vw ERROR: checkpoint request failed 2016-12-29 02:34:13 EET [30005-44213] postgres@vw HINT: Consult recent messages in the server log for details. 2016-12-29 02:34:13 EET [30005-44214] postgres@vw STATEMENT: CREATE DATABASE vwslow WITH TABLESPACE slowdisk;
手動
CHECKPOINT
でも同じエラーが発生しました。サーバーを再起動すると、チェックポイントエラーがなくなり、ツールを実行できます。私の質問に答え、それが機能する場合、コードを公開します。