Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7b8a899

Browse files
committed
Make pg_waldump report more detail information about PREPARE TRANSACTION record.
This commit changes xact_desc() so that it reports the detail information aboutPREPARE TRANSACTION record, like GID (global transaction identifier),timestamp at prepare transaction, delete-on-abort/commit relations,XID of subtransactions, and invalidation messages. These are helpfulwhen diagnosing 2PC-related troubles.Author: Fujii MasaoReviewed-by: Michael Paquier, Andrey Lepikhov, Kyotaro Horiguchi, Julien Rouhaud, Alvaro HerreraDiscussion:https://postgr.es/m/CAHGQGwEvhASad4JJnCv=0dW2TJypZgW_Vpb-oZik2a3utCqcrA@mail.gmail.com
1 parent94fec48 commit7b8a899

File tree

5 files changed

+125
-96
lines changed

5 files changed

+125
-96
lines changed

‎src/backend/access/rmgrdesc/standbydesc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ standby_desc_invalidations(StringInfo buf,
102102
{
103103
inti;
104104

105+
/* Do nothing if there are no invalidation messages */
106+
if (nmsgs <=0)
107+
return;
108+
105109
if (relcacheInitFileInval)
106110
appendStringInfo(buf,"; relcache init file inval dbid %u tsid %u",
107111
dbId,tsId);

‎src/backend/access/rmgrdesc/xactdesc.c

Lines changed: 101 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -209,43 +209,95 @@ ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
209209
}
210210
}
211211

