我写了一个在sqlite上运行良好的迁移脚本,但是如果我尝试将其应用于postgres,它将永远卡住。通过一个简单的ps,我可以看到postres卡在“创建表等待”上。有什么最佳实践吗?
7fyelxc51#
如果它真的卡在锁上,你需要看看它在等什么。CREATE TABLE卡在锁上是很奇怪的,但这不是不可能的。
CREATE TABLE
获取等待后端的进程ID。您可以在ps中找到它,或者通过SELECT从pg_stat_activity中查找waiting true的进程,以找到您感兴趣的命令:
ps
SELECT
pg_stat_activity
waiting
SELECT * FROM pg_stat_activity WHERE waiting;
字符串
通过查询pg_locks来查看被卡住的pid正在等待的锁:
pg_locks
SELECT * FROM pg_locks WHERE pid = <the-waiting-pid> AND NOT granted;
型您可以将这两个步骤合并与以下步骤结合:
\xSELECT * FROM pg_locks lINNER JOIN pg_stat_activity s ON (l.pid = s.pid)WHERE waitingAND NOT granted;
\x
SELECT *
FROM pg_locks l
INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
WHERE waiting
AND NOT granted;
型然后浏览结果,或者在s.query字段上使用LIKE过滤器来查找您试图识别锁定问题的查询。
s.query
LIKE
现在,您可以查询pg_locks,以了解哪些进程找到了该锁,以及它们正在做什么。假设我们发现create正在等待mode = AccessExclusiveLock on relation= 14421的locktype= relation锁被授予。我们想找到该关系上其他会话持有的锁:
create
AccessExclusiveLock
14421
relation
SELECT * FROM pg_locks l INNER JOIN pg_stat_activity s ON (l.pid = s.pid)WHERE locktype = 'relation'AND relation = 14421;
WHERE locktype = 'relation'
AND relation = 14421;
型这应该告诉你是什么阻止了创建。
有a handy lock monitoring query on the PostgreSQL wiki,但它只会找到 * 行级别的锁 *。所以它通常对加密没有帮助。另外,我故意没有将所有的锁合并到一个查询中。如果使用ExclusiveLock,通过pid找到阻塞给定后端的锁持有者是很简单的,但对于较弱的锁请求,就不那么简单了-我必须在SQL中写出关于哪些锁与哪些锁冲突的规则,这相当复杂。最好只是观察一下。
wqlqzqxt2#
你总是可以重启postgresql。
isr3a4wc3#
对于任何面临这个问题的人来说,这是为我解决的问题:alembic的标准env.py包含以下段落
with context.begin_transaction(): logger.info("Running Transaction.") context.run_migrations()
with context.begin_transaction():
logger.info("Running Transaction.")
context.run_migrations()
字符串但是,如果您随后在迁移脚本中引入引擎,
config = op.get_context().configengine = engine_from_config(config.get_section( config.config_ini_section), prefix='sqlalchemy.')
config = op.get_context().config
engine = engine_from_config(config.get_section(
config.config_ini_section), prefix='sqlalchemy.')
型事务将被卡在“transaction in idle”中。我不太清楚为什么,但它看起来像是事务内的事务,而外部事务永远不会提交。要解决这个问题,只需删除外部的开始_transaction()
# with context.begin_transaction():logger.info("Running Transaction.")context.run_migrations()
# with context.begin_transaction():
型你就可以走了
nwsw7zdq4#
您的数据库很可能被另一个查询锁定。特别是如果你用他们的GUI pgAdmin做一些事情,我发现这种情况经常发生。(截断表特别棘手,有时pgAdmin崩溃,数据库卡住)你要做的是重新启动整个postgresql服务并再试一次。确保您:1.尽量减少GUI pgadmin的使用1.如果你不需要,用psycopg 2关闭你的游标/数据库
7nbnzgx95#
在postgres上运行以下查询,看看查询是否被卡住:
SELECT * FROM pg_stat_activity where state = 'active'
5条答案
按热度按时间7fyelxc51#
如果它真的卡在锁上,你需要看看它在等什么。
CREATE TABLE
卡在锁上是很奇怪的,但这不是不可能的。获取卡住的进程id
获取等待后端的进程ID。您可以在
ps
中找到它,或者通过SELECT
从pg_stat_activity
中查找waiting
true的进程,以找到您感兴趣的命令:字符串
找出它在等待什么锁
通过查询
pg_locks
来查看被卡住的pid正在等待的锁:型
您可以将这两个步骤合并与以下步骤结合:
型
然后浏览结果,或者在
s.query
字段上使用LIKE
过滤器来查找您试图识别锁定问题的查询。找出谁持有那把锁
现在,您可以查询
pg_locks
,以了解哪些进程找到了该锁,以及它们正在做什么。假设我们发现
create
正在等待mode =AccessExclusiveLock
on relation=14421
的locktype=relation
锁被授予。我们想找到该关系上其他会话持有的锁:型
这应该告诉你是什么阻止了创建。
皱纹
有a handy lock monitoring query on the PostgreSQL wiki,但它只会找到 * 行级别的锁 *。所以它通常对加密没有帮助。
另外,我故意没有将所有的锁合并到一个查询中。如果使用ExclusiveLock,通过pid找到阻塞给定后端的锁持有者是很简单的,但对于较弱的锁请求,就不那么简单了-我必须在SQL中写出关于哪些锁与哪些锁冲突的规则,这相当复杂。最好只是观察一下。
wqlqzqxt2#
你总是可以重启postgresql。
isr3a4wc3#
对于任何面临这个问题的人来说,这是为我解决的问题:
alembic的标准env.py包含以下段落
字符串
但是,如果您随后在迁移脚本中引入引擎,
型
事务将被卡在“transaction in idle”中。我不太清楚为什么,但它看起来像是事务内的事务,而外部事务永远不会提交。
要解决这个问题,只需删除外部的开始_transaction()
型
你就可以走了
nwsw7zdq4#
您的数据库很可能被另一个查询锁定。
特别是如果你用他们的GUI pgAdmin做一些事情,我发现这种情况经常发生。(截断表特别棘手,有时pgAdmin崩溃,数据库卡住)
你要做的是重新启动整个postgresql服务并再试一次。
确保您:
1.尽量减少GUI pgadmin的使用
1.如果你不需要,用psycopg 2关闭你的游标/数据库
7nbnzgx95#
在postgres上运行以下查询,看看查询是否被卡住:
字符串