pg运维之checkpoint

news/2024/7/9 23:06:09 标签: 运维, postgresql

How PostgreSQL writes data

在我们更详细地讨论检查点之前,了解PostgreSQL如何写数据是很重要的。让我们看一下下面的图片。
在这里插入图片描述

最重要的是,我们必须假设崩溃可能在任何时候发生。为什么会有这样的关系?嗯,我们要确保你的数据库永远不会被破坏。其后果是,我们不能直接向数据文件写数据。这是为什么呢?假设我们想写 "1234 "到数据文件。如果我们在 "12 "之后崩溃了怎么办?其结果将是在表的某个地方出现断裂的行。也许索引项会丢失,等等–我们必须不惜一切代价来防止这种情况。

因此,有必要采用更复杂的方式来写入数据。它是如何工作的呢?PostgreSQL做的第一件事就是把数据发送到WAL(=Write Ahead Log)。WAL就像一个偏执的顺序磁带,包含二进制变化。如果增加了一行,WAL可能包含一条记录,表明数据文件中的一行必须被改变,它可能包含几条指令来改变索引条目,也许需要写一个额外的块,等等。它只是包含一个变化的流。

一旦数据被发送到WAL,PostgreSQL将对共享缓冲区中的块的缓存版本进行修改。注意,数据仍然不在数据文件中。我们现在有了WAL条目以及对共享缓冲区的修改。如果一个读取请求进来,它无论如何也不会进入数据文件–因为数据是在缓冲区中找到的。

在某些时候,这些修改过的内存页面会被后台写程序写入磁盘。这里重要的是,数据可能会被写错顺序,这没有问题。请记住,如果用户想读取数据,PostgreSQL会在向操作系统索取数据块之前检查共享缓冲区。因此,脏块的写入顺序并不那么相关。甚至晚一点写数据也是有意义的,这样可以增加在一次I/O请求中向磁盘发送许多变化的几率。

Getting rid of WAL

然而,我们不能无限期地将数据写入WAL中。在某些时候,空间必须被回收。这正是检查点的作用。

检查点的目的是确保到某一时刻为止创建的所有脏缓冲区都被写到磁盘上,这样到该时刻为止的WAL就可以被回收了。PostgreSQL的方法是启动一个检查点进程,将那些可能丢失的变化(还是share buffers)写到磁盘上。然而,这个进程并没有尽可能快地将数据发送到磁盘。原因是我们想把I/O曲线拉平,以保证稳定的响应时间。

在这里插入图片描述

test=# SHOW checkpoint_completion_target;
checkpoint_completion_target
------------------------------
0.5
(1 row)

这个参数的意思是:一个检查点完成一半后,下一个检查点才有望启动。
在生产中,0.7 - 0.9的值似乎是大多数工作负载的最佳选择,但可以试验一下。

注意:在PostgreSQL 14中,这个参数很可能不再存在了。硬编码的值将是0.9,
这将使终端用户更容易接受。

下一个重要问题是:检查点何时真正启动?有一些参数可以控制这种行为。

test=# SHOW checkpoint_timeout;
checkpoint_timeout
--------------------
5min
(1 row)
test=# SHOW max_wal_size;
max_wal_size
--------------
1GB
(1 row)

如果你的系统的负载很低,检查点会在一定时间后发生。默认值是5分钟。然而,我们建议增加这个值以优化写入性能。

max_wal_size是一个比较棘手的问题:首先,这是一个软限制–不是一个硬限制。所以,要做好准备。WAL的数量可以超过这个数字。这个参数的意思是告诉PostgreSQL它可能积累多少WAL,并相应地调整检查点。一般的规则是:增加这个值会导致更多的空间消耗,但同时也会提高写入性能。

那么,为什么不直接将max_wal_size设置为无穷大呢?第一个原因很明显:你将需要大量的空间。然而,还有更多的原因–在你的数据库崩溃的情况下,PostgreSQL必须重复上次检查点以来的所有变化。换句话说,在崩溃之后,你的数据库可能需要更长的时间来恢复–由于自上次检查点以来积累了大量的WAL。从正面看,如果增加检查点的距离,性能确实有所提高–但是,可以做的和实现的东西是有限的。在某些时候,在问题上投入更多的存储并不能改变什么。

