postgresql 从应用角度看快照snapshot使用,事务隔离控制不再神密
专栏内容:postgresql内核源码分析
个人主页:我的主页
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
快照使用
快照是事务中使用,配合事务的隔离级别,体现出不同的可见性。
快照在事务中自动获取,我们可以通过查看当前事务的快照和事务号来判断分析。为了方便演示,我们先创建一张表
postgres=> create table neworder(o_id integer primary key, o_info varchar, o_time timestamp);
CREATE TABLE
快照查询
第一个事务
postgres=*> select txid_current();txid_current
--------------685103
(1 row)
查看当前事务号为685103
注意 txid_current() 每调一次这个函数,会消费一个事务号,在事务中只消费一个。
postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685103:685103:
(1 row)
查看当前事务的快照,格式为xmin:xmax:运行中的xid列表。
我们看到xmin,xmax 为685103,说明当前没有运行的事务,最新分发的事务号就是685103注意 这里并没有分配正在运行的事务号,只有执行写操作后才开始分配
我们在另一个终端开启一个新事务,查看快照,并没有发现685103在正在运行的列表中
postgres=> begin;
BEGIN
postgres=*> select txid_current();txid_current
--------------685104
(1 row)postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685103:685103:
(1 row)postgres=*> end;
COMMIT
第二个事务
- 在终端一的事务上插入一行数据
postgres=*> insert into neworder values(1,'football',now());
INSERT 0 1
这样做,让此事务有运行中的事务号
- 我们这里在第二个终端重新开启一个事务
postgres=> begin;
BEGIN
postgres=*> select txid_current();txid_current
--------------685105
(1 row)postgres=*> select pg_current_snapshot();pg_current_snapshot
----------------------685103:685105:685103
(1 row)
我们看到当前快照中xmin为685103,正在运行的最小事务号;
xmax为685105 ,正在运行中只有一个事务
不同隔离级别的快照
读已提交
我们启动了两个默认为读已经提交的事务
- 现在在终端二上继续执行
postgres=*> create table neworder1(o1_id int);
CREATE TABLE
postgres=*> select pg_current_snapshot();pg_current_snapshot
----------------------685103:685105:685103
(1 row)
创建了一张表,快照没有发生变化
- 终端一上提交事务
postgres=*> commit;
COMMIT
- 在终端二事务中插入数据
postgres=*> insert into neworder values(2,'basketball',now());
INSERT 0 1
postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685105:685105:
(1 row)
此时查看到的快照发生了变化,xmin为自己事务,当前运行中的事务没有了。
- 原理
读已经提交的快照,在每次命令都会获取新的快照,如果有提交的事务,那么就会变为可见
postgres=*> select * from neworder;o_id | o_info | o_time
------+------------+----------------------------1 | football | 2023-06-21 08:56:43.5416682 | basketball | 2023-06-21 09:15:10.313662
(2 rows)
此时就可以看到前一事务插入的数据
可重复读
- 终端一启动可重复读事务
postgres=> begin isolation level repeatable read ;
BEGIN
postgres=*> insert into neworder values(3,'delicious food',now());
INSERT 0 1
postgres=*> select txid_current();txid_current
--------------685107
(1 row)postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685107:685107:
(1 row)
快照中,此时没有正在运行中的事务,xmin就是自己的事务号
- 终端二启动可重复读事务
postgres=> begin isolation level repeatable read ;
BEGIN
postgres=*> insert into neworder1 values(1);
INSERT 0 1
postgres=*> select txid_current();txid_current
--------------685108
(1 row)postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685107:685107:
(1 row)
快照中,此时运行中的事务xmin为685107,xmax也为685107
- 终端二提交事务
postgres=*> commit;
COMMIT
- 终端一执行插入
postgres=*> insert into neworder values(4,'delicious tomato',now());
INSERT 0 1
postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685107:685107:
(1 row)
事务快照并没有变化
- 原理
对于可重复读,每个事务只获取一次快照,这样可见性在事务开始时就已经确定
快照对于系统字典的隔离
在使用对应的表后,对于读写会产生冲突,导致阻塞;
如果没有使用要修改的表,则不会产生冲突。
读已提交
如果事务没有操作过该表,在另一事务修改提交,就可以看到修改;
先启动事务1,操作表neworder1,然后在事务2操作neworder的表定义,提交事务2后,在事务1进行查看。
事务1
postgres=> begin;
BEGIN
postgres=*> insert into neworder1 values(5);
INSERT 0 1
事务2 修改数据字典
postgres=> begin;
BEGIN
postgres=*>
postgres=*> alter table neworder drop column o_time;
ALTER TABLE
postgres=*> commit;
COMMIT
事务1 查询数据字典的同步,可以看到neworder已经没有了o_time列
postgres=*> select * from neworder;o_id | o_info
------+------------------1 | football2 | basketball3 | delicious food4 | delicious tomato10 | potato
(5 rows)postgres=*> commit;
COMMIT
可重复读
和上面顺序一样,先启动事务1,操作表neworder1,然后在事务2操作neworder的表定义,提交事务2后,在事务1进行查看。
事务1
postgres=> begin;
BEGIN
postgres=*> insert into neworder1 values(5);
INSERT 0 1
事务2 修改数据字典,增加列o_time
postgres=> begin isolation level repeatable read ;
BEGIN
postgres=*> alter table neworder add column o_time timestamp;
ALTER TABLE
postgres=*> commit;
COMMIT
事务1 查询数据字典的同步
postgres=*> select * from neworder;o_id | o_info | o_time
------+------------------+--------1 | football |2 | basketball |3 | delicious food |4 | delicious tomato |10 | potato |
(5 rows)postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685125:685125:
(1 row)postgres=*> select txid_current();txid_current
--------------685125
(1 row)postgres=*>
与预期不一样的事情发了 这里在可重复读时,系统字典的更新可以被看到了。
这一点在源码分析时,没有被关注到。
导出快照
快照还可以保存,被重复使用,有点像科幻中保存记忆一样。
下面我们来看看如何使用这一特异功能。
导出介绍
开启事务1,保存事务1的快照,然后在别一个事务中应用此快照,那么这两个事务看到的内容是一样的。
事务1 启动可重复读事务,并导出快照
postgres=> begin isolation level repeatable read ;
BEGIN
postgres=*> insert into neworder1 values(5);
INSERT 0 1postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685125:685125:
(1 row)postgres=*> select txid_current();txid_current
--------------685125
(1 row)postgres=*> select * from neworder;o_id | o_info | o_time
------+------------------+--------1 | football |2 | basketball |3 | delicious food |4 | delicious tomato |10 | potato |
(5 rows)postgres=*> SELECT pg_export_snapshot();pg_export_snapshot
---------------------00000004-00000058-1
(1 row)
使用旧快照
旧快照能被使用的前提是,生成旧快照必须有事务在使用,否则快照就是一个过期快照
事务2 在启动事务2前,向neworder表中插入数据,然后启动事务2,在其中使用保存的快照
postgres=> insert into neworder values(100,'test dic',now());
INSERT 0 1
postgres=> insert into neworder values(101,'erase',now());
INSERT 0 1
postgres=> select * from neworder;o_id | o_info | o_time
------+------------------+----------------------------1 | football |2 | basketball |3 | delicious food |4 | delicious tomato |10 | potato |100 | test dic | 2023-06-22 10:50:35.238614101 | erase | 2023-06-22 10:55:12.268132
(7 rows)
postgres=> BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGINpostgres=*> set transaction snapshot '00000004-00000058-1';
SET
postgres=*> select * from neworder;o_id | o_info | o_time
------+------------------+--------1 | football |2 | basketball |3 | delicious food |4 | delicious tomato |10 | potato |
(5 rows)postgres=*> select pg_current_snapshot();pg_current_snapshot
---------------------685125:685125:
(1 row)
结尾
非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!
相关文章:

