PostgreSQL的事务隔离分析
不懂的同学先补补概念
Reference: WiKi
有四种隔离级别:
可序列化(Serializable) 可重复读(Repeatable reads) 提交读(Read committed) 未提交读(Read uncommitted)昨天被问了一个问题
当存在表test(id int)并有id=1一条记录, 那么以下两种操作会有什么行为
顺着源码分析一下Postgres的是如何实现这种行为的。
提交读(PostgreSQL的默认设置)在提交读的隔离级别下,
1.行为a的结果,SessionA 进行更新操作前查询id变为2,更新操作成功后,查询id为4。
2.行为b的结果,在SessionB提交前,SessionA的查询id为1,如进行update操作,会一直阻塞直到SessionB提交或回滚,如SessionB成功提交查询id为4,若SessionB回滚,查询id结果为3。
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,
和提交读隔离级别的行为有点类似,但由于是可重复读的快照,所以一开始取得的目标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+的性价比提升。
相关文章
- Postgresql源码(73)两阶段事务PrepareTransaction事务如何与会话解绑(上)
- Oracle与Postgresql在PLSQL内事务回滚的重大差异
- [译]学习PostgreSQL内核
- Postgresql源码(102)子事务控制语句分析
- PostgreSQL 数据库ROW_NUMBER() OVER()的用法
- postgresql数据库安装部署搭建主从节点的详细过程(业务库)
- Postgresql创建新增、删除与修改触发器的方法
- PostgreSQL数据库事务出现未知状态的处理方法
- PostgreSQL 2201G: invalid_argument_for_width_bucket_function 报错 故障修复 远程处理
- postgresql 物理备份 tar + pigz详解程序员
- psycopg2.pool – Connections pooling / psycopg2.pool – 连接池 / postgresql 连接池详解数据库
- postgresql – 事务详解数据库
- 使用PostgreSQL管理工具简化数据库维护(postgresql管理工具)
- PostgreSQL编码协议:改变数据库架构(postgresql协议)
- 使用阿里云PostgreSQL轻松搭建数据库(阿里云postgresql)
- 能力 PostgreSQL的强大并发能力(postgresql并发)
- Python如何连接PostgreSQL数据库?(python连接postgresql)
- PostgreSQL存储过程:解放开发效率(postgresql存储过程)
- 简易教程:Linux下如何快速安装PostgreSQL数据库(linux安装postgresql)
- 深入解析PostgreSQL扩展:优化数据库性能与拓展功能(postgresql扩展)
- Postgresql安装之路:简单但又重要的指南(postgresql安装教程)
- 分析PostgreSQL源码深度剖析(postgresql源码)
- Postgresql数据库实现事务回滚技术(postgresql回滚)