当前位置: 首页 > news >正文

PostgreSQL数据库的事务ID和事务机制

PostgreSQL后续简称PG。PG只读事务不会分配事务ID。为了在共享锁等情况下对事务进行标识,需要一种非持久化的事务ID,即虚拟事务ID,vxid。虚拟事务ID不需要把事务ID持久化到磁盘。因为事务ID是很宝贵的资源,简单的select语句不会申请事务ID。vxid由两部分组成:backendId 和backend本地计数器。查看如下:

BEGIN;
SELECT locktype,virtualxid,virtualtransaction,mode FROM pg_locks; -- 查看vxid
SAVEPOINT p1;
SELECT locktype,virtualxid,virtualtransaction,mode FROM pg_locks; -- 子事务的vxid不变
ROLLBACK;
SELECT locktype,virtualxid,virtualtransaction,mode FROM pg_locks;
  • vxid的backendId不是真正的进程号PID,也只是一个简单的递增的编号。
  • vxid的backendId和命令编号都是递增的。
  • 子事务没有自己的vxid,他们用父事务的vxid。
  • vxid也有回卷,不过问题不严重,因为没有持久化,实例重启后vxid从头开始计数。

永久事务是指当发生数据变化的事务开始时,事务管理器会分配一个唯一事务号标识。后续事务指永久事务。事务号Transaction ID,txid,又叫xid,是32位无符号整型,总共可以存储 232=4294967296,42亿多个事务,范围为:0~232-1。同一个数据库中,存在的最旧和最新事务之间的年龄允许最大为2的31次方,约为20亿。其中xid:

  • 0:InvalidXid,无效事务ID。
  • 1:BootstrapXid,表示系统表初始化时的事务ID。最旧。
  • 2:FrozenXid,冻结的事务ID,比任何普通的事务ID都旧。

正常事务号从3开始。在PostgreSQL 7.2之前,当32位事务ID用完时,必须dump然后恢复数据库。之后使用64位I的FullTransactionId,获取epoch和xid如下:

#define EpochFromFullTransactionId(x)	((uint32) ((x).value >> 32))
#define XidFromFullTransactionId(x)		((uint32) (x).value)

epoch是FullTransactionId右移32位,xid(TransactionId)是FullTransactionId对232取模。这相当于把32位的TransactionId看成“环”,循环重复使用;64位的FullTransactionId是一直递增的“线”,几乎取不完。事务启动后会执行内置txid_current函数,该函数会在上次事务加1后返回事务号。

-- PG12及以前用txid_current()。返回的为扩展xid,uint64。
SELECT pg_current_xact_id();
SELECT pg_current_xact_id_if_assigned(); -- 返回当前事务id-- 查看系统初始化时的事务ID
SELECT xmin,count(*) FROM pg_class WHERE xmin=1 GROUP BY xmin;SHOW TRANSACTION_ISOLATION; -- 查看事务隔离级别,默认read committed读已提交-- begin不会立即分配事务id,begin后的第一个非查询语句分配事务id
-- 当一个事务插入了一tuple后,会将事务的txid写入这个tuple的xmin
BEGIN; -- 开启事务
INSERT INTO t_test VALUES(1),(2);
SAVEPOINT my_save; -- 设定事务保存点
INSERT INTO t_test VALUES(3);
ROLLBACK TO my_save; -- 回滚到保存点状态,即不要3这个数字
COMMIT; -- 提交后只有1,2

事务ID对比的函数结构如下:

bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
{/** If either ID is a permanent XID then we can just do unsigned* comparison. If both are normal, do a modulo-2^32 comparison.*/int32        diff;if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))return (id1 < id2);diff = (int32) (id1 - id2);return (diff < 0);
}

函数的基本逻辑为:

  1. TransactionIdIsNormal是判断id是否>=3(FirstNormalTransactionId)。
  2. id1-id2结果溢出,即超过数据存储范围,为使在范围内,对数值加减模长232,比如231减模长为-231
  3. 非正常事务比较:当id1=2,id2=100时,return(2<100),结果为真,正常事务较新;当id1=100,id2=2时,return (100<2),结果为假,正常事务较新。
  4. 正常事务比较:当id1=231+99,id2=100,id1-id2=231-1。int32可以存放,大txid较新;当id1=231+100,id2=100,id1-id2=231。超出int32范围,值为231-232=-231,小txid较新,相当于看不到id2;当id1=100,id2=231+100,id1-id2=-231。这没问题,int32刚好可以存放,大txid较新;当id1=100,id2=231+101,id1-id2=-231-1。超出int32范围,此时的值为-231-1+232=231-1>0,小txid较新,此时进入第1次回卷,即100大于231+101了。
  5. 为了防止出现两者相差231或231-1,将两者差值限制在20亿。这样可以保证提前处理冻结,防止出现4的错误情况。

上面比较看出,当发生数值溢出时,txid大的事务看不见更小的txid事务。为了解决这个问题,pg将40亿事务id分成两半,一半事务是可见的,另一半事务是不可见的。

事务回卷的理解包括两个方面:

  1. 事务ID回卷是为了让事务ID有一个环的概念,这一圈用完了继续向前转,继续循环使用。每到达最大值232之后,事务ID从下一个3开始,只是事务ID的扩展epoch加1。
  2. 因为事务ID将环分成2半,一般可见,一般不可见。事务ID跨越超过一半说明事务ID就是回卷了,此时超过一半的那部分事务数据虽然存在但无法查到等效于丢失了。为了解决这个问题需要处理冻结事务ID的操作。保证事务ID不超过21亿(具体是231-1)。冻结的事务ID都是可见的。

为了解决上面2的回卷问题,PG采用冻结的方式处理事务ID,相关配置参数:

  • vacuum_freeze_min_age:元组xmin比当前txid-该参数值的差更旧时,会进行freeze,也就是有元组年龄或表年龄超过该值后进行freeze。该参数最大值为20亿,最小值为2亿。
  • vacuum_freeze_table_age:表的年龄超过该值会进行aggressive vacuum。该参数最大值为20亿,最小值为1.5亿。如果为0,则每次扫描表都进行aggressive vacuum。
  • autovacuum_freeze_max_age:表的年龄超过该值强制执行autovacuum。该参数最小值为2亿,最大值为20亿。即经过autovacuum_freeze_max_age-vacuum_freeze_min_age的txid增长之后,表肯定会被强制进行一次freeze。因为autovacuum_freeze_max_age最大值为20亿,所以在两次freeze之间,txid的增长肯定不会超过20亿,这就保证了上文中所说的20亿原则。

每次表被freeze之后,会更新pg_class.relfrozenxid列为本次freeze的最大txid。该列保存对应表最近冻结的txid,意味着小于此值的txid均已被冻结。表的年龄为当前最新txid与relfrozenxid的差值。元组年龄其t_xmin与对应表relfrozenxid的差值。

相关文章:

PostgreSQL数据库的事务ID和事务机制

PostgreSQL后续简称PG。PG只读事务不会分配事务ID。为了在共享锁等情况下对事务进行标识&#xff0c;需要一种非持久化的事务ID&#xff0c;即虚拟事务ID&#xff0c;vxid。虚拟事务ID不需要把事务ID持久化到磁盘。因为事务ID是很宝贵的资源&#xff0c;简单的select语句不会申…...

LeetCode 热题 HOT 100 (020/100)【宇宙最简单版】[创作中]

【链表】No. 0142 环形链表 II【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#…...

XML动态sql查询当前时间之前的信息报错

如图&#xff0c;sql语句在数据库里可以正常运行但是再XML文件不可以正常运行&#xff0c;报错。 原因&#xff1a;在XML中小于号"<"是会被默认认定成文一个标签的开始&#xff0c;所以用小于号就会报错。 解决办法&#xff1a; 1.把表达式反过来改成大于号 2…...

EMQX服务器安装MQTT测试

cd /usr/local/develop wget https://www.emqx.com/en/downloads/broker/5.7.1/emqx-5.7.1-el7-amd64.tar.gz mkdir -p emqx && tar -zxvf emqx-5.7.1-el7-amd64.tar.gz -C emqx ./emqx/bin/emqx start 重启 ./emqx/bin/emqx restart http://10.8.0.1:18083/ 账号ad…...

3. 无重复字符的最长子串(滑动窗口)

目录 &#xff1a;题目&#xff1a; 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一&#xff1a;题目&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 二&#xff1a;代码&#xff1a; class Solution { …...

用javaagent和javassist实现Arthas的watch功能

一、被监控的服务 spring-boot-demo 1、 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&q…...

golang 图片转1bit color bmp图片

问题背景 一些打印机需要的都是1bit color bmp图片,但是golang中没有直接的办法,官方image库最低bpp为8,打印机无法使用。 在github上找到了很多资源,都没有直接能转的,突然看到一个老外,可以支持plattered图片转位1bit color bmp图片,然后自己先把图片转位plattered黑…...

Leetcode75-5 反转字符串的元音字母

