無効なタイムスタンプを含むタプルを削除しようとすると
_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が修正したまったく同じエラーメッセージについて説明していますが、OPがそれをどのように実行したのか、何が原因となっていたのかについての説明はありませんこのエラー。
Googleでのヒット数の不足とPostgreSQLの限られた知識のため、私は無力です。
私はPostgreSQL 9.5.5サーバー(〜4TBのデータ、すべてのデフォルト設定、メモリ上限を除いて)をOSカーネルがパニックしたときにDebian 8で実行しました-おそらくスワップが配置されていた/ dev/md1を再構築します。それ以前は、PostgreSQLはディスク容量のほぼすべてを400GBのログファイルで使い果たしていました。 OSが再度起動することはなく、ディスクチェックは問題なかったため、念のため、LiveCDから起動し、各ブロックデバイスをイメージにバックアップしました。/dev/md2から/ディレクトリを正常に再構築し、fsckはクリーンなファイルシステムを示し、PGDATAフォルダーを外部HDDにバックアップしました。
Mdデバイスをフォーマットし、OSを新しいpostgresql-9.5と共に再インストールした後、PostgreSQLサーバーを停止し、PGDATAフォルダーをpostgresユーザーに移動して起動し、サーバーを起動しました。すべて正常に動作し、エラーは発生しませんでした。
_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
_はエラーやメッセージを出さずに仕事をしました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
_で終了するようになりました–これは、他のエラーがポップアップしないすべてのテーブルで発生します。ON CONFLICT
_句を使用した大量の(重複の可能性)書き込みによってDBが打撃を受けていましたVACUUM
を実行していましたが、_nonexistent MultiXactIds
_と_invisible Tuple
_で問題を引き起こしているのはそれが残っていると思います以下は、現時点での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
_
VACUUM
リクエストを処理していました。ディスクに3%しか残っていないことに気付いたので、ウェブサーバーとクローラーをオフラインにしました。大きなファイルがないか_/var/log
_を確認する必要がありましたが、誤ってPostgreSQLを非難し、_VACUUM FULL
_を試しましたが、デバイスの空き容量が少ないため中止されたことがわかりました。だから私は普通のVACUUMを始めて、それをそのままにしました。(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に十分なスペースが残っていないため、8 TBのHDDにテーブルスペースslowdisk
を作成しました。 _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
でも同じエラーが発生しました。
サーバーの再起動により、チェックポイントエラーが解消され、ツールを実行できるようになりました。それが機能する場合、私の質問に答え、コードを公開します。
さて、SELECT
とINSERT INTO
のリカバリプロセスを自動化して、範囲をスキップし、サーバーがクラッシュした場合に待機しました。私は最初にそれをNode-でコード化しました-comments
からの損傷を受けていないデータをリッピングしました、そしてまだ続いています。
昨日Golangを試すことにしました。Goコードのリポジトリがここにあります: https://github.com/kaivi/pg_ripper 更新しますすぐにそれは本当に悪いタプルを回避し、それを含む範囲全体をあきらめるだけではありません。