我正在使用Postgres 9.4.5,但在其中一张表中检测到损坏。在特定表上运行查询时,我注意到了这一点,导致整个数据库进入恢复模式。症状与本文中发现的症状一致:
https://www.endpoint.com/blog/2010/06/01/tracking-down-database-corruption-with
我尝试按照以下步骤将损坏的块清零,但按照以下步骤操作,我的ctid为507578。
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目录并找到表的相应文件时,该文件仅为1073741824字节。在块大小为8192字节的情况下,这仅使我获得了131072的块计数,位于507578值之下(假定的损坏所在)。这是确定块偏移量的正确方法还是其他方法?
PostgreSQL将表数据存储在大小为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
扩展名。