当前位置: 首页 > news >正文

在PG或HGDB上启用块校验checksum

**瀚高数据库

目录

环境
文档用途
详细信息**

环境

系统平台:Linux x86-64 Red Hat Enterprise Linux 7
版本:14,N/A

文档用途

用途

使用checksum,对数据库提供块校验,以发现隐藏的块损坏问题,注意仅适用于原生PG或HGDB企业版,或未使用SM4加密的HGDB安全版。

HGDB安全版假如使用了SM4加密,会与checksum冲突导致数据文件损坏。

什么是坏块

坏块通常是指读取或写入的数据文件,由于存储介质故障、突然断电等问题,导致的数据块中存储的信息丢失,或由于没来得及写入完成导致的块断裂,坏块通常会带来数据损坏甚至数据丢失的风险。

checksum

PostgreSQL在9.3版本开始,引入了checksum,使用checksum可以检验数据块的损坏

checksum校验发生在数据页落盘之前和进入sharedbuffer之前。

checksum写入

当将页面从缓冲区缓存写入到操作系统页面缓存(OS Cache)时,就会计算checksum值并写入数据页中。

checksum校验

每次读取该块时,checksum值就会重新计算,并与所存储的checksum值进行比较。这可以检验数据是否损坏。

使用pg_checksums命令的注意事项

pg_checksums 命令:启用、禁用或检查PostgreSQL数据库集簇中的数据校验和(checksum)

在运行pg_checksums之前必须彻底关闭服务器。

验证checksum时:

(1)如果没有校验和错误,则退出状态为零;

(2)如果检测到至少一个checksum校验失败,则退出状态为非零。

(3)启用或禁用checksum时,如果操作失败,退出状态为非零。

验证checksum时,会扫描数据库集簇中的每个文件。

(1)启用校验和时,每个具有已更改校验和的relotion file block都会立刻重写。

(2)禁用checksum只会更新文件pg_control。

额外注意点:

(1)在大型数据库集簇中启用checksum可能需要很长时间。在此操作过程中,不得启动数据库或其他写入数据目录的程序,否则可能会导致数据丢失。

(2)当使用replication或执行关系文件块直接复制的工具(例如pg_rewind)时,如果没有在所有节点上做相同的操作(例如主库打开了checksum,备库没打开),

启用或禁用校验和可能会导致checksum计算错误。

(3)假如流复制环境下,那么建议停止和删除所有备库,在主库上执行启用checksum,最后重做所有备用数据库。

(4)如果在启用或禁用校验和时pg_checksums被中止,集群的数据校验和不会改变,可以通过重新运行pg_checksums来继续打开或关闭checksum。

详细信息

checksum使用示例

1. 检查数据库是否开启checksum

[postgres@centos7 data]$ pg_controldata -D $PGDATA |grep checksumData page checksum version:           0           <--0表示未启用,1表示打开

2. 创建并查询表的物理位置

create  table tab1(a int primary key ,b text);insert into tab1 values (1,'hello postgres');select pg_relation_filepath('tab1');

物理位置如下:

postgres=# select pg_relation_filepath('tab1');pg_relation_filepath ----------------------base/5/16397(1 row)

3. 关闭数据库,启用checksum

[postgres@centos7 data]$ pg_checksums -D $PGDATA --enable --progress22/22 MB (100%) computedChecksum operation completedFiles scanned:   953Blocks scanned:  2816Files written:  786Blocks written: 2816pg_checksums: syncing data directorypg_checksums: updating control fileChecksums enabled in cluster

–enable :-e, --enable 启用data checksums

–progress :-P, --progress 显示进度报告

检查pg_controldata

[postgres@centos7 data]$ pg_controldata -D $PGDATA |grep checksumData page checksum version:           1   <--checksum已经打开

4. 手动制造坏块

先看一下当前块的内容:物理文件是8KB,只有一个块

image.png

[postgres@centos7 5]$ dd bs=8192 count=1 seek=1 of=/data/highgo/data/base/5/16397 if=/data/highgo/data/base/5/163971+0 records in1+0 records out8192 bytes (8.2 kB) copied, 0.000373582 s, 21.9 MB/s

