PostgreSQL学习笔记十:锁机制详解

news2024/11/30 0:41:47

一、PostgreSQL 的锁机制

PostgreSQL中的锁机制是确保数据一致性和完整性的关键。它通过不同级别的锁来控制对数据对象的并发访问,主要包括表级锁、行级锁、页级锁、咨询锁(Advisory Locks)以及死锁(Deadlocks)。

在这里插入图片描述

1. 表级锁(Table-Level Locks)

表级锁主要分为以下几种:

  • ACCESS SHARE LOCK:用于数据查询(SELECT),与ACCESS EXCLUSIVE锁冲突。
  • ROW SHARE LOCK:用于SELECT FOR UPDATE或SELECT FOR SHARE,与EXCLUSIVE和ACCESS EXCLUSIVE锁冲突。
  • ROW EXCLUSIVE LOCK:用于数据的更新、插入和删除操作,与SHARE、SHARE ROW EXCLUSIVE和ACCESS EXCLUSIVE锁冲突。
  • SHARE UPDATE EXCLUSIVE LOCK:用于VACUUM和某些ALTER TABLE操作,防止并发的schema改变和VACUUM命令。
  • SHARE LOCK:用于创建索引(CREATE INDEX),防止并发的数据变更。
  • SHARE ROW EXCLUSIVE LOCK:用于某些不会自排他的操作,比如创建触发器。
  • EXCLUSIVE LOCK:用于防止并发的数据变更和读取操作,只允许并发的ACCESS SHARE锁。
  • ACCESS EXCLUSIVE LOCK:用于TRUNCATE、DROP TABLE等DDL操作,与其他所有锁冲突。

2. 行级锁(Row-Level Locks)

行级锁通常用于控制对特定行的并发访问,主要有:

  • FOR UPDATE:对整行进行更新,包括删除行,阻止其他事务对行的读取和更新。
  • FOR NO KEY UPDATE:对除主(唯一)键外的字段更新,对行加锁,但允许其他事务在不锁定键值的情况下进行更新。
  • FOR SHARE:读该行,不允许对行进行更新,阻止其他事务对行的更新。
  • FOR KEY SHARE:读该行的键值,但允许对除键外的其他字段更新,主要用于外键检查。

3. 页级锁(Page-Level Locks)

页级锁用于控制对数据页的并发访问,常见的有:

  • WalInsertLock:向WAL缓冲区写入WAL记录时需要的锁。
  • WALWriteLock:确保WAL数据被刷入磁盘的锁。
  • ProcArrayLock:用于追踪正在运行的后端进程和事务。

4. 咨询锁(Advisory Locks)

咨询锁用于在需要时提供额外的锁机制,它们不与PostgreSQL的内部锁机制冲突。咨询锁可以是会话级别的或事务级别的,允许用户在不同的进程或事务之间进行协调。

在这里插入图片描述

5. 死锁(Deadlocks)

死锁发生在两个或多个事务相互等待对方持有的锁时。PostgreSQL有参数如lock_timeoutdeadlock_timeoutlog_lock_waits来控制死锁的检测和处理。
在这里插入图片描述

使用锁的注意事项

  • 锁的获取和释放应该谨慎处理,以避免死锁和性能问题。
  • 锁的粒度越细,系统的并发能力越强,但同时锁的管理开销也越大。
  • 在设计数据库操作时,应考虑锁的影响,合理使用锁来保证数据的一致性和完整性。

在这里插入图片描述

二、PostgreSQL 的死锁检测和处理机制是如何工作的?

