简单的查询运行了几个小时,但只有一个表,原因是什么?
我尝试删除它,显然它也被拖住了,而且我不能对该表执行任何其他基本或复杂的查询。我在数字海洋,所以我不能只是重新启动数据库。我从一个带有python的URL中导入了这个表,并且在运行脚本之前忘记关闭psycopg2连接,所以我不得不终止它,这可能会导致问题。
顺便说一下。这是我的个人数据库,我没有其他管理员可以把我锁在外面什么的。我也看过日志,但没有任何异常活动的迹象。这是它,虽然,最初它的德语,我不得不翻译它。
09:18:35.644: PostgreSQL 14.2,由Visual C++ build 1914编译,64位启动
09:18:35.645: IPv6地址上的预期连接"::",端口25060
09:18:35.645:期望IPv4地址"0.0.0.0“上的连接,端口25060
09:18:35.691:数据库系统中断;2022年-06-16的最后一次操作23:54:18
09:18:36.137:数据库系统没有正确关闭;自动恢复正在进行中
09:18:36.140:重拍从0/172B560开始
09:18:36.141:无效记录长度为0/172B598: 24预期为0
09:18:36.141:重做完成在0/172B560系统的使用情况: CPU: user: 0.00 s,system: 0.00 s,complete : 0.00 s
09:18:36.164:数据库系统已准备好接受连接
20:34:07.203:要求快速关机
20:34:07.208:任何活动的事务都被中止。
20:34:07.232:后台工作者“逻辑复制启动程序”(PID 15088)以状态1终止
20:34:07.241:关闭
20:34:07.292:数据库系统关闭
发布于 2022-06-17 22:47:11
您可能有一个孤立的空闲进程,它已经在表上获得了一个由于未提交的事务而没有释放的锁定,因为您没有提交它的能力,所以-and永远不会释放。
如果像SELECT * FROM table这样的简单查询是阻塞的,那么很可能在表上有一个Access Exclusive Lock,它来自您取消的脚本中运行的ALTER/DROP语句。
您可以通过运行以下命令来验证这一点:
SELECT
psa.pid,
psa.query,
psa.state,
pg_locks.mode lock_mode,
relation::regclass locked_relation
FROM
pg_locks
JOIN pg_stat_activity psa on pg_locks.pid = psa.pid
WHERE
granted
and 'my_schema.my_table'::regclass = relation然后,您可以杀死表上有锁的任何进程:
SELECT
pg_terminate_backend(psa.pid),
FROM
pg_locks
JOIN pg_stat_activity psa on pg_locks.pid = psa.pid
WHERE
granted
and 'my_schema.my_table'::regclass = relation如果仍然有阻塞查询,则可以在阻塞查询运行时打开一个新连接,并执行以下操作:
SELECT
activity.pid pid,
activity.state state,
activity.query blocked_query,
blocking_pid,
blocking_activity.state blocking_state,
blocking_activity.query blocking_query,
locks.locked_relations blocking_relation_locks
FROM
pg_stat_activity activity
JOIN LATERAL unnest(pg_blocking_pids(activity.pid)) blocking_pids(blocking_pid) ON TRUE
JOIN pg_stat_activity blocking_activity ON (blocking_pids.blocking_pid = blocking_activity.pid)
JOIN LATERAL (
SELECT
string_agg(locks.relation::regclass::text,',') locked_relations
FROM
pg_locks locks
WHERE
locks.pid = blocking_pid
GROUP BY
blocking_pid
) locks ON TRUE;这将向您展示阻止另一个进程的每个进程。一旦发现了违规的进程,就可以使用pg_terminate_backend(pid)来清除它们。
如果您想要关闭每个pid阻塞另一个pid,您可以运行:
SELECT
pg_terminate_backend(unnest(pg_blocking_pids(pid)))
FROM
pg_stat_activity 如果没有其他关键进程正在运行,并且为了简单起见希望消除每个数据库连接,请执行以下操作:
SELECT
pg_terminate_backend(pg_stat_activity.pid)
FROM
pg_stat_activity
WHERE
--delete this line if you want to kill all connections on the whole cluster
pg_stat_activity.datname = '<your database name>'
AND pid <> pg_backend_pid();一旦完成,您将只拥有执行此查询的连接。
如果上述任何步骤都不起作用,那么-as Laurenz可能在注释-that中指出,您可能有一个正在锁定表的准备交易。准备好的事务创建的锁可以在后端终止( -and )中存活,甚至服务器重新启动。它们必须显式回滚或提交。
您可以使用以下查询检查准备好的事务是否正在锁定任何表
SELECT
ptx.transaction prep_tx_id,
ptx.gid prep_tx_name,
locks.mode lock_mode,
locks.relation::regclass locked_relation
FROM
pg_prepared_xacts ptx
JOIN pg_locks tx ON ptx.transaction = tx.transactionid and tx.locktype = 'transactionid'
JOIN pg_locks locks ON tx.virtualtransaction = locks.virtualtransaction
WHERE
locks.granted
and locks.relation = 'my_schema.my_table'::regclass然后,您可以回滚准备好的事务如下:
ROLLBACK PREPARED '<TRANSACTION_NAME>' https://stackoverflow.com/questions/72663734
复制相似问题