212-
staticvoid
213-
xact_desc_commit(StringInfobuf,uint8info,xl_xact_commit*xlrec,RepOriginIdorigin_id)
212+
/*
213+
* ParsePrepareRecord
214+
*/
215+
void
216+
ParsePrepareRecord(uint8info,xl_xact_prepare*xlrec,xl_xact_parsed_prepare*parsed)
214217
{
215-
xl_xact_parsed_commitparsed;
216-
inti;
218+
char*bufptr;
217219

218-
ParseCommitRecord(info,xlrec,&parsed);
220+
bufptr= ((char*)xlrec)+MAXALIGN(sizeof(xl_xact_prepare));
219221

220-
/* If this is a prepared xact, show the xid of the original xact */
221-
if (TransactionIdIsValid(parsed.twophase_xid))
222-
appendStringInfo(buf,"%u: ",parsed.twophase_xid);
222+
memset(parsed,0,sizeof(*parsed));
223223

224-
appendStringInfoString(buf,timestamptz_to_str(xlrec->xact_time));
224+
parsed->xact_time=xlrec->prepared_at;
225+
parsed->origin_lsn=xlrec->origin_lsn;
226+
parsed->origin_timestamp=xlrec->origin_timestamp;
227+
parsed->twophase_xid=xlrec->xid;
228+
parsed->dbId=xlrec->database;
229+
parsed->nsubxacts=xlrec->nsubxacts;
230+
parsed->nrels=xlrec->ncommitrels;
231+
parsed->nabortrels=xlrec->nabortrels;
232+
parsed->nmsgs=xlrec->ninvalmsgs;
233+
234+
strncpy(parsed->twophase_gid,bufptr,xlrec->gidlen);
235+
bufptr+=MAXALIGN(xlrec->gidlen);
236+
237+
parsed->subxacts= (TransactionId*)bufptr;
238+
bufptr+=MAXALIGN(xlrec->nsubxacts*sizeof(TransactionId));
239+
240+
parsed->xnodes= (RelFileNode*)bufptr;
241+
bufptr+=MAXALIGN(xlrec->ncommitrels*sizeof(RelFileNode));
242+
243+
parsed->abortnodes= (RelFileNode*)bufptr;
244+
bufptr+=MAXALIGN(xlrec->nabortrels*sizeof(RelFileNode));
225245

226-
if (parsed.nrels>0)
246+
parsed->msgs= (SharedInvalidationMessage*)bufptr;
247+
bufptr+=MAXALIGN(xlrec->ninvalmsgs*sizeof(SharedInvalidationMessage));
248+
}
249+
250+
staticvoid
251+
xact_desc_relations(StringInfobuf,char*label,intnrels,
252+
RelFileNode*xnodes)
253+
{
254+
inti;
255+
256+
if (nrels>0)
227257
{
228-
appendStringInfoString(buf,";rels:");
229-
for (i=0;i<parsed.nrels;i++)
258+
appendStringInfo(buf,";%s:",label);
259+
for (i=0;i<nrels;i++)
230260
{
231-
char*path=relpathperm(parsed.xnodes[i],MAIN_FORKNUM);
261+
char*path=relpathperm(xnodes[i],MAIN_FORKNUM);
232262

233263
appendStringInfo(buf," %s",path);
234264
pfree(path);
235265
}
236266
}
237-
if (parsed.nsubxacts>0)
267+
}
268+
269+
staticvoid
270+
xact_desc_subxacts(StringInfobuf,intnsubxacts,TransactionId*subxacts)
271+
{
272+
inti;
273+
274+
if (nsubxacts>0)
238275
{
239276
appendStringInfoString(buf,"; subxacts:");
240-
for (i=0;i<parsed.nsubxacts;i++)
241-
appendStringInfo(buf," %u",parsed.subxacts[i]);
242-
}
243-
if (parsed.nmsgs>0)
244-
{
245-
standby_desc_invalidations(
246-
buf,parsed.nmsgs,parsed.msgs,parsed.dbId,parsed.tsId,
247-
XactCompletionRelcacheInitFileInval(parsed.xinfo));
277+
for (i=0;i<nsubxacts;i++)
278+
appendStringInfo(buf," %u",subxacts[i]);
248279
}
280+
}
281+
282+
staticvoid
283+
xact_desc_commit(StringInfobuf,uint8info,xl_xact_commit*xlrec,RepOriginIdorigin_id)
284+
{
285+
xl_xact_parsed_commitparsed;
286+
287+
ParseCommitRecord(info,xlrec,&parsed);
288+
289+
/* If this is a prepared xact, show the xid of the original xact */
290+
if (TransactionIdIsValid(parsed.twophase_xid))
291+
appendStringInfo(buf,"%u: ",parsed.twophase_xid);
292+
293+
appendStringInfoString(buf,timestamptz_to_str(xlrec->xact_time));
294+
295+
xact_desc_relations(buf,"rels",parsed.nrels,parsed.xnodes);
296+
xact_desc_subxacts(buf,parsed.nsubxacts,parsed.subxacts);
297+
298+
standby_desc_invalidations(
299+
buf,parsed.nmsgs,parsed.msgs,parsed.dbId,parsed.tsId,
300+
XactCompletionRelcacheInitFileInval(parsed.xinfo));
249301

250302
if (XactCompletionForceSyncCommit(parsed.xinfo))
251303
appendStringInfoString(buf,"; sync");
@@ -264,7 +316,6 @@ static void
264316
xact_desc_abort(StringInfobuf,uint8info,xl_xact_abort*xlrec)
265317
{
266318
xl_xact_parsed_abortparsed;
267-
inti;
268319

269320
ParseAbortRecord(info,xlrec,&parsed);
270321

@@ -273,24 +324,29 @@ xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec)
273324
appendStringInfo(buf,"%u: ",parsed.twophase_xid);
274325

275326
appendStringInfoString(buf,timestamptz_to_str(xlrec->xact_time));
276-
if (parsed.nrels>0)
277-
{
278-
appendStringInfoString(buf,"; rels:");
279-
for (i=0;i<parsed.nrels;i++)
280-
{
281-
char*path=relpathperm(parsed.xnodes[i],MAIN_FORKNUM);
282327

283-
appendStringInfo(buf," %s",path);
284-
pfree(path);
285-
}
286-
}
328+
xact_desc_relations(buf,"rels",parsed.nrels,parsed.xnodes);
329+
xact_desc_subxacts(buf,parsed.nsubxacts,parsed.subxacts);
330+
}
287331

