postgresql共享行锁实现原理研究

news/2024/7/9 19:35:03 标签: postgresql, 共享行锁

postgresql_0">postgresql共享行锁实现原理研究

背景

锁是数据库很重要的机制,postgresql支持表锁,行锁,了解postgresql行锁机制有助于我们在应用中分析和解决行锁的问题。

锁模式

当前postgresql支持4种行锁模式: FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR
UPDATE,我们常见的delete场景获取的均为FOR UPDATE锁,而update场景会获取FOR NO KEY
UPDATE或者FOR UPDATE,要看有没有唯一索引了。 下面表格记录了4种锁模式的兼容情况。

在这里插入图片描述
加锁流程

  1. 首先加事务Exclusive锁
    行锁等到事务提交才会释放,其他事物如果等待这个行锁,必须等待这个事务锁释放。以Update为例,首先分配一个事务xid,这个时候会对事务xid加锁,AssignTransactionId->AssignTransactionId->LockAcquire,这个锁是个内存锁。

  2. 判断是否需要锁等待
    如果一个tuple被修改或者删除后,会记录xmax和t_infomask,ExecUpdate->heap_update->HeapTupleSatisfiesUpdate会返回tuple状态,只有当前Tuple上的Xmax或者MultiXactId还在活跃事务列表,会进行锁等待

在这里插入图片描述

  1. 加tuple锁
    tuple锁可以保证多个修改事务加锁的顺序问题,原则是先来先拿锁,修改完tuple后,tuple锁会立即释放,而事务锁不会释放。假设有3个事务,A、B、C依次对同一行修改,均未提交,这个时候,A处于idle
    in
    transaction状态,B持有tuple锁但是等待A的事务锁,C等待B持有的tupe锁。调用函数为ExecUpdate->heap_update->heap_acquire_tuplock

  2. 等待Xmax事务Share锁
    等待事务锁之前,需要释放page锁,这样不会阻塞当前page上其他tuple的访问。调用函数ExecUpdate->heap_update->XactLockTableWait,其他事务commit或者abort后,等待事务会被唤醒,这个时候需要重新检查tuple上的xmax是否发生变化,如果发生变化,需要等待新的xmax事务提交。

MultiXact

对于FOR UPDATE和FOR NO KEY
UPDATE锁,可以方便通过Tuple上的xmax判断谁持有锁,而对于FOR SHARE和FOR KEY
SHARE,一个Tuple上面可能会被多个事务加锁,Tuple上动态维护这些事务代价很高,为了便于维护这些事务状态,postgresql引入了MultiXact机制,把多事务记录到独立buffer和文件中,如图所示。当触发多事务机制时,会生成一个新的MultiXactId,把当前Tuple对应的所有锁成员放在MultiXactMemberPage中,并把新的MultiXactId保存在xmax中。

在这里插入图片描述

总结

postgresql行锁相对于Oracle和MySQL的实现还是有区别的,Oracle记录在ITL中,但是不支持select
for
share,MySQL记录在bitmap中,但是当更新特别多的时候,产生大量的行锁,bitmap会占用大量内存。


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

相关文章

线段树(单点更新 及 区间更新)

单点更新 #include <iostream> using namespace std; int tree[10000]; void buildtree(int arr[],int tree[],int node,int start,int end) {if(startend){tree[node]arr[end];return ;}int left_nodenode*21;int right_nodenode*22;int mid(startend)/2;buildtree(arr,…

mfence, lfence, sfence什么作用?

mfence, lfence, sfence什么作用? // src/backend/utils/rac/lock_free_queu.array_spsc_queue.c #define mb() asm volatile("mfence":::"memory") #define rmb() asm volatile("lfence":::"memory") #define wmb() asm volatile(…

PostgreSQL嵌套事务提交流程研究

PostgreSQL嵌套事务提交流程研究 父事务最终提交代码流程图 事务提交调用流程 其中值得拿出来讲的&#xff0c;主要是TransactionIdSetTreeStatus这个方法。 这里涉及到一个概念&#xff0c;子事务。在PG这个地方&#xff0c;子事务的概念主要指&#xff1a;事务从开始到结束…

Winserver-默认以管理员运行程序

打开secpol.msc 打开本地安全策略找到安全设置--本地策略--安全选项用户账户控制:以管理员批准模式运行所有管理员---改为禁用保存设置重启电脑 转载于:https://www.cnblogs.com/JinweiChang/p/10747632.html

PG内核分析 Question and Answer

PG内核分析 Question and Answer PG系统概述 为什么说PG是一种先进的对象—关系数据库系统 因为PG它不仅支持关系数据库的各种功能, 而且还具备类, 继承等对象数据库的特征. 面向对象数据库技术可望成为继关系数据库技术之后的新一代数据管理技术。 它是一种以关系数据库和…

【问题解决方案】ImportError: No module named 'pygal'

背景 《Python编程&#xff1a;从入门到实践》一书&#xff0c;第二个项目-可视化&#xff0c;第四节用到pygal安装部分用 ‘python -m pip install pygal1.7’ 安装&#xff0c;但使用时仍然报错 ImportError: No module named pygalGoogle后找到的解决方法&#xff1a;(但我这…

《Oracle RAC 核心技术详解》 Question and Answer

《Oracle RAC 核心技术详解》 Question and Answer 第一部分 集群管理软件 集群技术简介 EVM, CRS, CSS Oracle10g版本, Oracle推出了自己的集群管理软件产品----CRS (Cluster Ready Service). 对于集群管理软件—CRS, 主要分为3个组件: CSS (Cluster Synchronization Ser…

VMware centos无法ping通网关问题解决

VMware centos无法ping通网关问题解决 前提 VMware使用的是VMnet0, 在ifcfg-ens33中配置的是静态IP, 网关也是手动设置. 问题 在配置未做任何变化的情况下, 突然发现VMware centos 的网关无法ping通. 原因 VMware 菜单 “编辑” -> “虚拟网络编辑器”, 查看, 发现VMn…