Zsá*_*ila 2 python database postgresql psycopg2 digital-ocean
简单的查询运行了几个小时,但只针对一张表,这可能是什么原因?
我尝试删除它,显然它也被停滞了,而且我无法对该表执行任何其他基本或复杂的查询。我在 digitalocean,所以我不能只在数据库上重新启动。我使用 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 CEST
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:用户:0.00 秒,系统:0.00 秒,已用时间:0.00 秒
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:数据库系统关闭
您可能有一个孤立的空闲进程,该进程已获取表上的锁,但由于未提交的事务而尚未释放该锁,并且永远不会被释放,因为您无法提交它。
如果像这样的简单查询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
Run Code Online (Sandbox Code Playgroud)
然后你可以杀死任何在你的表上有锁的进程:
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
Run Code Online (Sandbox Code Playgroud)
如果仍有阻塞的查询,您可以在阻塞的查询运行时打开一个新连接,并执行以下命令:
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;
Run Code Online (Sandbox Code Playgroud)
这将向您显示阻塞另一个进程的每个进程。一旦找到有问题的进程,您可以使用以下方法消灭它们pg_terminate_backend(pid)
如果你想杀死阻塞另一个 pid 的每个 pid,你可以运行:
SELECT
pg_terminate_backend(unnest(pg_blocking_pids(pid)))
FROM
pg_stat_activity
Run Code Online (Sandbox Code Playgroud)
如果没有其他关键进程正在运行,并且为了简单起见想要消除每个数据库连接,请执行以下操作:
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();
Run Code Online (Sandbox Code Playgroud)
完成后,您将仅拥有执行此查询的连接。
如果上述步骤都不起作用,则可能 - 正如 Laurenz Albe 在评论中指出的那样 - 您可能有一个准备好的事务正在锁定您的表。准备好的事务创建的锁可以在后端终止时继续存在,甚至服务器重新启动。它们必须显式回滚或提交。
您可以使用以下查询检查准备好的事务是否锁定任何表
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
Run Code Online (Sandbox Code Playgroud)
然后您可以回滚准备好的事务,例如:
ROLLBACK PREPARED '<TRANSACTION_NAME>'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
672 次 |
| 最近记录: |