Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix minor 9.4-only bug in logical decoding.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 1 Sep 2016 15:45:16 +0000 (11:45 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 1 Sep 2016 15:45:16 +0000 (11:45 -0400)
The 9.4 version of log_heap_update() stores the full length of the
old_key_tuple in xlhdr.t_len, rather than the length less
offsetof(HeapTupleHeaderData, t_bits) as is customary elsewhere.
DecodeUpdate() was expecting the usual definition, which caused it
to copy 23 bytes too much out of the WAL-file buffer.  Most of the
time that's harmless, although Valgrind on buildfarm member skink
has been complaining about it, and there was one actual SIGSEGV
on curculio that might have been caused by this.  The reconstructed
key tuple would also have an over-length t_len, though offhand
I do not see how that could cause any visible problem.

The problem seems to have disappeared in the 9.5 WAL format changes
(commit 2c03216d8), so we only need to fix 9.4.

Discussion: <11035.1469058247@sss.pgh.pa.us>

src/backend/replication/logical/decode.c

index fafbd5f0ec21c5e315081e220dd1a4dce1620697..7ce1d619e18ed9500137888d6da52446c64a40bb 100644 (file)
@@ -702,16 +702,16 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
        memcpy(&xlhdr, data, sizeof(xlhdr));
        data += offsetof(xl_heap_header_len, header);
 
-       datalen = xlhdr.t_len + SizeOfHeapHeader;
-       tuplelen = xlhdr.t_len;
+       /* t_len is inconsistent with other cases, see log_heap_update */
+       tuplelen = xlhdr.t_len - offsetof(HeapTupleHeaderData, t_bits);
+       datalen = tuplelen + SizeOfHeapHeader;
 
        change->data.tp.oldtuple =
            ReorderBufferGetTupleBuf(ctx->reorder, tuplelen);
 
        DecodeXLogTuple(data, datalen, change->data.tp.oldtuple);
 #ifdef NOT_USED
-       data += SizeOfHeapHeader;
-       data += xlhdr.t_len;
+       data += datalen;
 #endif
    }