作者简介

王睿操,平安好医数据库架构岗,多年postgresql数据库运维开发工作。曾就职于中国民航信息,迪卡侬。对其他数据库产品也有一定的涉猎。

背景

笔者最近发现很多朋友经常遇到PostgreSQL坏块或者数据混乱的情况,网上中文资料比较少,于是整理了一下笔者遇到各种各样的报错以及解决方案

案例一:物理坏块

逻辑备份时报错

pg_dump: Dumping the contents of table "xxxx" failed: PQgetResult() failed.
pg_dump: Error message from server: ERROR: invalid memory alloc request size 18446744073709551613
pg_dump: The command was: COPY xxxxxx (id, active_flag, bkd, blk, go_show, grs, lss, lsv, lt, no_show, value, wl, inv_seg_cabin_id, ind) TO stdout;
pg_dump: [parallel archiver] a worker process died unexpectedly

原因:数据库产生坏行(可能是硬件损坏,可能是一个bug(piece of memory gets overwritten by random data pg9.2之前版本),也有可能是不正确的硬件配置)

首先笔者考虑了pg自带参数zero_damaged_pages,将这个参数修改为true,但发现仍然是报错,看了下官方文档,这种方法不会对物理文件作修改,只是把内存上,损坏页面的缓存变为0。如果这个方法解决了报错,请将这表备份出来重新恢复,或者select到另一张表。

解决方式:删除损坏行

create extension hstore;(过程省略)

1、定义函数

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;

2、通过函数查找问题行

js1=# select find_bad_row('public.description');
NOTICE: LAST CTID: (78497,6)
NOTICE: XX000: invalid memory alloc request size 18446744073709551613
find_bad_row
--------------
(78497,6)
(1 row) js1=# select * from xxxxxxx where ctid = '(78498,1)';
ERROR: invalid memory alloc request size 18446744073709551613
js1=# delete from xxxxxx where ctid = '(78498,1)';

在我们这里需要对xxxx表格进行处理

3、然后再执行pg_dump命令

详细分析可见:https://www.postgresql.org/message-id/54889986.3000308%40gmail.com

案例二:pgclog因断电文件损坏

pg_clog损坏

报错信息:Could not read from file ""pg_clog/0646"" at offset 243287

服务器异常断电,这台因为是测试库,所以没备份以及备库(所以对于dba来说备份就是生命啊,不管是测试库还是生产库一定要做好备份)

  1. 对数据库进行全库物理备份(为之后操作做保险)
  2. 用dd进行伪造这个数据块(数据块伪造全部提交),并且更改权限
for i in {1..262144}; do printf '\125'; done > committed
ls -l committed
od -xv committed | head
od -xv committed | tail $ ls -l committed
-rw-r--r-- 1 root root 262144 2009-06-25 11:01 committed $ od -xv committed | head
0000000 5555 5555 5555 5555 5555 5555 5555 5555
0000020 5555 5555 5555 5555 5555 5555 5555 5555
0000040 5555 5555 5555 5555 5555 5555 5555 5555
0000060 5555 5555 5555 5555 5555 5555 5555 5555
0000100 5555 5555 5555 5555 5555 5555 5555 5555
0000120 5555 5555 5555 5555 5555 5555 5555 5555
0000140 5555 5555 5555 5555 5555 5555 5555 5555
0000160 5555 5555 5555 5555 5555 5555 5555 5555
0000200 5555 5555 5555 5555 5555 5555 5555 5555
0000220 5555 5555 5555 5555 5555 5555 5555 5555
$ od -xv committed | tail
0777560 5555 5555 5555 5555 5555 5555 5555 5555
0777600 5555 5555 5555 5555 5555 5555 5555 5555
0777620 5555 5555 5555 5555 5555 5555 5555 5555
0777640 5555 5555 5555 5555 5555 5555 5555 5555
0777660 5555 5555 5555 5555 5555 5555 5555 5555
0777700 5555 5555 5555 5555 5555 5555 5555 5555
0777720 5555 5555 5555 5555 5555 5555 5555 5555
0777740 5555 5555 5555 5555 5555 5555 5555 5555
0777760 5555 5555 5555 5555 5555 5555 5555 5555
1000000 chown postgres.postgres committed
chmod 600 committed
mv -i committed $PGDATA/pg_clog/0646

注意这个只能解决这个问题,不可以修复底层文件的损坏,所以如果有备份还是备份还原比较好。

案例三:toast表损坏

missing chunk number x for toast value x in pg_toast_x

某张表关联的toast表发现数据损坏

解决方案引自:http://m.2cto.com/database/201802/720718.html

1、定位是哪张表的toast有问题:

select 2619::regclass;
regclass
--------------
pg_statistic

2、找到哪个表有问题后,先对该表做一下简单的修复

REINDEX table pg_toast.pg_toast_2619;
REINDEX table pg_statistic;
VACUUM ANALYZE pg_statistic;

3、定位该表中损坏的数据行。执行

DO $$
declare
v_rec record;
BEGIN
for v_rec in SELECT * FROM pg_statistic loop
raise notice ‘Parameter is:‘, v_rec.ctid;
raise notice ‘Parameter is:’, v_rec;
end loop;
END;
$$
LANGUAGE plpgsql;

4、将第3步中定位的记录删除:

delete from pg_statistic where ctid ='(50,3)';

5、重复执行第3,4步,直到全部有问题的记录被清除。

6、至此,toast问题就解决完了,解决之后,对数据库进行一次完整的维护或者索引重建。