PostgreSQL的死锁检测和处理机制是数据库并发控制的重要组成部分。当两个或多个事务相互等待对方持有的锁时,就会发生死锁。PostgreSQL通过以下方式来检测和处理死锁:

  1. 死锁检测:PostgreSQL数据库能够自动检测死锁情况。当检测到死锁时,数据库会采取措施来解决这个问题。死锁检测是通过周期性地检查事务等待图来完成的,这个图会显示每个事务正在等待哪些锁,以及这些锁被哪些其他事务持有。

  2. 死锁超时deadlock_timeout 参数定义了在检测到死锁之前等待锁的时间量。如果在这个时间内没有获得锁,PostgreSQL将检查是否存在死锁。如果检测到死锁,PostgreSQL将终止其中一个事务,以释放锁并允许其他事务继续进行。默认情况下,这个值设置为1秒(1s),这是一个合理的起点,但在高负载的服务器上,可能需要增加这个值。

  3. 锁等待日志:通过设置 log_lock_waits 参数,可以在日志中记录有关锁等待的信息。这有助于数据库管理员调查锁延迟和死锁问题。

  4. 查询死锁统计:可以通过查询 pg_stat_database 视图来检查数据库级别的统计信息,包括死锁次数。这有助于识别是否存在死锁问题,并对其进行监控和优化。

  5. 预防死锁:尽管PostgreSQL可以自动检测和解决死锁,但最好的方法是通过应用程序设计来预防死锁的发生。这通常涉及确保所有事务以一致的顺序获取锁,以及在事务中尽早获取最严格的锁模式。

  6. 咨询锁:PostgreSQL提供了咨询锁(Advisory Locks),这是一种可以由应用程序显式请求的锁。咨询锁可以用于实现更细粒度的锁控制,例如,在不同的事务之间同步对特定资源的访问。

  7. 事务设计:设计事务时,应尽量减少锁的持有时间,并避免长时间运行的事务,因为这会增加死锁的风险。此外,应用程序应该实现重试机制,以便在因死锁而中止的事务可以被重新尝试。

通过这些机制,PostgreSQL能够有效地管理和解决并发事务中的死锁问题,确保数据库操作的一致性和完整性。

在这里插入图片描述
在这里插入图片描述

三、如何正确使用锁来避免死锁?

在PostgreSQL中,正确的锁管理和事务设计对于避免死锁至关重要。以下是一些最佳实践,可以帮助减少死锁发生的概率:

  1. 一致的锁定顺序

    • 确保事务总是以相同的顺序获取锁。如果所有事务都按照相同的顺序请求锁,那么死锁的可能性将大大降低。
  2. 最小化锁的粒度

    • 尽可能使用行级锁而不是表级锁。行级锁提供了更细的粒度,可以减少锁定的资源量,从而降低与其他事务发生冲突的可能性。
  3. 锁的超时

    • 为锁请求设置合理的超时时间。如果一个事务在一定时间内不能获得所需的锁,它应该释放所有已持有的锁并回滚,以避免长时间持有锁导致的死锁。
  4. 避免长时间持有锁

    • 尽量缩短事务的执行时间。长时间运行的事务更有可能与其他事务发生死锁。通过优化查询和业务逻辑来减少事务的执行时间。
  5. 使用锁提示

    • 在SQL查询中使用FOR UPDATEFOR SHARE等锁提示,明确地锁定查询中涉及的行,而不是在事务的最后阶段隐式地锁定。
  6. 避免在循环中获取锁

    • 不要在循环中获取不同的锁,因为循环中的每一次迭代都可能改变锁的顺序,从而增加死锁的风险。
  7. 使用咨询锁

    • 如果你的应用程序需要显式的锁控制,可以使用咨询锁(Advisory Locks)。但是,必须确保应用程序逻辑正确地管理这些锁,以避免死锁。
  8. 死锁检测和解决

    • 监控数据库的死锁情况。如果检测到死锁,分析其原因,并调整应用程序逻辑以避免未来的死锁。
  9. 事务隔离级别

    • 根据应用程序的需求选择合适的事务隔离级别。更高的隔离级别(如可序列化)可以减少死锁的机会,但可能会影响并发性能。
  10. 锁监控和日志记录

    • 启用锁等待日志记录,以便在发生锁等待时记录详细信息。这有助于分析和解决潜在的死锁问题。
  11. 避免嵌套事务

    • 嵌套事务可能会增加锁的复杂性,尽量避免使用嵌套事务,或者确保嵌套事务中的锁顺序与外层事务一致。
  12. 锁的等级

    • 了解不同锁模式之间的兼容性,确保事务在需要时获取足够严格的锁模式,以防止其他事务的干扰。

