背景

sys_stat_activity视图中用两个字段表示:

backend_xid表示事务开始需要申请的事务id

backend_xmin表示一个事务快照,表示当前数据库中最小的正在运行的事务号,这个快照有可能是很久之前申请过的快照号,如果事务不结束,那么这个快照号一直保留,这符合MVCC特性,但是代价是表膨胀,vacuum不能及时回收。

我们可以通过这两个字段判断数据库中是否有长事务:

  1. select * from sys_stat_activity where state<>'idle' and pg_backend_pid() != pid and (backend_xid is not null or backend_xmin is not null ) and extract(epoch from (now() - xact_start)) > 3; <时间阈值,单位秒> ;

下面我们看一下不同隔离级别下xmin的变化情况,借此理解MVCC。

实验

repeatable read隔离级别的事务,事务的第一条SQL会获取快照(xmin),快照持续到事务结束释放。

[](javascript:void(0)

  1. session A:
  2. 获取当前会话PID,并开启一个repeatable read隔离级别的事务
  3. test=# select sys_backend_pid();
  4. sys_backend_pid
  5. ----------------
  6. 25481
  7. (1 row)
  8. test=# begin transaction isolation level repeatable read;
  9. BEGIN
  10. session B:
  11. 查询会话Axmin,xid
  12. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=25481;
  13. pid | backend_xid | backend_xmin
  14. -------+-------------+--------------
  15. 25481 | |
  16. (1 row)
  17. session A:
  18. 执行第一条SQL
  19. test=# select 1;
  20. ?column?
  21. ----------
  22. 1
  23. (1 row)
  24. session B:
  25. 115494session A事务开启时数据库集群中未分配的最小事务号,或者未结束的最小事务号
  26. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=25481;
  27. pid | backend_xid | backend_xmin
  28. -------+-------------+--------------
  29. 25481 | | 115494
  30. (1 row)
  31. session B消耗2个事务(使用两种方法,各消耗1个事务ID)
  32. test=# select txid_current();
  33. txid_current
  34. --------------
  35. 115494
  36. (1 row)
  37. test=# insert into tbl1 values (1);
  38. INSERT 0 1
  39. session A:
  40. 执行第二条SQL
  41. test=# select 2;
  42. ?column?
  43. ----------
  44. 2
  45. (1 row)
  46. session B:
  47. 对于repeatable read隔离级别的事务来说,xmin不会变化。
  48. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=25481;
  49. pid | backend_xid | backend_xmin
  50. -------+-------------+--------------
  51. 25481 | | 115494
  52. (1 row)
  53. session A:
  54. 执行一条会申请XIDSQL,例如插入数据。
  55. test=# insert into tbl1 values (1);
  56. INSERT 0 1
  57. session B:
  58. xid有值了,为session A对应事务申请下来的事务号,是已消耗掉的,XID不会变化。
  59. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=25481;
  60. pid | backend_xid | backend_xmin
  61. -------+-------------+--------------
  62. 25481 | 115495| 115494
  63. (1 row)

[](javascript:void(0)

read committed隔离级别的事务,事务的每一条SQL都会获取快照,SQL执行结束就会释放快照。

[](javascript:void(0)

  1. session A:
  2. 获取当前会话PID,并开启一个read committed隔离级别的事务
  3. test=# select sys_backend_pid();
  4. sys_backend_pid
  5. ----------------
  6. 57479
  7. (1 row)
  8. test=# begin transaction isolation level read committed;
  9. BEGIN
  10. session B:
  11. 查询会话Axmin,xid
  12. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=57479;
  13. pid | backend_xid | backend_xmin
  14. -------+-------------+--------------
  15. 57479 | |
  16. (1 row)
  17. session A:
  18. 执行第一条SQL
  19. test=# select 1;
  20. ?column?
  21. ----------
  22. 1
  23. (1 row)
  24. session B:
  25. 并没有观察到xmin,因为select 1;开始时获取,SQL执行结束,xmin马上就释放了
  26. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=57479;
  27. pid | backend_xid | backend_xmin
  28. -------+-------------+--------------
  29. 57479 | |
  30. (1 row)
  31. session A:
  32. 执行第一条long SQL
  33. test=# select sys_sleep(20);
  34. session B:
  35. sys_sleep执行结束前查看,可以观察到xminSQL执行结束再查看xmin就会消失。
  36. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=57479;
  37. pid | backend_xid | backend_xmin
  38. -------+-------------+--------------
  39. 57479 | | 78339
  40. (1 row)
  41. session B:
  42. session B消耗2个事务(使用两种方法,各消耗1个事务ID)
  43. test=# select txid_current();
  44. txid_current
  45. --------------
  46. 78339
  47. (1 row)
  48. test=# insert into tbl1 values (1);
  49. INSERT 0 1
  50. session A:
  51. 执行第2long SQL
  52. test=# select sys_sleep(20);
  53. session B:
  54. sys_sleep执行结束前查看,可以观察到xminSQL执行结束再查看xmin就会消失。
  55. xmin与第一条SQL看到的78339不一样,因为read committed隔离级别的事务,每条SQL开始时都会新申请快照。注意这里和repeatable read隔离级别不一样,它对应的xmin不会变化。
  56. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=57479;
  57. pid | backend_xid | backend_xmin
  58. -------+-------------+--------------
  59. 57479 | | 78341
  60. (1 row)
  61. session A:
  62. 执行一条会申请XIDSQL,例如插入数据。
  63. test=# insert into tbl1 values (1);
  64. INSERT 0 1
  65. session B:
  66. xid有值了,为session A对应事务申请下来的事务号,是已消耗掉的,XID不会变化,直到事务结束(session A commit后,backend_xid78341变为空)。而backend_xmin为空表示已经没有未结束的最老的快照版本。这是好的现象,这不会引起表膨胀后vacuum进程回收失败。
  67. test=# select pid,backend_xid,backend_xmin from sys_stat_activity where pid=57479;
  68. pid | backend_xid | backend_xmin
  69. -------+-------------+--------------
  70. 57479 | 78341 |
  71. (1 row)

[](javascript:void(0)

总结

以上实验帮助大家理解不同隔离级别下,根据pid查出backend_xid,backend_xmin对应的区别变化,更好理解这两个字段的涵义。当这两个字段任何一个有值时都表示有未结束的事务,这也对应起来开头提到的查询长事务的语句中的where条件:backend_xid is not null or backend_xmin is not null。

当然我们最常用的隔离级别是read committed,这是我们KES数据库的默认隔离级别,也是oracle的默认隔离级别。只有一些特殊的业务场景需要用到repeatable read隔离级别。

KingbaseESV8R6不同隔离级下xmin的区别的更多相关文章

  1. python 里面的单下划线与双下划线的区别

    python 里面的单下划线与双下划线的区别 Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __ ...

  2. 测试Python类成员的单下划线,双下划线,两头下划线的区别

    首先原谅一个菜鸟叫他“两头下划线”.记得在windows编程中,很多宏定义使用下划线+大写,给人逼格很高的错觉.对于Python下划线的认识,大概是从__dict__这个属性开始的,看__dict__ ...

  3. php windows与linux下的路径区别

    php windows与linux下的路径区别windows用的是"\",linux用的是"/"这一点要特别清楚,, ps:在PHP windows也可以用/表 ...

  4. 114、drawable和mipmap 目录下图片的区别

    android 在 API level 17 加入了 mipmap 技术,对 bitmap 图片的渲染支持 mipmap 技术,来提高渲染的速度和质量.mipmap 是一种很早就有的技术了,翻译过来就 ...

  5. C++和C在linux下 和在windows下有什么区别?

    一.函数库的区别 linux下的C函数库和windows下的函数库系统调用的机制不一样,Glibc包含了主要的C库.这个库提供了基本例程,用于分配内存.搜索目录.打开关闭文件.读写文件.字串处理.模式 ...

  6. Python 私有变量中两个下划线 _ _item 与 一个下划线的区别 _item

    python中没有常量的说法, 但是可以通过元组实现一个常量 在python的私有变量中, 存在两个下划线 _ _item 与一个下划线 _item 的区别 前面带两个下划线的私有变量: 只能在本类中 ...

  7. 【HTML&CSS】 第二章:标准模式下的页面与怪异模式下的页面区别

    盒模型 前面提到,盒模型(box mode)是浏览器 Quirks Mode 和 Standards Mode 的主要区别. 描述 对于“盒模型”一词并没有明确的文档定义,它是开发人员描述 CSS 中 ...

  8. linux下 open fopen区别

    open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲.linxu下的fopen是open的封装函数,fopen最终还是要调用底层的系统 ...

  9. linux中bin和xbin下可执行程序的区别

    /bin下的都是Linux最基础的,所有用户都可以使用的外部命令 /sbin下的都是只有超级用户root才能使用的.管理Linux系统的外部命令 /usr/bin以及/usr/local/bin下的都 ...

随机推荐

  1. BUUCTF-大白

    大白 使用16进制打开没发现什么异常的,根据提示来看图片可能没有显示完整 将第七位修改为02即可正常查看图片.

  2. zabbix主动式和被动式

    推荐: zabbix我们使用主动式,主动式的话,可以把压力都分散到agent上,压力小. 1: zabbix主动式和被动式是相对于agent来说的. zabbix server去获取zabbix ag ...

  3. Java服务假死后续之内存溢出

    一.现象分析 上篇博客说到,Java服务假死的原因是使用了Guava缓存,30分钟的有效期导致Full GC无法回收内存.经过优化后,已经不再使用Guava缓存,实时查询数据.从短期效果来看,确实解决 ...

  4. PaddleOCR系列(一)--环境搭建

    官方建议使用他们的docker镜像,所以我们按照他们建议的来. 环境搭建其实很简单,其实不需要在宿主机上配置cuda及cudnn,只需要保证宿主机上的cuda大于docker镜像中的就可以了. 所以我 ...

  5. Android刷第三方Recovery &获取root权限

    一.基础环境 Make sure your computer has working adb and fastboot. Setup instructions can be found here. E ...

  6. 啥也不是 -「OI 易犯错误整理」

    原帖出自 Nefelibata,不过他不想维护,所以就交给 STrAduts 了 awa.因为一些不可抗力,帖主转移至 XSC062.申请置顶! 前言 Nefelibata:因为笔者弱到无法形容,因此 ...

  7. $\mathcal{A\,F\,O}$

    突然间,告诉我不用学计算机了 真的有点像是做梦 回忆自己的OI生涯 真的不知从何说起 小学的时候 被家长哄着报名了当时很热门的 logo语言 在炎热的夏天,电脑里小海龟的步伐从未停歇 那时的自己很骄傲 ...

  8. 2022-7-11第五组 pan小堂 js基础

    ##为何学习 JavaScript? ###JavaScript 是 web 开发者必学的三种语言之一: HTML 定义网页的内容 CSS 规定网页的布局 JavaScript 对网页行为进行编程 在 ...

  9. DML添加数据&删除数据&修改数据

    DML:增删改表中数据 1.添加数据: 语法:insert into 表名(列名1,列名2).... values(值1,值2): 注意: 1.列名和值要一一对应. 2.如果表名后,不定义列名,则默认 ...

  10. Windows下安装新硬盘

    首先,插上一个硬盘然后开机,会发现"我的电脑/此电脑"里面并没有这个硬盘,这是因为此时硬盘还没初始化和分区,分完区后每个分区会被作为一个逻辑盘显示在里面.那么接下来就是过程. Wi ...