diff options
author | Heikki Linnakangas | 2015-01-16 23:14:32 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2015-01-16 23:15:23 +0000 |
commit | 94028691609f8e148bd4ce72c46163f018832a5b (patch) | |
tree | b27e0466f02336d5dad3f2594942e9a4cc23b4c2 /src/include | |
parent | 779fdcdeeeb9cdbfd271f8dc5bde76ed0c7b0813 (diff) |
Advance backend's advertised xmin more aggressively.
Currently, a backend will reset it's PGXACT->xmin value when it doesn't
have any registered snapshots left. That covered the common case that a
transaction in read committed mode runs several queries, one after each
other, as there would be no snapshots active between those queries.
However, if you hold cursors across each of the query, we didn't get a
chance to reset xmin.
To make that better, keep all the registered snapshots in a pairing heap,
ordered by xmin so that it's always quick to find the snapshot with the
smallest xmin. That allows us to advance PGXACT->xmin whenever the oldest
snapshot is deregistered, even if there are others still active.
Per discussion originally started by Jeff Davis back in 2009 and more
recently by Robert Haas.
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/lib/pairingheap.h | 19 | ||||
-rw-r--r-- | src/include/utils/snapshot.h | 5 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/include/lib/pairingheap.h b/src/include/lib/pairingheap.h index a7f28ec422d..e3e320fc434 100644 --- a/src/include/lib/pairingheap.h +++ b/src/include/lib/pairingheap.h @@ -30,6 +30,25 @@ typedef struct pairingheap_node } pairingheap_node; /* + * Return the containing struct of 'type' where 'membername' is the + * pairingheap_node pointed at by 'ptr'. + * + * This is used to convert a pairingheap_node * back to its containing struct. + */ +#define pairingheap_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, pairingheap_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, pairingheap_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Like pairingheap_container, but used when the pointer is 'const ptr' + */ +#define pairingheap_const_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, const pairingheap_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, pairingheap_node), \ + ((const type *) ((const char *) (ptr) - offsetof(type, membername)))) + +/* * For a max-heap, the comparator must return <0 iff a < b, 0 iff a == b, * and >0 iff a > b. For a min-heap, the conditions are reversed. */ diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h index 591f0efa21e..26fb2573c71 100644 --- a/src/include/utils/snapshot.h +++ b/src/include/utils/snapshot.h @@ -14,6 +14,7 @@ #define SNAPSHOT_H #include "access/htup.h" +#include "lib/pairingheap.h" #include "storage/buf.h" @@ -91,7 +92,9 @@ typedef struct SnapshotData */ CommandId curcid; /* in my xact, CID < curcid are visible */ uint32 active_count; /* refcount on ActiveSnapshot stack */ - uint32 regd_count; /* refcount on RegisteredSnapshotList */ + uint32 regd_count; /* refcount on RegisteredSnapshots */ + + pairingheap_node ph_node; /* link in the RegisteredSnapshots heap */ } SnapshotData; /* |