PostgreSQL的full_page_writes

概念介绍

页断裂

页断裂也可以称为页折断或者半页写。PostgreSQL中,一个page默认为8kb,数据的写入是以page为单位的。而操作系统的一个page往往是4kb或者更小,这将导致PostgreSQL在写一个page到磁盘时,操作系统可能会将PG的一个page,分两次写入到磁盘。 如果系统出现故障,则会出现PG的一个page,操作系统只写了一半到磁盘上,这种现象称之为页折断。

page=8kb
page=4kb
PostgreSQL
OS
Disk

当出现页折断后,页的操作可能只完成了一部分,导致磁盘上的页同时存在新旧数据,这个时候,仅通过wal的数据更改记录,并不足以恢复该页面。

目前市面上的数据库,解决页折断问题,一般有两种方法,一种是full_page_writes,一种是double write。

采用full_page_writes的数据库:

  • PostgreSQL

    采用double write的数据库:

  • openGauss

    • 需结合增量检查点使用;
  • MySQL

full_page_writes

full_page_write是PostgreSQL的GUC参数,如果启用了此参数,在PG执行了checkpoint后,会将Buffer Poll中首次修改的page,整个page连同DML修改语句,都存储到wal日志中。

PostgreSQL官网对其解释如下:
full_page_writes (boolean)
When this parameter is on, the PostgreSQL server writes the entire content of each disk page to WAL during the first modification of that page after a checkpoint. This is needed because a page write that is in process during an operating system crash might be only partially completed, leading to an on-disk page that contains a mix of old and new data. The row-level change data normally stored in WAL will not be enough to completely restore such a page during post-crash recovery. Storing the full page image guarantees that the page can be correctly restored, but at the price of increasing the amount of data that must be written to WAL. (Because WAL replay always starts from a checkpoint, it is sufficient to do this during the first change of each page after a checkpoint. Therefore, one way to reduce the cost of full-page writes is to increase the checkpoint interval parameters.)

Turning this parameter off speeds normal operation, but might lead to either unrecoverable data corruption, or silent data corruption, after a system failure. The risks are similar to turning off fsync, though smaller, and it should be turned off only based on the same circumstances recommended for that parameter.

Turning off this parameter does not affect use of WAL archiving for point-in-time recovery (PITR) (see Section 25.3).

This parameter can only be set in the postgresql.conf file or on the server command line. The default is on.

关键数据结构

XLogRecordBlockImageHeader

记录full-page image的相关信息,该image是否被压缩、在redo过程中,是否应该恢复整个image等信息。

typedef struct XLogRecordBlockImageHeader
{uint16        length;         /* number of page image bytes */uint16        hole_offset;    /* number of bytes before "hole" */uint8        bimg_info;      /* flag bits, see below */
} XLogRecordBlockImageHeader;

其中,bimg_info用于标识image的信息,其有如下取值:

#define BKPIMAGE_HAS_HOLE        0x01        /* page image has "hole" */
#define BKPIMAGE_IS_COMPRESSED        0x02    /* page image is compressed: image是否被压缩 */
#define BKPIMAGE_APPLY        0x04            /* page image should be restored during replay: 重放时,是否需要恢复整个image */

XLogRedoAction

枚举类型,XLogReadBufferForRedo函数的返回值为XLogRedoAction类型;

typedef enum
{BLK_NEEDS_REDO,     /* changes from WAL record need to be applied */BLK_DONE,           /* block is already up-to-date */BLK_RESTORED,       /* block was restored from a full-page image */BLK_NOTFOUND        /* block was not found (and hence does not need to be replayed) */
} XLogRedoAction;

DecodedBkpBlock

记录page相关的信息,该信息从xlog的record中解析出来,在redo该条record时,将根据has_image、apply_image等信息,决定是否恢复整个page;

typedef struct
{/* Is this block ref in use? */bool        in_use;/* Identify the block this refers to */RelFileNode rnode;ForkNumber    forknum;BlockNumber blkno;/* copy of the fork_flags field from the XLogRecordBlockHeader */uint8        flags;/* Information on full-page image, if any */bool        has_image;    /* has image, even for consistency checking */bool        apply_image;  /* has image that should be restored */char       *bkp_image;uint16        hole_offset;uint16        hole_length;uint16        bimg_len;uint8        bimg_info;/* Buffer holding the rmgr-specific data associated with this block */bool        has_data;char       *data;uint16        data_len;uint16        data_bufsz;
} DecodedBkpBlock;

full page的写入和恢复流程

数据块的写出和载入

在PostgreSQL数据库中,用户访问或者修改元组时,数据块的载入和写出的层次结构,如下所示:

读/写元组操作
写出
载入
写出
载入
写出
载入
写出
载入
元组访问
共享缓冲池
存储管理器
磁盘管理器
虚拟文件管理
物理文件

整页写入

当PostgreSQL修改了内存块,调用XlogInsert接口,记录wal日志时,在XlogRecordAssemble函数中,会判断该page是否为checkpoint后的首次修改,如果是首次修改,则将该page存储到wal文件中。

关键代码如下:

static XLogRecData *
XLogRecordAssemble(RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn)
{.../* Determine if this block needs to be backed up */if (regbuf->flags & REGBUF_FORCE_IMAGE)needs_backup = true;else if (regbuf->flags & REGBUF_NO_IMAGE)needs_backup = false;else if (!doPageWrites)needs_backup = false;else{/** We assume page LSN is first data on *every* page that can be* passed to XLogInsert, whether it has the standard page layout* or not.*/XLogRecPtr    page_lsn = PageGetLSN(regbuf->page);    //通过PageGetLSN函数,获取该page的LSNneeds_backup = (page_lsn <= RedoRecPtr);             // 将page的LSN,与上次checkpoint的redo点进行比较,如果该page是首次修改,LSN应该小于等于RedoRecPtrif (!needs_backup){if (*fpw_lsn == InvalidXLogRecPtr || page_lsn < *fpw_lsn)*fpw_lsn = page_lsn;}}...
}
首次修改
非首次修改
PostgreSQL修改了Buffer-Pool中的page
调用XlogInsert记录wal日志
调用XlogRecordAssemble组装record
判断该page是否为checkpoint后的首次修改?
记录整个page到wal文件中
仅记录修改该page的DML语句

整页恢复

从record中,解析出has_image、apply_image:

  1. 当PostgreSQL数据库异常关闭后,再重新启动PG,startup进程进入到故障恢复流程;
  2. 根据pg_control记录的checkpoint信息,结合xlog日志,获取redo点;
  3. 循环从redo点读取wal记录;
  4. 解析wal记录中,获取DecodedBkpBlock结构;
  5. 根据DecodedBkpBlock中的has_image、apply_image等参数,决定是否从WAL中读取image,恢复数据,使PostgreSQL重新达到数据一致性。

rmgr根据资源类型,调用不同的redo函数,重做wal日志:

  • 在redo的时候,资源管理器会根据资源的类型,调用该资源对应的redo函数进行重做;
  • 下面的流程,仅选取heap_redo做流程分析。
StartupXLOG
读取并解析wal日志
ReadRecord
XlogReadRecord
DecodeXLogRecord
从record中解析出has_image\apply_image等
重做读取的wal日志
rm_redo
xlog_redo
xact_redo
smgr_redo
relmap_redo
standby_redo
heap2_redo
heap_redo
btree_redo
hash_redo
gin_redo
gist_redo
...
heap_log_insert
XLogReadBufferForRedo
XLogReadBufferForRedoExtended
XlogRecBlockImageApply
XlogRecHasBlockImage
RestoreBlockImage

部分函数功能说明:

  bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg)功能:从record中,解析出has_image、apply_image等信息;bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)功能:从record中,解析出full-page image;#define XLogRecHasBlockImage(decoder, block_id) \    ((decoder)->blocks[block_id].has_image)功能:判断是否存储了image;#define XLogRecBlockImageApply(decoder, block_id) \    ((decoder)->blocks[block_id].apply_image)功能:判断是否需要重放该image;

小结

  • linux下,可使用getconf PAGE_SIZE指令,查看系统的块大小;
  • PostgreSQL的块大小,在编译pg时,可以通过–with-blocksize 参数修改;
  • 启用full_page_writes参数,必然带来性能的损耗,是否启用full_page_writes,需要看存储设备是否能避免半页写的问题,以及是否有其他手段恢复坏块等;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/645986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51-15 视频理解串讲—TimeSformer论文精读

