Skip to content

Commit 0f47e83

Browse files
committed
Fix alignment problem with bbsink_copystream buffer.
bbsink_copystream wants to store a type byte just before the buffer, but basebackup.c wants the buffer to be aligned so that it can call PageIsNew() and PageGetLSN() on it. Therefore, instead of inserting 1 extra byte before the buffer, insert MAXIMUM_ALIGNOF extra bytes and only use the last one. On most machines this doesn't cause any problem (except perhaps for performance) but some buildfarm machines with -fsanitize=alignment dump core. Discussion: http://postgr.es/m/CA+TgmoYx5=1A2K9JYV-9zdhyokU4KKTyNQ9q7CiXrX=YBBMWVw@mail.gmail.com
1 parent 44129c0 commit 0f47e83

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

src/backend/replication/basebackup_copy.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,22 @@ bbsink_copystream_begin_backup(bbsink *sink)
152152
{
153153
bbsink_copystream *mysink = (bbsink_copystream *) sink;
154154
bbsink_state *state = sink->bbs_state;
155+
char *buf;
155156

156157
/*
157158
* Initialize buffer. We ultimately want to send the archive and manifest
158159
* data by means of CopyData messages where the payload portion of each
159-
* message begins with a type byte, so we set up a buffer that begins with
160-
* a the type byte we're going to need, and then arrange things so that
161-
* the data we're given will be written just after that type byte. That
162-
* will allow us to ship the data with a single call to pq_putmessage and
163-
* without needing any extra copying.
160+
* message begins with a type byte. However, basebackup.c expects the
161+
* buffer to be aligned, so we can't just allocate one extra byte for the
162+
* type byte. Instead, allocate enough extra bytes that the portion of
163+
* the buffer we reveal to our callers can be aligned, while leaving room
164+
* to slip the type byte in just beforehand. That will allow us to ship
165+
* the data with a single call to pq_putmessage and without needing any
166+
* extra copying.
164167
*/
165-
mysink->msgbuffer = palloc(mysink->base.bbs_buffer_length + 1);
166-
mysink->base.bbs_buffer = mysink->msgbuffer + 1;
168+
buf = palloc(mysink->base.bbs_buffer_length + MAXIMUM_ALIGNOF);
169+
mysink->msgbuffer = buf + (MAXIMUM_ALIGNOF - 1);
170+
mysink->base.bbs_buffer = buf + MAXIMUM_ALIGNOF;
167171
mysink->msgbuffer[0] = 'd'; /* archive or manifest data */
168172

169173
/* Tell client the backup start location. */

0 commit comments

Comments
 (0)