本质上来说就是反转字符串 一部分需要反转 一部分不动 思路: 1.用String字符串倒序拼接 就是过滤掉不是元音字符 然后把所有的字符&#xff08;非元音的直接复制过来 元音字母直接从反转的字符串里边复制即可&#xff09; 2.看了题解发现自己写的啰嗦了 就是一个双指针问题用…...

static关键字在Java中的作用与用法

static关键字在Java中的作用与用法 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java中&#xff0c;static关键字是一个非常重要的概念&#xff0c;用于定义静态成员、方法和内部类。它的使用可…...

50etf期权行权采用什么交割方式 ?

50ETF期权是欧式期&#xff0c;要到期日当天才能行权交制&#xff0c;其交割方式是实物交割买卖双方在到期行权日时需要准备一手交钱&#xff0c;一手收货或是一手交&#xff0c;一手收钱&#xff0c;如果持有期权到达到期日之前&#xff0c;投资者认为行权并不划算&#xff0c…...

ts-node 报错 ERR_UNKNOWN_FILE_EXTENSION

问题 有个monorepo项目&#xff0c;在最外层一次性打包 3 个项目的脚本已经成功实现&#xff0c;如下&#xff1a; "build:test": "cross-env NODE_ENVtest vite build --mode test && esno ./build/script/postBuild.ts", "build:prod"…...

水域救援设备,保护水域安全_鼎跃安全

季作为一年中最炎热的季节&#xff0c;不仅带来了难耐的高温&#xff0c;也悄然间加剧了水域安全问题的严峻性。这一时期&#xff0c;正值学生群体享受悠长暑假的宝贵时光&#xff0c;他们往往倾向于寻找清凉之地以解酷暑&#xff0c;水域因此成为了不少学生的首选之地。然而&a…...

openmetadata本地编译环境搭建

openmetadata本地编译环境搭建 本地环境&#xff1a; Docker 20 or higher Java JDK 17 Antlr 4.9.2 - sudo make install_antlr_cli JQ - brew install jq (osx) apt-get install jq (Ubuntu) Maven 3.5.x or higher - (with Java JDK 11) Python 3.7, 3.8 or 3.9 Node…...

LeetCode Hard|【25. K 个一组翻转链表】

力扣题目链接 首先我们考虑一种很直观的思路&#xff1a; 遍历链表&#xff0c;统计链表长度遍历链表&#xff0c;进行翻转 对于每一组长度为 K 的节点&#xff0c;进行翻转如果剩余节点不足 K 个&#xff0c;则不进行翻转 连接翻转后的子链表 这里我们用的就是只用 O(1) 额外内…...

python爬虫预备知识三-多进程

python实现多进程的方法&#xff1a;fork、multiprocessing模块创建多进程。 os.fork方法 os.fork方法只适合于unix/linux系统&#xff0c;不支持windows系统。 fork方法调用一次会返回两次&#xff0c;原因在于操作系统将当前进程&#xff08;父进程&#xff09;复制出一份…...

【zlm】针对单个设备的音频的编码的设置

目录 结论 原理 测试 结论 为了防止zlm音频配置里设置成opus优先&#xff0c;在国标推流时&#xff0c;调用push时&#xff0c;默认加上codecpcma 如下 https://10.60.100.196:10443/index/api/webrtc?applive&streamtest&typepush&codecpcma 原理 测试 …...

文案人的梦工场,网易入职指南!

网易云对于咱们一些有点文艺的文案策划来说&#xff0c;简直就是梦中情司。 在这里工作锻炼机会很多&#xff0c;也很开拓眼界&#xff0c;能获得相当于在别处3倍能力的成长速度&#xff0c;福利待遇也是很好的。 要进入网易云音乐做文案策划&#xff0c;你可以按照以下步骤进…...

做一个能和你互动玩耍的智能机器人之七-接入对话和大模型

接入科大迅飞的语音识别&#xff1a; private void printResult(RecognizerResult results) {String text JsonParser2.parseIatResult(results.getResultString());String sn null;// 读取json结果中的sn字段try {JSONObject resultJson new JSONObject(results.getResult…...

阿里巴巴商家联系方式采集软件使用教程

以下是一个批量访问阿里巴巴商家店铺的Python代码示例&#xff1a; import requestsdef visit_shop(shop_url):try:response requests.get(shop_url)if response.status_code 200:print(f"成功访问店铺&#xff1a;{shop_url}")else:print(f"访问店铺失败&am…...

Golang | Leetcode Golang题解之第326题3的幂

题目&#xff1a; 题解&#xff1a; func isPowerOfThree(n int) bool {return n > 0 && 1162261467%n 0 }...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...