Alembic迁移坚持postgresql?

wfauudbj  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(5)|浏览(177)

我写了一个在sqlite上运行良好的迁移脚本,但是如果我尝试将其应用于postgres,它将永远卡住。通过一个简单的ps,我可以看到postres卡在“创建表等待”上。有什么最佳实践吗?

7fyelxc5

7fyelxc51#

如果它真的卡在锁上,你需要看看它在等什么。CREATE TABLE卡在锁上是很奇怪的,但这不是不可能的。

获取卡住的进程id

获取等待后端的进程ID。您可以在ps中找到它,或者通过SELECTpg_stat_activity中查找waiting true的进程,以找到您感兴趣的命令:

  1. SELECT * FROM pg_stat_activity WHERE waiting;

字符串

找出它在等待什么锁

通过查询pg_locks来查看被卡住的pid正在等待的锁:

  1. SELECT * FROM pg_locks WHERE pid = <the-waiting-pid> AND NOT granted;


您可以将这两个步骤合并与以下步骤结合:

  1. \x
  2. SELECT *
  3. FROM pg_locks l
  4. INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
  5. WHERE waiting
  6. AND NOT granted;


然后浏览结果,或者在s.query字段上使用LIKE过滤器来查找您试图识别锁定问题的查询。

找出谁持有那把锁

现在,您可以查询pg_locks,以了解哪些进程找到了该锁,以及它们正在做什么。
假设我们发现create正在等待mode = AccessExclusiveLock on relation= 14421的locktype= relation锁被授予。我们想找到该关系上其他会话持有的锁:

  1. SELECT *
  2. FROM pg_locks l
  3. INNER JOIN pg_stat_activity s ON (l.pid = s.pid)
  4. WHERE locktype = 'relation'
  5. AND relation = 14421;


这应该告诉你是什么阻止了创建。

皱纹

a handy lock monitoring query on the PostgreSQL wiki,但它只会找到 * 行级别的锁 *。所以它通常对加密没有帮助。
另外,我故意没有将所有的锁合并到一个查询中。如果使用ExclusiveLock,通过pid找到阻塞给定后端的锁持有者是很简单的,但对于较弱的锁请求,就不那么简单了-我必须在SQL中写出关于哪些锁与哪些锁冲突的规则,这相当复杂。最好只是观察一下。

展开查看全部
wqlqzqxt

wqlqzqxt2#

你总是可以重启postgresql。

isr3a4wc

isr3a4wc3#

对于任何面临这个问题的人来说,这是为我解决的问题:
alembic的标准env.py包含以下段落

  1. with context.begin_transaction():
  2. logger.info("Running Transaction.")
  3. context.run_migrations()

字符串
但是,如果您随后在迁移脚本中引入引擎,

  1. config = op.get_context().config
  2. engine = engine_from_config(config.get_section(
  3. config.config_ini_section), prefix='sqlalchemy.')


事务将被卡在“transaction in idle”中。我不太清楚为什么,但它看起来像是事务内的事务,而外部事务永远不会提交。
要解决这个问题,只需删除外部的开始_transaction()

  1. # with context.begin_transaction():
  2. logger.info("Running Transaction.")
  3. context.run_migrations()


你就可以走了

展开查看全部
nwsw7zdq

nwsw7zdq4#

您的数据库很可能被另一个查询锁定。
特别是如果你用他们的GUI pgAdmin做一些事情,我发现这种情况经常发生。(截断表特别棘手,有时pgAdmin崩溃,数据库卡住)
你要做的是重新启动整个postgresql服务并再试一次。
确保您:
1.尽量减少GUI pgadmin的使用
1.如果你不需要,用psycopg 2关闭你的游标/数据库

7nbnzgx9

7nbnzgx95#

在postgres上运行以下查询,看看查询是否被卡住:

  1. SELECT * FROM pg_stat_activity where state = 'active'

字符串

相关问题