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

Commita8d1075

Browse files
committed
Add a time-of-preparation column to the pg_prepared_xacts view, per an
old suggestion by Oliver Jowett. Also, add a transaction column to thepg_locks view to show the xid of each transaction holding or awaitinglocks; this allows prepared transactions to be properly associated withthe locks they own. There was already a column named 'transaction',and I chose to rename it to 'transactionid' --- since this column isnew in the current devel cycle there should be no backwards compatibilityissue to worry about.
1 parent66b0984 commita8d1075

File tree

8 files changed

+106
-54
lines changed

8 files changed

+106
-54
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--
22
Documentation of the system catalogs, directed toward PostgreSQL developers
3-
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.104 2005/06/17 22:32:41 tgl Exp $
3+
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.105 2005/06/18 19:33:41 tgl Exp $
44
-->
55

66
<chapter id="catalogs">
@@ -4090,7 +4090,7 @@
40904090
<literal>extend</>,
40914091
<literal>page</>,
40924092
<literal>tuple</>,
4093-
<literal>transaction</>,
4093+
<literal>transactionid</>,
40944094
<literal>object</>, or
40954095
<literal>userlock</>
40964096
</entry>
@@ -4132,7 +4132,7 @@
41324132
</entry>
41334133
</row>
41344134
<row>
4135-
<entry><structfield>transaction</structfield></entry>
4135+
<entry><structfield>transactionid</structfield></entry>
41364136
<entry><type>xid</type></entry>
41374137
<entry></entry>
41384138
<entry>
@@ -4168,13 +4168,21 @@
41684168
zero. NULL if the object is not a general database object
41694169
</entry>
41704170
</row>
4171+
<row>
4172+
<entry><structfield>transaction</structfield></entry>
4173+
<entry><type>xid</type></entry>
4174+
<entry></entry>
4175+
<entry>
4176+
ID of the transaction that is holding or awaiting this lock.
4177+
</entry>
4178+
</row>
41714179
<row>
41724180
<entry><structfield>pid</structfield></entry>
41734181
<entry><type>integer</type></entry>
41744182
<entry></entry>
41754183
<entry>
41764184
Process ID of the server process holding or awaiting this
4177-
lock.Zero if the lock is held by a prepared transaction.
4185+
lock.Null if the lock is held by a prepared transaction.
41784186
</entry>
41794187
</row>
41804188
<row>
@@ -4196,12 +4204,12 @@
41964204

41974205
<para>
41984206
<structfield>granted</structfield> is true in a row representing a lock
4199-
held by the indicatedsession. False indicates that thissession is
4207+
held by the indicatedtransaction. False indicates that thistransaction is
42004208
currently waiting to acquire this lock, which implies that some other
4201-
session is holding a conflicting lock mode on the same lockable object.
4202-
The waitingsession will sleep until the other lock is released (or a
4203-
deadlock situation is detected). A singlesession can be waiting to acquire
4204-
at most one lock at a time.
4209+
transaction is holding a conflicting lock mode on the same lockable object.
4210+
The waitingtransaction will sleep until the other lock is released (or a
4211+
deadlock situation is detected). A singletransaction can be waiting to
4212+
acquireat most one lock at a time.
42054213
</para>
42064214

42074215
<para>
@@ -4253,6 +4261,13 @@
42534261
<structfield>procpid</structfield> column of the
42544262
<structname>pg_stat_activity</structname> view to get more
42554263
information on the session holding or waiting to hold the lock.
4264+
Also, if you are using prepared transactions, the
4265+
<structfield>transaction</> column can be joined to the
4266+
<structfield>transaction</structfield> column of the
4267+
<structname>pg_prepared_xacts</structname> view to get more
4268+
information on prepared transactions that hold locks.
4269+
(A prepared transaction can never be waiting for a lock,
4270+
but it continues to hold the locks it acquired while running.)
42564271
</para>
42574272

