查询表出现报错:
报错信息: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操作,我不会)