今天读的论文题目是Is Space-Time Attention All You Need for Video Understanding? Facebook AI提出了一种称为TimeSformer视频理解的新架构&#xff0c;这个架构完全基于transformer&#xff0c;不使用卷积层。它通过分别对视频的时间和空间维度应用自注意力机制&#xff…

《动手学深度学习(PyTorch版)》笔记3.1

Chapter3 Linear Neural Networks 3.1 Linear Regression 3.1.1 Basic Concepts 我们通常使用 n n n来表示数据集中的样本数。对索引为 i i i的样本&#xff0c;其输入表示为 x ( i ) [ x 1 ( i ) , x 2 ( i ) , . . . , x n ( i ) ] ⊤ \mathbf{x}^{(i)} [x_1^{(i)}, x_2…

【机器学习】强化学习(七)-策略梯度算法-REINFORCE 训练月球着陆器代理(智能体)...

概 述 月球着陆器代理是一个模拟飞行器在月球表面着陆的环境&#xff0c;它有八个连续的状态变量&#xff0c;分别是水平坐标、垂直坐标、水平速度、垂直速度、角度、角速度、腿1触地、腿2触地。它有四个离散的动作&#xff0c;分别是什么都不做、发动左方向引擎、发动主引擎、…

gin如何实现热更新

什么是热更新&#xff1f; 一种不需要用户关闭应用或重新启动设备就能进行的软件更新技术。它可以快速地在线修复或升级应用程序的错误或功能&#xff0c;从而减少用户的等待时间并提高用户体验。 如何优雅停止服务&#xff1f; Go 1.8版本之后&#xff0c; http.Server 内置…

ZigBee学习——浅析协议栈

✨记录学习过程 文章目录 一、初识OSAL1.1 Z-Stack和Zigbee的OSAL是什么关系&#xff1f;1.2 OSAL可以解决Z-stack在不同厂商的芯片上的使用吗&#xff1f; 二、协议栈运行机制2.1 初始化涉及内容2.2 初始化过程 一、初识OSAL OSAL&#xff0c;全称是操作系统抽象层&#xff0…

【送书活动八期】docker容器中登陆并操作postgresql

这里的背景比较简单&#xff0c;因为区块链浏览器使用的是blockscout&#xff0c;blockscout的数据库选择的是postgresql&#xff0c;这些服务组件都是使用的docker容器来管理&#xff0c;今天进行区块链上交易查询的时候&#xff0c;发现数据存在部分问题&#xff0c;因此需要…

《WebKit 技术内幕》学习之十(4): 插件与JavaScript扩展

4 Chromium扩展机制 4.1 原理 Chromium的扩展&#xff08;Extension&#xff09;机制 (1) 原先是Chromium推出的一项技术&#xff0c;该机制能够扩展浏览器的能力&#xff0c;例如笔者使用的一个扩展实例名为“switchy proxy”&#xff0c;它可以帮助用户方便的切换Chromium…

Kotlin for loop: in、 until、 step、 downTo

