diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-11-29 14:50:39 -0500 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-11-29 14:52:07 -0500 |
| commit | 1dbd02dc37efb74b770aa834b2cb65dae2446640 (patch) | |
| tree | b2a6dd6301b09fb40e99f978017e3337c85e3595 /src/include | |
| parent | 3dfdf28152eb2df7cb4d4e43f461903fcc09e1d2 (diff) | |
Fix assorted bugs in CREATE INDEX CONCURRENTLY.
This patch changes CREATE INDEX CONCURRENTLY so that the pg_index
flag changes it makes without exclusive lock on the index are made via
heap_inplace_update() rather than a normal transactional update. The
latter is not very safe because moving the pg_index tuple could result in
concurrent SnapshotNow scans finding it twice or not at all, thus possibly
resulting in index corruption.
In addition, fix various places in the code that ought to check to make
sure that the indexes they are manipulating are valid and/or ready as
appropriate. These represent bugs that have existed since 8.2, since
a failed CREATE INDEX CONCURRENTLY could leave a corrupt or invalid
index behind, and we ought not try to do anything that might fail with
such an index.
Also fix RelationReloadIndexInfo to ensure it copies all the pg_index
columns that are allowed to change after initial creation. Previously we
could have been left with stale values of some fields in an index relcache
entry. It's not clear whether this actually had any user-visible
consequences, but it's at least a bug waiting to happen.
This is a subset of a patch already applied in 9.2 and HEAD. Back-patch
into all earlier supported branches.
Tom Lane and Andres Freund
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/index.h | 9 | ||||
| -rw-r--r-- | src/include/catalog/pg_index.h | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 9728d791b6a..a2381b1e5d4 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -27,6 +27,13 @@ typedef void (*IndexBuildCallback) (Relation index, bool tupleIsAlive, void *state); +/* Action code for index_set_state_flags */ +typedef enum +{ + INDEX_CREATE_SET_READY, + INDEX_CREATE_SET_VALID +} IndexStateFlagsAction; + extern Oid index_create(Oid heapRelationId, const char *indexRelationName, @@ -71,6 +78,8 @@ extern double IndexBuildHeapScan(Relation heapRelation, extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot); +extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action); + extern void reindex_index(Oid indexId, bool skip_constraint_checks); #define REINDEX_CHECK_CONSTRAINTS 0x1 diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h index 685fae3c0e7..2fe179a0cb8 100644 --- a/src/include/catalog/pg_index.h +++ b/src/include/catalog/pg_index.h @@ -88,4 +88,12 @@ typedef FormData_pg_index *Form_pg_index; #define INDOPTION_DESC 0x0001 /* values are in reverse order */ #define INDOPTION_NULLS_FIRST 0x0002 /* NULLs are first instead of last */ +/* + * Use of these macros is recommended over direct examination of the state + * flag columns where possible; this allows source code compatibility with + * 9.2 and up. + */ +#define IndexIsValid(indexForm) ((indexForm)->indisvalid) +#define IndexIsReady(indexForm) ((indexForm)->indisready) + #endif /* PG_INDEX_H */ |
