PostgresSQL中的死锁和锁等待

前言

关于数据库锁等待和死锁我相信所有DBA都已经了解其中的原理和发生的场景;今天在这咱再唠叨唠叨锁等待和死锁概念,首先探讨一下死锁和锁等待这两个事件的异同。

1.死锁和锁等待这两个事件的异同

相同点:
死锁和锁等待两者都是当前事物在试图请求被其他事物已经占用的锁,从而造成当前事物无法执行的现象。

不同点:
死锁是相关session双方或者多方中必然要牺牲(回滚)至少一个事务,否则双方(或者多方)都无法执行;
锁等待则不然,对于暂时无法申请到的锁,尝试持续地“等待一段时间”,这个等待的时间就是“锁等待”参数决定(lock_timeout默认值0),超出之后就不等了。 

2.Postgresql的死锁检测机制(deadlock_timeout)

死锁概念:
死锁是指两个或是两个以上的事务执行过程中因等待或是争抢资源而造成得互相等待得现象

锁等待有可能是发展成死锁,也有可能不是死锁,可能继续等待一段时间之后就可以正常申请到所需要的锁了。
发生死锁的情况下,一定会产生锁等待,因为此时的锁等待继续下去没有任何意义,所以必须(立刻)牺牲其中一个事务,大多关系型数据库都有类似的处理机制。
没有死锁等待时间一说,因为一旦死锁的条件生成,则没有任何缓冲的余地,必须至少牺牲(回滚)其中一个事物,释放其占用的锁,来打断这个死锁的闭环;在Postgresql中,有一个死锁等待事件的参数(deadlock_timeout),默认是1s中,也就是是说Postgresql后台进程会以1s的频率来检测是否存在死锁。
思考问题:
为什么postgresql中对于死锁要以类似于定时轮训的方式来实现死锁检测而不是实时监测?
官方给出解释:

This is the amount of time to wait on a lock before checking to see if there is a deadlock condition. The check for deadlock is relatively expensive, so the server doesn't run it every time it waits for a lock. We optimistically assume that deadlocks are not common in production applications and just wait on the lock for a while before checking for a deadlock. Increasing this value reduces the amount of time wasted in needless deadlock checks, but slows down reporting of real deadlock errors. If this value is specified without units, it is taken as milliseconds. The default is one second (1s), which is probably about the smallest value you would want in practice. On a heavily loaded server you might want to raise it. Ideally the setting should exceed your typical transaction time, so as to improve the odds that a lock will be released before the waiter decides to check for deadlock. Only superusers and users with the appropriate SET privilege can change this setting.

When log_lock_waits is set, this parameter also determines the amount of time to wait before a log message is issued about the lock wait. If you are trying to investigate locking delays you might want to set a shorter than normal deadlock_timeout.

大概意思是说在Postgresql中,deadlock_timeout是进行死锁检测之前在一个锁上等待的总时间(以毫秒计)。Postgresql的理念中认为死锁检测代价是比较高的,因此服务器不会在每次等待锁时都判断有没有形成死锁。我们乐观地假设在生产应用中死锁是不常出现的,并且只在开始检测死锁之前等待一会儿。增加这个值就减少了浪费在无用的死锁检测上的时间(频率),但是降低了报告真正死锁错误的速度。默认是 1 秒(1s),这可能是实际中你想要的最小值。在一个高负载的服务器上,你可能需要增大它。这个值的理想设置应该超过你通常的事务时间,这样就可以减少在锁释放之前就开始死锁检查的机会。同理,对于高并发小事务处理系统上,默认的1秒已经足够了。只有超级用户可以更改这个设置。

3.Postgresql锁超时(lock_timeout)

Postgresql中同样可以设置所等待的超时时间,意味着当前事务在请求一个锁的时候,一旦等待时长超出指定的时间,当前语句被中止;该参数的默认值为0,意味着发生锁等待的时候永远不超时,一直等待下去,与statement_timeout不同,这个超时只在等待锁时发生。注意如果statement_timeout为非零,设置lock_timeout为相同或更大的值没有意义,因为事务超时将总是先与锁超时触发。

参考网址:PostgreSQL 文档: lock_timeout 参数

关于lock_timeout官方给出的解释:

Abort any statement that waits longer than the specified amount of time while attempting to acquire a lock on a table, index, row, or other database object. The time limit applies separately to each lock acquisition attempt. The limit applies both to explicit locking requests (such as LOCK TABLE, or SELECT FOR UPDATE without NOWAIT) and to implicitly-acquired locks. If this value is specified without units, it is taken as milliseconds. A value of zero (the default) disables the timeout.

Unlike statement_timeout, this timeout can only occur while waiting for locks. Note that if statement_timeout is nonzero, it is rather pointless to set lock_timeout to the same or larger value, since the statement timeout would always trigger first. If log_min_error_statement is set to ERROR or lower, the statement that timed out will be logged.

Setting lock_timeout in postgresql.conf is not recommended because it would affect all sessions.