通过遵循这些最佳实践,你可以有效地减少PostgreSQL中死锁的发生,从而提高数据库的并发性能和稳定性。

在这里插入图片描述

四、LOCK锁的用法

在PostgreSQL中,LOCK命令用于获取表级锁。这些锁可以是行级的、事务级的,或者是咨询锁(advisory locks),它们用于控制对表或行的并发访问。以下是LOCK命令的一些关键点:

基本语法

LOCK TABLE [table_name] IN [lock_mode] MODE;
  • table_name:要锁定的表的名称。
  • lock_mode:锁的模式,如ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, 或 ACCESS EXCLUSIVE

LOCK TABLE 的不同模式

  • ACCESS SHARE:防止对表进行任何写入操作,但允许其他事务读取表。
  • ROW SHARE:用于SELECT ... FOR SHARE,防止对行进行更新或删除。
  • ROW EXCLUSIVE:用于SELECT ... FOR UPDATE,防止对行进行读取、更新或删除。
  • SHARE UPDATE EXCLUSIVE:用于某些不会自排他的操作,比如创建索引。
  • SHARE:用于防止对表进行写入操作,但允许其他事务读取表。
  • SHARE ROW EXCLUSIVE:用于某些不会自排他的操作,比如创建触发器。
  • EXCLUSIVE:允许只有读取操作,不允许其他任何形式的锁定。
  • ACCESS EXCLUSIVE:最严格的锁,防止所有其他锁,包括读取。

使用场景

  1. 防止数据变更:当你需要确保在一个事务中数据不被其他事务修改时,可以使用LOCK TABLE

  2. 控制并发访问:在需要控制对特定表的并发访问时,可以使用LOCK TABLE来限制其他事务的访问。

  3. 维护数据一致性:在执行某些需要保证数据一致性的操作时,比如数据迁移或批量更新,可以使用LOCK TABLE

注意事项

  • LOCK TABLE只在当前事务中有效,事务结束后锁会自动释放。
  • 如果需要立即获取锁而不等待,可以使用NOWAIT选项,如果无法立即获取锁,会返回错误。
  • LOCK TABLE之后,如果事务中发生错误,需要手动回滚(ROLLBACK)事务,否则锁不会被释放。
  • LOCK TABLE可能会与其他事务中的锁发生冲突,需要谨慎使用以避免死锁。

示例

BEGIN;

LOCK TABLE my_table IN ACCESS EXCLUSIVE MODE;

-- 执行需要表级锁的操作
SELECT * FROM my_table;
UPDATE my_table SET column_name = 'new_value' WHERE condition;

COMMIT;

在这个示例中,事务开始后,使用LOCK TABLE获取了my_tableACCESS EXCLUSIVE锁,这会阻止其他事务对my_table进行写入操作。在事务中执行了查询和更新操作,然后提交事务释放锁。

使用LOCK TABLE时,应该谨慎考虑其对并发性和数据库性能的影响,并确保遵循最佳实践以避免死锁。

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

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

相关文章

基于Java+Springboot+Vue开发的大学竞赛报名管理系统

项目简介 该项目是基于JavaSpringbootVue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java…

# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(九)--网络设置与文件上传下载

linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(九)–网络设置与文件上传下载 一、网络设置 1、首先知道网卡配置文件位置:/etc/sysconfig/network-scripts [rootlocalhost test1]# ls /etc/sysconfig/netwo…

JSON 格式化工具:快速便捷地格式化和查看 JSON 数据

JSON 格式化工具:快速便捷地格式化和查看 JSON 数据 为什么需要 JSON 格式化工具? 在日常开发和调试中,JSON 是非常常见的数据交换格式。无论是前端与后端的接口调用,还是数据存储和处理,JSON 格式都扮演着重要角色。…

【HarmonyOS开发笔记 2 】 -- ArkTS语法中的变量与常量

