On 02.08.2011 15:18, Simon Riggs wrote:
On Tue, Aug 2, 2011 at 12:43 PM, Heikki Linnakangas
<heikki.linnakan...@enterprisedb.com> wrote:
On 02.08.2011 14:36, Simon Riggs wrote:
Actually I think we can append the new information to the end of the page
split record, so that an old version server can read WAL generated by new
version, too.
Not sure how that would work. Lengths, CRCs?
Or do you mean we will support 2 versions, have them both called the
same thing, just resolve which is which by the record length. Don't
like that.
Here's a patch to do what I meant. The new fields are stored at the very
end of the WAL record, and you check the length to see if they're there
or not. The nice thing about this is that it's compatible in both
directions.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index 02c4ec3..60fc173 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -151,7 +151,6 @@ gistRedoPageUpdateRecord(XLogRecPtr lsn, XLogRecord *record)
*/
GistPageSetLeaf(page);
- GistPageGetOpaque(page)->rightlink = InvalidBlockNumber;
PageSetLSN(page, lsn);
PageSetTLI(page, ThisTimeLineID);
MarkBufferDirty(buffer);
@@ -222,16 +221,28 @@ gistRedoPageSplitRecord(XLogRecPtr lsn, XLogRecord *record)
Page page;
int i;
bool isrootsplit = false;
+ Buffer *buffers;
+ /*
+ * If this split inserted a downlink for a child at lower level, we can
+ * now set the NSN and clear the follow-right flag on that child. It's
+ * OK to do this before locking the parent page. If a concurrent scan
+ * reads this parent page after we've already cleared the follow-right
+ * flag on the child, it'll still follow the rightlink because of the
+ * NSN.
+ */
if (BlockNumberIsValid(xldata->leftchild))
gistRedoClearFollowRight(xldata->node, lsn, xldata->leftchild);
decodePageSplitRecord(&xlrec, record);
- /* loop around all pages */
+ /*
+ * Lock all the pages involved in the split first, so that any concurrent
+ * scans in hot standby mode will see the split as an atomic operation.
+ */
+ buffers = palloc(xlrec.data->npage * sizeof(Buffer));
for (i = 0; i < xlrec.data->npage; i++)
{
NewPage *newpage = xlrec.page + i;
- int flags;
if (newpage->header->blkno == GIST_ROOT_BLKNO)
{
@@ -239,8 +250,19 @@ gistRedoPageSplitRecord(XLogRecPtr lsn, XLogRecord *record)
isrootsplit = true;
}
- buffer = XLogReadBuffer(xlrec.data->node, newpage->header->blkno, true);
- Assert(BufferIsValid(buffer));
+ buffers[i] = XLogReadBuffer(xlrec.data->node,
+ newpage->header->blkno,
+ true);
+ Assert(BufferIsValid(buffers[i]));
+ }
+
+ /* Write out all the pages */
+ for (i = 0; i < xlrec.data->npage; i++)
+ {
+ NewPage *newpage = xlrec.page + i;
+ int flags;
+
+ buffer = buffers[i];
page = (Page) BufferGetPage(buffer);
/* ok, clear buffer */
@@ -277,6 +299,8 @@ gistRedoPageSplitRecord(XLogRecPtr lsn, XLogRecord *record)
MarkBufferDirty(buffer);
UnlockReleaseBuffer(buffer);
}
+
+ pfree(buffers);
}
static void
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers