我编写了一个在sqlite上工作正常的迁移脚本,但如果我尝试将其应用于postgres,它将永远停留。 通过一个简单的ps我可以看到postres卡在“创建表等待”。 有什么最好的做法吗?
答案 0 :(得分:23)
如果它真的卡在锁上,你需要看看它在等什么。 CREATE TABLE
被卡在锁上是很奇怪的,但这并非不可能。
获取等待后端的进程ID。您可以在ps
或SELECT
pg_stat_activity
中找到它,查找waiting
为true的流程,以找到您感兴趣的命令:< / p>
SELECT * FROM pg_stat_activity WHERE waiting;
通过查询pg_locks
来查看卡住的pid正在等待的锁定:
SELECT * FROM pg_locks WHERE pid = <the-waiting-pid> AND NOT granted;
您可以将这两个步骤合并到:
\x
SELECT *
FROM pg_locks l
INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
WHERE waiting
AND NOT granted;
然后查看结果,或使用LIKE
字段上的s.query
过滤器来查找您尝试识别锁定问题的查询。
您现在可以查询pg_locks
以找出哪个进程找到了锁定,以及他们正在做什么。
假设我们发现create
正在等待关系= relation
的locktype = AccessExclusiveLock
锁定模式= 14421
。我们想找到关于该关系的其他会话持有的锁:
SELECT *
FROM pg_locks l
INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
WHERE locktype = 'relation'
AND relation = 14421;
这应该告诉你阻止创建的内容。
有a handy lock monitoring query on the PostgreSQL wiki,但它只能找到行级锁。所以它对DDL一般没用。
另外,我故意没有将整个批次合并到一个查询中。在AccessExclusiveLock的情况下,它很容易找到通过pid阻止给定后端的锁定持有者,但是对于较弱的锁定请求,它不是那么简单 - 我必须写出来关于哪些锁与SQL中哪些锁冲突的规则,这非常复杂。最好只关注它。
答案 1 :(得分:3)
你总是可以重新启动postgresql。
答案 2 :(得分:1)
您的数据库很可能被另一个查询锁定。
特别是如果你使用他们的GUI pgAdmin做事,这可能会发生很多我发现。 (截断表格特别棘手,有时pgAdmin崩溃,数据库卡住了)
您要做的是重新启动完整的postgresql服务,然后重试。
请确保你:
答案 3 :(得分:0)
对于任何遇到此问题的人,这是为我解决的问题:
标准的alembic env.py包含该段落
with context.begin_transaction():
logger.info("Running Transaction.")
context.run_migrations()
但是,如果您随后将迁移引擎中的引擎引入
config = op.get_context().config
engine = engine_from_config(config.get_section(
config.config_ini_section), prefix='sqlalchemy.')
该交易将被卡在“空闲交易”中。我不太清楚为什么,但是看起来好像是事务内的事务,而外部事务从未提交。
要解决此问题,只需移除外部的begin_transaction()
# with context.begin_transaction():
logger.info("Running Transaction.")
context.run_migrations()
你应该很好。