15

Looking at the liquibase documention http://www.liquibase.org/documentation/changes/create_index.html, CIC is not possible with create index, as liquibase doesn't have a tag to specify concurrent option.

Is there a way to create index concurrently with liquibase?

3
  • You need a <sql> tag with the appropriate CREATE INDEX statement Commented Mar 15, 2018 at 13:26
  • I see this error CREATE INDEX CONCURRENTLY cannot run inside a transaction block. I'm assuming migrations are run in transaction to rollback if necessary. Is there something I'm doing wrong? Commented Mar 15, 2018 at 16:30
  • @user4988095 yes, each changeset is executed in transaction Commented Mar 17, 2018 at 7:23

3 Answers 3

19

You can specify runInTransaction as false to create the index concurrently.

Update Comments suggest you can put it in your sql file:

--changeset your.name: some_table_idx_name runInTransaction:false

Or put it in the changeset file like this:

<changeSet id="1.7" author="jrj" runInTransaction="false">
Sign up to request clarification or add additional context in comments.

5 Comments

the liquibase file is an sql file. where to specify ?
works flawlessly after adding it in liquibase changeSet
for those curious don't know where to specify this command - it should be put above the sql line that you want to execute in a comment like this: --changeset your.name: some_table_idx_name runInTransaction:false
putting it in the SQL file did not work for me. However, it worked to put it in the changeset file: <changeSet id="1.7" author="jrj" runInTransaction="false">
runInTransaction="false" does not force "CONCURRENTLY" in generated sql. Use <sql> tag
11

Creating a concurrent index must be done with the arbitrary sql change:

<changeSet runInTransaction="false" id="10-add-widgets-kind-index" author="username">
    <sql dbms="postgresql">
        CREATE INDEX CONCURRENTLY
        IF NOT EXISTS idx_widgets_kind 
        ON widgets(kind)
    </sql>
</changeSet>

This is a combination of a_horse_with_no_name's comment and TheDude's answer.

Comments

7

The previous answers do the job. I would like to offer an alternative that doesn't directly answer the OP's question, but does offer a solution with the same end result with some added advantages. I feel it is good to show other options for people that stumble upon this answer like I did.

In order to create the index using only Liquibase, you would need to use the <sql> tag. I caution against this as it can cause undesired consequences in the event that you use a different database for any reason (development, evaluation, testing, etc). The sql statement will be skipped and you can be left thinking that the index was added when in reality it was not.

Additionally, this can lead to a less controlled migration, assuming you are running this on a production system without taking it down for maintenance and the migration being part of the build process.

I would propose creating the index directly on Postgres and adding the index migration normally using Liquibase and a precondition check.

First, add the index manually:

CREATE INDEX CONCURRENTLY widgets_kind_idx ON widgets (kind);

And then add to your Liquibase changeSet:

<changeSet id="10-add-widgets-kind-index" author="username">

    <preConditions onFail="MARK_RAN">
        <not>
            <indexExists indexName="widgets_kind_idx" />
        </not>
    </preConditions>

    <createIndex tableName="widgets" indexName="widgets_kind_idx">
        <column name="kind" />
    </createIndex>

</changeSet>

This offers the ability to add the index in any manner desired and keeps your Liquibase migrations in a known state. A fresh database being setup would not require the CONCURRENTLY keyword.

2 Comments

The question is how to create index CONCURRENTLY using liquibase
Facing issue with h2 as you described, used sql tag, now my test won't run because apparantly h2 does not support creating, dropping indexes concurrently

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.