diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-07-31 20:09:10 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-07-31 20:09:10 +0000 |
commit | 09d3670df3e4593be1d2299a62d982829016b847 (patch) | |
tree | 7a62e91c1cf595d0334dd2c196d1c79835cc267b /doc/src | |
parent | 4cd72b53b9975bab5f4ca0792cf4f54c84829404 (diff) | |
download | postgresql-09d3670df3e4593be1d2299a62d982829016b847.tar.gz postgresql-09d3670df3e4593be1d2299a62d982829016b847.zip |
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.
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 9 | ||||
-rw-r--r-- | doc/src/sgml/indexam.sgml | 47 |
2 files changed, 14 insertions, 42 deletions
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 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.128 2006/07/27 08:30:41 petere Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.129 2006/07/31 20:08:55 tgl Exp $ --> <!-- Documentation of the system catalogs, directed toward PostgreSQL developers --> @@ -402,13 +402,6 @@ </row> <row> - <entry><structfield>amconcurrent</structfield></entry> - <entry><type>bool</type></entry> - <entry></entry> - <entry>Does the access method support concurrent updates?</entry> - </row> - - <row> <entry><structfield>amclusterable</structfield></entry> <entry><type>bool</type></entry> <entry></entry> 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 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.15 2006/07/03 22:45:36 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.16 2006/07/31 20:08:59 tgl Exp $ --> <chapter id="indexam"> <title>Index Access Method Interface Definition</title> @@ -94,8 +94,7 @@ <para> Some of the flag columns of <structname>pg_am</structname> have nonobvious implications. The requirements of <structfield>amcanunique</structfield> - are discussed in <xref linkend="index-unique-checks">, and those of - <structfield>amconcurrent</structfield> in <xref linkend="index-locking">. + are discussed in <xref linkend="index-unique-checks">. The <structfield>amcanmulticol</structfield> flag asserts that the access method supports multicolumn indexes, while <structfield>amoptionalkey</structfield> 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 - <structname>pg_am</>.<structfield>amconcurrent</>, it is sufficient to - handle these cases for insertions or deletions performed by the same - backend that's doing the scan. But when <structfield>amconcurrent</> is - true, insertions or deletions from other backends must be handled as well.) + deleted. </para> <para> @@ -506,31 +501,16 @@ amrestrpos (IndexScanDesc scan); <title>Index Locking Considerations</title> <para> - An index access method can choose whether it supports concurrent updates - of the index by multiple processes. If the method's - <structname>pg_am</>.<structfield>amconcurrent</> flag is true, then - the core <productname>PostgreSQL</productname> system obtains + Index access methods must handle concurrent updates + of the index by multiple processes. + The core <productname>PostgreSQL</productname> system obtains <literal>AccessShareLock</> on the index during an index scan, and - <literal>RowExclusiveLock</> when updating the index. Since these lock + <literal>RowExclusiveLock</> when updating the index (including plain + <command>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 - <literal>REINDEX</>. When <structfield>amconcurrent</> is false, - <productname>PostgreSQL</productname> still obtains - <literal>AccessShareLock</> during index scans, but it obtains - <literal>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. - </para> - - <para> - 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 <command>UPDATE</> - that uses the index to find the rows to be updated.) + will be taken only during index creation, destruction, + <command>REINDEX</>, or <command>VACUUM FULL</>. </para> <para> @@ -567,7 +547,7 @@ amrestrpos (IndexScanDesc scan); </listitem> <listitem> <para> - 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 <function>amgettuple</>, and <function>ambulkdelete</> cannot delete entries from pages that are pinned by other backends. The need @@ -576,11 +556,10 @@ amrestrpos (IndexScanDesc scan); </listitem> </itemizedlist> - 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 <command>VACUUM</>, and then to arrive at the corresponding heap entry after that was removed by - <command>VACUUM</>. (With a nonconcurrent index, this is not possible - because of the conflicting index-level locks that will be taken out.) + <command>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 <function>heap_fetch()</>. But what if a |