42584273
</sect1>
@@ -4306,6 +4321,14 @@
43064321
Global transaction identifier that was assigned to the transaction
43074322
</entry>
43084323
</row>
4324+
<row>
4325+
<entry><structfield>prepared</structfield></entry>
4326+
<entry><type>timestamp with time zone</type></entry>
4327+
<entry></entry>
4328+
<entry>
4329+
Time at which the transaction was prepared for commit
4330+
</entry>
4331+
</row>
43094332
<row>
43104333
<entry><structfield>owner</structfield></entry>
43114334
<entry><type>name</type></entry>

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

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
*$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.2 2005/06/1805:21:09 tgl Exp $
10+
*$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.3 2005/06/1819:33:41 tgl Exp $
1111
*
1212
* NOTES
1313
*Each global transaction is associated with a global transaction
@@ -104,6 +104,7 @@ int max_prepared_xacts = 50;
104104
typedefstructGlobalTransactionData
105105
{
106106
PGPROCproc;/* dummy proc */
107+
TimestampTzprepared_at;/* time of preparation */
107108
AclIdowner;/* ID of user that executed the xact */
108109
TransactionIdlocking_xid;/* top-level XID of backend working on xact */
109110
boolvalid;/* TRUE if fully prepared */
@@ -202,7 +203,8 @@ TwoPhaseShmemInit(void)
202203
* assuming that we can use very much backend context.
203204
*/
204205
GlobalTransaction
205-
MarkAsPreparing(TransactionIdxid,Oiddatabaseid,char*gid,AclIdowner)
206+
MarkAsPreparing(TransactionIdxid,constchar*gid,
207+
TimestampTzprepared_at,AclIdowner,Oiddatabaseid)
206208
{
207209
GlobalTransactiongxact;
208210
inti;
@@ -278,6 +280,7 @@ MarkAsPreparing(TransactionId xid, Oid databaseid, char *gid, AclId owner)
278280
gxact->proc.subxids.overflowed= false;
279281
gxact->proc.subxids.nxids=0;
280282

283+
gxact->prepared_at=prepared_at;
281284
gxact->owner=owner;
282285
gxact->locking_xid=xid;
283286
gxact->valid= false;
@@ -342,7 +345,7 @@ MarkAsPrepared(GlobalTransaction gxact)
342345
*Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
343346
*/
344347
staticGlobalTransaction
345-
LockGXact(char*gid,AclIduser)
348+
LockGXact(constchar*gid,AclIduser)
346349
{
347350
inti;
348351

@@ -509,14 +512,16 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
509512

510513
/* build tupdesc for result tuples */
511514
/* this had better match pg_prepared_xacts view in system_views.sql */
512-
tupdesc=CreateTemplateTupleDesc(4, false);
515+
tupdesc=CreateTemplateTupleDesc(5, false);
513516
TupleDescInitEntry(tupdesc, (AttrNumber)1,"transaction",
514517
XIDOID,-1,0);
515518
TupleDescInitEntry(tupdesc, (AttrNumber)2,"gid",
516519
TEXTOID,-1,0);
517-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"ownerid",
520+
TupleDescInitEntry(tupdesc, (AttrNumber)3,"prepared",
521+
TIMESTAMPTZOID,-1,0);
522+
TupleDescInitEntry(tupdesc, (AttrNumber)4,"ownerid",
518523
INT4OID,-1,0);
519-
TupleDescInitEntry(tupdesc, (AttrNumber)4,"dbid",
524+
TupleDescInitEntry(tupdesc, (AttrNumber)5,"dbid",
520525
OIDOID,-1,0);
521526

522527
funcctx->tuple_desc=BlessTupleDesc(tupdesc);
@@ -540,8 +545,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
540545
while (status->array!=NULL&&status->currIdx<status->ngxacts)
541546
{
542547
GlobalTransactiongxact=&status->array[status->currIdx++];
543-
Datumvalues[4];
544-
boolnulls[4];
548+
Datumvalues[5];
549+
boolnulls[5];
545550
HeapTupletuple;
546551
Datumresult;
547552

@@ -556,8 +561,9 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
556561

557562
values[0]=TransactionIdGetDatum(gxact->proc.xid);
558563
values[1]=DirectFunctionCall1(textin,CStringGetDatum(gxact->gid));
559-
values[2]=Int32GetDatum(gxact->owner);
560-
values[3]=ObjectIdGetDatum(gxact->proc.databaseId);
564+
values[2]=TimestampTzGetDatum(gxact->prepared_at);
565+
values[3]=Int32GetDatum(gxact->owner);
566+
values[4]=ObjectIdGetDatum(gxact->proc.databaseId);
561567

562568
tuple=heap_form_tuple(funcctx->tuple_desc,values,nulls);
563569
result=HeapTupleGetDatum(tuple);
@@ -636,14 +642,15 @@ TwoPhaseGetDummyProc(TransactionId xid)
636642
/*
637643
* Header for a 2PC state file
638644
*/
639-
#defineTWOPHASE_MAGIC0x57F94530/* format identifier */
645+
#defineTWOPHASE_MAGIC0x57F94531/* format identifier */
640646

641647
typedefstructTwoPhaseFileHeader
642648
{
643649
uint32magic;/* format identifier */
644650
uint32total_len;/* actual file length */
645651
TransactionIdxid;/* original transaction XID */
646652
Oiddatabase;/* OID of database it was in */
653+
TimestampTzprepared_at;/* time of preparation */
647654
AclIdowner;/* user running the transaction */
648655
int32nsubxacts;/* number of following subxact XIDs */
649656
int32ncommitrels;/* number of delete-on-commit rels */
@@ -741,8 +748,9 @@ StartPrepare(GlobalTransaction gxact)
741748
hdr.magic=TWOPHASE_MAGIC;
742749
hdr.total_len=0;/* EndPrepare will fill this in */
743750
hdr.xid=xid;
744-
hdr.database=MyDatabaseId;
745-
hdr.owner=GetUserId();
751+
hdr.database=gxact->proc.databaseId;
752+
hdr.prepared_at=gxact->prepared_at;
753+
hdr.owner=gxact->owner;
746754
hdr.nsubxacts=xactGetCommittedChildren(&children);
747755
hdr.ncommitrels=smgrGetPendingDeletes(true,&commitrels);
748756
hdr.nabortrels=smgrGetPendingDeletes(false,&abortrels);
@@ -1046,7 +1054,7 @@ ReadTwoPhaseFile(TransactionId xid)
10461054
* FinishPreparedTransaction: execute COMMIT PREPARED or ROLLBACK PREPARED
10471055
*/
10481056
void
1049-
FinishPreparedTransaction(char*gid,boolisCommit)
1057+
FinishPreparedTransaction(constchar*gid,boolisCommit)
10501058
{
10511059
GlobalTransactiongxact;
10521060
TransactionIdxid;
@@ -1474,15 +1482,20 @@ RecoverPreparedTransactions(void)
14741482

14751483
/*
14761484
* Reconstruct subtrans state for the transaction --- needed
1477-
* because pg_subtrans is not preserved over a restart
1485+
* because pg_subtrans is not preserved over a restart. Note
1486+
* that we are linking all the subtransactions directly to the
1487+
* top-level XID; there may originally have been a more complex
1488+
* hierarchy, but there's no need to restore that exactly.
14781489
*/
14791490
for (i=0;i<hdr->nsubxacts;i++)
14801491
SubTransSetParent(subxids[i],xid);
14811492

14821493
/*
14831494
* Recreate its GXACT and dummy PGPROC
14841495
*/
1485-
gxact=MarkAsPreparing(xid,hdr->database,hdr->gid,hdr->owner);
1496+
gxact=MarkAsPreparing(xid,hdr->gid,
1497+
hdr->prepared_at,
1498+
hdr->owner,hdr->database);
14861499
GXactLoadSubxactData(gxact,hdr->nsubxacts,subxids);
14871500
MarkAsPrepared(gxact);
14881501

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.205 2005/06/17 22:32:42 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.206 2005/06/18 19:33:41 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1630,6 +1630,9 @@ PrepareTransaction(void)
16301630
TransactionStates=CurrentTransactionState;
16311631
TransactionIdxid=GetCurrentTransactionId();
16321632
GlobalTransactiongxact;
1633+
TimestampTzprepared_at;
1634+
AbsoluteTimePreparedSec;/* integer part */
1635+
intPreparedUSec;/* microsecond part */
16331636

16341637
ShowTransactionState("PrepareTransaction");
16351638

@@ -1692,14 +1695,18 @@ PrepareTransaction(void)
16921695
*/
16931696
s->state=TRANS_PREPARE;
16941697

1698+
PreparedSec=GetCurrentAbsoluteTimeUsec(&PreparedUSec);
1699+
prepared_at=AbsoluteTimeUsecToTimestampTz(PreparedSec,PreparedUSec);
1700+
16951701
/* Tell bufmgr and smgr to prepare for commit */
16961702
BufmgrCommit();
16971703

16981704
/*
16991705
* Reserve the GID for this transaction. This could fail if the
17001706
* requested GID is invalid or already in use.
17011707
*/
1702-
gxact=MarkAsPreparing(xid,MyDatabaseId,prepareGID,GetUserId());
1708+
gxact=MarkAsPreparing(xid,prepareGID,prepared_at,
1709+
GetUserId(),MyDatabaseId);
17031710
prepareGID=NULL;
17041711

17051712
/*

‎src/backend/catalog/system_views.sql

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 1996-2005, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.14 2005/06/17 22:32:43 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.15 2005/06/18 19:33:42 tgl Exp $
77
*/
88

99
CREATEVIEWpg_userAS
@@ -106,15 +106,16 @@ CREATE VIEW pg_locks AS
106106
SELECT*
107107
FROM pg_lock_status()AS L
108108
(locktypetext, databaseoid, relationoid, page int4, tuple int2,
109-
transaction xid, classidoid, objidoid, objsubid int2,
110-
pid int4, modetext, grantedboolean);
109+
transactionid xid, classidoid, objidoid, objsubid int2,
110+
transaction xid,pid int4, modetext, grantedboolean);
111111

112112
CREATEVIEWpg_prepared_xactsAS
113-
SELECTP.transaction,P.gid,U.usenameAS owner,D.datnameAS database
113+
SELECTP.transaction,P.gid,P.prepared,
114+
U.usenameAS owner,D.datnameAS database
114115
FROM pg_prepared_xact()AS P
115-
(transaction xid, gidtext, ownerid int4, dbidoid)
116-
LEFT JOINpg_database DONP.dbid=D.oid
117-
LEFT JOINpg_shadow UONP.ownerid=U.usesysid;
116+
(transaction xid, gidtext,preparedtimestamptz,ownerid int4, dbidoid)
117+
LEFT JOINpg_shadow UONP.ownerid=U.usesysid
118+
LEFT JOINpg_database DONP.dbid=D.oid;
118119

119120
CREATEVIEWpg_settingsAS
120121
SELECT*

‎src/backend/utils/adt/lockfuncs.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
*$PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.18 2005/05/17 21:46:10 tgl Exp $
9+
*$PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.19 2005/06/18 19:33:42 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -26,7 +26,7 @@ static const char * const LockTagTypeNames[] = {
2626
"extend",
2727
"page",
2828
"tuple",
29-
"transaction",
29+
"transactionid",
3030
"object",
3131
"userlock"
3232
};
@@ -64,7 +64,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
6464

6565
/* build tupdesc for result tuples */
6666
/* this had better match pg_locks view in system_views.sql */
67-
tupdesc=CreateTemplateTupleDesc(12, false);
67+
tupdesc=CreateTemplateTupleDesc(13, false);
6868
TupleDescInitEntry(tupdesc, (AttrNumber)1,"locktype",
6969
TEXTOID,-1,0);
7070
TupleDescInitEntry(tupdesc, (AttrNumber)2,"database",
@@ -75,19 +75,21 @@ pg_lock_status(PG_FUNCTION_ARGS)
7575
INT4OID,-1,0);
7676
TupleDescInitEntry(tupdesc, (AttrNumber)5,"tuple",
7777
INT2OID,-1,0);
78-
TupleDescInitEntry(tupdesc, (AttrNumber)6,"transaction",
78+
TupleDescInitEntry(tupdesc, (AttrNumber)6,"transactionid",
7979
XIDOID,-1,0);
8080
TupleDescInitEntry(tupdesc, (AttrNumber)7,"classid",
8181
OIDOID,-1,0);
8282
TupleDescInitEntry(tupdesc, (AttrNumber)8,"objid",
8383
OIDOID,-1,0);
8484
TupleDescInitEntry(tupdesc, (AttrNumber)9,"objsubid",
8585
INT2OID,-1,0);
86-
TupleDescInitEntry(tupdesc, (AttrNumber)10,"pid",
86+
TupleDescInitEntry(tupdesc, (AttrNumber)10,"transaction",
87+
XIDOID,-1,0);
88+
TupleDescInitEntry(tupdesc, (AttrNumber)11,"pid",
8789
INT4OID,-1,0);
88-
TupleDescInitEntry(tupdesc, (AttrNumber)11,"mode",
90+
TupleDescInitEntry(tupdesc, (AttrNumber)12,"mode",
8991
TEXTOID,-1,0);
90-
TupleDescInitEntry(tupdesc, (AttrNumber)12,"granted",
92+
TupleDescInitEntry(tupdesc, (AttrNumber)13,"granted",
9193
BOOLOID,-1,0);
9294

9395
funcctx->tuple_desc=BlessTupleDesc(tupdesc);
@@ -118,8 +120,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
118120
LOCKMODEmode=0;
119121
constchar*locktypename;
120122
chartnbuf[32];
121-
Datumvalues[12];
122-
charnulls[12];
123+
Datumvalues[13];
124+
charnulls[13];
123125
HeapTupletuple;
124126
Datumresult;
125127

@@ -249,10 +251,14 @@ pg_lock_status(PG_FUNCTION_ARGS)
249251
break;
250252
}
251253

252-
values[9]=Int32GetDatum(proc->pid);
253-
values[10]=DirectFunctionCall1(textin,
254+
values[9]=TransactionIdGetDatum(proc->xid);
255+
if (proc->pid!=0)
256+
values[10]=Int32GetDatum(proc->pid);
257+
else
258+
nulls[10]='n';
259+
values[11]=DirectFunctionCall1(textin,
254260
CStringGetDatum(GetLockmodeName(mode)));
255-
values[11]=BoolGetDatum(granted);
261+
values[12]=BoolGetDatum(granted);
256262

257263
tuple=heap_formtuple(funcctx->tuple_desc,values,nulls);
258264
result=HeapTupleGetDatum(tuple);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp