为什么我在 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,一经查实,立即删除!

相关文章

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…

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: 前端代码助手 后端代码助手: 前端代码助手:

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

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

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

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

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

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

张大哥笔记:5种信息差赚钱模式

从古至今,赚钱最快的路子就一个,而且从未改变,那就是信息差!在商业活动中,信息不对称现象普遍存在,如果你善于利用这些信息差的话,就可以赚到钱! 1、价格的信息差 商品价格在不同地…

python pyautogui实现图片识别点击失败后重试

安装库 pip install Pillow pip install opencv-python confidence作用 confidence 参数是用于指定图像匹配的信度(或置信度)的,它表示图像匹配的准确程度。这个参数的值在 0 到 1 之间,数值越高表示匹配的要求越严格。 具体来…

ConcurrentHashMap(应对并发问题的工具类)

并发工具类 在JDK的并发包里提供了几个非常有用的并发容器和并发工具类。供我们在多线程开发中进行使用。 5.1 ConcurrentHashMap 5.1.1 概述以及基本使用 在集合类中HashMap是比较常用的集合对象,但是HashMap是线程不安全的(多线程环境下可能会存在问题)。为了…

可一件转化的视频生成模型:快手官方大模型“可灵”重磅来袭!

可一件转化的视频生成模型“可灵”重磅来袭! 前言 戴墨镜的蒙娜丽莎 达芬奇的画作《蒙娜丽莎的微笑》相信大家是在熟悉不过了,可《戴墨镜的蒙娜丽莎》大家是不是第一次见?而且这还不是以照片的形式,而是以视频的形式展示给大家。 …

Spring AOP实战--之优雅的统一打印web请求的出参和入参

背景介绍 由于实际项目内网开发,项目保密,因此本文以笔者自己搭建的demo做演示,方便大家理解。 在项目开发过程中,团队成员为了方便调试,经常会在方法的出口和入口处加上log输出,由于每个人的log需求和输…

奔驰EQS SUV升级原厂主动式氛围灯效果展示

以下是一篇关于奔驰 EQs 升级原厂主动氛围灯案例的宣传文案: 在汽车科技不断演进的今天,我们自豪地为您呈现奔驰 EQs 升级原厂主动氛围灯的精彩案例。 奔驰 EQs,作为豪华电动汽车的典范,其卓越品质与高端性能有目共睹。而此次升…

CVPR 2024盛况空前,上海科技大学夺得最佳学生论文奖,惊艳全场

CVPR 2024盛况空前!上海科技大学夺得最佳学生论文奖,惊艳全场! 会议之眼 快讯 2024 年 CVPR (Computer Vision and Pattern Recogntion Conference) 即国际计算机视觉与模式识别会议,于6月17日至21日正在美国西雅图召…

手把手教你java CPU飙升300%如何优化

背景 今天有个项目运行一段时间后,cpu老是不堪负载。 排查 top 命令 TOP 命令 top t 按cpu 排序 top m 按内存使用率排序 从上面看很快看出是 pid 4338 这个进程资源消耗很高。 top -Hp pid top -Hp 4338 找到对应线程消耗的资源shftp cpu占用进行排序&#xf…

【Java】已解决java.net.ProtocolException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.net.ProtocolException异常 在Java的网络编程中,java.net.ProtocolException异常通常表示在网络通信过程中,客户端或服务器违反了某种协议规则。…