mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Split out rmgr rm_desc functions into their own files
This is necessary (but not sufficient) to have them compilable outside of a backend environment.
This commit is contained in:
parent
dd7353dde8
commit
1577b46b7c
@ -8,6 +8,6 @@ subdir = src/backend/access
|
|||||||
top_builddir = ../../..
|
top_builddir = ../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
SUBDIRS = common gist hash heap index nbtree transam gin spgist
|
SUBDIRS = common gin gist hash heap index nbtree rmgrdesc spgist transam
|
||||||
|
|
||||||
include $(top_srcdir)/src/backend/common.mk
|
include $(top_srcdir)/src/backend/common.mk
|
||||||
|
@ -766,69 +766,6 @@ gin_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
MemoryContextReset(opCtx);
|
MemoryContextReset(opCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
desc_node(StringInfo buf, RelFileNode node, BlockNumber blkno)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "node: %u/%u/%u blkno: %u",
|
|
||||||
node.spcNode, node.dbNode, node.relNode, blkno);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gin_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
switch (info)
|
|
||||||
{
|
|
||||||
case XLOG_GIN_CREATE_INDEX:
|
|
||||||
appendStringInfo(buf, "Create index, ");
|
|
||||||
desc_node(buf, *(RelFileNode *) rec, GIN_ROOT_BLKNO);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_CREATE_PTREE:
|
|
||||||
appendStringInfo(buf, "Create posting tree, ");
|
|
||||||
desc_node(buf, ((ginxlogCreatePostingTree *) rec)->node, ((ginxlogCreatePostingTree *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_INSERT:
|
|
||||||
appendStringInfo(buf, "Insert item, ");
|
|
||||||
desc_node(buf, ((ginxlogInsert *) rec)->node, ((ginxlogInsert *) rec)->blkno);
|
|
||||||
appendStringInfo(buf, " offset: %u nitem: %u isdata: %c isleaf %c isdelete %c updateBlkno:%u",
|
|
||||||
((ginxlogInsert *) rec)->offset,
|
|
||||||
((ginxlogInsert *) rec)->nitem,
|
|
||||||
(((ginxlogInsert *) rec)->isData) ? 'T' : 'F',
|
|
||||||
(((ginxlogInsert *) rec)->isLeaf) ? 'T' : 'F',
|
|
||||||
(((ginxlogInsert *) rec)->isDelete) ? 'T' : 'F',
|
|
||||||
((ginxlogInsert *) rec)->updateBlkno);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_SPLIT:
|
|
||||||
appendStringInfo(buf, "Page split, ");
|
|
||||||
desc_node(buf, ((ginxlogSplit *) rec)->node, ((ginxlogSplit *) rec)->lblkno);
|
|
||||||
appendStringInfo(buf, " isrootsplit: %c", (((ginxlogSplit *) rec)->isRootSplit) ? 'T' : 'F');
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_VACUUM_PAGE:
|
|
||||||
appendStringInfo(buf, "Vacuum page, ");
|
|
||||||
desc_node(buf, ((ginxlogVacuumPage *) rec)->node, ((ginxlogVacuumPage *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_DELETE_PAGE:
|
|
||||||
appendStringInfo(buf, "Delete page, ");
|
|
||||||
desc_node(buf, ((ginxlogDeletePage *) rec)->node, ((ginxlogDeletePage *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_UPDATE_META_PAGE:
|
|
||||||
appendStringInfo(buf, "Update metapage, ");
|
|
||||||
desc_node(buf, ((ginxlogUpdateMeta *) rec)->node, GIN_METAPAGE_BLKNO);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_INSERT_LISTPAGE:
|
|
||||||
appendStringInfo(buf, "Insert new list page, ");
|
|
||||||
desc_node(buf, ((ginxlogInsertListPage *) rec)->node, ((ginxlogInsertListPage *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_GIN_DELETE_LISTPAGE:
|
|
||||||
appendStringInfo(buf, "Delete list pages (%d), ", ((ginxlogDeleteListPages *) rec)->ndeleted);
|
|
||||||
desc_node(buf, ((ginxlogDeleteListPages *) rec)->node, GIN_METAPAGE_BLKNO);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(PANIC, "gin_desc: unknown op code %u", info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gin_xlog_startup(void)
|
gin_xlog_startup(void)
|
||||||
{
|
{
|
||||||
|
@ -362,55 +362,6 @@ gist_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
MemoryContextReset(opCtx);
|
MemoryContextReset(opCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
out_target(StringInfo buf, RelFileNode node)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u",
|
|
||||||
node.spcNode, node.dbNode, node.relNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec)
|
|
||||||
{
|
|
||||||
out_target(buf, xlrec->node);
|
|
||||||
appendStringInfo(buf, "; block number %u", xlrec->blkno);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "page_split: ");
|
|
||||||
out_target(buf, xlrec->node);
|
|
||||||
appendStringInfo(buf, "; block number %u splits to %d pages",
|
|
||||||
xlrec->origblkno, xlrec->npage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gist_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
switch (info)
|
|
||||||
{
|
|
||||||
case XLOG_GIST_PAGE_UPDATE:
|
|
||||||
appendStringInfo(buf, "page_update: ");
|
|
||||||
out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec);
|
|
||||||
break;
|
|
||||||
case XLOG_GIST_PAGE_SPLIT:
|
|
||||||
out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec);
|
|
||||||
break;
|
|
||||||
case XLOG_GIST_CREATE_INDEX:
|
|
||||||
appendStringInfo(buf, "create_index: rel %u/%u/%u",
|
|
||||||
((RelFileNode *) rec)->spcNode,
|
|
||||||
((RelFileNode *) rec)->dbNode,
|
|
||||||
((RelFileNode *) rec)->relNode);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
appendStringInfo(buf, "unknown gist op code %u", info);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gist_xlog_startup(void)
|
gist_xlog_startup(void)
|
||||||
{
|
{
|
||||||
|
@ -712,8 +712,3 @@ hash_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
{
|
{
|
||||||
elog(PANIC, "hash_redo: unimplemented");
|
elog(PANIC, "hash_redo: unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
hash_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
@ -5678,154 +5678,6 @@ heap2_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
out_target(StringInfo buf, xl_heaptid *target)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
|
|
||||||
target->node.spcNode, target->node.dbNode, target->node.relNode,
|
|
||||||
ItemPointerGetBlockNumber(&(target->tid)),
|
|
||||||
ItemPointerGetOffsetNumber(&(target->tid)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
heap_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
info &= XLOG_HEAP_OPMASK;
|
|
||||||
if (info == XLOG_HEAP_INSERT)
|
|
||||||
{
|
|
||||||
xl_heap_insert *xlrec = (xl_heap_insert *) rec;
|
|
||||||
|
|
||||||
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
|
||||||
appendStringInfo(buf, "insert(init): ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "insert: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_DELETE)
|
|
||||||
{
|
|
||||||
xl_heap_delete *xlrec = (xl_heap_delete *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "delete: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_UPDATE)
|
|
||||||
{
|
|
||||||
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
|
||||||
|
|
||||||
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
|
||||||
appendStringInfo(buf, "update(init): ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "update: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
appendStringInfo(buf, "; new %u/%u",
|
|
||||||
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
|
||||||
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_HOT_UPDATE)
|
|
||||||
{
|
|
||||||
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
|
||||||
|
|
||||||
if (xl_info & XLOG_HEAP_INIT_PAGE) /* can this case happen? */
|
|
||||||
appendStringInfo(buf, "hot_update(init): ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "hot_update: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
appendStringInfo(buf, "; new %u/%u",
|
|
||||||
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
|
||||||
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_NEWPAGE)
|
|
||||||
{
|
|
||||||
xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "newpage: rel %u/%u/%u; fork %u, blk %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->forknum,
|
|
||||||
xlrec->blkno);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_LOCK)
|
|
||||||
{
|
|
||||||
xl_heap_lock *xlrec = (xl_heap_lock *) rec;
|
|
||||||
|
|
||||||
if (xlrec->shared_lock)
|
|
||||||
appendStringInfo(buf, "shared_lock: ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "exclusive_lock: ");
|
|
||||||
if (xlrec->xid_is_mxact)
|
|
||||||
appendStringInfo(buf, "mxid ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "xid ");
|
|
||||||
appendStringInfo(buf, "%u ", xlrec->locking_xid);
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP_INPLACE)
|
|
||||||
{
|
|
||||||
xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "inplace: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
info &= XLOG_HEAP_OPMASK;
|
|
||||||
if (info == XLOG_HEAP2_FREEZE)
|
|
||||||
{
|
|
||||||
xl_heap_freeze *xlrec = (xl_heap_freeze *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "freeze: rel %u/%u/%u; blk %u; cutoff %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->block,
|
|
||||||
xlrec->cutoff_xid);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP2_CLEAN)
|
|
||||||
{
|
|
||||||
xl_heap_clean *xlrec = (xl_heap_clean *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u remxid %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->block,
|
|
||||||
xlrec->latestRemovedXid);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP2_CLEANUP_INFO)
|
|
||||||
{
|
|
||||||
xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "cleanup info: remxid %u",
|
|
||||||
xlrec->latestRemovedXid);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP2_VISIBLE)
|
|
||||||
{
|
|
||||||
xl_heap_visible *xlrec = (xl_heap_visible *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "visible: rel %u/%u/%u; blk %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->block);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_HEAP2_MULTI_INSERT)
|
|
||||||
{
|
|
||||||
xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
|
|
||||||
|
|
||||||
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
|
||||||
appendStringInfo(buf, "multi-insert (init): ");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "multi-insert: ");
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u; blk %u; %d tuples",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
|
|
||||||
xlrec->blkno, xlrec->ntuples);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* heap_sync - sync a heap, for use when no WAL has been written
|
* heap_sync - sync a heap, for use when no WAL has been written
|
||||||
*
|
*
|
||||||
|
@ -1081,151 +1081,6 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
out_target(StringInfo buf, xl_btreetid *target)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
|
|
||||||
target->node.spcNode, target->node.dbNode, target->node.relNode,
|
|
||||||
ItemPointerGetBlockNumber(&(target->tid)),
|
|
||||||
ItemPointerGetOffsetNumber(&(target->tid)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
btree_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
switch (info)
|
|
||||||
{
|
|
||||||
case XLOG_BTREE_INSERT_LEAF:
|
|
||||||
{
|
|
||||||
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "insert: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_INSERT_UPPER:
|
|
||||||
{
|
|
||||||
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "insert_upper: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_INSERT_META:
|
|
||||||
{
|
|
||||||
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "insert_meta: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_SPLIT_L:
|
|
||||||
{
|
|
||||||
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "split_l: rel %u/%u/%u ",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode);
|
|
||||||
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
|
||||||
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
|
||||||
xlrec->level, xlrec->firstright);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_SPLIT_R:
|
|
||||||
{
|
|
||||||
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "split_r: rel %u/%u/%u ",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode);
|
|
||||||
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
|
||||||
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
|
||||||
xlrec->level, xlrec->firstright);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_SPLIT_L_ROOT:
|
|
||||||
{
|
|
||||||
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "split_l_root: rel %u/%u/%u ",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode);
|
|
||||||
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
|
||||||
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
|
||||||
xlrec->level, xlrec->firstright);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_SPLIT_R_ROOT:
|
|
||||||
{
|
|
||||||
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "split_r_root: rel %u/%u/%u ",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode);
|
|
||||||
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
|
||||||
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
|
||||||
xlrec->level, xlrec->firstright);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_VACUUM:
|
|
||||||
{
|
|
||||||
xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "vacuum: rel %u/%u/%u; blk %u, lastBlockVacuumed %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->block,
|
|
||||||
xlrec->lastBlockVacuumed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_DELETE:
|
|
||||||
{
|
|
||||||
xl_btree_delete *xlrec = (xl_btree_delete *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "delete: index %u/%u/%u; iblk %u, heap %u/%u/%u;",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
|
|
||||||
xlrec->block,
|
|
||||||
xlrec->hnode.spcNode, xlrec->hnode.dbNode, xlrec->hnode.relNode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_DELETE_PAGE:
|
|
||||||
case XLOG_BTREE_DELETE_PAGE_META:
|
|
||||||
case XLOG_BTREE_DELETE_PAGE_HALF:
|
|
||||||
{
|
|
||||||
xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "delete_page: ");
|
|
||||||
out_target(buf, &(xlrec->target));
|
|
||||||
appendStringInfo(buf, "; dead %u; left %u; right %u",
|
|
||||||
xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_NEWROOT:
|
|
||||||
{
|
|
||||||
xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode,
|
|
||||||
xlrec->rootblk, xlrec->level);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XLOG_BTREE_REUSE_PAGE:
|
|
||||||
{
|
|
||||||
xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "reuse_page: rel %u/%u/%u; latestRemovedXid %u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode,
|
|
||||||
xlrec->node.relNode, xlrec->latestRemovedXid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
btree_xlog_startup(void)
|
btree_xlog_startup(void)
|
||||||
{
|
{
|
||||||
|
15
src/backend/access/rmgrdesc/Makefile
Normal file
15
src/backend/access/rmgrdesc/Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# Makefile for the rmgr descriptor routines
|
||||||
|
#
|
||||||
|
# src/backend/access/rmgrdesc/Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
subdir = src/backend/access/rmgrdesc
|
||||||
|
top_builddir = ../../../..
|
||||||
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
|
OBJS = clogdesc.o dbasedesc.o gindesc.o gistdesc.o hashdesc.o heapdesc.o \
|
||||||
|
mxactdesc.o nbtdesc.o relmapdesc.o seqdesc.o smgrdesc.o spgdesc.o \
|
||||||
|
standbydesc.o tblspcdesc.o xactdesc.o xlogdesc.o
|
||||||
|
|
||||||
|
include $(top_srcdir)/src/backend/common.mk
|
41
src/backend/access/rmgrdesc/clogdesc.c
Normal file
41
src/backend/access/rmgrdesc/clogdesc.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* clogdesc.c
|
||||||
|
* rmgr descriptor routines for access/transam/clog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/clogdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/clog.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
clog_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == CLOG_ZEROPAGE)
|
||||||
|
{
|
||||||
|
int pageno;
|
||||||
|
|
||||||
|
memcpy(&pageno, rec, sizeof(int));
|
||||||
|
appendStringInfo(buf, "zeropage: %d", pageno);
|
||||||
|
}
|
||||||
|
else if (info == CLOG_TRUNCATE)
|
||||||
|
{
|
||||||
|
int pageno;
|
||||||
|
|
||||||
|
memcpy(&pageno, rec, sizeof(int));
|
||||||
|
appendStringInfo(buf, "truncate before: %d", pageno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
43
src/backend/access/rmgrdesc/dbasedesc.c
Normal file
43
src/backend/access/rmgrdesc/dbasedesc.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* dbasedesc.c
|
||||||
|
* rmgr descriptor routines for commands/dbcommands.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/dbasedesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "commands/dbcommands.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
dbase_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_DBASE_CREATE)
|
||||||
|
{
|
||||||
|
xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "create db: copy dir %u/%u to %u/%u",
|
||||||
|
xlrec->src_db_id, xlrec->src_tablespace_id,
|
||||||
|
xlrec->db_id, xlrec->tablespace_id);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_DBASE_DROP)
|
||||||
|
{
|
||||||
|
xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "drop db: dir %u/%u",
|
||||||
|
xlrec->db_id, xlrec->tablespace_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
83
src/backend/access/rmgrdesc/gindesc.c
Normal file
83
src/backend/access/rmgrdesc/gindesc.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* gindesc.c
|
||||||
|
* rmgr descriptor routines for access/transam/gin/ginxlog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/gindesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/gin_private.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "storage/relfilenode.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
desc_node(StringInfo buf, RelFileNode node, BlockNumber blkno)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "node: %u/%u/%u blkno: %u",
|
||||||
|
node.spcNode, node.dbNode, node.relNode, blkno);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gin_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
switch (info)
|
||||||
|
{
|
||||||
|
case XLOG_GIN_CREATE_INDEX:
|
||||||
|
appendStringInfo(buf, "Create index, ");
|
||||||
|
desc_node(buf, *(RelFileNode *) rec, GIN_ROOT_BLKNO);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_CREATE_PTREE:
|
||||||
|
appendStringInfo(buf, "Create posting tree, ");
|
||||||
|
desc_node(buf, ((ginxlogCreatePostingTree *) rec)->node, ((ginxlogCreatePostingTree *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_INSERT:
|
||||||
|
appendStringInfo(buf, "Insert item, ");
|
||||||
|
desc_node(buf, ((ginxlogInsert *) rec)->node, ((ginxlogInsert *) rec)->blkno);
|
||||||
|
appendStringInfo(buf, " offset: %u nitem: %u isdata: %c isleaf %c isdelete %c updateBlkno:%u",
|
||||||
|
((ginxlogInsert *) rec)->offset,
|
||||||
|
((ginxlogInsert *) rec)->nitem,
|
||||||
|
(((ginxlogInsert *) rec)->isData) ? 'T' : 'F',
|
||||||
|
(((ginxlogInsert *) rec)->isLeaf) ? 'T' : 'F',
|
||||||
|
(((ginxlogInsert *) rec)->isDelete) ? 'T' : 'F',
|
||||||
|
((ginxlogInsert *) rec)->updateBlkno);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_SPLIT:
|
||||||
|
appendStringInfo(buf, "Page split, ");
|
||||||
|
desc_node(buf, ((ginxlogSplit *) rec)->node, ((ginxlogSplit *) rec)->lblkno);
|
||||||
|
appendStringInfo(buf, " isrootsplit: %c", (((ginxlogSplit *) rec)->isRootSplit) ? 'T' : 'F');
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_VACUUM_PAGE:
|
||||||
|
appendStringInfo(buf, "Vacuum page, ");
|
||||||
|
desc_node(buf, ((ginxlogVacuumPage *) rec)->node, ((ginxlogVacuumPage *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_DELETE_PAGE:
|
||||||
|
appendStringInfo(buf, "Delete page, ");
|
||||||
|
desc_node(buf, ((ginxlogDeletePage *) rec)->node, ((ginxlogDeletePage *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_UPDATE_META_PAGE:
|
||||||
|
appendStringInfo(buf, "Update metapage, ");
|
||||||
|
desc_node(buf, ((ginxlogUpdateMeta *) rec)->node, GIN_METAPAGE_BLKNO);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_INSERT_LISTPAGE:
|
||||||
|
appendStringInfo(buf, "Insert new list page, ");
|
||||||
|
desc_node(buf, ((ginxlogInsertListPage *) rec)->node, ((ginxlogInsertListPage *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_GIN_DELETE_LISTPAGE:
|
||||||
|
appendStringInfo(buf, "Delete list pages (%d), ", ((ginxlogDeleteListPages *) rec)->ndeleted);
|
||||||
|
desc_node(buf, ((ginxlogDeleteListPages *) rec)->node, GIN_METAPAGE_BLKNO);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
appendStringInfo(buf, "unknown gin op code %u", info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
68
src/backend/access/rmgrdesc/gistdesc.c
Normal file
68
src/backend/access/rmgrdesc/gistdesc.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* gistdesc.c
|
||||||
|
* rmgr descriptor routines for access/gist/gistxlog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/gistdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/gist_private.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "storage/relfilenode.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
out_target(StringInfo buf, RelFileNode node)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u",
|
||||||
|
node.spcNode, node.dbNode, node.relNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec)
|
||||||
|
{
|
||||||
|
out_target(buf, xlrec->node);
|
||||||
|
appendStringInfo(buf, "; block number %u", xlrec->blkno);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "page_split: ");
|
||||||
|
out_target(buf, xlrec->node);
|
||||||
|
appendStringInfo(buf, "; block number %u splits to %d pages",
|
||||||
|
xlrec->origblkno, xlrec->npage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gist_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
switch (info)
|
||||||
|
{
|
||||||
|
case XLOG_GIST_PAGE_UPDATE:
|
||||||
|
appendStringInfo(buf, "page_update: ");
|
||||||
|
out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec);
|
||||||
|
break;
|
||||||
|
case XLOG_GIST_PAGE_SPLIT:
|
||||||
|
out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec);
|
||||||
|
break;
|
||||||
|
case XLOG_GIST_CREATE_INDEX:
|
||||||
|
appendStringInfo(buf, "create_index: rel %u/%u/%u",
|
||||||
|
((RelFileNode *) rec)->spcNode,
|
||||||
|
((RelFileNode *) rec)->dbNode,
|
||||||
|
((RelFileNode *) rec)->relNode);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
appendStringInfo(buf, "unknown gist op code %u", info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
22
src/backend/access/rmgrdesc/hashdesc.c
Normal file
22
src/backend/access/rmgrdesc/hashdesc.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* hashdesc.c
|
||||||
|
* rmgr descriptor routines for access/hash/hash.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/hashdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/hash.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
hash_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
}
|
165
src/backend/access/rmgrdesc/heapdesc.c
Normal file
165
src/backend/access/rmgrdesc/heapdesc.c
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* heapdesc.c
|
||||||
|
* rmgr descriptor routines for access/heap/heapam.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, 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_target(StringInfo buf, xl_heaptid *target)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
|
||||||
|
target->node.spcNode, target->node.dbNode, target->node.relNode,
|
||||||
|
ItemPointerGetBlockNumber(&(target->tid)),
|
||||||
|
ItemPointerGetOffsetNumber(&(target->tid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
heap_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
info &= XLOG_HEAP_OPMASK;
|
||||||
|
if (info == XLOG_HEAP_INSERT)
|
||||||
|
{
|
||||||
|
xl_heap_insert *xlrec = (xl_heap_insert *) rec;
|
||||||
|
|
||||||
|
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
||||||
|
appendStringInfo(buf, "insert(init): ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "insert: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_DELETE)
|
||||||
|
{
|
||||||
|
xl_heap_delete *xlrec = (xl_heap_delete *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "delete: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_UPDATE)
|
||||||
|
{
|
||||||
|
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
||||||
|
|
||||||
|
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
||||||
|
appendStringInfo(buf, "update(init): ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "update: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
appendStringInfo(buf, "; new %u/%u",
|
||||||
|
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
||||||
|
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_HOT_UPDATE)
|
||||||
|
{
|
||||||
|
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
||||||
|
|
||||||
|
if (xl_info & XLOG_HEAP_INIT_PAGE) /* can this case happen? */
|
||||||
|
appendStringInfo(buf, "hot_update(init): ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "hot_update: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
appendStringInfo(buf, "; new %u/%u",
|
||||||
|
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
||||||
|
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_NEWPAGE)
|
||||||
|
{
|
||||||
|
xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "newpage: rel %u/%u/%u; fork %u, blk %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->forknum,
|
||||||
|
xlrec->blkno);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_LOCK)
|
||||||
|
{
|
||||||
|
xl_heap_lock *xlrec = (xl_heap_lock *) rec;
|
||||||
|
|
||||||
|
if (xlrec->shared_lock)
|
||||||
|
appendStringInfo(buf, "shared_lock: ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "exclusive_lock: ");
|
||||||
|
if (xlrec->xid_is_mxact)
|
||||||
|
appendStringInfo(buf, "mxid ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "xid ");
|
||||||
|
appendStringInfo(buf, "%u ", xlrec->locking_xid);
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP_INPLACE)
|
||||||
|
{
|
||||||
|
xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "inplace: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
info &= XLOG_HEAP_OPMASK;
|
||||||
|
if (info == XLOG_HEAP2_FREEZE)
|
||||||
|
{
|
||||||
|
xl_heap_freeze *xlrec = (xl_heap_freeze *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "freeze: rel %u/%u/%u; blk %u; cutoff %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->block,
|
||||||
|
xlrec->cutoff_xid);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP2_CLEAN)
|
||||||
|
{
|
||||||
|
xl_heap_clean *xlrec = (xl_heap_clean *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u remxid %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->block,
|
||||||
|
xlrec->latestRemovedXid);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP2_CLEANUP_INFO)
|
||||||
|
{
|
||||||
|
xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "cleanup info: remxid %u",
|
||||||
|
xlrec->latestRemovedXid);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP2_VISIBLE)
|
||||||
|
{
|
||||||
|
xl_heap_visible *xlrec = (xl_heap_visible *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "visible: rel %u/%u/%u; blk %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->block);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_HEAP2_MULTI_INSERT)
|
||||||
|
{
|
||||||
|
xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
|
||||||
|
|
||||||
|
if (xl_info & XLOG_HEAP_INIT_PAGE)
|
||||||
|
appendStringInfo(buf, "multi-insert (init): ");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "multi-insert: ");
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u; blk %u; %d tuples",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
|
||||||
|
xlrec->blkno, xlrec->ntuples);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
51
src/backend/access/rmgrdesc/mxactdesc.c
Normal file
51
src/backend/access/rmgrdesc/mxactdesc.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* mxactdesc.c
|
||||||
|
* rmgr descriptor routines for access/transam/multixact.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/mxactdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/multixact.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
multixact_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
|
||||||
|
{
|
||||||
|
int pageno;
|
||||||
|
|
||||||
|
memcpy(&pageno, rec, sizeof(int));
|
||||||
|
appendStringInfo(buf, "zero offsets page: %d", pageno);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
|
||||||
|
{
|
||||||
|
int pageno;
|
||||||
|
|
||||||
|
memcpy(&pageno, rec, sizeof(int));
|
||||||
|
appendStringInfo(buf, "zero members page: %d", pageno);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_MULTIXACT_CREATE_ID)
|
||||||
|
{
|
||||||
|
xl_multixact_create *xlrec = (xl_multixact_create *) rec;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "create multixact %u offset %u:",
|
||||||
|
xlrec->mid, xlrec->moff);
|
||||||
|
for (i = 0; i < xlrec->nxids; i++)
|
||||||
|
appendStringInfo(buf, " %u", xlrec->xids[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
162
src/backend/access/rmgrdesc/nbtdesc.c
Normal file
162
src/backend/access/rmgrdesc/nbtdesc.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* nbtdesc.c
|
||||||
|
* rmgr descriptor routines for access/nbtree/nbtxlog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/nbtdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/nbtree.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
out_target(StringInfo buf, xl_btreetid *target)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
|
||||||
|
target->node.spcNode, target->node.dbNode, target->node.relNode,
|
||||||
|
ItemPointerGetBlockNumber(&(target->tid)),
|
||||||
|
ItemPointerGetOffsetNumber(&(target->tid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
btree_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
switch (info)
|
||||||
|
{
|
||||||
|
case XLOG_BTREE_INSERT_LEAF:
|
||||||
|
{
|
||||||
|
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "insert: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_INSERT_UPPER:
|
||||||
|
{
|
||||||
|
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "insert_upper: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_INSERT_META:
|
||||||
|
{
|
||||||
|
xl_btree_insert *xlrec = (xl_btree_insert *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "insert_meta: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_SPLIT_L:
|
||||||
|
{
|
||||||
|
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "split_l: rel %u/%u/%u ",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode);
|
||||||
|
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
||||||
|
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
||||||
|
xlrec->level, xlrec->firstright);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_SPLIT_R:
|
||||||
|
{
|
||||||
|
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "split_r: rel %u/%u/%u ",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode);
|
||||||
|
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
||||||
|
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
||||||
|
xlrec->level, xlrec->firstright);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_SPLIT_L_ROOT:
|
||||||
|
{
|
||||||
|
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "split_l_root: rel %u/%u/%u ",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode);
|
||||||
|
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
||||||
|
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
||||||
|
xlrec->level, xlrec->firstright);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_SPLIT_R_ROOT:
|
||||||
|
{
|
||||||
|
xl_btree_split *xlrec = (xl_btree_split *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "split_r_root: rel %u/%u/%u ",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode);
|
||||||
|
appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
|
||||||
|
xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
|
||||||
|
xlrec->level, xlrec->firstright);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_VACUUM:
|
||||||
|
{
|
||||||
|
xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "vacuum: rel %u/%u/%u; blk %u, lastBlockVacuumed %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->block,
|
||||||
|
xlrec->lastBlockVacuumed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_DELETE:
|
||||||
|
{
|
||||||
|
xl_btree_delete *xlrec = (xl_btree_delete *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "delete: index %u/%u/%u; iblk %u, heap %u/%u/%u;",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
|
||||||
|
xlrec->block,
|
||||||
|
xlrec->hnode.spcNode, xlrec->hnode.dbNode, xlrec->hnode.relNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_DELETE_PAGE:
|
||||||
|
case XLOG_BTREE_DELETE_PAGE_META:
|
||||||
|
case XLOG_BTREE_DELETE_PAGE_HALF:
|
||||||
|
{
|
||||||
|
xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "delete_page: ");
|
||||||
|
out_target(buf, &(xlrec->target));
|
||||||
|
appendStringInfo(buf, "; dead %u; left %u; right %u",
|
||||||
|
xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_NEWROOT:
|
||||||
|
{
|
||||||
|
xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode,
|
||||||
|
xlrec->rootblk, xlrec->level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XLOG_BTREE_REUSE_PAGE:
|
||||||
|
{
|
||||||
|
xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "reuse_page: rel %u/%u/%u; latestRemovedXid %u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode,
|
||||||
|
xlrec->node.relNode, xlrec->latestRemovedXid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
33
src/backend/access/rmgrdesc/relmapdesc.c
Normal file
33
src/backend/access/rmgrdesc/relmapdesc.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* relmapdesc.c
|
||||||
|
* rmgr descriptor routines for utils/cache/relmapper.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/relmapdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "utils/relmapper.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
relmap_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_RELMAP_UPDATE)
|
||||||
|
{
|
||||||
|
xl_relmap_update *xlrec = (xl_relmap_update *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "update relmap: database %u tablespace %u size %u",
|
||||||
|
xlrec->dbid, xlrec->tsid, xlrec->nbytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
36
src/backend/access/rmgrdesc/seqdesc.c
Normal file
36
src/backend/access/rmgrdesc/seqdesc.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* seqdesc.c
|
||||||
|
* rmgr descriptor routines for commands/sequence.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/seqdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "commands/sequence.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
seq_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
xl_seq_rec *xlrec = (xl_seq_rec *) rec;
|
||||||
|
|
||||||
|
if (info == XLOG_SEQ_LOG)
|
||||||
|
appendStringInfo(buf, "log: ");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u",
|
||||||
|
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
|
||||||
|
}
|
45
src/backend/access/rmgrdesc/smgrdesc.c
Normal file
45
src/backend/access/rmgrdesc/smgrdesc.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* smgrdesc.c
|
||||||
|
* rmgr descriptor routines for catalog/storage.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/smgrdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/storage_xlog.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_SMGR_CREATE)
|
||||||
|
{
|
||||||
|
xl_smgr_create *xlrec = (xl_smgr_create *) rec;
|
||||||
|
char *path = relpathperm(xlrec->rnode, xlrec->forkNum);
|
||||||
|
|
||||||
|
appendStringInfo(buf, "file create: %s", path);
|
||||||
|
pfree(path);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_SMGR_TRUNCATE)
|
||||||
|
{
|
||||||
|
xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
|
||||||
|
char *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
|
||||||
|
|
||||||
|
appendStringInfo(buf, "file truncate: %s to %u blocks", path,
|
||||||
|
xlrec->blkno);
|
||||||
|
pfree(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
89
src/backend/access/rmgrdesc/spgdesc.c
Normal file
89
src/backend/access/rmgrdesc/spgdesc.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* spgdesc.c
|
||||||
|
* rmgr descriptor routines for access/spgist/spgxlog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/spgdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/spgist_private.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
out_target(StringInfo buf, RelFileNode node)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "rel %u/%u/%u ",
|
||||||
|
node.spcNode, node.dbNode, node.relNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spg_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
switch (info)
|
||||||
|
{
|
||||||
|
case XLOG_SPGIST_CREATE_INDEX:
|
||||||
|
appendStringInfo(buf, "create_index: rel %u/%u/%u",
|
||||||
|
((RelFileNode *) rec)->spcNode,
|
||||||
|
((RelFileNode *) rec)->dbNode,
|
||||||
|
((RelFileNode *) rec)->relNode);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_ADD_LEAF:
|
||||||
|
out_target(buf, ((spgxlogAddLeaf *) rec)->node);
|
||||||
|
appendStringInfo(buf, "add leaf to page: %u",
|
||||||
|
((spgxlogAddLeaf *) rec)->blknoLeaf);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_MOVE_LEAFS:
|
||||||
|
out_target(buf, ((spgxlogMoveLeafs *) rec)->node);
|
||||||
|
appendStringInfo(buf, "move %u leafs from page %u to page %u",
|
||||||
|
((spgxlogMoveLeafs *) rec)->nMoves,
|
||||||
|
((spgxlogMoveLeafs *) rec)->blknoSrc,
|
||||||
|
((spgxlogMoveLeafs *) rec)->blknoDst);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_ADD_NODE:
|
||||||
|
out_target(buf, ((spgxlogAddNode *) rec)->node);
|
||||||
|
appendStringInfo(buf, "add node to %u:%u",
|
||||||
|
((spgxlogAddNode *) rec)->blkno,
|
||||||
|
((spgxlogAddNode *) rec)->offnum);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_SPLIT_TUPLE:
|
||||||
|
out_target(buf, ((spgxlogSplitTuple *) rec)->node);
|
||||||
|
appendStringInfo(buf, "split node %u:%u to %u:%u",
|
||||||
|
((spgxlogSplitTuple *) rec)->blknoPrefix,
|
||||||
|
((spgxlogSplitTuple *) rec)->offnumPrefix,
|
||||||
|
((spgxlogSplitTuple *) rec)->blknoPostfix,
|
||||||
|
((spgxlogSplitTuple *) rec)->offnumPostfix);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_PICKSPLIT:
|
||||||
|
out_target(buf, ((spgxlogPickSplit *) rec)->node);
|
||||||
|
appendStringInfo(buf, "split leaf page");
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_VACUUM_LEAF:
|
||||||
|
out_target(buf, ((spgxlogVacuumLeaf *) rec)->node);
|
||||||
|
appendStringInfo(buf, "vacuum leaf tuples on page %u",
|
||||||
|
((spgxlogVacuumLeaf *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_VACUUM_ROOT:
|
||||||
|
out_target(buf, ((spgxlogVacuumRoot *) rec)->node);
|
||||||
|
appendStringInfo(buf, "vacuum leaf tuples on root page %u",
|
||||||
|
((spgxlogVacuumRoot *) rec)->blkno);
|
||||||
|
break;
|
||||||
|
case XLOG_SPGIST_VACUUM_REDIRECT:
|
||||||
|
out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
|
||||||
|
appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
|
||||||
|
((spgxlogVacuumRedirect *) rec)->blkno,
|
||||||
|
((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
appendStringInfo(buf, "unknown spgist op code %u", info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
65
src/backend/access/rmgrdesc/standbydesc.c
Normal file
65
src/backend/access/rmgrdesc/standbydesc.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* standbydesc.c
|
||||||
|
* rmgr descriptor routines for storage/ipc/standby.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/standbydesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "storage/standby.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
standby_desc_running_xacts(StringInfo buf, xl_running_xacts *xlrec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfo(buf, " nextXid %u latestCompletedXid %u oldestRunningXid %u",
|
||||||
|
xlrec->nextXid,
|
||||||
|
xlrec->latestCompletedXid,
|
||||||
|
xlrec->oldestRunningXid);
|
||||||
|
if (xlrec->xcnt > 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "; %d xacts:", xlrec->xcnt);
|
||||||
|
for (i = 0; i < xlrec->xcnt; i++)
|
||||||
|
appendStringInfo(buf, " %u", xlrec->xids[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xlrec->subxid_overflow)
|
||||||
|
appendStringInfo(buf, "; subxid ovf");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
standby_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_STANDBY_LOCK)
|
||||||
|
{
|
||||||
|
xl_standby_locks *xlrec = (xl_standby_locks *) rec;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "AccessExclusive locks:");
|
||||||
|
|
||||||
|
for (i = 0; i < xlrec->nlocks; i++)
|
||||||
|
appendStringInfo(buf, " xid %u db %u rel %u",
|
||||||
|
xlrec->locks[i].xid, xlrec->locks[i].dbOid,
|
||||||
|
xlrec->locks[i].relOid);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_RUNNING_XACTS)
|
||||||
|
{
|
||||||
|
xl_running_xacts *xlrec = (xl_running_xacts *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, " running xacts:");
|
||||||
|
standby_desc_running_xacts(buf, xlrec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
40
src/backend/access/rmgrdesc/tblspcdesc.c
Normal file
40
src/backend/access/rmgrdesc/tblspcdesc.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* tblspcdesc.c
|
||||||
|
* rmgr descriptor routines for commands/tablespace.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/tblspcdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "commands/tablespace.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
tblspc_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_TBLSPC_CREATE)
|
||||||
|
{
|
||||||
|
xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "create tablespace: %u \"%s\"",
|
||||||
|
xlrec->ts_id, xlrec->ts_path);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_TBLSPC_DROP)
|
||||||
|
{
|
||||||
|
xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "drop tablespace: %u", xlrec->ts_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
194
src/backend/access/rmgrdesc/xactdesc.c
Normal file
194
src/backend/access/rmgrdesc/xactdesc.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* xactdesc.c
|
||||||
|
* rmgr descriptor routines for access/transam/xact.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/xactdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/xact.h"
|
||||||
|
#include "catalog/catalog.h"
|
||||||
|
#include "storage/sinval.h"
|
||||||
|
#include "utils/timestamp.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
TransactionId *subxacts;
|
||||||
|
|
||||||
|
subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
|
||||||
|
|
||||||
|
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
||||||
|
|
||||||
|
if (xlrec->nrels > 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "; rels:");
|
||||||
|
for (i = 0; i < xlrec->nrels; i++)
|
||||||
|
{
|
||||||
|
char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
|
||||||
|
|
||||||
|
appendStringInfo(buf, " %s", path);
|
||||||
|
pfree(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xlrec->nsubxacts > 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "; subxacts:");
|
||||||
|
for (i = 0; i < xlrec->nsubxacts; i++)
|
||||||
|
appendStringInfo(buf, " %u", subxacts[i]);
|
||||||
|
}
|
||||||
|
if (xlrec->nmsgs > 0)
|
||||||
|
{
|
||||||
|
SharedInvalidationMessage *msgs;
|
||||||
|
|
||||||
|
msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
|
||||||
|
|
||||||
|
if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
|
||||||
|
appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
|
||||||
|
xlrec->dbId, xlrec->tsId);
|
||||||
|
|
||||||
|
appendStringInfo(buf, "; inval msgs:");
|
||||||
|
for (i = 0; i < xlrec->nmsgs; i++)
|
||||||
|
{
|
||||||
|
SharedInvalidationMessage *msg = &msgs[i];
|
||||||
|
|
||||||
|
if (msg->id >= 0)
|
||||||
|
appendStringInfo(buf, " catcache %d", msg->id);
|
||||||
|
else if (msg->id == SHAREDINVALCATALOG_ID)
|
||||||
|
appendStringInfo(buf, " catalog %u", msg->cat.catId);
|
||||||
|
else if (msg->id == SHAREDINVALRELCACHE_ID)
|
||||||
|
appendStringInfo(buf, " relcache %u", msg->rc.relId);
|
||||||
|
/* remaining cases not expected, but print something anyway */
|
||||||
|
else if (msg->id == SHAREDINVALSMGR_ID)
|
||||||
|
appendStringInfo(buf, " smgr");
|
||||||
|
else if (msg->id == SHAREDINVALRELMAP_ID)
|
||||||
|
appendStringInfo(buf, " relmap");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, " unknown id %d", msg->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
||||||
|
|
||||||
|
if (xlrec->nsubxacts > 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "; subxacts:");
|
||||||
|
for (i = 0; i < xlrec->nsubxacts; i++)
|
||||||
|
appendStringInfo(buf, " %u", xlrec->subxacts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
||||||
|
if (xlrec->nrels > 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "; rels:");
|
||||||
|
for (i = 0; i < xlrec->nrels; i++)
|
||||||
|
{
|
||||||
|
char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
|
||||||
|
|
||||||
|
appendStringInfo(buf, " %s", path);
|
||||||
|
pfree(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xlrec->nsubxacts > 0)
|
||||||
|
{
|
||||||
|
TransactionId *xacts = (TransactionId *)
|
||||||
|
&xlrec->xnodes[xlrec->nrels];
|
||||||
|
|
||||||
|
appendStringInfo(buf, "; subxacts:");
|
||||||
|
for (i = 0; i < xlrec->nsubxacts; i++)
|
||||||
|
appendStringInfo(buf, " %u", xacts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "subxacts:");
|
||||||
|
|
||||||
|
for (i = 0; i < xlrec->nsubxacts; i++)
|
||||||
|
appendStringInfo(buf, " %u", xlrec->xsub[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xact_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_XACT_COMMIT_COMPACT)
|
||||||
|
{
|
||||||
|
xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "commit: ");
|
||||||
|
xact_desc_commit_compact(buf, xlrec);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_COMMIT)
|
||||||
|
{
|
||||||
|
xl_xact_commit *xlrec = (xl_xact_commit *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "commit: ");
|
||||||
|
xact_desc_commit(buf, xlrec);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_ABORT)
|
||||||
|
{
|
||||||
|
xl_xact_abort *xlrec = (xl_xact_abort *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "abort: ");
|
||||||
|
xact_desc_abort(buf, xlrec);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_PREPARE)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "prepare");
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_COMMIT_PREPARED)
|
||||||
|
{
|
||||||
|
xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
|
||||||
|
xact_desc_commit(buf, &xlrec->crec);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_ABORT_PREPARED)
|
||||||
|
{
|
||||||
|
xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
|
||||||
|
xact_desc_abort(buf, &xlrec->arec);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_XACT_ASSIGNMENT)
|
||||||
|
{
|
||||||
|
xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that we ignore the WAL record's xid, since we're more
|
||||||
|
* interested in the top-level xid that issued the record and which
|
||||||
|
* xids are being reported here.
|
||||||
|
*/
|
||||||
|
appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
|
||||||
|
xact_desc_assignment(buf, xlrec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
120
src/backend/access/rmgrdesc/xlogdesc.c
Normal file
120
src/backend/access/rmgrdesc/xlogdesc.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* xlogdesc.c
|
||||||
|
* rmgr descriptor routines for access/transam/xlog.c
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/access/rmgrdesc/xlogdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/xlog_internal.h"
|
||||||
|
#include "catalog/pg_control.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GUC support
|
||||||
|
*/
|
||||||
|
const struct config_enum_entry wal_level_options[] = {
|
||||||
|
{"minimal", WAL_LEVEL_MINIMAL, false},
|
||||||
|
{"archive", WAL_LEVEL_ARCHIVE, false},
|
||||||
|
{"hot_standby", WAL_LEVEL_HOT_STANDBY, false},
|
||||||
|
{NULL, 0, false}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||||
|
{
|
||||||
|
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||||
|
|
||||||
|
if (info == XLOG_CHECKPOINT_SHUTDOWN ||
|
||||||
|
info == XLOG_CHECKPOINT_ONLINE)
|
||||||
|
{
|
||||||
|
CheckPoint *checkpoint = (CheckPoint *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "checkpoint: redo %X/%X; "
|
||||||
|
"tli %u; fpw %s; xid %u/%u; oid %u; multi %u; offset %u; "
|
||||||
|
"oldest xid %u in DB %u; oldest running xid %u; %s",
|
||||||
|
(uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo,
|
||||||
|
checkpoint->ThisTimeLineID,
|
||||||
|
checkpoint->fullPageWrites ? "true" : "false",
|
||||||
|
checkpoint->nextXidEpoch, checkpoint->nextXid,
|
||||||
|
checkpoint->nextOid,
|
||||||
|
checkpoint->nextMulti,
|
||||||
|
checkpoint->nextMultiOffset,
|
||||||
|
checkpoint->oldestXid,
|
||||||
|
checkpoint->oldestXidDB,
|
||||||
|
checkpoint->oldestActiveXid,
|
||||||
|
(info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
|
||||||
|
}
|
||||||
|
else if (info == XLOG_NOOP)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "xlog no-op");
|
||||||
|
}
|
||||||
|
else if (info == XLOG_NEXTOID)
|
||||||
|
{
|
||||||
|
Oid nextOid;
|
||||||
|
|
||||||
|
memcpy(&nextOid, rec, sizeof(Oid));
|
||||||
|
appendStringInfo(buf, "nextOid: %u", nextOid);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_SWITCH)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "xlog switch");
|
||||||
|
}
|
||||||
|
else if (info == XLOG_RESTORE_POINT)
|
||||||
|
{
|
||||||
|
xl_restore_point *xlrec = (xl_restore_point *) rec;
|
||||||
|
|
||||||
|
appendStringInfo(buf, "restore point: %s", xlrec->rp_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (info == XLOG_BACKUP_END)
|
||||||
|
{
|
||||||
|
XLogRecPtr startpoint;
|
||||||
|
|
||||||
|
memcpy(&startpoint, rec, sizeof(XLogRecPtr));
|
||||||
|
appendStringInfo(buf, "backup end: %X/%X",
|
||||||
|
(uint32) (startpoint >> 32), (uint32) startpoint);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_PARAMETER_CHANGE)
|
||||||
|
{
|
||||||
|
xl_parameter_change xlrec;
|
||||||
|
const char *wal_level_str;
|
||||||
|
const struct config_enum_entry *entry;
|
||||||
|
|
||||||
|
memcpy(&xlrec, rec, sizeof(xl_parameter_change));
|
||||||
|
|
||||||
|
/* Find a string representation for wal_level */
|
||||||
|
wal_level_str = "?";
|
||||||
|
for (entry = wal_level_options; entry->name; entry++)
|
||||||
|
{
|
||||||
|
if (entry->val == xlrec.wal_level)
|
||||||
|
{
|
||||||
|
wal_level_str = entry->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s",
|
||||||
|
xlrec.MaxConnections,
|
||||||
|
xlrec.max_prepared_xacts,
|
||||||
|
xlrec.max_locks_per_xact,
|
||||||
|
wal_level_str);
|
||||||
|
}
|
||||||
|
else if (info == XLOG_FPW_CHANGE)
|
||||||
|
{
|
||||||
|
bool fpw;
|
||||||
|
|
||||||
|
memcpy(&fpw, rec, sizeof(bool));
|
||||||
|
appendStringInfo(buf, "full_page_writes: %s", fpw ? "true" : "false");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "UNKNOWN");
|
||||||
|
}
|
@ -18,7 +18,7 @@
|
|||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/spgist_private.h"
|
#include "access/spgist_private.h"
|
||||||
#include "access/transam.h"
|
#include "access/transam.h"
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage_xlog.h"
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
@ -1113,78 +1113,6 @@ spg_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
MemoryContextReset(opCtx);
|
MemoryContextReset(opCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
out_target(StringInfo buf, RelFileNode node)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u ",
|
|
||||||
node.spcNode, node.dbNode, node.relNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
spg_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
switch (info)
|
|
||||||
{
|
|
||||||
case XLOG_SPGIST_CREATE_INDEX:
|
|
||||||
appendStringInfo(buf, "create_index: rel %u/%u/%u",
|
|
||||||
((RelFileNode *) rec)->spcNode,
|
|
||||||
((RelFileNode *) rec)->dbNode,
|
|
||||||
((RelFileNode *) rec)->relNode);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_ADD_LEAF:
|
|
||||||
out_target(buf, ((spgxlogAddLeaf *) rec)->node);
|
|
||||||
appendStringInfo(buf, "add leaf to page: %u",
|
|
||||||
((spgxlogAddLeaf *) rec)->blknoLeaf);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_MOVE_LEAFS:
|
|
||||||
out_target(buf, ((spgxlogMoveLeafs *) rec)->node);
|
|
||||||
appendStringInfo(buf, "move %u leafs from page %u to page %u",
|
|
||||||
((spgxlogMoveLeafs *) rec)->nMoves,
|
|
||||||
((spgxlogMoveLeafs *) rec)->blknoSrc,
|
|
||||||
((spgxlogMoveLeafs *) rec)->blknoDst);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_ADD_NODE:
|
|
||||||
out_target(buf, ((spgxlogAddNode *) rec)->node);
|
|
||||||
appendStringInfo(buf, "add node to %u:%u",
|
|
||||||
((spgxlogAddNode *) rec)->blkno,
|
|
||||||
((spgxlogAddNode *) rec)->offnum);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_SPLIT_TUPLE:
|
|
||||||
out_target(buf, ((spgxlogSplitTuple *) rec)->node);
|
|
||||||
appendStringInfo(buf, "split node %u:%u to %u:%u",
|
|
||||||
((spgxlogSplitTuple *) rec)->blknoPrefix,
|
|
||||||
((spgxlogSplitTuple *) rec)->offnumPrefix,
|
|
||||||
((spgxlogSplitTuple *) rec)->blknoPostfix,
|
|
||||||
((spgxlogSplitTuple *) rec)->offnumPostfix);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_PICKSPLIT:
|
|
||||||
out_target(buf, ((spgxlogPickSplit *) rec)->node);
|
|
||||||
appendStringInfo(buf, "split leaf page");
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_VACUUM_LEAF:
|
|
||||||
out_target(buf, ((spgxlogVacuumLeaf *) rec)->node);
|
|
||||||
appendStringInfo(buf, "vacuum leaf tuples on page %u",
|
|
||||||
((spgxlogVacuumLeaf *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_VACUUM_ROOT:
|
|
||||||
out_target(buf, ((spgxlogVacuumRoot *) rec)->node);
|
|
||||||
appendStringInfo(buf, "vacuum leaf tuples on root page %u",
|
|
||||||
((spgxlogVacuumRoot *) rec)->blkno);
|
|
||||||
break;
|
|
||||||
case XLOG_SPGIST_VACUUM_REDIRECT:
|
|
||||||
out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
|
|
||||||
appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
|
|
||||||
((spgxlogVacuumRedirect *) rec)->blkno,
|
|
||||||
((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
appendStringInfo(buf, "unknown spgist op code %u", info);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
spg_xlog_startup(void)
|
spg_xlog_startup(void)
|
||||||
{
|
{
|
||||||
|
@ -768,26 +768,3 @@ clog_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "clog_redo: unknown op code %u", info);
|
elog(PANIC, "clog_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
clog_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == CLOG_ZEROPAGE)
|
|
||||||
{
|
|
||||||
int pageno;
|
|
||||||
|
|
||||||
memcpy(&pageno, rec, sizeof(int));
|
|
||||||
appendStringInfo(buf, "zeropage: %d", pageno);
|
|
||||||
}
|
|
||||||
else if (info == CLOG_TRUNCATE)
|
|
||||||
{
|
|
||||||
int pageno;
|
|
||||||
|
|
||||||
memcpy(&pageno, rec, sizeof(int));
|
|
||||||
appendStringInfo(buf, "truncate before: %d", pageno);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -2053,36 +2053,3 @@ multixact_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "multixact_redo: unknown op code %u", info);
|
elog(PANIC, "multixact_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
multixact_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
|
|
||||||
{
|
|
||||||
int pageno;
|
|
||||||
|
|
||||||
memcpy(&pageno, rec, sizeof(int));
|
|
||||||
appendStringInfo(buf, "zero offsets page: %d", pageno);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
|
|
||||||
{
|
|
||||||
int pageno;
|
|
||||||
|
|
||||||
memcpy(&pageno, rec, sizeof(int));
|
|
||||||
appendStringInfo(buf, "zero members page: %d", pageno);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_MULTIXACT_CREATE_ID)
|
|
||||||
{
|
|
||||||
xl_multixact_create *xlrec = (xl_multixact_create *) rec;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "create multixact %u offset %u:",
|
|
||||||
xlrec->mid, xlrec->moff);
|
|
||||||
for (i = 0; i < xlrec->nxids; i++)
|
|
||||||
appendStringInfo(buf, " %u", xlrec->xids[i]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "access/spgist.h"
|
#include "access/spgist.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "access/xlog_internal.h"
|
#include "access/xlog_internal.h"
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage_xlog.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "commands/sequence.h"
|
#include "commands/sequence.h"
|
||||||
#include "commands/tablespace.h"
|
#include "commands/tablespace.h"
|
||||||
|
@ -4825,176 +4825,3 @@ xact_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "xact_redo: unknown op code %u", info);
|
elog(PANIC, "xact_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
TransactionId *subxacts;
|
|
||||||
|
|
||||||
subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
|
|
||||||
|
|
||||||
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
|
||||||
|
|
||||||
if (xlrec->nrels > 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "; rels:");
|
|
||||||
for (i = 0; i < xlrec->nrels; i++)
|
|
||||||
{
|
|
||||||
char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
|
|
||||||
|
|
||||||
appendStringInfo(buf, " %s", path);
|
|
||||||
pfree(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xlrec->nsubxacts > 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "; subxacts:");
|
|
||||||
for (i = 0; i < xlrec->nsubxacts; i++)
|
|
||||||
appendStringInfo(buf, " %u", subxacts[i]);
|
|
||||||
}
|
|
||||||
if (xlrec->nmsgs > 0)
|
|
||||||
{
|
|
||||||
SharedInvalidationMessage *msgs;
|
|
||||||
|
|
||||||
msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
|
|
||||||
|
|
||||||
if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
|
|
||||||
appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
|
|
||||||
xlrec->dbId, xlrec->tsId);
|
|
||||||
|
|
||||||
appendStringInfo(buf, "; inval msgs:");
|
|
||||||
for (i = 0; i < xlrec->nmsgs; i++)
|
|
||||||
{
|
|
||||||
SharedInvalidationMessage *msg = &msgs[i];
|
|
||||||
|
|
||||||
if (msg->id >= 0)
|
|
||||||
appendStringInfo(buf, " catcache %d", msg->id);
|
|
||||||
else if (msg->id == SHAREDINVALCATALOG_ID)
|
|
||||||
appendStringInfo(buf, " catalog %u", msg->cat.catId);
|
|
||||||
else if (msg->id == SHAREDINVALRELCACHE_ID)
|
|
||||||
appendStringInfo(buf, " relcache %u", msg->rc.relId);
|
|
||||||
/* remaining cases not expected, but print something anyway */
|
|
||||||
else if (msg->id == SHAREDINVALSMGR_ID)
|
|
||||||
appendStringInfo(buf, " smgr");
|
|
||||||
else if (msg->id == SHAREDINVALRELMAP_ID)
|
|
||||||
appendStringInfo(buf, " relmap");
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, " unknown id %d", msg->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
|
||||||
|
|
||||||
if (xlrec->nsubxacts > 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "; subxacts:");
|
|
||||||
for (i = 0; i < xlrec->nsubxacts; i++)
|
|
||||||
appendStringInfo(buf, " %u", xlrec->subxacts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
|
||||||
if (xlrec->nrels > 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "; rels:");
|
|
||||||
for (i = 0; i < xlrec->nrels; i++)
|
|
||||||
{
|
|
||||||
char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
|
|
||||||
|
|
||||||
appendStringInfo(buf, " %s", path);
|
|
||||||
pfree(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xlrec->nsubxacts > 0)
|
|
||||||
{
|
|
||||||
TransactionId *xacts = (TransactionId *)
|
|
||||||
&xlrec->xnodes[xlrec->nrels];
|
|
||||||
|
|
||||||
appendStringInfo(buf, "; subxacts:");
|
|
||||||
for (i = 0; i < xlrec->nsubxacts; i++)
|
|
||||||
appendStringInfo(buf, " %u", xacts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "subxacts:");
|
|
||||||
|
|
||||||
for (i = 0; i < xlrec->nsubxacts; i++)
|
|
||||||
appendStringInfo(buf, " %u", xlrec->xsub[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xact_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_XACT_COMMIT_COMPACT)
|
|
||||||
{
|
|
||||||
xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "commit: ");
|
|
||||||
xact_desc_commit_compact(buf, xlrec);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_COMMIT)
|
|
||||||
{
|
|
||||||
xl_xact_commit *xlrec = (xl_xact_commit *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "commit: ");
|
|
||||||
xact_desc_commit(buf, xlrec);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_ABORT)
|
|
||||||
{
|
|
||||||
xl_xact_abort *xlrec = (xl_xact_abort *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "abort: ");
|
|
||||||
xact_desc_abort(buf, xlrec);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_PREPARE)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "prepare");
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_COMMIT_PREPARED)
|
|
||||||
{
|
|
||||||
xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
|
|
||||||
xact_desc_commit(buf, &xlrec->crec);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_ABORT_PREPARED)
|
|
||||||
{
|
|
||||||
xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
|
|
||||||
xact_desc_abort(buf, &xlrec->arec);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_XACT_ASSIGNMENT)
|
|
||||||
{
|
|
||||||
xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that we ignore the WAL record's xid, since we're more
|
|
||||||
* interested in the top-level xid that issued the record and which
|
|
||||||
* xids are being reported here.
|
|
||||||
*/
|
|
||||||
appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
|
|
||||||
xact_desc_assignment(buf, xlrec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -99,16 +99,10 @@ bool XLOG_DEBUG = false;
|
|||||||
*/
|
*/
|
||||||
#define XLOGfileslop (2*CheckPointSegments + 1)
|
#define XLOGfileslop (2*CheckPointSegments + 1)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GUC support
|
* GUC support
|
||||||
*/
|
*/
|
||||||
const struct config_enum_entry wal_level_options[] = {
|
|
||||||
{"minimal", WAL_LEVEL_MINIMAL, false},
|
|
||||||
{"archive", WAL_LEVEL_ARCHIVE, false},
|
|
||||||
{"hot_standby", WAL_LEVEL_HOT_STANDBY, false},
|
|
||||||
{NULL, 0, false}
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct config_enum_entry sync_method_options[] = {
|
const struct config_enum_entry sync_method_options[] = {
|
||||||
{"fsync", SYNC_METHOD_FSYNC, false},
|
{"fsync", SYNC_METHOD_FSYNC, false},
|
||||||
#ifdef HAVE_FSYNC_WRITETHROUGH
|
#ifdef HAVE_FSYNC_WRITETHROUGH
|
||||||
@ -588,25 +582,6 @@ static bool InRedo = false;
|
|||||||
/* Have we launched bgwriter during recovery? */
|
/* Have we launched bgwriter during recovery? */
|
||||||
static bool bgwriterLaunched = false;
|
static bool bgwriterLaunched = false;
|
||||||
|
|
||||||
/*
|
|
||||||
* Information logged when we detect a change in one of the parameters
|
|
||||||
* important for Hot Standby.
|
|
||||||
*/
|
|
||||||
typedef struct xl_parameter_change
|
|
||||||
{
|
|
||||||
int MaxConnections;
|
|
||||||
int max_prepared_xacts;
|
|
||||||
int max_locks_per_xact;
|
|
||||||
int wal_level;
|
|
||||||
} xl_parameter_change;
|
|
||||||
|
|
||||||
/* logs restore point */
|
|
||||||
typedef struct xl_restore_point
|
|
||||||
{
|
|
||||||
TimestampTz rp_time;
|
|
||||||
char rp_name[MAXFNAMELEN];
|
|
||||||
} xl_restore_point;
|
|
||||||
|
|
||||||
|
|
||||||
static void readRecoveryCommandFile(void);
|
static void readRecoveryCommandFile(void);
|
||||||
static void exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo);
|
static void exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo);
|
||||||
@ -8031,97 +8006,6 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_CHECKPOINT_SHUTDOWN ||
|
|
||||||
info == XLOG_CHECKPOINT_ONLINE)
|
|
||||||
{
|
|
||||||
CheckPoint *checkpoint = (CheckPoint *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "checkpoint: redo %X/%X; "
|
|
||||||
"tli %u; fpw %s; xid %u/%u; oid %u; multi %u; offset %u; "
|
|
||||||
"oldest xid %u in DB %u; oldest running xid %u; %s",
|
|
||||||
(uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo,
|
|
||||||
checkpoint->ThisTimeLineID,
|
|
||||||
checkpoint->fullPageWrites ? "true" : "false",
|
|
||||||
checkpoint->nextXidEpoch, checkpoint->nextXid,
|
|
||||||
checkpoint->nextOid,
|
|
||||||
checkpoint->nextMulti,
|
|
||||||
checkpoint->nextMultiOffset,
|
|
||||||
checkpoint->oldestXid,
|
|
||||||
checkpoint->oldestXidDB,
|
|
||||||
checkpoint->oldestActiveXid,
|
|
||||||
(info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
|
|
||||||
}
|
|
||||||
else if (info == XLOG_NOOP)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "xlog no-op");
|
|
||||||
}
|
|
||||||
else if (info == XLOG_NEXTOID)
|
|
||||||
{
|
|
||||||
Oid nextOid;
|
|
||||||
|
|
||||||
memcpy(&nextOid, rec, sizeof(Oid));
|
|
||||||
appendStringInfo(buf, "nextOid: %u", nextOid);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_SWITCH)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "xlog switch");
|
|
||||||
}
|
|
||||||
else if (info == XLOG_RESTORE_POINT)
|
|
||||||
{
|
|
||||||
xl_restore_point *xlrec = (xl_restore_point *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "restore point: %s", xlrec->rp_name);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (info == XLOG_BACKUP_END)
|
|
||||||
{
|
|
||||||
XLogRecPtr startpoint;
|
|
||||||
|
|
||||||
memcpy(&startpoint, rec, sizeof(XLogRecPtr));
|
|
||||||
appendStringInfo(buf, "backup end: %X/%X",
|
|
||||||
(uint32) (startpoint >> 32), (uint32) startpoint);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_PARAMETER_CHANGE)
|
|
||||||
{
|
|
||||||
xl_parameter_change xlrec;
|
|
||||||
const char *wal_level_str;
|
|
||||||
const struct config_enum_entry *entry;
|
|
||||||
|
|
||||||
memcpy(&xlrec, rec, sizeof(xl_parameter_change));
|
|
||||||
|
|
||||||
/* Find a string representation for wal_level */
|
|
||||||
wal_level_str = "?";
|
|
||||||
for (entry = wal_level_options; entry->name; entry++)
|
|
||||||
{
|
|
||||||
if (entry->val == xlrec.wal_level)
|
|
||||||
{
|
|
||||||
wal_level_str = entry->name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s",
|
|
||||||
xlrec.MaxConnections,
|
|
||||||
xlrec.max_prepared_xacts,
|
|
||||||
xlrec.max_locks_per_xact,
|
|
||||||
wal_level_str);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_FPW_CHANGE)
|
|
||||||
{
|
|
||||||
bool fpw;
|
|
||||||
|
|
||||||
memcpy(&fpw, rec, sizeof(bool));
|
|
||||||
appendStringInfo(buf, "full_page_writes: %s", fpw ? "true" : "false");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WAL_DEBUG
|
#ifdef WAL_DEBUG
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "catalog/pg_type_fn.h"
|
#include "catalog/pg_type_fn.h"
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage.h"
|
||||||
|
#include "catalog/storage_xlog.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/typecmds.h"
|
#include "commands/typecmds.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "access/xlogutils.h"
|
#include "access/xlogutils.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage.h"
|
||||||
|
#include "catalog/storage_xlog.h"
|
||||||
#include "storage/freespace.h"
|
#include "storage/freespace.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
@ -60,30 +61,6 @@ typedef struct PendingRelDelete
|
|||||||
|
|
||||||
static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
|
static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
|
||||||
|
|
||||||
/*
|
|
||||||
* Declarations for smgr-related XLOG records
|
|
||||||
*
|
|
||||||
* Note: we log file creation and truncation here, but logging of deletion
|
|
||||||
* actions is handled by xact.c, because it is part of transaction commit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XLOG gives us high 4 bits */
|
|
||||||
#define XLOG_SMGR_CREATE 0x10
|
|
||||||
#define XLOG_SMGR_TRUNCATE 0x20
|
|
||||||
|
|
||||||
typedef struct xl_smgr_create
|
|
||||||
{
|
|
||||||
RelFileNode rnode;
|
|
||||||
ForkNumber forkNum;
|
|
||||||
} xl_smgr_create;
|
|
||||||
|
|
||||||
typedef struct xl_smgr_truncate
|
|
||||||
{
|
|
||||||
BlockNumber blkno;
|
|
||||||
RelFileNode rnode;
|
|
||||||
} xl_smgr_truncate;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationCreateStorage
|
* RelationCreateStorage
|
||||||
* Create physical storage for a relation.
|
* Create physical storage for a relation.
|
||||||
@ -523,29 +500,3 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "smgr_redo: unknown op code %u", info);
|
elog(PANIC, "smgr_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_SMGR_CREATE)
|
|
||||||
{
|
|
||||||
xl_smgr_create *xlrec = (xl_smgr_create *) rec;
|
|
||||||
char *path = relpathperm(xlrec->rnode, xlrec->forkNum);
|
|
||||||
|
|
||||||
appendStringInfo(buf, "file create: %s", path);
|
|
||||||
pfree(path);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_SMGR_TRUNCATE)
|
|
||||||
{
|
|
||||||
xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
|
|
||||||
char *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
|
|
||||||
|
|
||||||
appendStringInfo(buf, "file truncate: %s to %u blocks", path,
|
|
||||||
xlrec->blkno);
|
|
||||||
pfree(path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -1992,27 +1992,3 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "dbase_redo: unknown op code %u", info);
|
elog(PANIC, "dbase_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
dbase_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_DBASE_CREATE)
|
|
||||||
{
|
|
||||||
xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "create db: copy dir %u/%u to %u/%u",
|
|
||||||
xlrec->src_db_id, xlrec->src_tablespace_id,
|
|
||||||
xlrec->db_id, xlrec->tablespace_id);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_DBASE_DROP)
|
|
||||||
{
|
|
||||||
xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "drop db: dir %u/%u",
|
|
||||||
xlrec->db_id, xlrec->tablespace_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -1595,21 +1595,3 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
|
|
||||||
pfree(localpage);
|
pfree(localpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
seq_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
xl_seq_rec *xlrec = (xl_seq_rec *) rec;
|
|
||||||
|
|
||||||
if (info == XLOG_SEQ_LOG)
|
|
||||||
appendStringInfo(buf, "log: ");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendStringInfo(buf, "rel %u/%u/%u",
|
|
||||||
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
|
|
||||||
}
|
|
||||||
|
@ -1424,25 +1424,3 @@ tblspc_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "tblspc_redo: unknown op code %u", info);
|
elog(PANIC, "tblspc_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
tblspc_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_TBLSPC_CREATE)
|
|
||||||
{
|
|
||||||
xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "create tablespace: %u \"%s\"",
|
|
||||||
xlrec->ts_id, xlrec->ts_path);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_TBLSPC_DROP)
|
|
||||||
{
|
|
||||||
xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "drop tablespace: %u", xlrec->ts_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -787,54 +787,6 @@ standby_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
elog(PANIC, "standby_redo: unknown op code %u", info);
|
elog(PANIC, "standby_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
standby_desc_running_xacts(StringInfo buf, xl_running_xacts *xlrec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfo(buf, " nextXid %u latestCompletedXid %u oldestRunningXid %u",
|
|
||||||
xlrec->nextXid,
|
|
||||||
xlrec->latestCompletedXid,
|
|
||||||
xlrec->oldestRunningXid);
|
|
||||||
if (xlrec->xcnt > 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(buf, "; %d xacts:", xlrec->xcnt);
|
|
||||||
for (i = 0; i < xlrec->xcnt; i++)
|
|
||||||
appendStringInfo(buf, " %u", xlrec->xids[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xlrec->subxid_overflow)
|
|
||||||
appendStringInfo(buf, "; subxid ovf");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
standby_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_STANDBY_LOCK)
|
|
||||||
{
|
|
||||||
xl_standby_locks *xlrec = (xl_standby_locks *) rec;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "AccessExclusive locks:");
|
|
||||||
|
|
||||||
for (i = 0; i < xlrec->nlocks; i++)
|
|
||||||
appendStringInfo(buf, " xid %u db %u rel %u",
|
|
||||||
xlrec->locks[i].xid, xlrec->locks[i].dbOid,
|
|
||||||
xlrec->locks[i].relOid);
|
|
||||||
}
|
|
||||||
else if (info == XLOG_RUNNING_XACTS)
|
|
||||||
{
|
|
||||||
xl_running_xacts *xlrec = (xl_running_xacts *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, " running xacts:");
|
|
||||||
standby_desc_running_xacts(buf, xlrec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log details of the current snapshot to WAL. This allows the snapshot state
|
* Log details of the current snapshot to WAL. This allows the snapshot state
|
||||||
* to be reconstructed on the standby.
|
* to be reconstructed on the standby.
|
||||||
|
16
src/backend/utils/cache/relmapper.c
vendored
16
src/backend/utils/cache/relmapper.c
vendored
@ -891,19 +891,3 @@ relmap_redo(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
else
|
else
|
||||||
elog(PANIC, "relmap_redo: unknown op code %u", info);
|
elog(PANIC, "relmap_redo: unknown op code %u", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
relmap_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|
||||||
{
|
|
||||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
|
||||||
|
|
||||||
if (info == XLOG_RELMAP_UPDATE)
|
|
||||||
{
|
|
||||||
xl_relmap_update *xlrec = (xl_relmap_update *) rec;
|
|
||||||
|
|
||||||
appendStringInfo(buf, "update relmap: database %u tablespace %u size %u",
|
|
||||||
xlrec->dbid, xlrec->tsid, xlrec->nbytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
appendStringInfo(buf, "UNKNOWN");
|
|
||||||
}
|
|
||||||
|
@ -205,6 +205,25 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
|
|||||||
(uint32) ((logSegNo) / XLogSegmentsPerXLogId), \
|
(uint32) ((logSegNo) / XLogSegmentsPerXLogId), \
|
||||||
(uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset)
|
(uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information logged when we detect a change in one of the parameters
|
||||||
|
* important for Hot Standby.
|
||||||
|
*/
|
||||||
|
typedef struct xl_parameter_change
|
||||||
|
{
|
||||||
|
int MaxConnections;
|
||||||
|
int max_prepared_xacts;
|
||||||
|
int max_locks_per_xact;
|
||||||
|
int wal_level;
|
||||||
|
} xl_parameter_change;
|
||||||
|
|
||||||
|
/* logs restore point */
|
||||||
|
typedef struct xl_restore_point
|
||||||
|
{
|
||||||
|
TimestampTz rp_time;
|
||||||
|
char rp_name[MAXFNAMELEN];
|
||||||
|
} xl_restore_point;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Method table for resource managers.
|
* Method table for resource managers.
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#ifndef STORAGE_H
|
#ifndef STORAGE_H
|
||||||
#define STORAGE_H
|
#define STORAGE_H
|
||||||
|
|
||||||
#include "access/xlog.h"
|
|
||||||
#include "storage/block.h"
|
#include "storage/block.h"
|
||||||
#include "storage/relfilenode.h"
|
#include "storage/relfilenode.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
@ -34,9 +33,4 @@ extern void AtSubCommit_smgr(void);
|
|||||||
extern void AtSubAbort_smgr(void);
|
extern void AtSubAbort_smgr(void);
|
||||||
extern void PostPrepare_smgr(void);
|
extern void PostPrepare_smgr(void);
|
||||||
|
|
||||||
extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum);
|
|
||||||
|
|
||||||
extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record);
|
|
||||||
extern void smgr_desc(StringInfo buf, uint8 xl_info, char *rec);
|
|
||||||
|
|
||||||
#endif /* STORAGE_H */
|
#endif /* STORAGE_H */
|
||||||
|
49
src/include/catalog/storage_xlog.h
Normal file
49
src/include/catalog/storage_xlog.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* storage_xlog.h
|
||||||
|
* prototypes for XLog support for backend/catalog/storage.c
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* src/include/catalog/storage_xlog.h
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef STORAGE_XLOG_H
|
||||||
|
#define STORAGE_XLOG_H
|
||||||
|
|
||||||
|
#include "access/xlog.h"
|
||||||
|
#include "storage/block.h"
|
||||||
|
#include "storage/relfilenode.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declarations for smgr-related XLOG records
|
||||||
|
*
|
||||||
|
* Note: we log file creation and truncation here, but logging of deletion
|
||||||
|
* actions is handled by xact.c, because it is part of transaction commit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XLOG gives us high 4 bits */
|
||||||
|
#define XLOG_SMGR_CREATE 0x10
|
||||||
|
#define XLOG_SMGR_TRUNCATE 0x20
|
||||||
|
|
||||||
|
typedef struct xl_smgr_create
|
||||||
|
{
|
||||||
|
RelFileNode rnode;
|
||||||
|
ForkNumber forkNum;
|
||||||
|
} xl_smgr_create;
|
||||||
|
|
||||||
|
typedef struct xl_smgr_truncate
|
||||||
|
{
|
||||||
|
BlockNumber blkno;
|
||||||
|
RelFileNode rnode;
|
||||||
|
} xl_smgr_truncate;
|
||||||
|
|
||||||
|
extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum);
|
||||||
|
|
||||||
|
extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record);
|
||||||
|
extern void smgr_desc(StringInfo buf, uint8 xl_info, char *rec);
|
||||||
|
|
||||||
|
#endif /* STORAGE_XLOG_H */
|
Loading…
x
Reference in New Issue
Block a user