1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

BRIN de-summarization

When the BRIN summary tuple for a page range becomes too "wide" for the
values actually stored in the table (because the tuples that were
present originally are no longer present due to updates or deletes), it
can be useful to remove the outdated summary tuple, so that a future
summarization can install a tighter summary.

This commit introduces a SQL-callable interface to do so.

Author: Álvaro Herrera
Reviewed-by: Eiji Seki
Discussion: https://postgr.es/m/20170228045643.n2ri74ara4fhhfxf@alvherre.pgsql
This commit is contained in:
Alvaro Herrera
2017-04-01 16:10:04 -03:00
parent 3a82129a40
commit c655899ba9
12 changed files with 340 additions and 5 deletions

View File

@@ -254,6 +254,46 @@ brin_xlog_revmap_extend(XLogReaderState *record)
UnlockReleaseBuffer(metabuf);
}
static void
brin_xlog_desummarize_page(XLogReaderState *record)
{
XLogRecPtr lsn = record->EndRecPtr;
xl_brin_desummarize *xlrec;
Buffer buffer;
XLogRedoAction action;
xlrec = (xl_brin_desummarize *) XLogRecGetData(record);
/* Update the revmap */
action = XLogReadBufferForRedo(record, 0, &buffer);
if (action == BLK_NEEDS_REDO)
{
ItemPointerData iptr;
ItemPointerSetInvalid(&iptr);
brinSetHeapBlockItemptr(buffer, xlrec->pagesPerRange, xlrec->heapBlk, iptr);
PageSetLSN(BufferGetPage(buffer), lsn);
MarkBufferDirty(buffer);
}
if (BufferIsValid(buffer))
UnlockReleaseBuffer(buffer);
/* remove the leftover entry from the regular page */
action = XLogReadBufferForRedo(record, 1, &buffer);
if (action == BLK_NEEDS_REDO)
{
Page regPg = BufferGetPage(buffer);
PageIndexTupleDeleteNoCompact(regPg, xlrec->regOffset);
PageSetLSN(regPg, lsn);
MarkBufferDirty(buffer);
}
if (BufferIsValid(buffer))
UnlockReleaseBuffer(buffer);
}
void
brin_redo(XLogReaderState *record)
{
@@ -276,6 +316,9 @@ brin_redo(XLogReaderState *record)
case XLOG_BRIN_REVMAP_EXTEND:
brin_xlog_revmap_extend(record);
break;
case XLOG_BRIN_DESUMMARIZE:
brin_xlog_desummarize_page(record);
break;
default:
elog(PANIC, "brin_redo: unknown op code %u", info);
}