其实一般来说,数据库会根据归档或者wal去自行将postgres中未提交事务进行回滚操作,笔者这个环境当时是因为缺失了归档,所以只能手动将混乱数据进行删除。

最后,笔者想说,很多情况下都是因为没有一个靠谱的备份而导致很多问题,所以建议大家不管什么情况,备份为先,检查备份很重要!

转载自:

http://blog.sina.com.cn/s/blog_67d069a90102vibc.html

PostgreSQL物理坏块和文件损坏案例分享的更多相关文章

  1. 12 oracle 数据库坏块--物理坏块-ORA-01578/ORA-01110

    oracle 数据库坏块--物理坏块 数据坏块的类型物理坏块:通常是由于硬件损坏如磁盘异常导致.内存有问题.存储链有问题. IO有问题.文件系统有问题. Oracle本身的问题等逻辑坏块:可能都是软件 ...

  2. PostgreSQL 索引坏块处理

    今天应用反应有张表查询报错,报错信息如下 back=# select max(create_time) from public.tbl_index_table where create_time> ...

  3. 对Oracle数据库坏块的理解

    1.物理坏块和逻辑坏块 在数据库中有一个概念叫做数据块的一致性,Oracle的数据块的一致性包括了两个层次:物理一致性和逻辑一致性,如果一个数据块在这两个层次上存在不一致性,那就对应到了我们今天要要说 ...

  4. Oracle corrupt block(坏块) 详解

    转自:http://blog.csdn.net/tianlesoftware/article/details/5024966 一. 坏块说明 1.1 相关链接 在看坏块之前,先看几个相关的链接,在后面 ...

  5. Oracle 处理坏块

    本文主要介绍如何去处理在Oracle数据库中出现坏块的问题,对于坏块产生在不同的对象上,处理的方法会有所不同,本文将大致对这些方法做一些介绍.因为数据库运行时间长了,由于硬件设备的老化,出现坏块的几率 ...

  6. 【转载】 使用rman进行坏块修复(ORA-01578、ORA-01110)

    [转自]http://blog.itpub.net/21256317/viewspace-1062055/ 使用rman进行坏块修复(ORA-01578.ORA-01110) 2012年的一天,处理的 ...

  7. HDFS源码分析数据块汇报之损坏数据块检测checkReplicaCorrupt()

    无论是第一次,还是之后的每次数据块汇报,名字名字节点都会对汇报上来的数据块进行检测,看看其是否为损坏的数据块.那么,损坏数据块是如何被检测的呢?本文,我们将研究下损坏数据块检测的checkReplic ...

  8. 13 oracle数据库坏块-逻辑坏块(模拟/修复)

    13 oracle数据库坏块-逻辑坏块 逻辑数据坏块的场景1)oracle bug也可能导致逻辑坏块的产生. 特别是parallel dml. 例如:Bug 5621677 Logical corru ...

  9. Oracle current redo.log出现坏块后的不完全恢复案例一则

    1异常出现      8月30日下午2时左右,接同事电话,说数据库异常宕机了,现在启动不了. 2初步分析 我让现场把alert.log发过来,先看看是什么问题.   关于ORA-00353和ORA-0 ...

随机推荐

  1. mysql实践一:SQL基础

    mysql简介 mysql是有名的开放源代码关系型数据库.它最早是AB公司开源的,后来到Sun公司手中.之后Sun公司被Oracle公司收购,mysql就归Oracle所有.从此mysql走向商业化, ...

  2. egit报错:cannot open git-upload-pack

    第一次通过eclipse导入github 项目,按照百度步骤进行操作,发现不能连接 github,cannot open git-upload-pack. 报错原因通过 eclipse 日志排查报错 ...

  3. Ubuntu /etc/security/limits.conf 不生效问题

    一.问题描述 修改 /etc/security/limits.conf ,重启之后不生效 内容如下: * soft nofile * hard nofile root soft nofile root ...

  4. db跟随集群自启动

    AME=ora.newora920.db TYPE=ora.database.type ACL=owner:oracle:rwx,pgrp:oinstall:r--,other::r--,group: ...

  5. (转)项目迁移_.NET项目迁移到.NET Core操作指南

    原文地址:https://www.cnblogs.com/heyuquan/p/dotnet-migration-to-dotnetcore.html 这篇文章,汇集了大量优秀作者写的关于" ...

  6. 【阿里云开发】- 搭建和卸载svn服务器

    Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据. 这些数据放置在一个中央资料档案库(repository) 中.这个档案库很像一个普 ...

  7. border-radius圆角属性

    border-radius圆角 当盒子的宽高一样时,设置盒子的border-radius为50%,得到一个圆形 border-radius: 20px 30px 200px 200px; 只写一个值: ...

  8. Referer和空Referer

    参考CSDN 原文:https://blog.csdn.net/hxl188/article/details/38964743 Referer和空Referer 最近公司有个接口需要针对几个域名加白名 ...

  9. 分享linux系统more基本命令python源码

    此python源码是linux系统more基本命令的实现. 实现linux中more的基本功能,当more后加一个文件名参数时候,分屏显示按空格换页,按回车换行',在左下角显示百分比; 以处理管道参数 ...

  10. vs code 调试设置

    首先vs code 安装插件:Debugger for Chrome vscode 设置:点击调试按钮,然后调试面板界面再点击设置按钮,添加一个配置,选择环境为:chrome编辑器自动生成一个laun ...