为什么我在 PostgreSQL 中 Commit 很慢?

在这里插入图片描述
有时,我们的一位客户会查看数据库中最耗时的语句(使用pg_stat_statements或pgBadger),并发现COMMIT排名靠前。通常,COMMIT这是 PostgreSQL 中非常快的语句,因此值得研究。在本文中,我将探讨速度缓慢的可能原因COMMIT并讨论您可以采取的措施。
#PG培训#PG考试#postgresql培训#postgresql考试#postgresql认证
在这里插入图片描述

Commit PostgreSQL中的基本活动

缓慢COMMIT是一个令人惊讶的观察结果,因为在 PostgreSQL 中提交事务是一个非常简单的活动。在大多数情况下,COMMIT只需

  • 将提交日志中事务的两位设置为TRANSACTION_STATUS_COMMITTED(0b01) (持久保存pg_xact)
  • 如果track_commit_timestamp设置为on,则记录提交时间戳(保留在 中pg_commit_ts)
  • 将预写日志(WAL)(保存在)刷新pg_wal到磁盘,除非synchronous_commit设置为off

请注意,由于 PostgreSQL 的多版本架构,和通常COMMIT都是ROLLBACK非常快的操作:它们都不需要触及表,它们仅在提交日志中注册事务的状态。

最常见的速度慢原因Commit:磁盘问题

从上面可以看出,导致速度缓慢的一个潜在原因是磁盘 I/O。毕竟,将 WAL 刷新到磁盘会导致 I/O 请求。因此,您应该检查的第一件事是磁盘是否有问题或负载过大:

  • 在 Linux 上,您可以使用“ vmstat 1”或“ sar -p 1”等命令来测量等待 I/O 所花费的 CPU 时间百分比(“wa”vmstat和“ %iowait” sar)。如果该值持续高于 10,则可以肯定 I/O 系统处于压力之下。

  • 使用NAS时,您应该检查 TCP 网络是否过载。

  • 如果存储是共享SAN或NAS,则磁盘可能会与其他机器共享,您应该检查存储系统是否存在争用。

  • 磁盘故障、其他硬件问题或操作系统问题可能会导致间歇性性能问题。检查内核日志以获取消息。

如果我们可以排除磁盘问题是导致提交缓慢的原因,我们就必须进行进一步调查。

阅读源代码以了解更多信息

如果我们想了解事务提交期间发生了什么,最简单的方法就是阅读源代码。许多人没有意识到开源的真正威力:你不必猜测或从软件供应商那里购买支持,而是可以自己查看。PostgreSQL 源代码写得很好,文档齐全,许多部分不需要专家 C 技能即可理解。相关代码位于CommitTransaction()中的函数中src/backend/access/transam/xact.c。

在特殊情况下,导致速度变慢的原因有多种COMMIT,例如许多并发NOTIFY语句的争用(您可以从 中的数据库 0 上的锁来诊断这种情况pg_locks)。但是,通常罪魁祸首是以下部分中描述的三种情况之一。

Commit由于延迟约束和触发器导致速度缓慢

通常,PostgreSQL 会在修改受约束表的语句中检查约束。使用延迟约束时,PostgreSQL 会等待检查,直到事务结束。一个用例是,如果您将数据插入具有循环外键约束的表中:

CREATE TABLE department (department_id bigint PRIMARY KEY,name text NOT NULL,manager bigint NOT NULL
);CREATE TABLE employee (employee_id bigint PRIMARY KEY,name text NOT NULL,department_id bigintREFERENCES department NOT NULL
);-- deferred foreign key
ALTER TABLE departmentADD FOREIGN KEY (manager) REFERENCES employeeDEFERRABLE INITIALLY DEFERRED;

延迟外键可以轻松创建新的部门:


START TRANSACTION;-- won't raise a foreign key violation yet
INSERT INTO department(department_id, name, manager)
VALUES (12, 'Flower Picking', 123);INSERT INTO employee(employee_id, name, department_id)
VALUES (123, 'John Wurzelrupfer', 12);-- deferred constraint is valid now
COMMIT;

由于 PostgreSQL 在提交时检查延迟约束,因此它们可能会减慢COMMIT处理速度。通常,检查约束非常快 — 这是索引查找。但是,许多此类检查可能会累积在较大的事务中,并且总执行时间可能会大大减慢COMMIT。

PostgreSQL 还具有可延迟的约束触发器COMMIT,并且像延迟约束一样会减慢速度。有关约束触发器用例的进一步讨论,请参阅本文。

如果您能确定延迟约束或触发器是导致 缓慢的原因COMMIT,那么可能就没问题了,无需担心。毕竟,您必须在某个时候检查这些约束。

Commit游标导致速度慢With Hold

