Commit 398cf255 authored by Heikki Linnakangas's avatar Heikki Linnakangas

In GIN recompression code, use mmemove rather than memcpy, for vacuum.

When vacuuming a data leaf page, any compressed posting lists that are not
modified, are copied back to the buffer from a later location in the same
buffer rather than from  a palloc'd copy. IOW, they are just moved
downwards in the same buffer. Because the source and destination addresses
can overlap, we must use memmove rather than memcpy.

Report and fix by Alexander Korotkov.
parent fbe19ee3
...@@ -753,6 +753,13 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs) ...@@ -753,6 +753,13 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
* *prdata is filled with WAL information about this operation. The caller * *prdata is filled with WAL information about this operation. The caller
* is responsible for inserting to the WAL, along with any other information * is responsible for inserting to the WAL, along with any other information
* about the operation that triggered this recompression. * about the operation that triggered this recompression.
*
* NOTE: The segment pointers can point directly to the same buffer, with
* the limitation that any earlier segment must not overlap with an original,
* later segment. In other words, some segments may point the original buffer
* as long as you don't make any segments larger. Currently, leafRepackItems
* satisies this rule because it rewrites all segments after the first
* modified one, and vacuum can only make segments shorter.
*/ */
static void static void
dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf, dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
...@@ -798,7 +805,13 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf, ...@@ -798,7 +805,13 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
if (!modified) if (!modified)
unmodifiedsize += segsize; unmodifiedsize += segsize;
else else
memcpy(ptr, seginfo->seg, segsize); {
/*
* Use memmove rather than memcpy, in case the segment points
* to the same buffer
*/
memmove(ptr, seginfo->seg, segsize);
}
ptr += segsize; ptr += segsize;
newsize += segsize; newsize += segsize;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment