Header And Logo

PostgreSQL
| The world's most advanced open source database.

heapdesc.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * heapdesc.c
00004  *    rmgr descriptor routines for access/heap/heapam.c
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/access/rmgrdesc/heapdesc.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include "access/heapam_xlog.h"
00018 
00019 static void
00020 out_target(StringInfo buf, xl_heaptid *target)
00021 {
00022     appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
00023              target->node.spcNode, target->node.dbNode, target->node.relNode,
00024                      ItemPointerGetBlockNumber(&(target->tid)),
00025                      ItemPointerGetOffsetNumber(&(target->tid)));
00026 }
00027 
00028 static void
00029 out_infobits(StringInfo buf, uint8 infobits)
00030 {
00031     if (infobits & XLHL_XMAX_IS_MULTI)
00032         appendStringInfo(buf, "IS_MULTI ");
00033     if (infobits & XLHL_XMAX_LOCK_ONLY)
00034         appendStringInfo(buf, "LOCK_ONLY ");
00035     if (infobits & XLHL_XMAX_EXCL_LOCK)
00036         appendStringInfo(buf, "EXCL_LOCK ");
00037     if (infobits & XLHL_XMAX_KEYSHR_LOCK)
00038         appendStringInfo(buf, "KEYSHR_LOCK ");
00039     if (infobits & XLHL_KEYS_UPDATED)
00040         appendStringInfo(buf, "KEYS_UPDATED ");
00041 }
00042 
00043 void
00044 heap_desc(StringInfo buf, uint8 xl_info, char *rec)
00045 {
00046     uint8       info = xl_info & ~XLR_INFO_MASK;
00047 
00048     info &= XLOG_HEAP_OPMASK;
00049     if (info == XLOG_HEAP_INSERT)
00050     {
00051         xl_heap_insert *xlrec = (xl_heap_insert *) rec;
00052 
00053         if (xl_info & XLOG_HEAP_INIT_PAGE)
00054             appendStringInfo(buf, "insert(init): ");
00055         else
00056             appendStringInfo(buf, "insert: ");
00057         out_target(buf, &(xlrec->target));
00058     }
00059     else if (info == XLOG_HEAP_DELETE)
00060     {
00061         xl_heap_delete *xlrec = (xl_heap_delete *) rec;
00062 
00063         appendStringInfo(buf, "delete: ");
00064         out_target(buf, &(xlrec->target));
00065         appendStringInfoChar(buf, ' ');
00066         out_infobits(buf, xlrec->infobits_set);
00067     }
00068     else if (info == XLOG_HEAP_UPDATE)
00069     {
00070         xl_heap_update *xlrec = (xl_heap_update *) rec;
00071 
00072         if (xl_info & XLOG_HEAP_INIT_PAGE)
00073             appendStringInfo(buf, "update(init): ");
00074         else
00075             appendStringInfo(buf, "update: ");
00076         out_target(buf, &(xlrec->target));
00077         appendStringInfo(buf, " xmax %u ", xlrec->old_xmax);
00078         out_infobits(buf, xlrec->old_infobits_set);
00079         appendStringInfo(buf, "; new tid %u/%u xmax %u",
00080                          ItemPointerGetBlockNumber(&(xlrec->newtid)),
00081                          ItemPointerGetOffsetNumber(&(xlrec->newtid)),
00082                          xlrec->new_xmax);
00083     }
00084     else if (info == XLOG_HEAP_HOT_UPDATE)
00085     {
00086         xl_heap_update *xlrec = (xl_heap_update *) rec;
00087 
00088         if (xl_info & XLOG_HEAP_INIT_PAGE)      /* can this case happen? */
00089             appendStringInfo(buf, "hot_update(init): ");
00090         else
00091             appendStringInfo(buf, "hot_update: ");
00092         out_target(buf, &(xlrec->target));
00093         appendStringInfo(buf, " xmax %u ", xlrec->old_xmax);
00094         out_infobits(buf, xlrec->old_infobits_set);
00095         appendStringInfo(buf, "; new tid %u/%u xmax %u",
00096                          ItemPointerGetBlockNumber(&(xlrec->newtid)),
00097                          ItemPointerGetOffsetNumber(&(xlrec->newtid)),
00098                          xlrec->new_xmax);
00099     }
00100     else if (info == XLOG_HEAP_NEWPAGE)
00101     {
00102         xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
00103 
00104         appendStringInfo(buf, "newpage: rel %u/%u/%u; fork %u, blk %u",
00105                          xlrec->node.spcNode, xlrec->node.dbNode,
00106                          xlrec->node.relNode, xlrec->forknum,
00107                          xlrec->blkno);
00108     }
00109     else if (info == XLOG_HEAP_LOCK)
00110     {
00111         xl_heap_lock *xlrec = (xl_heap_lock *) rec;
00112 
00113         appendStringInfo(buf, "lock %u: ", xlrec->locking_xid);
00114         out_target(buf, &(xlrec->target));
00115         appendStringInfoChar(buf, ' ');
00116         out_infobits(buf, xlrec->infobits_set);
00117     }
00118     else if (info == XLOG_HEAP_INPLACE)
00119     {
00120         xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
00121 
00122         appendStringInfo(buf, "inplace: ");
00123         out_target(buf, &(xlrec->target));
00124     }
00125     else
00126         appendStringInfo(buf, "UNKNOWN");
00127 }
00128 void
00129 heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
00130 {
00131     uint8       info = xl_info & ~XLR_INFO_MASK;
00132 
00133     info &= XLOG_HEAP_OPMASK;
00134     if (info == XLOG_HEAP2_FREEZE)
00135     {
00136         xl_heap_freeze *xlrec = (xl_heap_freeze *) rec;
00137 
00138         appendStringInfo(buf, "freeze: rel %u/%u/%u; blk %u; cutoff xid %u multi %u",
00139                          xlrec->node.spcNode, xlrec->node.dbNode,
00140                          xlrec->node.relNode, xlrec->block,
00141                          xlrec->cutoff_xid, xlrec->cutoff_multi);
00142     }
00143     else if (info == XLOG_HEAP2_CLEAN)
00144     {
00145         xl_heap_clean *xlrec = (xl_heap_clean *) rec;
00146 
00147         appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u remxid %u",
00148                          xlrec->node.spcNode, xlrec->node.dbNode,
00149                          xlrec->node.relNode, xlrec->block,
00150                          xlrec->latestRemovedXid);
00151     }
00152     else if (info == XLOG_HEAP2_CLEANUP_INFO)
00153     {
00154         xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
00155 
00156         appendStringInfo(buf, "cleanup info: remxid %u",
00157                          xlrec->latestRemovedXid);
00158     }
00159     else if (info == XLOG_HEAP2_VISIBLE)
00160     {
00161         xl_heap_visible *xlrec = (xl_heap_visible *) rec;
00162 
00163         appendStringInfo(buf, "visible: rel %u/%u/%u; blk %u",
00164                          xlrec->node.spcNode, xlrec->node.dbNode,
00165                          xlrec->node.relNode, xlrec->block);
00166     }
00167     else if (info == XLOG_HEAP2_MULTI_INSERT)
00168     {
00169         xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
00170 
00171         if (xl_info & XLOG_HEAP_INIT_PAGE)
00172             appendStringInfo(buf, "multi-insert (init): ");
00173         else
00174             appendStringInfo(buf, "multi-insert: ");
00175         appendStringInfo(buf, "rel %u/%u/%u; blk %u; %d tuples",
00176                 xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
00177                          xlrec->blkno, xlrec->ntuples);
00178     }
00179     else if (info == XLOG_HEAP2_LOCK_UPDATED)
00180     {
00181         xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
00182 
00183         appendStringInfo(buf, "lock updated: xmax %u msk %04x; ", xlrec->xmax,
00184                          xlrec->infobits_set);
00185         out_target(buf, &(xlrec->target));
00186     }
00187     else
00188         appendStringInfo(buf, "UNKNOWN");
00189 }