游标允许客户端分块提取查询结果集,这可以简化处理并避免客户端内存不足。但是,常规游标只能存在于数据库事务的上下文中。因此,在涉及用户交互时不能使用游标:游标持有的快照会阻碍进程VACUUM并导致表膨胀和更严重的问题。此外,ACCESS SHARE在事务期间持有的锁会导致并发ALTER TABLE或问题TRUNCATE。

为了避免与事务绑定的限制,您可以使用游标WITH HOLD。此类游标可以比创建它的事务存活更久,例如可用于实现分页。PostgreSQL 通过在提交时具体化结果集来实现WITH HOLD游标。如果游标后面的查询很昂贵,那么速度会变得非常慢。此外,您一定不要忘记在完成后关闭此类游标,否则具体化结果集将占用服务器资源,直到数据库会话结束。COMMIT

如果您可以将游标确定WITH HOLD为提交缓慢的原因,则可以通过调整游标定义中的查询以使其运行得更快来改善这种情况。由于 PostgreSQL 不会优化游标中的查询以加快计算完整结果集的速度,因此有时将其设置cursor_tuple_fraction为 1.0 可以帮助加快提交处理速度。

Commit同步复制导致速度慢

流式复制和逻辑复制默认都是异步的。如果您使用复制来实现高可用性,并且不想冒丢失已提交事务的风险,则可以使用同步复制。使用同步复制时,提交时的操作顺序为:

将COMMIT记录写入WAL并刷新(这是实际的持久提交)

等待同步备用数据库报告已获取所有WAL信息

使事务在主服务器上可见

向客户报告成功

如果主服务器和同步备用服务器之间的网络延迟较高,COMMIT则需要很长时间。您可以通过检查pg_stat_activity频繁或持续时间较长的“ SyncRep”等待事件来诊断。通常,您只想在网络延迟较低的机器(即物理上靠近的机器)之间使用同步复制。

Commit第三方扩展导致速度缓慢

PostgreSQL 最出色的特性之一是其可扩展性。它允许您编写与 PostgreSQL 核心交互的扩展,而无需修改服务器代码。第三方代码可以“挂接”到 PostgreSQL 中以修改其行为。在许多其他选项中,您可以使用 C 函数RegisterXactCallback()注册 PostgreSQL 在提交时执行的回调。因此,如果您要查找 PostgreSQL 速度缓慢的原因COMMIT,还应该查看数据库中安装的扩展。例如,在远程数据源实现事务处理的外部数据包装器可能希望在 PostgreSQL 提交本地事务时提交远程事务。那么,远程端的高网络延迟或缓慢的事务处理将减慢 PostgreSQL 的速度COMMIT。

结论

查看源代码,我们可以轻松找到导致速度慢的可能原因COMMIT:除了磁盘问题的明显原因之外,还应该将延迟约束、游标WITH HOLD和同步复制视为可能的原因。

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

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

相关文章

求职刷题力扣DAY24--回溯算法

1. 77. 组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2: 输入&#xff1…

Go微服务: redis分布式锁在集群中可能遇到的问题及其解决方案

概述 我们的 redis 一般都是集群来给我们程序提供服务的,单体的redis现在也不多见 看到上面是主节点redis和下面是6个重节点redis,主节点和重节点的通讯都是畅通没问题的这个时候,我们有 gorouting 写我们的数据,那它就会用到我们…

(Python)可变类型不可变类型;引用传递值传递;浅拷贝深拷贝

从一段代码开始说事,先上代码: a [[1],[2],[3]] b [[4,5],[6,7],[7,8]] for i,j in zip(a,b):print(i,j)i [9]#i[0] 8j[:2][1,2]print(i, j) print(a) print(b) 运行的结果: [1] [4, 5] [9] [1, 2] [2] [6, 7] [9] [1, 2] [3] [7, 8] …

Homebrew使用

官网:https://brew.sh/ 安装: 简介:https://www.jianshu.com/p/f4c9cf0733ea 比如,安装maven: 1、brew install maven 2、查看安装路径:brew list maven 具体参考:https://blog.csdn.net/m0_67402970/arti…

日语 13 14

13. スピーチの依頼 いらい 自信 自信 自信 自信 自信 じしん 折り入って 折り入って 折り入って おりいって  诚恳 頼み 頼み 頼み 頼み 頼み  たのみ 请求 整備 整備 整備 整備 整備 せいび 维修 肥満 肥満 肥満 肥満 肥満 ひまん 肥胖 権利 …

jigdo无法下载的文件

问题描述 用jigdo下载Debian的iso镜像,剩下最后一个文件下载不了,提示信息: Found 0 of the 1 files required by the template Copied input files to temporary file debian-12.5.0-amd64-DLBD-2.iso.tmp - repeat command and supply mo…