background writer正在向磁盘写入一些脏块。然而,在许多情况下,更多的工作是由检查点进程本身完成的。因此,把注意力放在检查点上比放在优化后台写程序上更有意义。

min_wal_size: The mysterious parameter

人们经常询问min_wal_size和max_wal_size的含义。关于这两个参数,外面有很多混乱的说法。让我试着解释一下这里发生了什么。如前所述,PostgreSQL会自行调整其检查点距离。它试图使WAL保持在max_wal_size以下。然而,如果你的系统是空闲的,PostgreSQL将逐渐减少WAL的数量,再次一直减少到min_wal_size。这不是一个快速的过程–它是逐渐发生的,在很长的一段时间内。

让我们假设一个简单的场景来说明这个情况。假设你有一个系统,在一周内有很大的写入负荷,但在周末闲置。周五下午,WAL的大小因此很大。然而,在周末,PostgreSQL会逐渐减少WAL的大小。当周一负载再次增加时,那些丢失的WAL文件将被重新创建(从性能上讲,这可能是一个问题)。

因此,不要把min_wal_size设置得太低(与max_wal_size相比),以减少在负载再次增加时创建新的WAL文件的需要,可能是一个好主意。


http://www.niftyadmin.cn/n/5179358.html

相关文章

k8s自定义Endpoint实现内部pod访问外部应用

自定义endpoint实现内部pod访问外部应用 endpoint除了可以暴露pod的IP和端口还可以代理到外部的ip和端口 使用场景 公司业务还还没有完成上云, 一部分云原生的,一部分是实体的 业务上云期间逐步实现上云,保证各个模块之间的解耦性 比如使…

第二章 (导数与微分)

导数简介 路程与时间关系函数 就是 速度与时间关系函数 的 原函数。 路程与时间关系函数 求导 (或者叫导函数) —————求导—————> 就是 vt关系的导数 求导得到》导函数 导函数积分 得到 原函数 你一开始速度为0,然后速度不断…

关于笔记的保存问题

踩过的坑 第一次是在ediary这种不可共享的单机笔记软件上进行保存,弊端非常明显,后来看很多人在知乎上记录笔记,试过几次后发现不合适自己,于是转csdn,csdn用了很长的时间,可以记录私有,共有&a…

父组件用ref获取子组件数据

子组件 Son/index.vue 子组件的数据和方法一定要记得用defineExpose暴露&#xff0c;不然父组件用ref是获取不到的&#xff01;&#xff01;&#xff01; <script setup> import { ref } from "vue"; const sonNum ref(1); const changeSon () > {sonNum.…

Java架构核心基础知识硬核整理,赶快收藏起来吧!!!

Java架构核心基础 lecture&#xff1a;波哥 一、数据结构和算法 1.数据结构 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同…

自动化测试中几种常见验证码的处理方式及如何实现?

自动化测试中几种常见验证码的处理方式及如何实现&#xff1f; 1 去掉验证码2 设置万能码3 保留一个资源4 光学字符识别4.1 识别对象4.2 pytesseract安装4.3 Pillow安装4.4 OCR安装4.5 识别原理4.6 处理过程4.6.1 转灰度处理4.6.2 二值化处理4.6.3 图像增强4.6.4 完整代码 5 打…

【Vue】过滤器Filters

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如对您有用&#xff0c;可以点赞收藏哈 过滤器 filters过滤器已从Vue 3.0中删除&#xff0c;不再支持了&#xff0c;这里可以作为了解进行学习 vue3要精简代码&…

python使用redis模块来跟redis实现交互

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 redis模块的使用&#xff1a; 1.安装模块: pip3 install redis 2.导入模块&#xff1a;import redis 3.连接方式&#xff1a; 严格连接模式&#xff1a;rredis.StrictR…