.png)
感谢华为曹宇老师的指点,我对自己接下来的研究工作再一次燃起了信心!
2024-12-22 发布68 浏览 · 2 点赞 · 0 收藏
所有的研究都是一砖一瓦堆砌起来的结果,而我们在做研究工作中,难免遇到这样的或者那样的困难,这就需要我们想方设法地去解决问题,跨越障碍,而来自于前辈的指导,往往可以为我们扫除很大一部分的迷津。
原问题
/* 起步条件,创建测试表 */
drop table if exists test;
create table test(id int,create_timestamp timestamp);
/* 分别在两个进程上面执行 */
insert into test select n,now() from generate_series(1,10) n;
do
$do$
BEGIN
FOR i IN 1..10 LOOP
UPDATE test
SET create_timestamp = clock_timestamp()
WHERE id>=2;
COMMIT;
END LOOP;
END;
$do$ language plpgsql;
即可以出现死锁问题,请教原理?
解答
这可能与存储引擎的设计机制是有关系的,PostgreSQL 采取了基于时间戳的 MVCC 的事务支持办法,在这种设计下,同一个页面将会维持着多个版本,同时对于页面的锁定将会牵涉到大量的数据行,而同时高并发的读写加锁,一旦出现顺序的不一致,就容易导致 ABBA 死锁问题,如图所示:
解决的办法,一在于改进存储引擎的设计,比如采取原位修改的方式(将修改信息直接精准到页面,而不是另外空出许多行来追加记录,缩小加锁的范围,规避死锁问题),二在于对于代码本身进行调整,比如可以加宽限制条件等等(这就涉及到 SQL 优化的有关知识)。
写在最后
谢谢彭冲老师提出了这个问题,有效地推进了我在存储引擎方面的研究,谢谢郑高启老师的引荐,谢谢曹宇老师的解答,非常谢谢。
同时感谢开放原子开源基金会提供了这样一个好的平台帮助我们记录知识,我们将继续前进,为建设一个更为开放繁荣的开源基础软件生态而奋斗。
请前往 登录/注册 即可发表您的看法…