postgresql select for update 多行加锁顺序_insert into select加锁规则补充

本文探讨了在PostgreSQL中使用`select for update`进行多行加锁的情况,特别是在`insert into select`语句中的锁行为。在statement模式下,会对源表B施加记录锁和间隙锁,而在row模式下,源表B不会被锁定。通过实验,证实了row模式下不产生全表记录锁,这可能导致并发更新问题。对于详细加锁规则,建议查阅Percona博客和StackOverflow的相关讨论。
摘要由CSDN通过智能技术生成
1f1c81a26f3dc3a1dc07db9bf4c86938.pnginsert into select加锁规则补充

  昨天的文章中,针对insert into select语句的加锁情况进行了分析:

insert into A select * from B;

形如这样的语句,在statement模式的binlog下,会对B加记录锁和间隙锁,A上会有自增锁;而在row模式下,经过测试,B表上并不会有锁。

row格式下的测试过程如下(下面分别是执行顺序和代码):

1829045f1b4368d014f6368ffc1d6f85.png

会话1:

----------------会话1---------------
mysql>>select * from table_log order by id desc limit 2\G
*************************** 1. row ***************************
  id: 10000000
code: 10000000
time: 2020-06-04 12:57:42
*************************** 2. row ***************************
  id: 9999999
code: 9999999
time: 2020-06-04 12:57:42

2 rows in set (0.00 sec)

mysql>>insert into table_log_new select * from table_log where time>='2020-06-04 12:30:00';



#在会话1的insert into select返回结果前执行会话2中的update,发现update并没有阻塞
#
-----------------会话2---------------
mysql>>update table_log set code=9999999000 where id=9999999; 
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

----------------会话1---------------
此时insert into select 返回结果
Query OK, 9096543 rows affected (1 min 39.29 sec)
Records: 9096543  Duplicates: 0  Warnings: 0

mysql>>select * from table_log order by id desc limit 5\G                                  
*************************** 1. row ***************************
  id: 10000000
code: 10000000
time: 2020-06-04 12:57:42
*************************** 2. row ***************************
  id: 9999999
code: 9999999000
time: 2020-06-04 12:57:42

    可以看到,insert into select之前,id=9999999的code值是9999999,而在执行insert into select的时候,在另外一个会话里面,对这个id=9999999的code值进行更改,在row模式下并未产生阻塞。

因此可以判断:

insert into A select * from B;

这个语句的row模式下,并未对表B产生全表的记录锁。

而在statement模式下,上述语句会对表B产生记录锁和间隙锁。

关于这个语句的加锁方法,可以参看percona官网的一篇博客和stackoverflow的一篇讨论,这里给出链接,有兴趣的同学可以继续研究:

https://www.percona.com/blog/2006/07/12/insert-into-select-performance-with-innodb-tables/ 

http://stackoverflow.com/questions/2640898/how-to-improve-insert-into-select-locking-behavior 

95735566312b408b53f6fce4ec9b05ae.png 49dd81493b3d91b00ee9494624980c1c.png 西安 62d9d203eb3419c88bf7929b870dcc14.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值