Create Indexes Concurrently
CREATE INDEX CONCURRENTLY
This document describes how to create indexes concurrently in SynxDB, that is, to execute insert, update, and delete statements while creating indexes.
When using CREATE INDEX to create an index in SynxDB, although other transactions can read table data normally, SynxDB blocks DML operations such as data insertion, updates, and deletions on the table. SynxDB only executes these DML operations after the index creation is complete.
For tables in production environments, if the table has a large amount of data, using CREATE INDEX to create an index might take a long time, causing table data updates to be blocked for an extended period, which can lead to serious problems.
To solve this problem, you can use the CREATE INDEX CONCURRENTLY syntax to create indexes concurrently. During index creation, SynxDB will not block corresponding table data updates.
Tip
When this option is specified, SynxDB will perform two table scans and wait for all transactions that update table data to complete. This adds some additional table scanning overhead when creating indexes, which might take longer than normal index creation. However, because this method does not block normal table update operations, it is very useful for data tables in production environments.
Use cases
Suitable for tables with large amounts of data in production environments, where you want to perform DML operations such as insert, update, and delete normally while creating indexes for the table.
When there are no high requirements for index creation speed, and there are sufficient system resources available for consumption, you can accept that index creation takes slightly longer than
CREATE INDEX.
Usage
Execute the following command and restart the SynxDB database to enable GDD-related configuration parameters.
gpconfig -c gp_enable_global_deadlock_detector -v true gpstop -ra
Note
In the SynxDB database, GDD is disabled by default (controlled by the configuration parameter
gp_enable_global_deadlock_detector). In this case,UPDATEorDELETEstatements executed onheaptables will holdExclusiveLocklocks, which will conflict withCREATE INDEX CONCURRENTLY. Therefore, to avoid blockingUPDATEorDELETEoperations on tables when creating indexes concurrently, you must first enable GDD.Use the
CREATE INDEX CONCURRENTLYsyntax to create indexes concurrently.Assuming there is a table named
ordersthat contains a date column namedorder_date, you can concurrently create an indexidx_orders_order_datebased on that column:CREATE INDEX CONCURRENTLY idx_orders_order_date ON orders (order_date);
Usage restrictions
Creating indexes concurrently on temporary tables is not supported.
Explicitly starting a transaction with
BEGINand then executingCREATE INDEX CONCURRENTLYis not supported.Currently, concurrent index creation only supports
heaptables, notAO/AOCStables and partitioned tables. However, for partitioned tables, you can create indexes concurrently for each partition table individually.
Common issue handling
When using CREATE INDEX CONCURRENTLY to create table indexes, if errors occur, such as deadlocks or unique constraint validation failures for unique indexes, the index creation will fail, but an INVALID invalid index will be left in the table. During queries, SynxDB will ignore this invalid index because it is incomplete.
To view invalid indexes of a table, you can use the \d option to view the INVALID indexes of that table:
\d tab
Table "public.tab"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
col | integer | | |
Indexes:
"idx_col" btree (col) INVALID
Distributed by: (col)
For such INVALID invalid indexes, you can manually DROP delete them or rebuild the indexes using REINDEX.
REINDEX CONCURRENTLY
This section describes how to rebuild indexes concurrently in SynxDB, that is, to execute insert, update, and delete statements while rebuilding indexes.
When using REINDEX to rebuild indexes in SynxDB, SynxDB locks the table whose index is being rebuilt to prevent writes and performs the entire index rebuild through a single scan of the table. During this period, although other transactions can read table data normally, SynxDB blocks DML operations such as data insertion, updates, and deletions on the table. SynxDB only executes these DML operations after the index rebuild is complete.
For databases in real-time production environments, executing REINDEX index rebuilds on large tables might take hours to complete. Even for smaller tables, index rebuilds lock writers for a period of time, which is unacceptable for production systems.
To solve this problem, you can use the REINDEX CONCURRENTLY syntax to rebuild indexes concurrently, allowing SynxDB to rebuild indexes with minimal write locking, enabling DML operations such as insert, update, and delete during index rebuilding.
Use cases
Suitable for tables with large amounts of data in production environments, where you want to perform DML operations such as insert, update, and delete normally while rebuilding indexes for the table.
When there are no high requirements for index rebuilding speed, and there are sufficient system resources available for consumption, you can accept that index rebuilding takes longer than
REINDEX.
How it works
When using REINDEX CONCURRENTLY to rebuild indexes concurrently, SynxDB performs the following internal operations in multiple separate transactions:
SynxDB adds a new temporary index definition to the
pg_indextable to replace the old index. It also acquires aSHARE UPDATE EXCLUSIVElock at the session level to prevent any schema modifications to the table during processing.Scans the table data and performs the first index creation operation. Once the index is built, its flag
pg_index.indisreadyis set totrueto prepare for insertion. After the transaction that executes the index creation ends, the index is visible to other sessions. This step is completed in a separate transaction for each index.SynxDB performs another table scan to update the data that was modified during the first scan into the index. This step is also completed in a separate transaction.
Changes the old index definition to reference the new index definition and modifies the index name. The value of
pg_index.indisvalidis switched totruefor the new index and tofalsefor the old index.The old index’s
pg_index.indisreadyis switched tofalseto prevent any new tuple insertions.The old index is dropped. The
SHARE UPDATE EXCLUSIVElocks on the index and table are released.
Usage
Execute the following command and restart the SynxDB database to enable GDD-related configuration parameters.
gpconfig -c gp_enable_global_deadlock_detector -v true gpstop -ra
Use the
REINDEX CONCURRENTLYsyntax to rebuild indexes concurrently.Assuming there is a table named
ordersthat contains a date column namedorder_date, and the index for this column isidx_orders_order_date, you can concurrently rebuild the indexidx_orders_order_date:REINDEX INDEX CONCURRENTLY idx_orders_order_date;
Usage restrictions
Executing
REINDEX CONCURRENTLYin a transaction block is not supported, which means you cannot explicitly start a transaction withBEGINand then execute concurrent index rebuilding.REINDEX SYSTEMdoes not supportCONCURRENTLYconcurrent rebuilding because system catalogs cannot be rebuilt concurrently.
Common issue handling
When using REINDEX CONCURRENTLY to rebuild indexes, if problems occur, such as violating uniqueness constraints in a unique index, the REINDEX CONCURRENTLY command will fail. In addition to the existing old index, an INVALID temporary index will be left, which will be ignored in queries because it is incomplete.
To view the INVALID index of this table, you can use the \d option:
\d tab
Table "public.tab"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
col | integer | | |
Indexes:
"idx_col_ccnew" btree (col) INVALID
Distributed by: (col)
If the index marked as
INVALIDhas the suffixccnew(as in the example above), it corresponds to the temporary index created during the concurrent rebuild operation. It is recommended to useDROP INDEXto drop this index and then tryREINDEX CONCURRENTLYagain.If the index marked as
INVALIDhas the suffixccold, it corresponds to the original index. It is recommended to drop this index directly usingDROP INDEXbecause the rebuild work has already succeeded.