git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d64a9c8)
Add comments explaining how unique and exclusion constraints are enforced.
2015年4月24日 18:12:32 +0000 (21:12 +0300)
2015年4月24日 18:13:28 +0000 (21:13 +0300)

diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index de8fcdb941ad8f8a5bb656913f85919983e4c1d1..a697682b20e8cff4d8ebde6b485b796d7939314b 100644 (file)
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -1,7 +1,55 @@
/*-------------------------------------------------------------------------
*
* execIndexing.c
- * executor support for maintaining indexes
+ * routines for inserting index tuples and enforcing unique and
+ * exclusive constraints.
+ *
+ * ExecInsertIndexTuples() is the main entry point. It's called after
+ * inserting a tuple to the heap, and it inserts corresponding index tuples
+ * into all indexes. At the same time, it enforces any unique and
+ * exclusion constraints:
+ *
+ * Unique Indexes
+ * --------------
+ *
+ * Enforcing a unique constraint is straightforward. When the index AM
+ * inserts the tuple to the index, it also checks that there are no
+ * conflicting tuples in the index already. It does so atomically, so that
+ * even if two backends try to insert the same key concurrently, only one
+ * of them will succeed. All the logic to ensure atomicity, and to wait
+ * for in-progress transactions to finish, is handled by the index AM.
+ *
+ * If a unique constraint is deferred, we request the index AM to not
+ * throw an error if a conflict is found. Instead, we make note that there
+ * was a conflict and return the list of indexes with conflicts to the
+ * caller. The caller must re-check them later, by calling index_insert()
+ * with the UNIQUE_CHECK_EXISTING option.
+ *
+ * Exclusion Constraints
+ * ---------------------
+ *
+ * Exclusion constraints are different from unique indexes in that when the
+ * tuple is inserted to the index, the index AM does not check for
+ * duplicate keys at the same time. After the insertion, we perform a
+ * separate scan on the index to check for conflicting tuples, and if one
+ * is found, we throw an error and the transaction is aborted. If the
+ * conflicting tuple's inserter or deleter is in-progress, we wait for it
+ * to finish first.
+ *
+ * There is a chance of deadlock, if two backends insert a tuple at the
+ * same time, and then perform the scan to check for conflicts. They will
+ * find each other's tuple, and both try to wait for each other. The
+ * deadlock detector will detect that, and abort one of the transactions.
+ * That's fairly harmless, as one of them was bound to abort with a
+ * "duplicate key error" anyway, although you get a different error
+ * message.
+ *
+ * If an exclusion constraint is deferred, we still perform the conflict
+ * checking scan immediately after inserting the index tuple. But instead
+ * of throwing an error if a conflict is found, we return that information
+ * to the caller. The caller must re-check them later by calling
+ * check_exclusion_constraint().
+ *
*
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
@@ -134,13 +182,10 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo)
* This routine takes care of inserting index tuples
* into all the relations indexing the result relation
* when a heap tuple is inserted into the result relation.
- * Much of this code should be moved into the genam
- * stuff as it only exists here because the genam stuff
- * doesn't provide the functionality needed by the
- * executor.. -cim 9/27/89
*
- * This returns a list of index OIDs for any unique or exclusion
- * constraints that are deferred and that had
+ * Unique and exclusion constraints are enforced at the same
+ * time. This returns a list of index OIDs for any unique or
+ * exclusion constraints that are deferred and that had
* potential (unconfirmed) conflicts.
*
* CAUTION: this must not be called for a HOT update.
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /