summaryrefslogtreecommitdiff
path: root/src/backend/access/hash/hashinsert.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-03-14 13:27:02 -0400
committerRobert Haas <rhaas@postgresql.org>2017-03-14 13:27:02 -0400
commitc11453ce0aeaa377cbbcc9a3fc418acb94629330 (patch)
treeb7e0c1952bd7167ce826b8ed4bf8204012f4a47b /src/backend/access/hash/hashinsert.c
parent2b32ac2a59df18246c3b79e96a209bfdb39bb918 (diff)
downloadpostgresql-c11453ce0aeaa377cbbcc9a3fc418acb94629330.tar.gz
hash: Add write-ahead logging support.
The warning about hash indexes not being write-ahead logged and their use being discouraged has been removed. "snapshot too old" is now supported for tables with hash indexes. Most importantly, barring bugs, hash indexes will now be crash-safe and usable on standbys. This commit doesn't yet add WAL consistency checking for hash indexes, as we now have for other index types; a separate patch has been submitted to cure that lack. Amit Kapila, reviewed and slightly modified by me. The larger patch series of which this is a part has been reviewed and tested by Álvaro Herrera, Ashutosh Sharma, Mark Kirkwood, Jeff Janes, and Jesper Pedersen. Discussion: http://postgr.es/m/CAA4eK1JOBX=YU33631Qh-XivYXtPSALh514+jR8XeD7v+K3r_Q@mail.gmail.com
Diffstat (limited to 'src/backend/access/hash/hashinsert.c')
-rw-r--r--src/backend/access/hash/hashinsert.c59
1 files changed, 45 insertions, 14 deletions
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index 354e7339cf..241728fe6b 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -16,6 +16,8 @@
#include "postgres.h"
#include "access/hash.h"
+#include "access/hash_xlog.h"
+#include "miscadmin.h"
#include "utils/rel.h"
@@ -40,6 +42,7 @@ _hash_doinsert(Relation rel, IndexTuple itup)
bool do_expand;
uint32 hashkey;
Bucket bucket;
+ OffsetNumber itup_off;
/*
* Get the hash key for the item (it's stored in the index tuple itself).
@@ -158,25 +161,20 @@ restart_insert:
Assert(pageopaque->hasho_bucket == bucket);
}
- /* found page with enough space, so add the item here */
- (void) _hash_pgaddtup(rel, buf, itemsz, itup);
-
- /*
- * dirty and release the modified page. if the page we modified was an
- * overflow page, we also need to separately drop the pin we retained on
- * the primary bucket page.
- */
- MarkBufferDirty(buf);
- _hash_relbuf(rel, buf);
- if (buf != bucket_buf)
- _hash_dropbuf(rel, bucket_buf);
-
/*
* Write-lock the metapage so we can increment the tuple count. After
* incrementing it, check to see if it's time for a split.
*/
LockBuffer(metabuf, BUFFER_LOCK_EXCLUSIVE);
+ /* Do the update. No ereport(ERROR) until changes are logged */
+ START_CRIT_SECTION();
+
+ /* found page with enough space, so add the item here */
+ itup_off = _hash_pgaddtup(rel, buf, itemsz, itup);
+ MarkBufferDirty(buf);
+
+ /* metapage operations */
metap = HashPageGetMeta(metapage);
metap->hashm_ntuples += 1;
@@ -184,10 +182,43 @@ restart_insert:
do_expand = metap->hashm_ntuples >
(double) metap->hashm_ffactor * (metap->hashm_maxbucket + 1);
- /* Write out the metapage and drop lock, but keep pin */
MarkBufferDirty(metabuf);
+
+ /* XLOG stuff */
+ if (RelationNeedsWAL(rel))
+ {
+ xl_hash_insert xlrec;
+ XLogRecPtr recptr;
+
+ xlrec.offnum = itup_off;
+
+ XLogBeginInsert();
+ XLogRegisterData((char *) &xlrec, SizeOfHashInsert);
+
+ XLogRegisterBuffer(1, metabuf, REGBUF_STANDARD);
+
+ XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
+ XLogRegisterBufData(0, (char *) itup, IndexTupleDSize(*itup));
+
+ recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_INSERT);
+
+ PageSetLSN(BufferGetPage(buf), recptr);
+ PageSetLSN(BufferGetPage(metabuf), recptr);
+ }
+
+ END_CRIT_SECTION();
+
+ /* drop lock on metapage, but keep pin */
LockBuffer(metabuf, BUFFER_LOCK_UNLOCK);
+ /*
+ * Release the modified page and ensure to release the pin on primary
+ * page.
+ */
+ _hash_relbuf(rel, buf);
+ if (buf != bucket_buf)
+ _hash_dropbuf(rel, bucket_buf);
+
/* Attempt to split if a split is needed */
if (do_expand)
_hash_expandtable(rel, metabuf);