mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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.
This commit is contained in:
parent
fbe19ee3b8
commit
398cf255ad
@ -753,6 +753,13 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
|
||||
* *prdata is filled with WAL information about this operation. The caller
|
||||
* is responsible for inserting to the WAL, along with any other information
|
||||
* 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
|
||||
dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
|
||||
@ -798,7 +805,13 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
|
||||
if (!modified)
|
||||
unmodifiedsize += segsize;
|
||||
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;
|
||||
newsize += segsize;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user