如何解决postgresql UPDATE 查询永远占用 300 万行
这是表架构:
CREATE TABLE public.page_by_category
(
id integer NOT NULL DEFAULT nextval('page_by_category_id_seq'::regclass),page_id bigint NOT NULL,category_id bigint NOT NULL,weight integer NOT NULL,CONSTRAINT id_pk PRIMARY KEY (id),CONSTRAINT category_id_fkey FOREIGN KEY (category_id)
CONSTRAINT page_id_fkey FOREIGN KEY (page_id)
)
这是一个耗时较长的查询:UPDATE page_by_category SET weight=0 在 3m 行上。
查看 pg_stat_activity 这是结果:
30366 "2 days 18:32:12.141453" "user" "UPDATE page_by_category SET weight=0"
如何检查查询是否卡住?因为没有 IO,CPU 大量使用......在我的 Centos 上,我正在使用 top,iotop 来查看是否使用了 cpu 或磁盘,但仅使用 5% 以上......
PostgreSQL 版本:""PostgreSQL 10.7 on x86_64-pc-linux-gnu"
解决方法
这应该不会花费太多时间。杀死进程并再次执行查询并检查它是否再次卡住。
SELECT pg_cancel_backend(<pid of the process>)
如果您不知道pid,那么您可以尝试以下查询:
SELECT * FROM pg_stat_activity WHERE state = 'active';
然后找到你要杀死的进程。
如果进程仍然存在,则尝试:
SELECT pg_terminate_backend(<pid of the process>)
(如果可能,在终止查询后重新启动DB,然后重试。)
,由于您的挂起更新的进程 ID 是 30366,您应该查找持有阻塞语句的锁的打开事务:
SELECT pg_blocking_pids(30366);
找出这些连接有什么问题,以及为什么它们持有锁这么长时间。
要杀死他们,请运行
SELECT pg_terminate_backend(?????);
其中 ?????
是通过上述查询找到的阻塞进程 ID 之一。
如果不是锁阻止了您的查询,则以下可能性仍然存在:
-
您的存储速度非常慢
-
你有昂贵的行级触发器
-
你有很多索引
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。