From 09d3670df3e4593be1d2299a62d982829016b847 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 31 Jul 2006 20:09:10 +0000 Subject: Change the relation_open protocol so that we obtain lock on a relation (table or index) before trying to open its relcache entry. This fixes race conditions in which someone else commits a change to the relation's catalog entries while we are in process of doing relcache load. Problems of that ilk have been reported sporadically for years, but it was not really practical to fix until recently --- for instance, the recent addition of WAL-log support for in-place updates helped. Along the way, remove pg_am.amconcurrent: all AMs are now expected to support concurrent update. --- doc/src/sgml/catalogs.sgml | 9 +-------- doc/src/sgml/indexam.sgml | 47 +++++++++++++--------------------------------- 2 files changed, 14 insertions(+), 42 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index dfb6348e1d6..80ed7d829bc 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ - + @@ -401,13 +401,6 @@ Can index storage data type differ from column data type? - - amconcurrent - bool - - Does the access method support concurrent updates? - - amclusterable bool diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index 7febd0c9072..1afa120766e 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -1,4 +1,4 @@ - + Index Access Method Interface Definition @@ -94,8 +94,7 @@ Some of the flag columns of pg_am have nonobvious implications. The requirements of amcanunique - are discussed in , and those of - amconcurrent in . + are discussed in . The amcanmulticol flag asserts that the access method supports multicolumn indexes, while amoptionalkey asserts that it allows scans @@ -474,11 +473,7 @@ amrestrpos (IndexScanDesc scan); a concurrent delete may or may not be reflected in the results of a scan. What is important is that insertions or deletions not cause the scan to miss or multiply return entries that were not themselves being inserted or - deleted. (For an index type that does not set - pg_am.amconcurrent, it is sufficient to - handle these cases for insertions or deletions performed by the same - backend that's doing the scan. But when amconcurrent is - true, insertions or deletions from other backends must be handled as well.) + deleted. @@ -506,31 +501,16 @@ amrestrpos (IndexScanDesc scan); Index Locking Considerations - An index access method can choose whether it supports concurrent updates - of the index by multiple processes. If the method's - pg_am.amconcurrent flag is true, then - the core PostgreSQL system obtains + Index access methods must handle concurrent updates + of the index by multiple processes. + The core PostgreSQL system obtains AccessShareLock on the index during an index scan, and - RowExclusiveLock when updating the index. Since these lock + RowExclusiveLock when updating the index (including plain + VACUUM). Since these lock types do not conflict, the access method is responsible for handling any fine-grained locking it may need. An exclusive lock on the index as a whole - will be taken only during index creation, destruction, or - REINDEX. When amconcurrent is false, - PostgreSQL still obtains - AccessShareLock during index scans, but it obtains - AccessExclusiveLock during any update. This ensures that - updaters have sole use of the index. Note that this implicitly assumes - that index scans are read-only; an access method that might modify the - index during a scan will still have to do its own locking to handle the - case of concurrent scans. - - - - Recall that a backend's own locks never conflict; therefore, even a - non-concurrent index type must be prepared to handle the case where - a backend is inserting or deleting entries in an index that it is itself - scanning. (This is of course necessary to support an UPDATE - that uses the index to find the rows to be updated.) + will be taken only during index creation, destruction, + REINDEX, or VACUUM FULL. @@ -567,7 +547,7 @@ amrestrpos (IndexScanDesc scan); - For concurrent index types, an index scan must maintain a pin + An index scan must maintain a pin on the index page holding the item last returned by amgettuple, and ambulkdelete cannot delete entries from pages that are pinned by other backends. The need @@ -576,11 +556,10 @@ amrestrpos (IndexScanDesc scan); - If an index is concurrent then it is possible for an index reader to + Without the third rule, it is possible for an index reader to see an index entry just before it is removed by VACUUM, and then to arrive at the corresponding heap entry after that was removed by - VACUUM. (With a nonconcurrent index, this is not possible - because of the conflicting index-level locks that will be taken out.) + VACUUM. This creates no serious problems if that item number is still unused when the reader reaches it, since an empty item slot will be ignored by heap_fetch(). But what if a -- cgit v1.2.3