提交 b74f174b 编写于 作者: I Ivan Leskin 提交者: Ashwin Agrawal

Implement TwoPhaseFileHeader details output in pg_xlogdump

Output the following in pg_xlogdump for prepare transaction records:
* Global transaction ID
* Prepare time
* Tablespace OIDs:
	* 'tablespace_oid_to_delete_on_abort'
	* 'tablespace_oid_to_delete_on_commit'

These data come from TwoPhaseFileHeader structure which is written in
xlog in GPDB.

Move TwoPhaseFileHeader to `twophase.h` in order for that structure to
be used by `xact_desc_prepare()` in `xactdesc.c`
Co-Authored-By: NDavid Kimura <dkimura@pivotal.io>
上级 02f573b8
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "storage/dbdirnode.h" #include "storage/dbdirnode.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "utils/timestamp.h" #include "utils/timestamp.h"
#include "access/twophase.h"
static char* static char*
...@@ -205,6 +206,25 @@ xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec) ...@@ -205,6 +206,25 @@ xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
appendStringInfo(buf, " %u", xlrec->xsub[i]); appendStringInfo(buf, " %u", xlrec->xsub[i]);
} }
static void
xact_desc_prepare(StringInfo buf, XLogRecord *record) {
uint8 info = record->xl_info & ~XLR_INFO_MASK;
char *rec = XLogRecGetData(record);
Assert(info == XLOG_XACT_PREPARE);
TwoPhaseFileHeader *tpfh = (TwoPhaseFileHeader*) rec;
appendStringInfo(buf, "at = %s", timestamptz_to_str(tpfh->prepared_at));
appendStringInfo(buf, "; gid = %s", tpfh->gid);
if (tpfh->tablespace_oid_to_delete_on_commit != InvalidOid)
appendStringInfo(buf, "; tablespace_oid_to_delete_on_commit = %u", tpfh->tablespace_oid_to_delete_on_commit);
if (tpfh->tablespace_oid_to_delete_on_abort != InvalidOid)
appendStringInfo(buf, "; tablespace_oid_to_delete_on_abort = %u", tpfh->tablespace_oid_to_delete_on_abort);
}
void void
xact_desc(StringInfo buf, XLogRecord *record) xact_desc(StringInfo buf, XLogRecord *record)
{ {
...@@ -234,7 +254,8 @@ xact_desc(StringInfo buf, XLogRecord *record) ...@@ -234,7 +254,8 @@ xact_desc(StringInfo buf, XLogRecord *record)
} }
else if (info == XLOG_XACT_PREPARE) else if (info == XLOG_XACT_PREPARE)
{ {
appendStringInfoString(buf, "prepare"); appendStringInfoString(buf, "prepare: ");
xact_desc_prepare(buf, record);
} }
else if (info == XLOG_XACT_COMMIT_PREPARED) else if (info == XLOG_XACT_COMMIT_PREPARED)
{ {
......
...@@ -113,7 +113,6 @@ int max_prepared_xacts = 0; ...@@ -113,7 +113,6 @@ int max_prepared_xacts = 0;
* typedef struct GlobalTransactionData *GlobalTransaction appears in * typedef struct GlobalTransactionData *GlobalTransaction appears in
* twophase.h * twophase.h
*/ */
#define GIDSIZE 200
typedef struct GlobalTransactionData typedef struct GlobalTransactionData
{ {
...@@ -962,26 +961,6 @@ TwoPhaseGetDummyProc(TransactionId xid) ...@@ -962,26 +961,6 @@ TwoPhaseGetDummyProc(TransactionId xid)
*/ */
#define TWOPHASE_MAGIC 0x57F94532 /* format identifier */ #define TWOPHASE_MAGIC 0x57F94532 /* format identifier */
typedef struct TwoPhaseFileHeader
{
uint32 magic; /* format identifier */
uint32 total_len; /* actual file length */
TransactionId xid; /* original transaction XID */
Oid database; /* OID of database it was in */
TimestampTz prepared_at; /* time of preparation */
Oid owner; /* user running the transaction */
int32 nsubxacts; /* number of following subxact XIDs */
int32 ncommitrels; /* number of delete-on-commit rels */
int32 nabortrels; /* number of delete-on-abort rels */
int32 ncommitdbs; /* number of delete-on-commit dbs */
int32 nabortdbs; /* number of delete-on-abort dbs */
int32 ninvalmsgs; /* number of cache invalidation messages */
bool initfileinval; /* does relcache init file need invalidation? */
Oid tablespace_oid_to_delete_on_abort;
Oid tablespace_oid_to_delete_on_commit;
char gid[GIDSIZE]; /* GID for transaction */
} TwoPhaseFileHeader;
/* /*
* Header for each record in a state file * Header for each record in a state file
* *
......
...@@ -54,6 +54,36 @@ typedef struct prepared_transaction_agg_state ...@@ -54,6 +54,36 @@ typedef struct prepared_transaction_agg_state
*/ */
typedef struct GlobalTransactionData *GlobalTransaction; typedef struct GlobalTransactionData *GlobalTransaction;
/* GPDB-specific: GIDSIZE is defined in twophase.c in Postgres */
#define GIDSIZE 200
/* GPDB-specific: TwoPhaseFileHeader is defined in twophase.c in Postgres */
/*
* Header for a 2PC state file
*/
typedef struct TwoPhaseFileHeader
{
uint32 magic; /* format identifier */
uint32 total_len; /* actual file length */
TransactionId xid; /* original transaction XID */
Oid database; /* OID of database it was in */
TimestampTz prepared_at; /* time of preparation */
Oid owner; /* user running the transaction */
int32 nsubxacts; /* number of following subxact XIDs */
int32 ncommitrels; /* number of delete-on-commit rels */
int32 nabortrels; /* number of delete-on-abort rels */
int32 ncommitdbs; /* number of delete-on-commit dbs */
int32 nabortdbs; /* number of delete-on-abort dbs */
int32 ninvalmsgs; /* number of cache invalidation messages */
bool initfileinval; /* does relcache init file need invalidation? */
Oid tablespace_oid_to_delete_on_abort;
Oid tablespace_oid_to_delete_on_commit;
char gid[GIDSIZE]; /* GID for transaction */
} TwoPhaseFileHeader;
/* GPDB-specific end */
/* GUC variable */ /* GUC variable */
extern PGDLLIMPORT int max_prepared_xacts; extern PGDLLIMPORT int max_prepared_xacts;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册