pg数据库断电出现invalid page

查询表出现报错:
报错信息:ERROR: invalid page in block 7302 of relation “base/13593/11025587”

可能原因:断电时,这个表正在读写,导致损坏

作为一个非专业的数据库操作员,不敢随意乱动,以下是网上搜到的方法,仅做记录使用,对于其他情况不一定适用,数据无价,慎重操作!!!

  • 方案一:查找并删除损坏行

创建扩展:
create extension hstore;
定义函数:

CREATE OR REPLACE FUNCTION
  find_bad_row(tableName TEXT)
  RETURNS tid
  as $find_bad_row$
DECLARE
  result tid;
  curs REFCURSOR;
  row1 RECORD;
  row2 RECORD;
  tabName TEXT;
  count BIGINT := 0;
BEGIN
  SELECT reverse(split_part(reverse($1), '.', 1)) INTO tabName;
  OPEN curs FOR EXECUTE 'SELECT ctid FROM ' || tableName;

  count := 1;
  FETCH curs INTO row1;
  WHILE row1.ctid IS NOT NULL LOOP
    result = row1.ctid;
    count := count + 1;
    FETCH curs INTO row1;
    EXECUTE 'SELECT (each(hstore(' || tabName || '))).* FROM '
         || tableName || ' WHERE ctid = $1' INTO row2
         USING row1.ctid;
    IF count % 100000 = 0 THEN
      RAISE NOTICE 'rows processed: %', count;
    END IF;
  END LOOP;

  CLOSE curs;
  RETURN row1.ctid;
  EXCEPTION
    WHEN OTHERS THEN
      RAISE NOTICE 'LAST CTID: %', result;
      RAISE NOTICE '%: %', SQLSTATE, SQLERRM;
  RETURN result;
END
$find_bad_row$
LANGUAGE plpgsql;

然后查找并删除

delete from t_dev where ctid = (select find_bad_row('t_dev'))

t_dev 是那个坏掉的表

这个方案,如果损坏行很多,这要执行好多次,麻烦,,放弃了

  • 方案二:使用zero_damaged_pages来忽略坏块

set zero_damaged_pages=on

这时查询该表,会自动忽略坏块,可以把正常的数据查出来了。这时可以将该表导出,重新建表,并将正常的数据导入

最后使用该方案。

  • 方案三:使用备份数据恢复,这个前提需要有数据备份。或者用归档日志恢复(高级DBA操作,我不会)

你可能感兴趣的:(数据库,postgresql,数据库)