Postgres ctid 阻止计数不匹配
Postgres ctid to block count mismatch
我正在使用 Postgres 9.4.5,我在我的 table 之一中检测到损坏。当 运行 对特定 table 的查询导致整个数据库进入恢复模式时,我注意到了这一点。这些症状与本文中发现的症状一致:
https://www.endpoint.com/blog/2010/06/01/tracking-down-database-corruption-with
我尝试按照步骤将损坏的块清零,但在按照这些步骤操作后,我得到了 507578 的 ctid。
database=# \set FETCH_COUNT 1
database=# \pset pager off
Pager usage is off.
database=# SELECT ctid, left(coded_element_key::text, 20) FROM coded_element WHERE ctid >= '(507577,1)';
ctid | left
------------+----------
(507577,1) | 30010491
(507577,2) | 30010507
(507577,3) | 30010552
(507577,4) | 30010556
(507577,5) | 30010559
(507577,6) | 30010564
(507577,7) | 30010565
(507577,8) | 30010625
...
...
...
(507578,26) | 0A1717281.0002L270&.
(507578,27) | L270&.*)0000.0000000
(507578,28) | 30011452
(507578,29) | -L0092917\x10)*(0117001
(507578,30) | 0.00003840\x10)*)300114
ERROR: invalid memory alloc request size 1908473862
问题是当我进入我的 /data/base 目录并为我的 table 找到相应的文件时,该文件只有 1073741824 字节。对于 8192 字节的块大小,这只会给我 131072 的块计数,远低于假定损坏所在的 507578 值。这是确定块偏移的正确方法还是有不同的方法?
PostgreSQL 将 table 数据存储在 1GB 大小的文件中。
假设
的结果
SELECT relfilenode
FROM pg_class
WHERE relname = 'coded_element';
是 12345,这些文件将被称为 12345
、12345.1
、12345.2
等等。
由于每个1GB的段包含131072个块,所以块507578实际上是12345.4
中的块114362。
数据损坏要么在那个块中,要么在下一个块中。
此时,请确保您备份了完整的数据目录。
要将块 507578 归零,您可以使用
dd if=/dev/zero of=12345.4 bs=8192 seek=114362 count=1 conv=notrunc,nocreat,fsync
如果还是不行,试试下一个方块。
要在清零之前从块中抢救数据,您可以使用 pageinspect
扩展。
我正在使用 Postgres 9.4.5,我在我的 table 之一中检测到损坏。当 运行 对特定 table 的查询导致整个数据库进入恢复模式时,我注意到了这一点。这些症状与本文中发现的症状一致:
https://www.endpoint.com/blog/2010/06/01/tracking-down-database-corruption-with
我尝试按照步骤将损坏的块清零,但在按照这些步骤操作后,我得到了 507578 的 ctid。
database=# \set FETCH_COUNT 1
database=# \pset pager off
Pager usage is off.
database=# SELECT ctid, left(coded_element_key::text, 20) FROM coded_element WHERE ctid >= '(507577,1)';
ctid | left
------------+----------
(507577,1) | 30010491
(507577,2) | 30010507
(507577,3) | 30010552
(507577,4) | 30010556
(507577,5) | 30010559
(507577,6) | 30010564
(507577,7) | 30010565
(507577,8) | 30010625
...
...
...
(507578,26) | 0A1717281.0002L270&.
(507578,27) | L270&.*)0000.0000000
(507578,28) | 30011452
(507578,29) | -L0092917\x10)*(0117001
(507578,30) | 0.00003840\x10)*)300114
ERROR: invalid memory alloc request size 1908473862
问题是当我进入我的 /data/base 目录并为我的 table 找到相应的文件时,该文件只有 1073741824 字节。对于 8192 字节的块大小,这只会给我 131072 的块计数,远低于假定损坏所在的 507578 值。这是确定块偏移的正确方法还是有不同的方法?
PostgreSQL 将 table 数据存储在 1GB 大小的文件中。
假设
的结果SELECT relfilenode
FROM pg_class
WHERE relname = 'coded_element';
是 12345,这些文件将被称为 12345
、12345.1
、12345.2
等等。
由于每个1GB的段包含131072个块,所以块507578实际上是12345.4
中的块114362。
数据损坏要么在那个块中,要么在下一个块中。
此时,请确保您备份了完整的数据目录。
要将块 507578 归零,您可以使用
dd if=/dev/zero of=12345.4 bs=8192 seek=114362 count=1 conv=notrunc,nocreat,fsync
如果还是不行,试试下一个方块。
要在清零之前从块中抢救数据,您可以使用 pageinspect
扩展。