ArkTS是HarmonyOS开发的编程语言 ArkTS语法中的变量 【语法格式】: let 变量名: 类型 值 let:是定义变量的关键字类型: 值数据类型, 常用的数据类型 字符型(string)、数字型(number&#xf…

PG 17 增量备份功能介绍

背景 PG 17 新增了增量备份功能,可以通过 pg_basebackup --incrementalPATH_TO_MANIFEST 命令进行增量备份。 官方文档:https://www.postgresql.org/docs/current/app-pgbasebackup.html 使用方法 全量备份 启动实例后,首先配置参数 sum…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第三十五章 嵌入式开发概述及环境构建

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐…

数据库表使用方法:

数据库表: 提供四种类型的约束保证完整性: 1.域完整性,2.实体完整性 3.自定义完整性 4.引用完整性 实体完整性: 约束方法:唯一约束,主键约束,标识列 域完整性: 约束方法&#x…

基于depth anything模型理解深度估计运行机理

文章目录 前言一、概念说明1、深度概念2、绝对深度概念3、相对深度概念4、深度估计表示方法二、相对深度估计与绝对(即度量)深度估计1、模型预测绝对深度劣势与应用优势2、模型预测相对深度必然性3、小结三、深度估计模型loss方法四、深度估计模型评估方法1、绝对相对误差2、…

Python:方法的链式调用

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 在Python编程中,方法的链式调用是一种简洁且优雅的编程风格,它允许你在一行代码中连续调用多个方法,这种编程模式在简化代码、提升可…

22.安卓逆向-frida基础-objection工具1-安装和简单使用(Python的pip指令安装完提示不是内部命令解决办法)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。 工…

java4~~~

日期 第一代 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.SimpleFormatter;public class Main {public static void main(String[] args) throws ParseException {//两种构造器的使用//1、获取当…

OpenCV高级图形用户界面(1)创建滑动条函数createTrackbar()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 创建一个滑动条并将其附加到指定的窗口。 该函数 createTrackbar 创建一个具有指定名称和范围的滑动条(滑块或范围控制)…

Flexbox 弹性盒子布局

Flexbox,全称弹性盒子布局,提供更精细的控制,能轻松解决困扰我们许久的垂直居中和登高列问题。 1 display: flex 将容器设置为弹性容器,容器会占据100%的可用宽度,高度则由自身的内容来决定,即使改变主轴…

基于SSM的“企业人事管理系统”的设计与实现(源码+数据库+文档)

基于SSM的“企业人事管理系统”的设计与实现(源码数据库文档) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 登陆页面 部门管理页面 加班页面 考勤页面 请假页面 工资页面 …

leetcode链表(三)-反转链表

题目 . - 力扣(LeetCode) 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 思路 首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为None。 然后就要开始反转了&…

使用tgz包下载安装clickhouse低版本

1.下载安装包 官方下载地址:https://packages.clickhouse.com/tgz/stable 阿里云下载地址:clickhouse-tgz-stable安装包下载_开源镜像站-阿里云 共需要下载四个文件 clickhouse-common-static-20.3.10.75.tgz clickhouse-common-static-dbg-20.3.10.7…

如何通过零工市场小程序提高匹配效率?

零工市场正往好的方向逐步发展,零工市场小程序就是数字化转型成功的标志,那么零工市场小程序作为求职者和雇主之间沟通的桥梁,通过利用现代技术,例如Java算法,提高了灵活就业市场的效率。 Java通过数据分析&#xff0…

AI预测体彩排3采取888=3策略+和值012路或胆码测试10月11日升级新模型预测第101弹

经过100多期的测试,当然有很多彩友也一直在观察我每天发的预测结果,得到了一个非常有价值的信息,那就是9码定位的命中率非常高,已到达90%的命中率,这给喜欢打私菜的朋友提供了极高价值的预测结果~当然了,大…

Docker Overlay2 空间优化

目录 分析优化数据路径规划日志大小限制overlay2 大小限制清理冗余数据 总结 分析 overlay2 目录占用磁盘空间较大的原因通常与 Docker 容器和镜像的存储机制以及它们的长期累积相关,其实我之前在 Docker 原理那里已经提到过了。 通常时以下几种原因导致&#xff…

Java:数据结构-LinkedList与链表(1)

一 链表 1.. ArrayList的缺陷(LinkedList的优点) 在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后 搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除…