解释:使用seek=1偏移8K,也就是在原来的一个块后再追加一个块,这样假如未开启checksum,实际是能查出2行数据的

image.png

由1个块变成2个块

5. 此时启动数据库,查询该表

发现:

postgres=# select * from tab1;WARNING:  page verification failed, calculated checksum 5783 but expected 5782  <--提示checksum不一致了,事务直接中止ERROR:  invalid page in block 1 of relation base/5/16397

6. 停掉数据库,使用checksum检查数据页的错误

[postgres@centos7 5]$ pg_checksums -D $PGDATA --checkpg_checksums: error: checksum verification failed in file "/data/highgo/data/base/5/16397", block 1: calculated checksum 1697 but block contains 1696Checksum operation completedFiles scanned:   953Blocks scanned:  2817Bad checksums:  1Data checksum version: 1

这里提示的:1696是16进制,转换为10进制,正好是5782,和数据库中的报错相同

7. 关闭checksum,检查发现异常块也可以被读取

[postgres@centos7 5]$ pg_checksums -D $PGDATA --disable --progresspg_checksums: syncing data directorypg_checksums: updating control fileChecksums disabled in cluster
[postgres@centos7 5]$ pg_ctl start[postgres@centos7 5]$ psqlpostgres=# select * from tab1;a |       b        ---+----------------1 | hello postgres1 | hello postgres     <-- 原来只有1行,dd到文件后追加了1个块,导致查出2行了(2 rows)

8. 如何忽略坏块错误?

可以通过:

(1). ignore_checksum_failure:该参数仅在开启checksum下生效,作用就是忽略checksum的报错,读出坏块中的数据,但是假如page header错误,那么也读不出来,事务依旧会中止。

(2). zero_damaged_pages:数据库会在内存中将损坏的page都置为空,然后获取剩下的结果,即使page header损坏,执行事务也不会退出,只会报warning,这个参数,官方文档上说不会写入物理文件,但是实际情况下,还是建议先原样备份后,再打开该参数。

下面进行测试:

重新开启checksum并制造坏块:

pg_ctl stoppg_checksums -D $PGDATA --enable --progressdd bs=8192 count=1 seek=1 of=/data/highgo/data/base/5/16397 if=/data/highgo/data/base/5/16397

发现有坏块了:

[postgres@centos7 5]$ pg_checksums -D $PGDATA --checkpg_checksums: error: checksum verification failed in file "/data/highgo/data/base/5/16397", block 1: calculated checksum 8E26 but block contains 8E27Checksum operation completedFiles scanned:   953Blocks scanned:  2817Bad checksums:  1Data checksum version: 1

8.1 使用ignore_checksum_failure参数忽略checksum

该参数仅当启用checksum时才有效,在读取过程中检测到checksum失败通常会导致PG报告错误,从而中止当前事务。设置ignore_checksum_failure为 on 会导致系统忽略故障(但仍报告警告),并继续处理。此行为可能会导致崩溃、传播或隐藏损坏或其他严重问题。但是,如果page header仍然正常,它可能允许您克服错误并检索可能仍然存在于表中的未损坏的元组。如果page header损坏,即使启用此选项,也会报告错误。默认设置为off。只有超级用户和具有适当SET权限的用户才能更改此设置。
postgres=# show ignore_checksum_failure;ignore_checksum_failure -------------------------off(1 row)postgres=# set ignore_checksum_failure = on;SETpostgres=# select * from tab1;WARNING:  page verification failed, calculated checksum 36390 but expected 36391a |       b        ---+----------------1 | hello postgres1 | hello postgres    <--忽略了checksum的报错,直接读出2个块的数据(2 rows)

8.2 使用参数 zero_damaged_pages忽略坏块

该参数不要求启用checksum,它总会让数据库忽略坏块。