Kotlin for loop: in、 until、 step、 downTo fun loop1() {for (i in 0..5) {print("$i ")}println("\n1-end\n") }fun loop2() {for (i in 0 until 5) {print("$i ")}println("\n2-end\n") }fun loop3() {for (i in 0 until (5)) {…

提高塑料制品的塑料透光率测量仪

塑料透光率检测仪是一种用于测量塑料材料透光率的仪器。透光率是指光线通过材料后&#xff0c;被吸收、反射和散射的量与总光线量的比例。塑料透光率检测仪在塑料制品的研发、生产和质量控制等方面具有广泛的应用。 塑料透光率检测仪的原理是使用光束通过待测塑料样品&#xff…

【神奇代码岛】VOXA新岛畅玩指南

前言 最近神奇代码岛不是迎来了重大更新嘛&#xff0c;有可能有很多人还不知道新版的神岛有什么重大更新&#xff0c;我现在来一一说明 重大更新 这一次我们将以代码、地图编辑器、建模编辑器来说明 代码 主要是增加了许多API&#xff0c;比如UI、玩家皮肤等许多新的API …

【推荐100个unity插件之16】3D物品描边效果——Quick Outline免费插件

文章目录 前言地址介绍使用例子完结 前言 关于3D描边&#xff0c;其实之前有用shader弄过一个&#xff1a;【实现100个unity特效】shader实现3D物品闪光和描边效果 但是很遗憾的是他不支持URP项目&#xff0c;所以现在推荐这款插件&#xff0c;他能很好的支持URP&#xff0c;…

Pycharm终端显示PS而不显示虚拟环境venv

PS表示当前使用的是powershell.exe&#xff0c;如果你要显示虚拟环境名&#xff0c;则要改为cmd.exe 解决办法&#xff1a; 打开File-settings-Tools-Terminal-shell path 在文件中找到设置&#xff0c;在工具中找到终端 把第四个Shell路径设置为cmd.exe 3. 点击确定&#xf…

springCloud的ribbon和feign

ribbon方式调用 就是将原来的具体地址&#xff0c;改为了通过服务名去调用。注册中心中有多个服务&#xff0c;相同服务名&#xff0c;就会算作可以调用的服务。 首先得有一个注册中心&#xff0c;然后各种服务注册进去&#xff0c;然后利用ribbon或者feign去调用。 ribbon是直…

map地图

地图想必大家都很熟悉&#xff0c;地图的应用非常广泛&#xff0c;我们出远门通常都会用到&#xff0c;下面我来给大家讲解一下地图&#xff01; 首先我们要知道该怎样下载地图&#xff1f; 1.地图的版本有很多&#xff0c;我们选择一款&#xff0c;前往地图开发者中心。 2.…

《机器学习》客户流失判断-python实现

客户流失判断 题目赛题描述数据说明赛题来源-DataCastle 问题描述解题思路Python实现读取数据并初步了解导入宏包读取数据查看数据类型检查缺失值描述性统计分析 可视化分析用户流失分析特征分析任期年数与客户流失的关系&#xff1a;服务类属性分析特征相关性分析 数据预处理类…

༺༽༾ཊ—Unity之-01-单例模式—ཏ༿༼༻

在游戏开发过程中&#xff0c;我们会创建各种各样的类&#xff0c;再用new生成实例&#xff0c;有些时候我们需要这个类在整个游戏中是唯一出现的&#xff0c;比如一些管理器比如声音管理器等&#xff0c;没必要创建很多实例&#xff0c;就算有很多模块需要各种声音功能&#x…

信号量机制解决经典同步互斥问题

生产者 / 消费者问题、读者 / 写者问题和哲学家问题是操作系统的三大经典同步互斥问题。本文将介绍这三个问题的基本特点以及如何用信号量机制进行解决。 在分析这三个问题之前&#xff0c;我们首先需要了解用信号量机制解决同步互斥问题的一般规律&#xff1a; 实现同步与互斥…

制造领域 物料清单(BOM)与零件明细表的区别

有许多人分不清物料清单(BOM)与零件明细表的区别,其实它们在企业的生产管理软件中起着不同的作用,各有各的特色,但是却有不尽相同。接下来我们就来区分一下吧 物料清单(BOM)&#xff0c;是详细记录一个项目所用到的所有下阶材料及相关属性&#xff0c;亦即母件与所有子件的从属…

求职应聘找工作,你一定会遇到的人才测评

信息时代&#xff0c;越来越多的公司在招聘时引入了人才测评机制。企业和单位希望通过人才测评在广大的应聘者中&#xff0c;找到符合自己要求的人才。虽然很多应聘者能力和简历都比较出众&#xff0c;但却在最开始的人才测评中吃了亏。有的公司很看重人才测评结果。测评就相当…

76.Go分布式ID总览

文章目录 简介一&#xff1a;UUID二、雪花算法三&#xff1a;Leaf-snowflake四&#xff1a;数据库自增ID五&#xff1a;使用Redis实现分布式ID生成六&#xff1a;使用数据库分段&#xff08;Leaf-segment&#xff09;七 &#xff1a;增强版Leaf-segment八&#xff1a;Tinyid九&…