zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

PostgreSQL的事务隔离分析

postgresql事务 分析 隔离
2023-09-14 09:02:10 时间

不懂的同学先补补概念
Reference: WiKi

隔离级别(Isolation levels)

有四种隔离级别:

可序列化(Serializable) 可重复读(Repeatable reads) 提交读(Read committed) 未提交读(Read uncommitted)

昨天被问了一个问题
当存在表test(id int)并有id=1一条记录, 那么以下两种操作会有什么行为

SessionA启动事务后,SessionB做了更新id=2操作后,此时SessionA进行 UPDATE test SET id=id+2,结果如何。 SessionA启动事务后,SessionB在事务中做了更新id=2操作后,先不提交,此时SessionA进行 UPDATE test SET id=id+2,结果如何。

顺着源码分析一下Postgres的是如何实现这种行为的。

提交读(PostgreSQL的默认设置)

在提交读的隔离级别下,
1.行为a的结果,SessionA 进行更新操作前查询id变为2,更新操作成功后,查询id为4。
2.行为b的结果,在SessionB提交前,SessionA的查询id为1,如进行update操作,会一直阻塞直到SessionB提交或回滚,如SessionB成功提交查询id为4,若SessionB回滚,查询id结果为3。

行为1分析

SessionA的运行流程和普通的更新流程类似,先得到需要更新的row,然后进入heap_update,对选定的row使用HeapTupleSatisfiesUpdate进行版本(MVCC)检查,由于SessionB的事务已经提交,所以会得到HeapTupleMayBeUpdated的状态,然后真正进行更新操作。(其中包括hot-update等各种流程就不在此描述)

行为2分析

此时的运行流程会和上面略有不同,当获取目标row时候会得到尚未更新的那行row(因为此row虽然被标记为已删除,但是因为SessionB尚未提交,所以仍然可见),对row进行更新版本检查时,发现此row已经删除,且SessionB还未提交,标记为HeapTupleBeingUpdated,接着尝试取得该row的锁(会等待直到SessionB提交或者回滚),之后检查此row,如果被更新成功(SessionB提交),则进行row的refresh,对refresh后的row重新进行之前的操作,如果更新失败(SessionB回滚),则直接更新。

在可重复读的隔离级别下,
1.行为a的结果, SessionA 进行更新操作前查询id为1,若进行更新操作, 则报错 “could not serialize access due to concurrent update”。
2.行为b的结果, 在SessionB提交前,SessionA的查询id为1,如进行update操作,会一直阻塞直到SessionB提交或回滚,如SessionB成功提交则报错 “could not serialize access due to concurrent update”, 若SessionB回滚,则sessionA 的 UPDATE操作成功,查询id结果为3,

行为1分析

和提交读隔离级别的行为有点类似,但由于是可重复读的快照,所以一开始取得的目标row是更新前的row,也就是id=1(提交读id=2)的行,于是在更新操作的mvcc版本检查中会认为此row是HeapTupleUpdated状态,需要重新refresh row,在refresh对隔离级别进行检查,如果大于等于可重复读的级别,则抛错。

行为2分析

和提交读隔离级别的代码路径一致,只是在 refresh row 时 对隔离级别进行检查,因为此时为可重复读,所以抛错。


云栖重磅发布 - AnalyticDB PostgreSQL 7.0版本,企业级分析能力升级! 云原生数据仓库AnalyticDB PostgreSQL(简称ADB PG) 7.0版本发布公开测试。该版本着重于提升企业级分析能力,安全管理,执行性能等方面,整体性价比显著提升!
【实操系列】基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析 云数据仓库AnalyticDB PostgreSQL 版发布了最新自研的云原生架构实例,实现了跨实例间的数据共享能力。允许进行跨实例间的实时数据共享且无需进行数据迁移,可支持构建安全、高效、灵活的数据分析场景。本文介绍了依托数据共享实现云数仓跨多业务实例的敏捷数据分析方案;
【走进RDS】之SQL Server性能诊断案例分析 数据库性能诊断不仅对其数据库技能要求较高,而且需要大量的前期准备工作,如收集各种性能基线、性能指标和慢SQL日志等,尤其是面对多数据库性能调优时,往往事倍功半。
基于AnalyticDB PostgreSQL + OSS + SLS构建面向应用内行为数据的分析全链路 AnalyticDB PostgreSQL助力某互联网企业完成数仓建设和面向用户行为的全链路分析。通过Serverless版本的性能助力,轻松实现了10+的性价比提升。