检测到损坏的page header通常会导致PostgreSQL报告错误,从而中止当前事务。设置zero_damaged_pages = on 会导致系统报告警告,将内存中损坏的页面清零,然后继续处理。此行为会破坏数据,即损坏页上的所有行。但是,它确实允许您克服错误并从表中可能存在的任何未损坏的页面中检索行。如果由于硬件或软件错误而发生损坏,它对于恢复数据很有用。通常,在您放弃从表的损坏页恢复数据的希望之前,不应将其设置为打开。清零页不会强制写入磁盘,因此建议在再次关闭此参数之前重新创建表或索引。默认设置为off。只有超级用户和具有适当SET权限的用户才能更改此设置。

该参数是最后的希望,在使用该参数之前,必须要对原始数据进行完整的物理备份。

[postgres@centos7 5]$ pg_ctl restart[postgres@centos7 5]$ psqlpostgres=# show zero_damaged_pages;zero_damaged_pages --------------------off(1 row)postgres=# set zero_damaged_pages=on;SETpostgres=# select * from tab1;WARNING:  page verification failed, calculated checksum 36390 but expected 36391WARNING:  invalid page in block 1 of relation base/5/16397; zeroing out pagea |       b        ---+----------------1 | hello postgres(1 row)

可以看到,该参数会忽略实际损坏的块,而不是像ignore_checksum_failure那样,仅是忽略checksum错误。

注意:使用这两种方式后,应当尽快采用逻辑导出对应表,并重建表后导入。

9.数据库恢复期间遇到坏块怎么办?

还有一个其他的参数,仅在恢复期间使用的

ignore_invalid_pages(boolean)

如果设置为off(默认值),则数据库在恢复期间检测到引用无效page的WAL记录,会导致PostgreSQL引发PANIC级错误,从而中止恢复。设置ignore_invalid_pages为on会导致系统忽略 WAL 记录中的无效页面引用(但仍报告警告),并继续恢复。此行为可能会导致崩溃、数据丢失、传播或隐藏损坏或其他严重问题。但是,它可能允许您克服 PANIC级错误,完成恢复并启动服务器。该参数只能在服务器启动时设置。它仅在recovery或standby模式下有效。

相关文章:

  • 男人的玩具系统wordpress外贸网站主题模板
  • ANTLR4规则解析生成器(三):遍历语法分析树
  • chatgpt与人类有何不同?
  • 【C语言】操作符详解,手把手教你,保姆级!!!
  • 抢占先机,创新出海丨Flat Ads邀您共话AI+未来式工具创新增长!
  • 【机器人最短路径规划问题(栅格地图)】基于模拟退火算法求解
  • IEEE754标准的c语言阐述,以及几个浮点数常量
  • 运行json文件变成api服务器模拟,json-server
  • YOLOv9独家原创改进|加入RT-DETR中的HGBlock!
  • 服务器宝塔是什么意思?
  • 【笔记】Android 漫游定制SPN定制有关字段
  • Spring Mybatis Mapper 模糊查询的几种方法
  • 计算机网络 - 第一章 概述
  • K8S之实现业务的蓝绿部署
  • vue3+element plus 实现百度地图显示路径
  • 3.7、@ResponseBody 和 @RestController
  • Android 架构优化~MVP 架构改造
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Angular数据绑定机制
  • canvas 绘制双线技巧
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • es6(二):字符串的扩展
  • Fundebug计费标准解释:事件数是如何定义的?
  • HTTP 简介
  • jQuery(一)
  • Laravel 菜鸟晋级之路
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • mysql常用命令汇总
  • Netty源码解析1-Buffer
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • ViewService——一种保证客户端与服务端同步的方法
  • Vue 动态创建 component
  • 从重复到重用
  • 工作中总结前端开发流程--vue项目
  • 记一次删除Git记录中的大文件的过程
  • 聊聊flink的BlobWriter
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 我的业余项目总结
  • 一道闭包题引发的思考
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 智能合约开发环境搭建及Hello World合约
  • k8s使用glusterfs实现动态持久化存储
  • MyCAT水平分库
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​configparser --- 配置文件解析器​
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​什么是bug?bug的源头在哪里?
  • (03)光刻——半导体电路的绘制
  • (6)设计一个TimeMap
  • (ZT)一个美国文科博士的YardLife
  • (分布式缓存)Redis持久化
  • (附源码)计算机毕业设计SSM智慧停车系统