postgresql 从应用角度看快照snapshot使用,事务隔离控制不再神密
专栏内容:postgresql内核源码分析 个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 快照使用 快照是事务中使用,配合事务的隔离级别,体现出不同的可见性。…...
mysql(mariadb)读写分离部署
目录 一、原理 二、准备环境 三、部署mysql主从复制 1.五台服务器下载mariadb 2.修改master配置文件,重启数据库 3.登录mysql创建replication 4.从服务器登录验证 5.获得master服务器 DB的相关信息 6.备份master原有数据 7.修改slave1、slave2配置 8. 进入…...

ES-工作原理
前言 搜索引擎是对数据的检索,而数据总体分为两种:结构化数据和非结构化数据。而对于结构化数据,因为他们具有特定的结构,所以一般都是可以通过关系型数据库MySQL/oracle的二维表的方式存储和搜索,也可以建立索引。…...
C++小结(4)
C 字符串 C 提供了两种类型的字符串表示形式: C 风格字符串C 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字…...

Java框架之spring 的 messaging
写在前面 本文看下spring message相关的内容。 1:Message?Messaging? Message是消息的意思,是一个名词。而Messaging是一个动名词,是将消息发送出去的意思,因此,我们的消息系统是messaging s…...

linux使用grep命令查询nginx的进程情况时总是出现 grep --color=auto nginx
问题: 每次使用ps aux | grep 服务名 命令查询某个服务的进程时,总会出现一条grep --colorauto 服务名 例如: ps aux | grep nginx # 会出现图片中的情况解答: 这是因为grep 也是一条命令,它在输出时,会…...
FFmpeg音视频开发知识点(二)
系列文章目录 FFmpeg音视频开发知识点(一) 文章目录 系列文章目录前言一、AAC音频编码1. ffmpeg编译第三方的libfdk_aac2. S16重采样FLTP 二、AAC音频解码总结 前言 该篇讲解一下,音频编解码中的难点,以及开发过程中遇到问题&am…...

【Java可执行命令】(十)JAR文件签名工具 jarsigner:通过数字签名及验证保证代码信任与安全,深入解析 Java的 jarsigner命令~
Java可执行命令之jarsigner 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法3.1.1 可选参数:jarsigner -keystore < url>3.1.2 可选参数:jarsigner -storepass <口令>3.1.3 可选参数:jarsigner -keypass <口令>3.1.4 可选参…...

c#调用c++ dll,Release版本内存访问错误
最近遇到个比较经典的案例,在c#中调用yara进行文件检测,yara是c编写的一个非常强大库,github有个大佬用c#对其进行了封装,使其能在跨平台下,只需编译yara的so或dll就能直接跑。但总是在Release版本下时不时就崩溃&…...

内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 )
内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 ) 在渗透中,有时候 Cobalt Strike 会话可能会受限制,所以我们需要把 Cobalt Strike 会话转移到 MSF 上进行后面的渗透。也有的时候会话在 MSF 上,但是…...

性能测试讲解超详细Jmeter
目录 什么是性能 性能测试的目的 功能测试和性能测试 基准测试 负载测试 稳定性测试 压力测试 并发测试 总结 性能测试指标 响应时间 并发数 吞吐量 点击数 错误率 资源使用率 总结 性能测试流程 性能测试需求分析 性能测试计划和方案 编辑性能测试用例编辑 性…...
微服务 – Spring Cloud – Nacos 配置中心
微服务 – Spring Cloud – Nacos 配置中心 文章目录 微服务 – Spring Cloud – Nacos 配置中心打开nacos面板新建配置引入依赖配置文件启动类业务类打开nacos面板新建配置 Data ID: nacos-config-client-dev.yaml Group: DEV-CLOUD2023 config:info: config info lalalal …...

超细,设计一个“完美“的测试用例,用户登录模块实例...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 好的测试用例一定…...

【C#】文件拖拽,获取文件路径
系列文章 【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器(开始日期、结束日期) 本文链接:h…...
SAP PI/PO初步了解 2023.07.03
SAP PI/PO 是SAP 提供的一种集成中间件解决方案,用于在组织内部或不同组织之间实现系统的无缝通信和数据交换。它使企业能够以统一高效的方式集成各种应用和系统,无论这些系统的技术平台或数据格式如何。 以下是关于SAP PI/PO的简要概述: 1…...
Java中生产者消费者模型
在Java中,生产者消费者模型是一种常见的多线程编程模型,用于解决生产者和消费者之间的数据交互问题。 简介 生产者(Producer)负责生成数据,并将数据放入共享的缓冲区(队列)中。消费者…...

测试Hyperledger Fabric环境
首先进入fabric-samples目录中的first-networked 子目录 cd fabric-samples/first-network 在first-network目录下有一个自动化脚本byfn.sh,可以使用-help参数查看相应的可 用命令,在命令提示符中输入如下命令: ./byfn.sh --help命令执行成功后&#…...
ClickHouse查询sql长度超超过最大限制
ClickHouse查询sql长度超超过最大限制 Max query size exceeded ClickHouse exception, message: Code: 62. DB::Exception: Syntax error: failed at position 262102 (‘fwm00ud6a3ynu0kaxr.ya0eyemkbzdvrxkhwgchccll’) (line 10406, col 17): fwm00ud6a3ynu0kaxr.ya0eyemk…...

【Axure教程】拖动调整行高列宽的表格
表格是在系统软件中非常常用的工具。表格通常由行和列组成,用于以结构化的方式显示和组织数据。它们在各种场景中都有广泛的应用,包括数据分析、数据录入、报表生成、项目管理和数据可视化等领域。 今天作者就教大家如何在Axure里制作一个能通过鼠标拖动…...

中间件-netty(1)
netty 前言篇 文章目录 一、IO基础篇1.概念1.1 阻塞(Block)和非阻塞(Non-Block)1.2 同步(Synchronization)和异步(Asynchronous)1.3 BIO 与 NIO 对比1.3.1 面向流与面向缓冲1.3.2 阻塞与非阻塞1.3.3 选择器的问世 2.NIO 和 BIO 如何影响应用程序的设计2.1 API调用2.2 数据处理2…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...