我们的数据库似乎坏了,通常它使用大约 1-2% 的 cpu,但是如果我们运行一些额外的后端服务,对 1000 万行表进行更新和插入查询(每 3 秒大约 1 次查询)一切都会 hell (包括 CPU 使用率从 2% 增加到 98%)。
我们决定调试正在发生的事情,运行 VACUUM 和 ANALYZE 来了解 db 出了什么问题,但是......
production=# ANALYZE VERBOSE users_user;
INFO: analyzing "public.users_user"
INFO: "users_user": scanned 280 of 280 pages, containing 23889 live rows and 57 dead rows; 23889 rows in sample, 23889 estimated total rows
INFO: analyzing "public.users_user"
INFO: "users_user": scanned 280 of 280 pages, containing 23889 live rows and 57 dead rows; 23889 rows in sample, 23889 estimated total rows
ERROR: tuple already updated by self
我们无法在任何表上完成 ANALYZE,也找不到有关此问题的任何信息。有什么错误的建议吗?
PostgreSQL 9.6.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16), 64-bit
评论中要求的附加信息:
Maybe you have a corrupted pg_class
SELECT * FROM pg_class WHERE relname = 'users_user';
输出:https://pastebin.com/WhmkH34U
So the first thing to do would be to kick out all other sessions and try again
没有额外的 session ,我们已经将整个数据库转储到新的测试服务器上,问题仍然存在,没有客户端连接到这个数据库
最佳答案
我建议您在搜索重复行之前使用以下参数启动服务器:
enable_indexscan = off
enable_bitmapscan = off
ignore_system_indexes = on
如果您的服务器崩溃,索引可能处于与表数据不同的状态。例如,当损坏影响事务可见性 (pg_clog
) 时,就会发生这种情况。
然后在 pg_class
或 pg_statistic
上搜索重复的行,如评论中所述。
您也可以尝试清理 pg_statistic
。首先,启动服务器:
allow_system_table_mods = on
然后发出 TRUNCATE TABLE
和 ANALYZE
:
--Cleaning pg_statistic
TRUNCATE TABLE pg_catalog.pg_statistic;
--Analyze entire database
ANALYZE VERBOSE;
如果问题出在 pg_statistic 中,这就足够了。
关于PostgreSQL "tuple already updated by self",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50450162/