论Postgres的“已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的”...
1.阐述
最近在网上看到这样一句话Postgres“已提交的而且 xmin 比当前事务的XID小的记录对当前事务才是可见的”。先不评断这句话的正确性;看下这句话的结构,因果关系;
- 事务已经提交(commit);
- 提交时插入记录的xmin 小于 当前current_txid(事务id)。
2. 举例验证
- 事务隔离级别READ COMMITTED
--session A 事务id为1844;
postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1844--session B 事务id为1845;并在插入一条记录在lottu05表(未提交)
postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1845postgres=# insert into lottu05 values (1001,'lottu');
INSERT 0 1--在session A/B查看记录; session A读不到记录; session B可以读到记录。
postgres=# select * from lottu05;id | name
----+------
(0 rows)--在session B提交插入的记录;在查看session A是否可以看到记录。
postgres=# select xmin,* from lottu05;xmin | id | name
------+------+-------1845 | 1001 | lottu
--表明session A(当前事务为ID:1844)可以读 插入记录事务id为1845 已经提交的记录。
--总结: 事务隔离级别为读已提交(READ COMMITTED)就是读已经提交的记录。
由此可见,对读已提交隔离级别而言"已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的"是不正确的。
而网上的解释:也是必要不充分条件。那该如何诠释这说话呢?请看下文讲解
是根据当前postgres系统的当前事务ID相比;目前系统下一个事务ID为1846
-- 我们现在看下当前postgres系统 下一个事务id
[postgres@localhost ~]$ pg_controldata |grep NextXID
Latest checkpoint's NextXID: 0/1846
--意思是说这条记录后面开启会话从事务id:1846是可见的。不充分的是事务ID:1844也可以读到该记录。
--然而这句话来源何处;我想是有依据的。接下来我们做一个实验。模拟postgrs穿越到过去。 --session C 现在插入1002-1008条记录;结果如下:
postgres=# select xmin,id,name from lottu05;xmin | id | name
------+------+---------1845 | 1001 | lottu1846 | 1002 | lottu021847 | 1003 | lottu031848 | 1004 | lottu041849 | 1005 | lottu051850 | 1006 | lottu061851 | 1007 | lottu071852 | 1008 | lottu08 --我们现在使用将数据库postgres回到 txid 为1849。注意:该动作不建议操作;
[postgres@localhost ~]$ pg_stop
waiting for server to shut down.......... done
server stopped
[postgres@localhost ~]$ pg_resetxlog -x 1849 $PGDATA
Transaction log reset
[postgres@localhost ~]$ pg_start
server starting
[postgres@localhost ~]$ psql
psql (9.5.0)
Type "help" for help.postgres=# select xmin,id,name from lottu05;xmin | id | name
------+------+---------1845 | 1001 | lottu1846 | 1002 | lottu021847 | 1003 | lottu031848 | 1004 | lottu041849 | 1005 | lottu05
--可以看到上面的xmin:(1850-1852)是不可见的。
--等数据库的事务ID超过1852;这些数据可以展示出来。
postgres=# select txid_current();txid_current
--------------1850postgres=# select txid_current();txid_current
--------------1851postgres=# select txid_current();txid_current
--------------1852postgres=# select xmin,id,name from lottu05;xmin | id | name
------+------+---------1845 | 1001 | lottu1846 | 1002 | lottu021847 | 1003 | lottu031848 | 1004 | lottu041849 | 1005 | lottu051850 | 1006 | lottu061851 | 1007 | lottu071852 | 1008 | lottu08 --从这个实验看来 确实是需要满足网上所说的两个条件。上面也提过;该操作不建议操作。设想;当前时代若可以穿越到历史上各个时代;那历史不乱套了吗?同理如此。
所以说对隔离级别为READ COMMITTED而言;如同它字面解释一样;只要记录COMMITTED;就可以读到。注意:
--1.该操作不等同 oracle的flashback操作;虽然回到了历史;历史上已经发生的还是会发生。
--2.该操作并不能做数据恢复操作。若对数据做删除进行恢复;可以参考--http://www.cnblogs.com/lottu/p/5761885.html
- 事务隔离级别:REPEATABLE READ
--开启SESSION A; ctid为1857。
postgres=# truncate table lottu05;
TRUNCATE TABLE
postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1857--开启session B;隔离级别为REPEATABLE READ。事务id为:1858
postgres=# begin ISOLATION LEVEL REPEATABLE READ;
BEGIN
postgres=# select txid_current();txid_current
--------------1858 --在session A插入 10条记录并提交
postgres=# insert into lottu05 select generate_series(1001,1010),'lottu'||generate_series(1,10);
INSERT 0 10
postgres=# commit;
COMMIT--在session B查看是否可以读到记录
postgres=# select * from lottu05;id | name
----+------
(0 rows) --结果表明session B 读不到 已经提交且 事务ID:1857比session B的事务ID为1858要小的记录。
3.总结
论Postgres的“已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的”...相关推荐
- MVCC如何实现数据库读已提交和可重复读这两种隔离级别?
文章目录 隐藏列 undo log ReadView 读已提交和可重复读的实现 我们都知道Mysql有四种事务隔离级别: 读未提交 读已提交 可重复读 串行化 这四个隔离级别的特点就不多赘述了,这次主 ...
- git更改已提交作者用户名
git更改已提交作者用户名 官网地址 配置作者用户名 为当前本地库单独配置作者信息 git config -f .git/config user.name "name" git c ...
- 将.gitignore应用于已提交的文件
本文翻译自:Applying .gitignore to committed files I have committed loads of files that I now want to igno ...
- 如何修改git已提交记录的邮箱?
有时候,公司提交的代码必须使用公司邮箱,而你误操作,直接把自己个人邮箱提交上去了,此时你就会遇到这样的需求:如何修改git已提交的邮箱? 而这个需求对于新手来说,往往要花费半天的时间才能理解修改过程, ...
- git修改已提交记录的注释
已提交暂存区但还未提交远端仓库 命令:git commit --amend -m 已提交远端仓库 命令:git rebase 可以参考:http://www.cnblogs.com/dudu/p/47 ...
- php表单的提交方法有什么,php – 确定哪个表单已提交的最佳方法是什么?
目前,当我设计表单时,我喜欢将提交按钮的名称保持等于表单的id.然后,在我的php中,我只是执行if(isset($_ POST ['submitName']))以检查表单是否已提交以及表单已提交. ...
- 本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github
一.关于NoSQL的项目需求 这些年在做AgileEAS.NET SOA 中间件平台的推广.技术咨询服务过程之中,特别是针对我们最熟悉的医疗行业应用之中,针对大数据分析,大并发性能的需求,我们也在慢慢 ...
- 科创板拟上市企业申联生物和传音控股已提交注册
[TechWeb]8月9日消息,今日,上交所官网更新的信息显示,科创板拟上市企业申联生物医药(上海)股份有限公司和深圳传音控股股份有限公司已提交注册. 申联生物医药(上海)股份有限公司成立于2001年 ...
- git修改已提交commit的Author信息
在 git 中可以通过 git commit --amend 来修改最近一个已提交 commit 的 Author 信息,使用如下: git commit --amend --author " ...
最新文章
- elasticsearch查询
- Javascript中的0,false,null,undefined,空字符串对比
- matlab从入门到精通-matlab计算机仿真与蒙特卡洛法【数学建模】
- 在linux中安装oracle中文包,在Linux命令行下安装Oracle 10g
- 服务中没有telnet_win7 服务中没有 prints pooler
- Go 语言为什么能成功?
- synchronized锁机制 之 代码块锁
- tensorflow错误:InvalidArgumentError (see above for traceback): Cannot assign a device for operation
- python - super 寻找继承关系
- 彭旭老师《一线员工执行力提升训练》
- linux分布式文件部署,Linux的企业-分布式文件系统mfs(moosefs)搭建与配置
- truecrypt linux用法,TrueCrypt for Linux好吗
- Photoshop cc2019 破解教程
- Radon变换理论介绍
- 我的个人网站:红色石头的机器学习之路
- 市面上的手机银行的简介
- win7配置计算机失败还原更改,win7系统更新失败 卡在还原更改处的解决方法
- oracle function
- Vuex - 持久化
- weblogic8.1 下载地址
热门文章
- 【Hive】Hive分区表
- WCF中因序列化问题引起的异常和错误。
- 【ROS系统】解决找不到用户工作空间下的程序包的问题——E:No such package
- [Android Pro] java.lang.IllegalStateException: Fragment(XXFragment) not attached to Activity异常
- 另一个SqlParameterCollection 中已包含 SqlParameter[解决方案]
- 前端常见跨域解决方案
- 深度学习解决NLP问题:语义相似度计算
- Windows10 解决“装了 .NET Framework 4.5.2/4.6.1/4.7.1等等任何版本 或版本更高的更新”问题
- 【问答语录】为什么各大公司请敏捷开发咨询顾问,都偏向项目管理,是不是偏了?没有核心技术思想,管理能解决实质问题?
- SSH连接linux时,长时间不操作就断开的解决方案(增强版)