mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Protect against torn pages when deleting GIN list pages.
To-be-deleted list pages contain no useful information, as they are being deleted, but we must still protect the writes from being torn by a crash after a partial write. To do that, re-initialize the pages on WAL replay. Jeff Janes caught this with a test program to test partial writes. Backpatch to all supported versions.
This commit is contained in:
parent
02c9a93805
commit
4f7bb4b2a3
@ -884,25 +884,25 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
* cannot get past a reader that is on, or due to visit, any page we are
|
* cannot get past a reader that is on, or due to visit, any page we are
|
||||||
* going to delete. New incoming readers will block behind our metapage
|
* going to delete. New incoming readers will block behind our metapage
|
||||||
* lock and then see a fully updated page list.
|
* lock and then see a fully updated page list.
|
||||||
|
*
|
||||||
|
* No full-page images are taken of the deleted pages. Instead, they are
|
||||||
|
* re-initialized as empty, deleted pages. Their right-links don't need to
|
||||||
|
* be preserved, because no new readers can see the pages, as explained
|
||||||
|
* above.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < data->ndeleted; i++)
|
for (i = 0; i < data->ndeleted; i++)
|
||||||
{
|
{
|
||||||
Buffer buffer = XLogReadBuffer(data->node, data->toDelete[i], false);
|
Buffer buffer;
|
||||||
|
Page page;
|
||||||
|
|
||||||
if (BufferIsValid(buffer))
|
buffer = XLogReadBuffer(data->node, data->toDelete[i], true);
|
||||||
{
|
page = BufferGetPage(buffer);
|
||||||
Page page = BufferGetPage(buffer);
|
GinInitBuffer(buffer, GIN_DELETED);
|
||||||
|
|
||||||
if (lsn > PageGetLSN(page))
|
PageSetLSN(page, lsn);
|
||||||
{
|
MarkBufferDirty(buffer);
|
||||||
GinPageGetOpaque(page)->flags = GIN_DELETED;
|
|
||||||
|
|
||||||
PageSetLSN(page, lsn);
|
UnlockReleaseBuffer(buffer);
|
||||||
MarkBufferDirty(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnlockReleaseBuffer(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UnlockReleaseBuffer(metabuffer);
|
UnlockReleaseBuffer(metabuffer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user