写点什么

PostgreSQL 物理坏块和文件损坏案例分享

  • 2019-08-29
  • 本文字数:2649 字

    阅读完需:约 9 分钟

PostgreSQL 物理坏块和文件损坏案例分享

本文经授权转载自 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 18446744073709551613pg_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 FUNCTIONfind_bad_row(tableName TEXT)RETURNS tidas $find_bad_row$DECLAREresult tid;curs REFCURSOR;row1 RECORD;row2 RECORD;tabName TEXT;count BIGINT := 0;BEGINSELECT 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 LOOPresult = row1.ctid;count := count + 1;FETCH curs INTO row1; EXECUTE 'SELECT (each(hstore(' || tabName || '))).* FROM '|| tableName || ' WHERE ctid = $1' INTO row2USING row1.ctid;IF count % 100000 = 0 THENRAISE NOTICE 'rows processed: %', count;END IF;END LOOP;CLOSE curs;RETURN row1.ctid;EXCEPTIONWHEN OTHERS THENRAISE 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 18446744073709551613find_bad_row--------------(78497,6)(1 row)
js1=# select * from xxxxxxx where ctid = '(78498,1)';ERROR: invalid memory alloc request size 18446744073709551613js1=# 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 > committedls -l committedod -xv committed | headod -xv committed | tail
$ ls -l committed-rw-r--r-- 1 root root 262144 2009-06-25 11:01 committed
$ od -xv committed | head0000000 5555 5555 5555 5555 5555 5555 5555 55550000020 5555 5555 5555 5555 5555 5555 5555 55550000040 5555 5555 5555 5555 5555 5555 5555 55550000060 5555 5555 5555 5555 5555 5555 5555 55550000100 5555 5555 5555 5555 5555 5555 5555 55550000120 5555 5555 5555 5555 5555 5555 5555 55550000140 5555 5555 5555 5555 5555 5555 5555 55550000160 5555 5555 5555 5555 5555 5555 5555 55550000200 5555 5555 5555 5555 5555 5555 5555 55550000220 5555 5555 5555 5555 5555 5555 5555 5555$ od -xv committed | tail0777560 5555 5555 5555 5555 5555 5555 5555 55550777600 5555 5555 5555 5555 5555 5555 5555 55550777620 5555 5555 5555 5555 5555 5555 5555 55550777640 5555 5555 5555 5555 5555 5555 5555 55550777660 5555 5555 5555 5555 5555 5555 5555 55550777700 5555 5555 5555 5555 5555 5555 5555 55550777720 5555 5555 5555 5555 5555 5555 5555 55550777740 5555 5555 5555 5555 5555 5555 5555 55550777760 5555 5555 5555 5555 5555 5555 5555 55551000000
chown postgres.postgres committedchmod 600 committedmv -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 $$declarev_rec record;BEGINfor v_rec in SELECT * FROM pg_statistic loopraise 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 中未提交事务进行回滚操作,笔者这个环境当时是因为缺失了归档,所以只能手动将混乱数据进行删除。


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


作者介绍:


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


原文链接:


https://mp.weixin.qq.com/s/mBLxAfVT6_cDOAOD8J0_aw


2019-08-29 09:265610

评论

发布
暂无评论
发现更多内容

ABAP和Java的destination和JNDI

汪子熙

SAP JNDI hana 11月日更

MySQL Operator 01 | 架构设计概览

RadonDB

MySQL 数据库 Kubernetes RadonDB

浪潮云说丨GPU云服务器,助力AI计划轻松实现

云计算

个人项目管理软件解决方案

低代码小观

项目管理 管理系统 企业管理系统 项目管理工具 企业管理工具

共筑数据库未来 | 2021 OceanBase 原生分布式数据库论坛回顾

OceanBase 数据库

开源 分布式 #数据库 云栖大会 圆桌论坛

300行ABAP代码实现一个最简单的区块链原型

汪子熙

区块链 SAP abap 11月日更

Cube 技术解读 | 详解「支付宝」全新的卡片技术栈

蚂蚁集团移动开发平台 mPaaS

大前端 支付宝 移动开发 mPaaS cube

京东三面(后端)凭借这份Java面试复盘手册,已斩获60K*15offer

Java spring 程序员 算法 JVM

Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞

CODING DevOps

Linux Nocalhost Meetup CDF

加速拥抱支持开源生态 | OceanBase 开源版3.1.1正式发布

OceanBase 数据库

数据库 开源 开发者 成绩单 DTCC

OceanBase 3.2 正式发布 | 更硬核的 HTAP,TPC-H 性能提升6倍!

OceanBase 数据库

数据库 分布式 云栖大会 核心系统 一体化架构

融合通信技术趋势和演进方向

网易云信

云通信 通信云 传输协议

解决大数据分布式计算痛点:腾讯正式开源分布式远程Shuffle服务Firestorm

科技热闻

杨冰:OceanBase助力数字化转型,原生分布式数据库成核心系统首选

OceanBase 数据库

数据库 开源 分布式 云栖大会 核心系统

互联网+质量基础设施服务平台,NQI一站式服务平台搭建

电微13828808271

长隆熊猫酒店联合番禺消防大队开展“我是小小消防员”活动

江湖老铁

阿里云云合计划走进深圳,实践助推生态持续创新

技术 科技革命 生态 “互联网+”

OpenMLDB v0.3.0 正式发布,支持快速部署使用的单机模式

第四范式开发者社区

开源 第四范式 OpenMLDB

Python代码阅读(第55篇):获取字典的所有键或所有值的列表

Felix

Python 编程 阅读代码 字典 Python初学者

出自清华大牛之手的Redis源码核心手册,已被列为GitHub首推书籍

Java redis 编程 程序员

测试编排必要性

FunTester

敏捷 测试 敏捷测试 FunTester 测试编排

使用 OpenCV 和 Python 识别数字

AI浩

OCR

如何巧妙使用Camtasia库中的素材?

淋雨

Camtasia

“初雪”与“向量化” | StarRocks Hacker Meetup 小记

StarRocks

数据库 大数据

新赛季集结!“百度AI创意派”正在寻找有创意的你

科技热闻

“你好,天津”网络短视频大赛月内启动

InfoQ 天津

腾讯大数据全场景在离线混部系统Caelus正式开源

科技热闻

git submodule 添加/删除

webrtc developer

OceanBase 创始人阳振坤 | 十余年打磨 国产数据库之路砥砺前行

OceanBase 数据库

数据库 开发者 趋势 1024 CSDN

如何用WebIDE打开并运行CRM Fiori应用

汪子熙

Cloud SAP 11月日更

SAP x EMQ 碳中和方案亮相进博会,数据基础设施支撑低碳发展

EMQ映云科技

物联网 IoT mqtt 进博会 SAP

PostgreSQL 物理坏块和文件损坏案例分享_数据库_王睿操_InfoQ精选文章