【发布时间】:2018-01-31 09:37:02
【问题描述】:
总的来说,我对数据库设计和 PostgreSQL 很陌生,但我知道 Postgres 中行版本控制、事务和排他锁背后的一般概念(例如,this 文章给出了很好的概述)。
我目前的问题是 a) 我不知道为什么我的 PG 数据库日志文件中出现这么多排他锁,以及 b) 为什么这些锁是完全发生了。
我运行 PostgreSQL 10(+ PostGIS 扩展),在 5 个表 (200GB) 上有大约 3 亿行。我有大约 5 个脚本(4x PHP 和 1x Python Psycopg2)24/7 运行,可以进行大量插入(以及 DO UPDATE 和 COALESCE,以防条目已经存在)。但是,据我了解,PHP Postgres 扩展在每个 SQL 查询之后和我的 Python 脚本中自动提交,增加提交并不会显着减少锁。我有几个动态更新行的触发器,但据我从日志文件中可以看出,它们不是锁定的原因。我的两个或多个脚本同时插入/更新同一行的情况通常很少见。
这是一个示例日志条目:
2018-01-31 01:04:02 CET [808]: [258-1] user=user1,db=maindb,app=[unknown],client=::1 LOG: process 808 still waiting for ExclusiveLock on page 0 of relation 26889 of database 16387 after 1015.576 ms
2018-01-31 01:04:02 CET [808]: [259-1] user=user1,db=maindb,app=[unknown],client=::1 DETAIL: Process holding the lock: 680. Wait queue: 1728, 152, 808.
2018-01-31 01:04:02 CET [808]: [260-1] user=user1,db=maindb,app=[unknown],client=::1 STATEMENT:
INSERT INTO "table1" (...)
VALUES (...)
ON CONFLICT (...)
DO UPDATE SET
...;
我大约每 2-3 分钟就有一次类似的日志条目。他们有问题吗?它们究竟是什么意思,是锁最终解决了还是事务的数据丢失了?没有日志条目表明锁已解决或更新最终提交到数据库。
第二种频繁日志条目类似这样:
2018-01-31 07:22:16 CET [2504]: [16384-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 9999 buffers (3.8%); 0 WAL file(s) added, 0 removed, 7 recycled; write=269.842 s, sync=0.218 s, total=270.123 s; sync files=85, longest=0.054 s, average=0.002 s; distance=66521 kB, estimate=203482 kB
2018-01-31 07:22:46 CET [2504]: [16385-1] user=,db=,app=,client= LOG: checkpoint starting: time
这是否意味着解决所有锁定的 Auto-Vaccum 或 Auto-Commit?
我的一般问题:我应该关心并做某事还是干脆保持现状?
【问题讨论】:
-
这意味着进程 680 设置了排他锁。您将不得不检查此过程的作用。它可能会做大量工作,或者有时数据库中存在潜在的延迟问题(例如,I/O 速度慢)。
-
谢谢克劳斯。您能解释一下我如何找出进程 680 的作用吗?它似乎没有出现在日志中(例如“680...acquired ExclusiveLock”
-
我发现this 页面解释了如何监控锁。看起来我的锁的存在时间都不超过几分钟,这表明它们根本没有问题
-
您的日志行抱怨大约 1 秒。那么为什么现在分钟还可以呢?
-
大多数锁在 1000 到 100.000 毫秒之间,但似乎有相当大的波动。上面的日志行只是一个有代表性的例子。
标签: php python postgresql locking plpgsql