288-
if (parsed.nsubxacts>0)
289-
{
290-
appendStringInfoString(buf,"; subxacts:");
291-
for (i=0;i<parsed.nsubxacts;i++)
292-
appendStringInfo(buf," %u",parsed.subxacts[i]);
293-
}
332+
staticvoid
333+
xact_desc_prepare(StringInfobuf,uint8info,xl_xact_prepare*xlrec)
334+
{
335+
xl_xact_parsed_prepareparsed;
336+
337+
ParsePrepareRecord(info,xlrec,&parsed);
338+
339+
appendStringInfo(buf,"gid %s: ",parsed.twophase_gid);
340+
appendStringInfoString(buf,timestamptz_to_str(parsed.xact_time));
341+
342+
xact_desc_relations(buf,"rels(commit)",parsed.nrels,parsed.xnodes);
343+
xact_desc_relations(buf,"rels(abort)",parsed.nabortrels,
344+
parsed.abortnodes);
345+
xact_desc_subxacts(buf,parsed.nsubxacts,parsed.subxacts);
346+
347+
standby_desc_invalidations(
348+
buf,parsed.nmsgs,parsed.msgs,parsed.dbId,parsed.tsId,
349+
xlrec->initfileinval);
294350
}
295351

296352
staticvoid
@@ -323,6 +379,12 @@ xact_desc(StringInfo buf, XLogReaderState *record)
323379

