mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
There are still some alignment-related failures in the buildfarm, which might or might not be able to be fixed quickly, but I've also just realized that it increased the size of many WAL records by 4 bytes because a block reference contains a RelFileLocator. The effect of that hasn't been studied or discussed, so revert for now.
266 lines
6.5 KiB
C
266 lines
6.5 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* heapdesc.c
|
|
* rmgr descriptor routines for access/heap/heapam.c
|
|
*
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* src/backend/access/rmgrdesc/heapdesc.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "access/heapam_xlog.h"
|
|
|
|
static void
|
|
out_infobits(StringInfo buf, uint8 infobits)
|
|
{
|
|
if (infobits & XLHL_XMAX_IS_MULTI)
|
|
appendStringInfoString(buf, "IS_MULTI ");
|
|
if (infobits & XLHL_XMAX_LOCK_ONLY)
|
|
appendStringInfoString(buf, "LOCK_ONLY ");
|
|
if (infobits & XLHL_XMAX_EXCL_LOCK)
|
|
appendStringInfoString(buf, "EXCL_LOCK ");
|
|
if (infobits & XLHL_XMAX_KEYSHR_LOCK)
|
|
appendStringInfoString(buf, "KEYSHR_LOCK ");
|
|
if (infobits & XLHL_KEYS_UPDATED)
|
|
appendStringInfoString(buf, "KEYS_UPDATED ");
|
|
}
|
|
|
|
void
|
|
heap_desc(StringInfo buf, XLogReaderState *record)
|
|
{
|
|
char *rec = XLogRecGetData(record);
|
|
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
|
|
|
|
info &= XLOG_HEAP_OPMASK;
|
|
if (info == XLOG_HEAP_INSERT)
|
|
{
|
|
xl_heap_insert *xlrec = (xl_heap_insert *) rec;
|
|
|
|
appendStringInfo(buf, "off %u flags 0x%02X", xlrec->offnum,
|
|
xlrec->flags);
|
|
}
|
|
else if (info == XLOG_HEAP_DELETE)
|
|
{
|
|
xl_heap_delete *xlrec = (xl_heap_delete *) rec;
|
|
|
|
appendStringInfo(buf, "off %u flags 0x%02X ",
|
|
xlrec->offnum,
|
|
xlrec->flags);
|
|
out_infobits(buf, xlrec->infobits_set);
|
|
}
|
|
else if (info == XLOG_HEAP_UPDATE)
|
|
{
|
|
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
|
|
|
appendStringInfo(buf, "off %u xmax %u flags 0x%02X ",
|
|
xlrec->old_offnum,
|
|
xlrec->old_xmax,
|
|
xlrec->flags);
|
|
out_infobits(buf, xlrec->old_infobits_set);
|
|
appendStringInfo(buf, "; new off %u xmax %u",
|
|
xlrec->new_offnum,
|
|
xlrec->new_xmax);
|
|
}
|
|
else if (info == XLOG_HEAP_HOT_UPDATE)
|
|
{
|
|
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
|
|
|
appendStringInfo(buf, "off %u xmax %u flags 0x%02X ",
|
|
xlrec->old_offnum,
|
|
xlrec->old_xmax,
|
|
xlrec->flags);
|
|
out_infobits(buf, xlrec->old_infobits_set);
|
|
appendStringInfo(buf, "; new off %u xmax %u",
|
|
xlrec->new_offnum,
|
|
xlrec->new_xmax);
|
|
}
|
|
else if (info == XLOG_HEAP_TRUNCATE)
|
|
{
|
|
xl_heap_truncate *xlrec = (xl_heap_truncate *) rec;
|
|
int i;
|
|
|
|
if (xlrec->flags & XLH_TRUNCATE_CASCADE)
|
|
appendStringInfoString(buf, "cascade ");
|
|
if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS)
|
|
appendStringInfoString(buf, "restart_seqs ");
|
|
appendStringInfo(buf, "nrelids %u relids", xlrec->nrelids);
|
|
for (i = 0; i < xlrec->nrelids; i++)
|
|
appendStringInfo(buf, " %u", xlrec->relids[i]);
|
|
}
|
|
else if (info == XLOG_HEAP_CONFIRM)
|
|
{
|
|
xl_heap_confirm *xlrec = (xl_heap_confirm *) rec;
|
|
|
|
appendStringInfo(buf, "off %u", xlrec->offnum);
|
|
}
|
|
else if (info == XLOG_HEAP_LOCK)
|
|
{
|
|
xl_heap_lock *xlrec = (xl_heap_lock *) rec;
|
|
|
|
appendStringInfo(buf, "off %u: xid %u: flags 0x%02X ",
|
|
xlrec->offnum, xlrec->locking_xid, xlrec->flags);
|
|
out_infobits(buf, xlrec->infobits_set);
|
|
}
|
|
else if (info == XLOG_HEAP_INPLACE)
|
|
{
|
|
xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
|
|
|
|
appendStringInfo(buf, "off %u", xlrec->offnum);
|
|
}
|
|
}
|
|
void
|
|
heap2_desc(StringInfo buf, XLogReaderState *record)
|
|
{
|
|
char *rec = XLogRecGetData(record);
|
|
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
|
|
|
|
info &= XLOG_HEAP_OPMASK;
|
|
if (info == XLOG_HEAP2_PRUNE)
|
|
{
|
|
xl_heap_prune *xlrec = (xl_heap_prune *) rec;
|
|
|
|
appendStringInfo(buf, "latestRemovedXid %u nredirected %u ndead %u",
|
|
xlrec->latestRemovedXid,
|
|
xlrec->nredirected,
|
|
xlrec->ndead);
|
|
}
|
|
else if (info == XLOG_HEAP2_VACUUM)
|
|
{
|
|
xl_heap_vacuum *xlrec = (xl_heap_vacuum *) rec;
|
|
|
|
appendStringInfo(buf, "nunused %u", xlrec->nunused);
|
|
}
|
|
else if (info == XLOG_HEAP2_FREEZE_PAGE)
|
|
{
|
|
xl_heap_freeze_page *xlrec = (xl_heap_freeze_page *) rec;
|
|
|
|
appendStringInfo(buf, "cutoff xid %u ntuples %u",
|
|
xlrec->cutoff_xid, xlrec->ntuples);
|
|
}
|
|
else if (info == XLOG_HEAP2_VISIBLE)
|
|
{
|
|
xl_heap_visible *xlrec = (xl_heap_visible *) rec;
|
|
|
|
appendStringInfo(buf, "cutoff xid %u flags 0x%02X",
|
|
xlrec->cutoff_xid, xlrec->flags);
|
|
}
|
|
else if (info == XLOG_HEAP2_MULTI_INSERT)
|
|
{
|
|
xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
|
|
|
|
appendStringInfo(buf, "%d tuples flags 0x%02X", xlrec->ntuples,
|
|
xlrec->flags);
|
|
}
|
|
else if (info == XLOG_HEAP2_LOCK_UPDATED)
|
|
{
|
|
xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
|
|
|
|
appendStringInfo(buf, "off %u: xmax %u: flags 0x%02X ",
|
|
xlrec->offnum, xlrec->xmax, xlrec->flags);
|
|
out_infobits(buf, xlrec->infobits_set);
|
|
}
|
|
else if (info == XLOG_HEAP2_NEW_CID)
|
|
{
|
|
xl_heap_new_cid *xlrec = (xl_heap_new_cid *) rec;
|
|
|
|
appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
|
|
xlrec->target_locator.spcOid,
|
|
xlrec->target_locator.dbOid,
|
|
xlrec->target_locator.relNumber,
|
|
ItemPointerGetBlockNumber(&(xlrec->target_tid)),
|
|
ItemPointerGetOffsetNumber(&(xlrec->target_tid)));
|
|
appendStringInfo(buf, "; cmin: %u, cmax: %u, combo: %u",
|
|
xlrec->cmin, xlrec->cmax, xlrec->combocid);
|
|
}
|
|
}
|
|
|
|
const char *
|
|
heap_identify(uint8 info)
|
|
{
|
|
const char *id = NULL;
|
|
|
|
switch (info & ~XLR_INFO_MASK)
|
|
{
|
|
case XLOG_HEAP_INSERT:
|
|
id = "INSERT";
|
|
break;
|
|
case XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE:
|
|
id = "INSERT+INIT";
|
|
break;
|
|
case XLOG_HEAP_DELETE:
|
|
id = "DELETE";
|
|
break;
|
|
case XLOG_HEAP_UPDATE:
|
|
id = "UPDATE";
|
|
break;
|
|
case XLOG_HEAP_UPDATE | XLOG_HEAP_INIT_PAGE:
|
|
id = "UPDATE+INIT";
|
|
break;
|
|
case XLOG_HEAP_HOT_UPDATE:
|
|
id = "HOT_UPDATE";
|
|
break;
|
|
case XLOG_HEAP_HOT_UPDATE | XLOG_HEAP_INIT_PAGE:
|
|
id = "HOT_UPDATE+INIT";
|
|
break;
|
|
case XLOG_HEAP_TRUNCATE:
|
|
id = "TRUNCATE";
|
|
break;
|
|
case XLOG_HEAP_CONFIRM:
|
|
id = "HEAP_CONFIRM";
|
|
break;
|
|
case XLOG_HEAP_LOCK:
|
|
id = "LOCK";
|
|
break;
|
|
case XLOG_HEAP_INPLACE:
|
|
id = "INPLACE";
|
|
break;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
const char *
|
|
heap2_identify(uint8 info)
|
|
{
|
|
const char *id = NULL;
|
|
|
|
switch (info & ~XLR_INFO_MASK)
|
|
{
|
|
case XLOG_HEAP2_PRUNE:
|
|
id = "PRUNE";
|
|
break;
|
|
case XLOG_HEAP2_VACUUM:
|
|
id = "VACUUM";
|
|
break;
|
|
case XLOG_HEAP2_FREEZE_PAGE:
|
|
id = "FREEZE_PAGE";
|
|
break;
|
|
case XLOG_HEAP2_VISIBLE:
|
|
id = "VISIBLE";
|
|
break;
|
|
case XLOG_HEAP2_MULTI_INSERT:
|
|
id = "MULTI_INSERT";
|
|
break;
|
|
case XLOG_HEAP2_MULTI_INSERT | XLOG_HEAP_INIT_PAGE:
|
|
id = "MULTI_INSERT+INIT";
|
|
break;
|
|
case XLOG_HEAP2_LOCK_UPDATED:
|
|
id = "LOCK_UPDATED";
|
|
break;
|
|
case XLOG_HEAP2_NEW_CID:
|
|
id = "NEW_CID";
|
|
break;
|
|
case XLOG_HEAP2_REWRITE:
|
|
id = "REWRITE";
|
|
break;
|
|
}
|
|
|
|
return id;
|
|
}
|