首页 > 数据库 >POSTGRESQL RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解

POSTGRESQL RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解

时间:2023-06-19 17:05:14浏览次数:47  
标签:POSTGRESQL -- 事务处理 txid assigned xmin SESSION xmax test


POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_数据

有一个同学在PGFANS 群里面提了一个问题,在他实验的某个操作中发现PG 和 ORACLE 使用同样的操作流程后,得到的结果不一致。所以下面准备验证并找到一些可以解释的原因。

测试库名test

测试表 test

测试数据

id    age 

1     20

2     22

3     24

首先我们要确认 PG 的隔离 RC的模式 ,另外我要排除一些不存在的问题

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_数据库_02

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_隔离级别_03

下面是整个的操作流程,由于截图需要截图好几个,不利于查看,所以将其变成文字,并序列化, 每行中有执行的顺序号 和 属于的SESSION 

1   test=# begin;  SESSION 1   #开始SESSION 1 

BEGIN

2 test=# select xmin,xmax,cmin,cmax,* from test;  SESSION 1

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

 2027735 |    0 |    1 |    1 |  1 |  20

(2 rows)

#查看当前的每行的事务情况

3  test=# select txid_current_if_assigned();   SESSION 1

 txid_current_if_assigned 

--------------------------

                         

(1 row)

# 当前并未生成事务号

4 test=# begin;  SESSION 2  # 同时启动SESSION 2

BEGIN

test=# select * from test;  SESSION 2

 id | age 

----+-----

  2 |  40

  1 |  20

(2 rows)

# SESSION 2 中查看到的数据

 5 test=# select txid_current_if_assigned();  SESSION 2

 txid_current_if_assigned 

--------------------------

                         

(1 row)

6 test=# select txid_current_if_assigned();  SESSION 2

 txid_current_if_assigned 

--------------------------

                         

(1 row)

7 test=# delete from test where id =1 ;  SESSION 1

DELETE 1

test=# select txid_current_if_assigned();

 txid_current_if_assigned 

--------------------------

                  2027737

(1 row)


#SESSION 1 删除了数据

8 test=# update test set age = 100 where id =1 ;  SESSION 2   WAITING...................

UPDATE 0

test=# select txid_current_if_assigned();

 txid_current_if_assigned 

--------------------------

                  2027738

(1 row)

#SESSION 2 更新数据  处于等待状态

9  test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

(1 row)

10test=# select txid_current_if_assigned();  SESSION 1

 txid_current_if_assigned 

--------------------------

                  2027737

(1 row)

11 test=# select xmin,xmax,cmin,cmax,* from test;  SESSION 2

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

 2027737 |    0 |    1 |    1 |  1 |  20

(2 rows)

#SESSION 1 插入数据

12 test=# insert into test (id,age) values (1,20);  SESSION 1

INSERT 0 1

test=# select txid_current_if_assigned();

 txid_current_if_assigned 

--------------------------

                  2027737

(1 row)

13 test=# select xmin,xmax,cmin,cmax,* from test;  SESSION 1

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

 2027737 |    0 |    1 |    1 |  1 |  20

(2 rows)

14  test=# commit;  SESSION 1

COMMIT

#SESSION 1 COMMIT

15  test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

 2027737 |    0 |    1 |    1 |  1 |  20

(2 rows)

16   test=# commit;         SESSION  2   

COMMIT

#SESSION 2 COMMIT

17 test=# select xmin,xmax,cmin,cmax,* from test;  SESSION 2

  xmin   | xmax | cmin | cmax | id | age 

---------+------+------+------+----+-----

 2027732 |    0 |    0 |    0 |  2 |  40

 2027737 |    0 |    1 |    1 |  1 |  20

(2 rows)

结果:SESSION 2 不会更新 SESSION 1中后插入的数据。

从上面的步骤中我们能看到或者领会到PG 的那些特性

  • 事务ID 是自增的  
  • 每行数据会用(t_xmin, t_xmax)来标示自己的可用性
  • t_xmin 存储的是产生这个元组的事务ID,可能是insert或者update语句t_xmax 存储的是删除或者锁定这个元组的XID
  • 事务只能看见t_xmin比自己XID 小且没有被删除的元组

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_数据库_04

以上是官方文档中的提示,已经明确的说明了上述的问题,并且也给出了一些建议。

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_隔离级别_05

那我们的工作到底完成了没有,没有,我们提升PG 的隔离级别到 RR.

结果如下:

SESSION 1

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_隔离级别_06

SESSION 2

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_数据_07

在将SESSION的级别提升后,结果就变化了,再次在SESSION 2中操作,直接报错。

最后的问题是,提出问题的同学反映ORACLE 与PG的在类似的环节情况下,反馈的情况不一。同时我这边也通过MYSQL 8 来将上述的操作同样做了,与那位同学反映的情况一样。

个人认为这并不是PG数据库本身的缺陷,这是一种数据库处理某种复杂情况和隔离级别对数据一致性的一种取舍。

