首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法访问postgresql表

无法访问postgresql表
EN

Stack Overflow用户
提问于 2022-06-17 18:59:22
回答 1查看 91关注 0票数 0

简单的查询运行了几个小时,但只有一个表,原因是什么?

我尝试删除它,显然它也被拖住了,而且我不能对该表执行任何其他基本或复杂的查询。我在数字海洋,所以我不能只是重新启动数据库。我从一个带有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:数据库系统关闭

EN

回答 1

Stack Overflow用户

发布于 2022-06-17 22:47:11

您可能有一个孤立的空闲进程,它已经在表上获得了一个由于未提交的事务而没有释放的锁定,因为您没有提交它的能力,所以-and永远不会释放。

如果像SELECT * FROM table这样的简单查询是阻塞的,那么很可能在表上有一个Access Exclusive Lock,它来自您取消的脚本中运行的ALTER/DROP语句。

您可以通过运行以下命令来验证这一点:

代码语言:javascript
复制
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

然后,您可以杀死表上有锁的任何进程:

代码语言:javascript
复制
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

如果仍然有阻塞查询,则可以在阻塞查询运行时打开一个新连接,并执行以下操作:

代码语言:javascript
复制
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,您可以运行:

代码语言:javascript
复制
SELECT 
  pg_terminate_backend(unnest(pg_blocking_pids(pid)))
FROM
  pg_stat_activity 

如果没有其他关键进程正在运行,并且为了简单起见希望消除每个数据库连接,请执行以下操作:

代码语言:javascript
复制
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 )中存活,甚至服务器重新启动。它们必须显式回滚或提交。

您可以使用以下查询检查准备好的事务是否正在锁定任何表

代码语言:javascript
复制
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

然后,您可以回滚准备好的事务如下:

代码语言:javascript
复制
ROLLBACK PREPARED '<TRANSACTION_NAME>' 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72663734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档