如何在postgres中与flyway同时创建索引?

时间:2013-12-03 11:56:04

标签: postgresql flyway

Postgres允许使用CONCURRENTLY选项创建索引而不锁定表。事务中不允许使用此选项,因此当它添加到flyway迁移脚本时,flyway会失败:

错误:由org.postgresql.util.PSQLException引起:错误:CREATE INDEX CONCURRENTLY无法在事务块内运行

ActiveRecord支持disable_ddl_transaction!来解决此问题。 flyway是否支持某种方式在事务之外运行这样的脚本?

3 个答案:

答案 0 :(得分:3)

这是在Flyway 4.1中实现的,请参阅票证851Non-Transactional PostgreSQL Support in Flyway

此功能通过检测应该在没有事务的情况下执行语句来工作。据我所知,目前只支持PostgreSQL。

  

第一个障碍是检测迁移何时需要在外部运行   交易前进的两条道路是明显的。第一条路,[..],   是创建文件名注释。第二条路径是添加一个   语句解析器到Flyway,检测非事务性命令和   在适当的隔离级别运行它们。尽管额外的工作   Boxfuse团队坚定不移地要求他们   遵循第二条道路。它为用户提供了更好的用户体验   从长远来看,Flyway用户。

默认情况下,以这种方式执行的迁移应该只包含需要在没有事务的情况下执行的语句。默认情况下,不允许将其与事务性语句混合,并且需要使用属性启用。

  

创建迁移不得与事务混合的条件   非事务性语句会产生可能引入的限制   未来用户看不见的问题。如果这个未知   需要通常在内部运行的DDL的情况   需要处理事务,称为属性    flyway.allowMixedMigrations 已添加到配置中。默认情况下为false。我强烈建议永远不要打开它。

非事务处理的语句由PostgreSQLSqlStatementBuilder中的代码确定:

if (statementStart.matches("(CREATE|DROP) (DATABASE|TABLESPACE) .*")
        || statementStart.matches("ALTER SYSTEM .*")
        || statementStart.matches("(CREATE|DROP)( UNIQUE)? INDEX CONCURRENTLY .*")
        || statementStart.matches("REINDEX( VERBOSE)? (SCHEMA|DATABASE|SYSTEM) .*")
        || statementStart.matches("VACUUM .*")
        || statementStart.matches("DISCARD ALL .*")
        || statementStart.matches("ALTER TYPE .* ADD VALUE .*")
        ) {
    executeInTransaction = false;
}

答案 1 :(得分:1)

不是在这一点上。所有迁移当前都在事务中运行。您可以在问题跟踪器中提交增强请求。

答案 2 :(得分:0)

根据这篇文章:

Flyway migration hangs for postgres CREATE INDEX CONCURRENTLY

您只需添加NT作为迁移的前缀即可

V201609121806__create_index_for_table.sql

成为

NTV201609121806__create_index_for_table.sql