【问题标题】:Why does Drop Index require commit?为什么 Drop Index 需要提交?
【发布时间】:2025-12-21 15:20:13
【问题描述】:

在我的多线程程序中,一个线程删除表上的索引(首先发生这种情况),其他线程在同一个表中插入记录。碰巧当尝试删除索引时,表被锁定并且插入事务变为“等待”

在没有解决问题的问题上浪费了大量时间后,我发现真正的解决方案是在删除索引后立即commit。当发出 commit 时,表被解锁并且插入事务成功完成。

我的问题是,为什么?我的印象是 Drop Index 是一个 DDL 语句,因此不需要提交。 Postgres 似乎证明我错了。

【问题讨论】:

  • 如果您需要在删除索引后发出 COMMIT,那么您用于连接数据库的任何工具都会打开事务。你在使用 JDBC 吗?我相信自动提交模式有一个切换。 DROP INDEX 需要取出一个足够长的独占锁来执行命令,并确定没有其他事务正在使用该索引(否则您可能会得到不一致或不正确的结果)。
  • 你说得对,是因为打开了一笔交易。不得不承诺。

标签: sql database postgresql postgresql-9.1 ddl


【解决方案1】:

在 PostgreSQL 中,所有 DDL 命令都是事务性的。所以如果你启动了一个事务块,或者你的驱动程序为你启动了一个事务块,或者你的驱动程序没有处于自动提交模式,你需要提交所有的 DDL 命令,就像其他 SQL 命令一样。

其他 SQL 数据库的做法不同。

(吹毛求疵:PostgreSQL 中的某些 DDL 命令不能在事务块中运行,只能在事务中单独运行。因此,您可能会认为这些是上述“所有 DDL 命令”声明的例外。但这并不完全相同作为您的问题:这些命令仍然需要提交,它们只是不能与其他命令一起在事务中运行。)

【讨论】:

    【解决方案2】:

    我不了解 Postgres,但 DDL 语句并不总是自动提交的。 例如,在 Oracle 中它们是,但在 DB2 中它们不是(您可以执行 create table + indexes 然后回滚整个批次)。我认为 SQL Server 也需要提交(除非启用自动提交)。

    基本上(取决于 DB 风格)DDL 语句并不总是自动提交。

    【讨论】:

    • 提交模式由您连接到数据库的应用程序决定,并且 DDL 在大多数工具中都是隐式提交的。冒着听起来迂腐的风险,它是“Postgres”或“PostgreSQL”,而不是“postgress”。
    • Transactional DDL in PostgreSQL: A Competitive Analysis 比较不同引擎对事务 DDL 的影响。
    • 我喜欢在Wikipedia's article about DDL Postgres 中如何被引用为示例。
    • 谢谢大家。这是一个很好的链接丹尼尔。来自 Oracle,我(和这里的其他人)期望 Postgres DDL 不需要提交。好吧,你知道的越多!
    最近更新 更多