aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogreader.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-11-26 15:17:25 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2017-11-26 15:17:25 -0500
commitc0ef3af4ebf2dcc2de8edf87be69cd7773dc0f8d (patch)
treec6dcbc0bfdae0224d47e0d7a81d5ae06686e016a /src/backend/access/transam/xlogreader.c
parentdb714c62bed9dea71ed1700855fb755f2e75f2da (diff)
downloadpostgresql-c0ef3af4ebf2dcc2de8edf87be69cd7773dc0f8d.tar.gz
postgresql-c0ef3af4ebf2dcc2de8edf87be69cd7773dc0f8d.zip
Pad XLogReaderState's main_data buffer more aggressively.
Originally, we palloc'd this buffer just barely big enough to hold the largest xlog record seen so far. It turns out that that can result in valgrind complaints, because some compilers will emit code that assumes it can safely fetch padding bytes at the end of a struct, and those padding bytes were unallocated so far as aset.c was concerned. We can fix that by MAXALIGN'ing the palloc request size, ensuring that it is big enough to include any possible padding that might've been omitted from the on-disk record. An additional objection to the original coding is that it could result in many repeated palloc cycles, in the worst case where we see a series of gradually larger xlog records. We can ameliorate that cheaply by imposing a minimum buffer size that's large enough for most xlog records. BLCKSZ/2 was chosen after a bit of discussion. In passing, remove an obsolete comment in struct xl_heap_new_cid that the combocid field is free due to alignment considerations. Perhaps that was true at some point, but it's not now. Back-patch to 9.5 where this code came in. Discussion: https://postgr.es/m/E1eHa4J-0006hI-Q8@gemulon.postgresql.org
Diffstat (limited to 'src/backend/access/transam/xlogreader.c')
-rw-r--r--src/backend/access/transam/xlogreader.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 0973d778ac9..db8f3a34e21 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1248,7 +1248,22 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg)
{
if (state->main_data)
pfree(state->main_data);
- state->main_data_bufsz = state->main_data_len;
+
+ /*
+ * main_data_bufsz must be MAXALIGN'ed. In many xlog record
+ * types, we omit trailing struct padding on-disk to save a few
+ * bytes; but compilers may generate accesses to the xlog struct
+ * that assume that padding bytes are present. If the palloc
+ * request is not large enough to include such padding bytes then
+ * we'll get valgrind complaints due to otherwise-harmless fetches
+ * of the padding bytes.
+ *
+ * In addition, force the initial request to be reasonably large
+ * so that we don't waste time with lots of trips through this
+ * stanza. BLCKSZ / 2 seems like a good compromise choice.
+ */
+ state->main_data_bufsz = MAXALIGN(Max(state->main_data_len,
+ BLCKSZ / 2));
state->main_data = palloc(state->main_data_bufsz);
}
memcpy(state->main_data, ptr, state->main_data_len);