官网说不推荐在postgresql.conf中设置lock_timeout,因为它会影响所有会话。
实际这个建议值得商榷,如果不设置lock_timeout,一个Session的锁等待将无限拉长(如果statement_timeout不限制的话),一旦大量的连接涌入进来等待一个短时间内无法释放的不兼容锁,那么数据库的连接数可能在短时间内被打爆,影响一些正常的连接。这里认为应该根据系统中事务轻重程度,设置成超过deadlock_timeout且小于statement_timeout的一个值,强制一些超锁等待超时的Session自动终止,不要无限期等待而占用数据库连接,引发系统级的异常。

4.Postgresql中的锁超时后事务的处理

默认情况下,Postgresql在当前Session锁超时之后,会回滚整个事务,而不是当前语句。

对于Postgresql中的deadlock_timeout参数设置成不同的值,一方面取决于业务,另外一方面,对系统整体的性能影响,该如何科学地衡量?

5.Postgresql设置数据库执行超时时间(statement_timeout)

statement_timeout是一个PostgreSQL服务器参数,用于设置单个SQL语句的执行超时时间。当一个查询执行的时间超过了设定的超时时间,PostgreSQL将终止该查询并返回一个错误信息。这个参数可以帮助我们防止长时间运行的查询对数据库性能造成影响,同时也有助于保护数据库免受恶意攻击。

应用场景:

1.防止长时间运行的查询:有时,由于数据量过大或其他原因,查询可能会运行很长时间。通过设置合适的statement_timeout值,我们可以确保查询不会无限制地运行,从而避免对数据库性能造成影响。

2.保护数据库免受恶意攻击:恶意用户可能会尝试执行大量计算密集型操作,以消耗数据库资源并使其无法正常工作。通过设置statement_timeout,我们可以限制单个查询的执行时间,从而降低这种攻击的风险。

3.优化查询性能:在某些情况下,我们可能需要优化查询性能。通过观察查询的执行时间,我们可以确定是否需要调整statement_timeout值以提高整体性能。

最佳实践
1.在使用statement_timeout时,我们需要遵循一些最佳实践以确保其有效性和安全性,不会对业务造成中断。

2.合理设置超时时间:设置过短的超时时间可能会导致频繁中断查询,而设置过长的超时时间则可能无法达到预期的保护效果。因此,我们需要根据实际业务需求和数据库性能来合理设置超时时间。

3.监控查询执行时间:定期监控查询的执行时间可以帮助我们了解数据库的性能状况,并及时发现潜在的问题。我们可以使用各种工具(如pgBadger、pgAdmin等)来分析查询执行时间和性能瓶颈。

4.重要查询设置优先级:对于重要的查询,我们可以通过设置较低的statement_timeout值来确保它们能够顺利完成。这样可以避免因超时而导致的重要查询失败。

5.考虑使用事务:在某些情况下,我们可以考虑将多个查询封装在一个事务中。这样,即使某个查询超时,其他查询仍然可以继续执行。但请注意,这可能会增加事务提交的复杂性。

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

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

相关文章

发展的挺快的Rust

C 可能在将来会逐步的退出历史舞台 Rust 在linux 上出现的频次越来越多了 新的语言和重构带来了更方便快捷的体验 好玩的命令集合 https://github.com/ibraheemdev/modern-unix.git 这速度,这花活儿

鬼灭之刃-激情台词-02(解释来自文心一言)

愤怒吧,不共戴天的仇恨,强悍而纯粹的愤怒,将会化作坚不可摧的原动力,督促你变强 —— 吾峠呼世晴《鬼灭之刃》 愤怒和仇恨是一种强烈的情感,它们可以驱使人们去寻求改变,去变得更加强大。在故事中&#xff…

07、面向对象进阶

面向对象进阶 文章目录 面向对象进阶static关键字继承多态包final抽象类与抽象方法接口拓展 内部类成员内部类静态内部类局部内部类匿名内部类 static关键字 static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量 静态变量是随着…

Python实战:加密解密技术

一、引言 在当今数字化时代,数据安全变得日益重要。为了保护数据不被未授权访问和泄露,加密技术成为了一种重要的手段。Python作为一种广泛使用的编程语言,提供了多种加密解密库,使得在Python程序中实现加密解密功能变得相对简单…

活动报名 | 数能涌现,三生万物,长安链发布三周年庆暨生态年会邀您共聚

数据作为一种基础资源和创新引擎,正在成为促进经济发展的新动能。在数据引擎的推动下传统产业被重塑,新的产业形态不断涌现。长安链自2021年1月27日发布三年以来,持续迭代已更新至3.0正式版本,以技术创新推动数据可信共享与业务高…

C++ Qt开发:QProcess进程管理模块

Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QProcess组件实现针对进程的控制管理…

mysqly索引(explain 执行计划)

关键词 执行计划 EXPLAIN 语句查看mysql 优化后的语句 show warnings;EXPLAIN 执行后,各列的含义 要点: select_type 如何查询 表type 如何查询 行key 如何使用 索引key_len 索引 使用多少rows 行 预计使用多少extra 表 的额外信息 1.id id列的编…

route和router的区别

Router 和 Route 是两个不同的概念,它们在计算机网络和前端开发中有不同的应用和含义: Router(路由器)是一种网络设备,用于连接不同的网络并转发数据包。路由器通过学习路由表中的信息,根据目标IP地址…

Spring之@Qualifier注解

场景重现 当我们注入的依赖存在多个候选者,我们得使用一些方法来筛选出唯一候选者,否则就会抛出异常 demo演示 创建接口Car,以及两个实现其接口的bean public interface Car { }Component public class RedCar implements Car { }Component public class WhiteCar implemen…

荒野大嫖客2找不到emp.dll解决办法

首先我参考了几篇文章尝试来解决这个问题, s霍格沃兹emp.dll文件丢失要怎么处理?快速修复emp.dll的方法-CSDN博客 使用电脑自带的修复工具,直接按键盘的winr,然后输入cmd,打开小黑板,我们再在小黑板上输入…

MQTT 简介

MQTT 简介 MQTT 是非常简单的协议,最初由 IBM 的两位工程师 Andy Stanford-Clark 以及 Arlen Nipper 在 1999 年为监控输油管道设计的。它被设计的场景就是有限的带宽、轻量级以及很小的耗电量,在那个时候,卫星宽带就是那么小,且…

element-plus-button 按钮点击之后颜色不还原的问题

出问题的代码 .el-button:focus, .el-button:hover {color: var(--el-button-hover-text-color);border-color: var(--el-button-hover-border-color);background-color: var(--el-button-hover-bg-color);outline: 0; }以下是引用 另一个博主的说明: 所以有如下动…

【理解机器学习算法】之Clustering算法(Agglomerative Clustering)

聚合聚类(Agglomerative Clustering)是一种层次聚类算法,通过逐步合并或“聚集”它们来构建嵌套聚类。这种方法采用自底向上的方式构建聚类层次:它从将每个数据点作为单个聚类开始,然后迭代合并最接近的聚类对,直到所有数据点合并…

【机器学习】一文搞懂算法模型之:Transformer

Transformer 1、引言2、Transformer2.1 定义2.2 原理2.3 算法公式2.3.1 自注意力机制2.3.1 多头自注意力机制2.3.1 位置编码 2.4 代码示例 3、总结 1、引言 小屌丝:鱼哥, 你说transformer是个啥? 小鱼:嗯… 啊… 嗯…就是… 小屌…

【Java Web基础】一些网页设计基础(四)

文章目录 1. 做Tab切换2. 下面的内容展示——Card样式3. 采供分类&#xff0c;分类用面包屑导航做4. 出名企业展示&#xff0c;就是普通的图片5. 用热门商品类似的panel做一个农博会展览 1. 做Tab切换 使用BootStrap提供的样式&#xff1a; <ul class"nav nav-tabs&q…

【Redis】缓存穿透

问题发生背景&#xff1a;客户端请求的数据再缓存中和数据库中都不存在。 导致的问题&#xff1a;缓存永远不会生效&#xff0c;这些请求都会去请求数据库—导致数据库压力增大。 解决方案&#xff1a; 1.缓存空对象 在Redis中缓存空对象&#xff0c;告诉客户端数据库中没有该值…

uni-app攻略:如何对接驰腾打印机

一.引言 在当前的移动开发生态中&#xff0c;跨平台框架如uni-app因其高效、灵活的特点受到了开发者们的青睐。同时&#xff0c;随着物联网技术的飞速发展&#xff0c;智能打印设备已成为许多业务场景中不可或缺的一环。今天&#xff0c;我们就来探讨如何使用uni-app轻松对接驰…

Codeforces Round 935 (Div. 3)A~E

A. Setting up Camp 题目分析: 有三种人&#xff0c;内向、外向、综合&#xff0c;内向必须独自一个帐篷&#xff0c;外向必须3个人一个帐篷&#xff0c;综合介于1~3人一个帐篷&#xff0c;我们发现非法情况只会存在外向的人凑不成3个人一个帐篷的情况&#xff0c;因外向不够可…

软件管理rpm与yum

源代码包下载 Compare, Download & Develop Open Source & Business Software - SourceForgehttps://sourceforge.net/ rpm包下载 Welcome to the RPM repository on fr2.rpmfind.nethttp://rpmfind.net/linux/RPM/ 软件包管理 1.rpm包管理: 1)查询: 安装…

微隔离有哪些作用

当前&#xff0c;在零信任安全渐渐被大家熟知的情况下&#xff0c;很多用户在网络安全方面有了更深的认知。在网络安全领域&#xff0c;许多企业用户认为零信任对于降低网络安全风险至关重要&#xff0c;有助于在复杂的网络环境中保护自身企业资源免受未经授权的访问和潜在的网…