torch.max函数

torch.max函数的用法 第一种第二种 官方介绍:Link 有两种使用场景,输入的参数不同以及返回值不同: 第一种 没有参数dim,但这种只适合一维张量。 torch.max(input) → Tensor Returns the maximum value of all elements in the…

MPLS-LDP(个人学习笔记)

定义 标签分发协议LDP(Label Distribution Protocol)是多协议标签交换MPLS的一种控制协议,负责转发等价类FEC的分类、标签的分配以及标签交换路径LSP的建立和维护等操作。LDP规定了标签分发过程中的各种消息以及相关处理过程 术语 LDP会话&a…

【尚庭公寓SpringBoot + Vue 项目实战】移动端找房功能(二十一)

【尚庭公寓SpringBoot Vue 项目实战】移动端找房功能(二十一) 文章目录 【尚庭公寓SpringBoot Vue 项目实战】移动端找房功能(二十一)1、业务介绍2、接口开发2.1、地区信息2.2、获取全部支付方式列表2.3、房间信息2.2.1. 根据条…

python基础1.1-格式化输出(%用法和format用法)

目录 %用法 format用法 %用法 1、整数的输出 %o —— oct 八进制 %d —— dec 十进制 %x —— hex 十六进制 1 >>> print(%o % 20) 2 24 3 >>> print(%d % 20) 4 20 5 >>> print(%x % 20) 6 142、浮点数输出 (1)格式化…

鸿蒙开发系统基础能力:【@ohos.accessibility (辅助功能)】

辅助功能 说明: 本模块首批接口从 API version 7 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import accessibility from ohos.accessibility;AbilityState 辅助应用状态类型。 系统能力:以下各项对应的…

智能体合集

海外版coze: 前端代码助手 后端代码助手: 前端代码助手:

glXMakeCurrent 退出

glXMakeCurrent 退出 X Error of failed request: GLXBadDrawable Major opcode of failed request: 146 (GLX) Minor opcode of failed request: 29 (X_GLXGetDrawableAttributes) Serial number of failed request: 90 Current serial number in output stream: …

优惠券核销业务

优惠券核销业务,包含 买券,券核销,退券,退款,过期自动退。 优惠券 为了促销,商家有时会发放一些优惠券,比如 80 抵 100。抖音、美团,都有类似的业务。 购买优惠券 优惠券&#x…

C++核心编程运算符的重载

C核心编程运算符的重载 文章目录 C核心编程运算符的重载1.“”运算符的重载1.1 作为成员函数重载1.2 作为全局函数重载 2."<<"运算符重载2.1为什么需要重载左移运算符2.2如何重载左移运算符2.3注意事项 3.""运算符重载3.1 前置递增运算符重载3.2后置…

添加右键菜单(以git为例)

1、打开注册表编辑器 打开系统注册表&#xff0c;使用组合键“Win R”输入“regedit”。 依次展开”HKEY_CLASSES_ROOT\Directory\Background\shell”。 2、新建右键菜单项 在[Background]下找到“shell”如果没有则新建项shell&#xff0c;接着在“shell”下右键-新建项名…

算法训练营day66-孤岛总面积-沉没孤岛-水流问题-建造最大岛屿

题目1&#xff1a;101. 孤岛的总面积 (kamacoder.com) #include <iostream> #include <vector> #include <queue> using namespace std; int dir[4][2] {0,-1,-1,0,0,1,1,0}; int count 0; void bfs(vector<vector<int>>& map, vector<…

智能农业管理系统设计

一、引言 随着物联网、云计算和大数据技术的快速发展&#xff0c;智能农业管理系统成为提高农业生产效率、优化资源配置、降低环境污染的重要手段。本设计旨在构建一个集数据采集、传输、处理、分析于一体的智能农业管理系统&#xff0c;为农业生产提供全方位、精准化的服务。 …

基于DPU的云原生裸金属网络解决方案

1. 方案背景和挑战 裸金属服务器是云上资源的重要部分&#xff0c;其网络需要与云上的虚拟机和容器互在同一个VPC下&#xff0c;并且能够像容器和虚拟机一样使用云的网络功能和能力。 传统的裸金属服务器使用开源的 OpenStack Ironic 组件&#xff0c;配合 OpenStack Neutron…

修改主频睡眠模式停止模式待机模式

代码示例&#xff1a; 接线图&#xff1a;修改主频 接线图&#xff1a;睡眠模式串口发送接收 CH340 USB转串口模块。GND和stm32共地。RXD接PA9&#xff0c;TXD接PA10。 接线图&#xff1a;停止模式对射式红外传感器计次 对射式红外传感器模块的VCC和GND接上供电。DO输出接S…