1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * mxactdesc.c |
4 | * rmgr descriptor routines for access/transam/multixact.c |
5 | * |
6 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
7 | * Portions Copyright (c) 1994, Regents of the University of California |
8 | * |
9 | * |
10 | * IDENTIFICATION |
11 | * src/backend/access/rmgrdesc/mxactdesc.c |
12 | * |
13 | *------------------------------------------------------------------------- |
14 | */ |
15 | #include "postgres.h" |
16 | |
17 | #include "access/multixact.h" |
18 | |
19 | static void |
20 | out_member(StringInfo buf, MultiXactMember *member) |
21 | { |
22 | appendStringInfo(buf, "%u " , member->xid); |
23 | switch (member->status) |
24 | { |
25 | case MultiXactStatusForKeyShare: |
26 | appendStringInfoString(buf, "(keysh) " ); |
27 | break; |
28 | case MultiXactStatusForShare: |
29 | appendStringInfoString(buf, "(sh) " ); |
30 | break; |
31 | case MultiXactStatusForNoKeyUpdate: |
32 | appendStringInfoString(buf, "(fornokeyupd) " ); |
33 | break; |
34 | case MultiXactStatusForUpdate: |
35 | appendStringInfoString(buf, "(forupd) " ); |
36 | break; |
37 | case MultiXactStatusNoKeyUpdate: |
38 | appendStringInfoString(buf, "(nokeyupd) " ); |
39 | break; |
40 | case MultiXactStatusUpdate: |
41 | appendStringInfoString(buf, "(upd) " ); |
42 | break; |
43 | default: |
44 | appendStringInfoString(buf, "(unk) " ); |
45 | break; |
46 | } |
47 | } |
48 | |
49 | void |
50 | multixact_desc(StringInfo buf, XLogReaderState *record) |
51 | { |
52 | char *rec = XLogRecGetData(record); |
53 | uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; |
54 | |
55 | if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE || |
56 | info == XLOG_MULTIXACT_ZERO_MEM_PAGE) |
57 | { |
58 | int pageno; |
59 | |
60 | memcpy(&pageno, rec, sizeof(int)); |
61 | appendStringInfo(buf, "%d" , pageno); |
62 | } |
63 | else if (info == XLOG_MULTIXACT_CREATE_ID) |
64 | { |
65 | xl_multixact_create *xlrec = (xl_multixact_create *) rec; |
66 | int i; |
67 | |
68 | appendStringInfo(buf, "%u offset %u nmembers %d: " , xlrec->mid, |
69 | xlrec->moff, xlrec->nmembers); |
70 | for (i = 0; i < xlrec->nmembers; i++) |
71 | out_member(buf, &xlrec->members[i]); |
72 | } |
73 | else if (info == XLOG_MULTIXACT_TRUNCATE_ID) |
74 | { |
75 | xl_multixact_truncate *xlrec = (xl_multixact_truncate *) rec; |
76 | |
77 | appendStringInfo(buf, "offsets [%u, %u), members [%u, %u)" , |
78 | xlrec->startTruncOff, xlrec->endTruncOff, |
79 | xlrec->startTruncMemb, xlrec->endTruncMemb); |
80 | } |
81 | } |
82 | |
83 | const char * |
84 | multixact_identify(uint8 info) |
85 | { |
86 | const char *id = NULL; |
87 | |
88 | switch (info & ~XLR_INFO_MASK) |
89 | { |
90 | case XLOG_MULTIXACT_ZERO_OFF_PAGE: |
91 | id = "ZERO_OFF_PAGE" ; |
92 | break; |
93 | case XLOG_MULTIXACT_ZERO_MEM_PAGE: |
94 | id = "ZERO_MEM_PAGE" ; |
95 | break; |
96 | case XLOG_MULTIXACT_CREATE_ID: |
97 | id = "CREATE_ID" ; |
98 | break; |
99 | case XLOG_MULTIXACT_TRUNCATE_ID: |
100 | id = "TRUNCATE_ID" ; |
101 | break; |
102 | } |
103 | |
104 | return id; |
105 | } |
106 | |