324380
xact_desc_abort(buf,XLogRecGetInfo(record),xlrec);
325381
}
382+
elseif (info==XLOG_XACT_PREPARE)
383+
{
384+
xl_xact_prepare*xlrec= (xl_xact_prepare*)rec;
385+
386+
xact_desc_prepare(buf,XLogRecGetInfo(record),xlrec);
387+
}
326388
elseif (info==XLOG_XACT_ASSIGNMENT)
327389
{
328390
xl_xact_assignment*xlrec= (xl_xact_assignment*)rec;

‎src/backend/access/transam/twophase.c

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -910,23 +910,7 @@ TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
910910
*/
911911
#defineTWOPHASE_MAGIC0x57F94534/* format identifier */
912912

913-
typedefstructTwoPhaseFileHeader
914-
{
915-
uint32magic;/* format identifier */
916-
uint32total_len;/* actual file length */
917-
TransactionIdxid;/* original transaction XID */
918-
Oiddatabase;/* OID of database it was in */
919-
TimestampTzprepared_at;/* time of preparation */
920-
Oidowner;/* user running the transaction */
921-
int32nsubxacts;/* number of following subxact XIDs */
922-
int32ncommitrels;/* number of delete-on-commit rels */
923-
int32nabortrels;/* number of delete-on-abort rels */
924-
int32ninvalmsgs;/* number of cache invalidation messages */
925-
boolinitfileinval;/* does relcache init file need invalidation? */
926-
uint16gidlen;/* length of the GID - GID follows the header */
927-
XLogRecPtrorigin_lsn;/* lsn of this record at origin node */
928-
TimestampTzorigin_timestamp;/* time of prepare at origin node */
929-
}TwoPhaseFileHeader;
913+
typedefxl_xact_prepareTwoPhaseFileHeader;
930914

931915
/*
932916
* Header for each record in a state file
@@ -1331,44 +1315,6 @@ ReadTwoPhaseFile(TransactionId xid, bool missing_ok)
13311315
returnbuf;
13321316
}
13331317

1334-
/*
1335-
* ParsePrepareRecord
1336-
*/
1337-
void
1338-
ParsePrepareRecord(uint8info,char*xlrec,xl_xact_parsed_prepare*parsed)
1339-
{
1340-
TwoPhaseFileHeader*hdr;
1341-
char*bufptr;
1342-
1343-
hdr= (TwoPhaseFileHeader*)xlrec;
1344-
bufptr=xlrec+MAXALIGN(sizeof(TwoPhaseFileHeader));
1345-
1346-
parsed->origin_lsn=hdr->origin_lsn;
1347-
parsed->origin_timestamp=hdr->origin_timestamp;
1348-
parsed->twophase_xid=hdr->xid;
1349-
parsed->dbId=hdr->database;
1350-
parsed->nsubxacts=hdr->nsubxacts;
1351-
parsed->nrels=hdr->ncommitrels;
1352-
parsed->nabortrels=hdr->nabortrels;
1353-
parsed->nmsgs=hdr->ninvalmsgs;
1354-
1355-
strncpy(parsed->twophase_gid,bufptr,hdr->gidlen);
1356-
bufptr+=MAXALIGN(hdr->gidlen);
1357-
1358-
parsed->subxacts= (TransactionId*)bufptr;
1359-
bufptr+=MAXALIGN(hdr->nsubxacts*sizeof(TransactionId));
1360-
1361-
parsed->xnodes= (RelFileNode*)bufptr;
1362-
bufptr+=MAXALIGN(hdr->ncommitrels*sizeof(RelFileNode));
1363-
1364-
parsed->abortnodes= (RelFileNode*)bufptr;
1365-
bufptr+=MAXALIGN(hdr->nabortrels*sizeof(RelFileNode));
1366-
1367-
parsed->msgs= (SharedInvalidationMessage*)bufptr;
1368-
bufptr+=MAXALIGN(hdr->ninvalmsgs*sizeof(SharedInvalidationMessage));
1369-
}
1370-
1371-
13721318

13731319
/*
13741320
* Reads 2PC data from xlog. During checkpoint this data will be moved to

‎src/include/access/twophase.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ extern bool StandbyTransactionIdIsPrepared(TransactionId xid);
4747

4848
externTransactionIdPrescanPreparedTransactions(TransactionId**xids_p,
4949
int*nxids_p);
50-
externvoidParsePrepareRecord(uint8info,char*xlrec,
51-
xl_xact_parsed_prepare*parsed);
5250
externvoidStandbyRecoverPreparedTransactions(void);
5351
externvoidRecoverPreparedTransactions(void);
5452

‎src/include/access/xact.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,24 @@ typedef struct xl_xact_abort
292292
}xl_xact_abort;
293293
#defineMinSizeOfXactAbort sizeof(xl_xact_abort)
294294

295+
typedefstructxl_xact_prepare
296+
{
297+
uint32magic;/* format identifier */
298+
uint32total_len;/* actual file length */
299+
TransactionIdxid;/* original transaction XID */
300+
Oiddatabase;/* OID of database it was in */
301+
TimestampTzprepared_at;/* time of preparation */
302+
Oidowner;/* user running the transaction */
303+
int32nsubxacts;/* number of following subxact XIDs */
304+
int32ncommitrels;/* number of delete-on-commit rels */
305+
int32nabortrels;/* number of delete-on-abort rels */
306+
int32ninvalmsgs;/* number of cache invalidation messages */
307+
boolinitfileinval;/* does relcache init file need invalidation? */
308+
uint16gidlen;/* length of the GID - GID follows the header */
309+
XLogRecPtrorigin_lsn;/* lsn of this record at origin node */
310+
TimestampTzorigin_timestamp;/* time of prepare at origin node */
311+
}xl_xact_prepare;
312+
295313
/*
296314
* Commit/Abort records in the above form are a bit verbose to parse, so
297315
* there's a deconstructed versions generated by ParseCommit/AbortRecord() for
@@ -435,6 +453,7 @@ extern const char *xact_identify(uint8 info);
435453
/* also in xactdesc.c, so they can be shared between front/backend code */
436454
externvoidParseCommitRecord(uint8info,xl_xact_commit*xlrec,xl_xact_parsed_commit*parsed);
437455
externvoidParseAbortRecord(uint8info,xl_xact_abort*xlrec,xl_xact_parsed_abort*parsed);
456+
externvoidParsePrepareRecord(uint8info,xl_xact_prepare*xlrec,xl_xact_parsed_prepare*parsed);
438457

439458
externvoidEnterParallelMode(void);
440459
externvoidExitParallelMode(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp