PostgreSQL 数据库中异常多的独占锁
Unusual high number of exclusive locks in PostgreSQL database
总的来说,我对数据库设计和 PostgreSQL 还很陌生,但我知道 Postgres 中行版本控制、事务和独占锁背后的一般概念(例如 this 文章给出了很好的概述)。
我目前的问题是 a) 我不确定为什么我的 PG 数据库日志文件中会出现这么多独占锁 b) 为什么会出现这些锁。
I 运行 PostgreSQL 10(+ PostGIS 扩展)在 5 个表 (200GB) 上有大约 3 亿行。我有大约 5 个脚本(4x PHP 和 1x Python Psycopg2)运行ning 24/7 进行了大量插入(以及 DO UPDATE
和 COALESCE
,如果该条目已经存在)。然而,据我所知,PHP Postgres 扩展在每个 SQL 查询后自动提交,在我的 Python 脚本中,增加提交并不会显着减少锁定。我有几个动态更新行的触发器,但据我从日志文件中可以看出它们不是锁的原因。我的两个或多个脚本 insert/update 同时出现在同一行的情况通常很少见。
这是一个示例日志条目:
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
这是否意味着解决所有锁定的自动真空或自动提交?
我的一般问题:我应该关注并做某事还是干脆保持现状?
一段时间后,我发现了导致这些锁定的原因以及如何解决它们。所有排他锁都发生在数据库中的一个关系上:
...ExclusiveLock on page 0 of relation 26889 of database...
26889 是多少?
SELECT relname FROM pg_class WHERE OID=26889
结果:idx_post_hashtags
这一切都是由 GIN 索引在带有 Array (Text) 的特定列上引起的。此外,这个 GIN 索引是无用的,因为数组的长度是可变的,查找任何特定的数组值都无法从索引中获益。我放弃了它:所有独占锁都消失了!
仔细阅读日志确实有帮助。
总的来说,我对数据库设计和 PostgreSQL 还很陌生,但我知道 Postgres 中行版本控制、事务和独占锁背后的一般概念(例如 this 文章给出了很好的概述)。
我目前的问题是 a) 我不确定为什么我的 PG 数据库日志文件中会出现这么多独占锁 b) 为什么会出现这些锁。
I 运行 PostgreSQL 10(+ PostGIS 扩展)在 5 个表 (200GB) 上有大约 3 亿行。我有大约 5 个脚本(4x PHP 和 1x Python Psycopg2)运行ning 24/7 进行了大量插入(以及 DO UPDATE
和 COALESCE
,如果该条目已经存在)。然而,据我所知,PHP Postgres 扩展在每个 SQL 查询后自动提交,在我的 Python 脚本中,增加提交并不会显着减少锁定。我有几个动态更新行的触发器,但据我从日志文件中可以看出它们不是锁的原因。我的两个或多个脚本 insert/update 同时出现在同一行的情况通常很少见。
这是一个示例日志条目:
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
这是否意味着解决所有锁定的自动真空或自动提交?
我的一般问题:我应该关注并做某事还是干脆保持现状?
一段时间后,我发现了导致这些锁定的原因以及如何解决它们。所有排他锁都发生在数据库中的一个关系上:
...ExclusiveLock on page 0 of relation 26889 of database...
26889 是多少?
SELECT relname FROM pg_class WHERE OID=26889
结果:idx_post_hashtags
这一切都是由 GIN 索引在带有 Array (Text) 的特定列上引起的。此外,这个 GIN 索引是无用的,因为数组的长度是可变的,查找任何特定的数组值都无法从索引中获益。我放弃了它:所有独占锁都消失了!
仔细阅读日志确实有帮助。