如果遇到这样的情况如何操作,有如下建议

1  可以提高数据库的隔离级别到RR (如果你的数据库中有类似业务或操作)

2  在设计业务逻辑时,通过逻辑删除而不是物理删除来对业务表进行操作。

3 可以在操作时添加 selecr for update 类似这样的语句对于数据的可操作性进行一个确认。

POSTGRESQL  RC事务处理与ORACLE MYSQL 的区别 --对PGFANS 群里面的问题的分解_数据库_08

标签:POSTGRESQL,--,事务处理,txid,assigned,xmin,SESSION,xmax,test
From: https://blog.51cto.com/u_14150796/6515998

相关文章

  • 数智人力:如何通过搭建全球人才供应链帮助企业海外扩张?
    在不确定性、不连续性的复杂商业环境和数字化浪潮的推动下,中国企业正在寻求全球化经营的新模式。过去依赖单一能力(如规模市场、低成本产品、渠道拓展等)的发展模式已经不再适用,取而代之的是战略能力、业务能力、组织能力的全球化经营模式。为了支撑进一步的飞跃,中国企业需要不断领先......
  • vim敲字如弹琴
    本篇文章主要讲解vim的常用命令,当你在妹子面前像弹琴一样的敲代码完成给她的惊喜的时候,萌妹子会不会对你顶礼膜拜,发出崇拜的小星星呢?1.显示行数vim打开文件之后输入:setnumber或:setnu2.光标移动h光标向左移动j光标向下移动k光标......
  • POSTGRESQL analyze table 到底做了什么与扩展统计
    PostgreSQL 中对表的状态是有单独的命令来进行状态的收集的,到底怎么对表来进行状态的收集,并且都做了什么,我们怎么来依靠这些信息来对查询进行有益的帮助。这些都将在这篇文章里面探讨。首先我们对PG12中,关于Analyze 的注释来仔细的阅读一遍ANALYZE collectsstatisticsabout......
  • POSTGRESQL PG_REWIND 从源代码看功能
    PG_REWIND是PG9.6开始提供的功能,主要的作用在于通过PG_REWIND让PG复制中的数据库快速的与预定的“主库”进行数据同步,而复制的方式是是文件块的方式,并且可以避过重复的数据块。所以复制的速度是快的,在不少的高可用方式中都被作为主库失败后的快速的将主库加入原有集群并作为从......
  • 分布式两大流派 POSTGRESQL -XC 了解一下
    分布式数据库有两大流派,NEWSQLVS POSTGRESQL-XC,NEWSQL的分布式主流的理论来源自GOOGLE的分布式数据库spanner,以及相关理论的白皮书,而令一派的分布式数据库来自于POSTGRESQL-XC,今天我们看看到底POSTGRESQL-XC这个流派的方式是什么,有什么特点,当下那些分布式数据库采用了......
  • POSTGRESQL Postgres-XL 了解一下
    上次分析的POSTGRES-XC的结构, 实际上POSTGRES-X系列一直在发展, POSTGRES除了XC还有XL的高可用的结构.Postgres-XL是一款Postgres-XC升级的产品,如果说PGXC是在PG添加了集群的功能主打OLTP的功能为卖点,PGXL是一款基于PGXC添加了OLAP功能的支持MPP架构的,但不是简单的PO......
  • POSTGRESQL 创建一个表到底有什么说的? 可说的挺多的
    创建一张表,到底有什么说的, 下面是POSTGRESQL创建数据表的官方文档的内容截图. 那我们就往下看,到底我们可以说点什么建表的开头是关于临时表的问题,其中临时表的global和local,在目前的V12的版本中并没有具体的含义,问题1,POSTGRESQL怎么创建一个看似global的temparytab......
  • POSTGRESQL 主节点失败后, 在多变的情况下重新让他融入复制中
    POSTGRESQL 在主从流复制中,在主库失败切换后,从库变为主库后,如果主库不是因为硬件的原因,想继续拉起来,并且加入到新的复制关系中,一般都会通过pg_rewind的程序来进行拉起来.但不少问题反馈对pg_rewind在重新拉起旧主库出现问题,到底有什么情况下pg_rewind对你的数据库重新建立......
  • POSTGRESQL 设置hugepage 可以让系统使用内存更有效率,防止OOM
    https://www.percona.com/blog/why-linux-hugepages-are-super-important-for-database-servers-a-case-with-postgresql/https://bbs.huaweicloud.com/blogs/detail/156799Hugepage是什么,基于LINUX系统,大页面对虚拟内存管理是有必要的。除标准的4KB页面之外,还进行内存中的大页面......
  • POSTGRESQL 怎么通过explain 来分析SQL查询性能
    Explain命令是大多数数据库常用的一种展示SQL执行计划和cost的一种方式。在POSTGRESQL中EXPLAIN命令展示的信息比较详细,并且附带explain有不少的附加的命令来进行更多的展示。从命令来命令和功能来划分explainselecta.first_name,a.last_name,a.last_update,fa.film_idfrom......