Skip to content

Commit c432061

Browse files
committed
Change the timestamps recorded in transaction commit/abort xlog records
from time_t to TimestampTz representation. This provides full gettimeofday() resolution of the timestamps, which might be useful when attempting to do point-in-time recovery --- previously it was not possible to specify the stop point with sub-second resolution. But mostly this is to get rid of TimestampTz-to-time_t conversion overhead during commit. Per my proposal of a day or two back.
1 parent 641912b commit c432061

File tree

7 files changed

+67
-42
lines changed

7 files changed

+67
-42
lines changed

src/backend/access/transam/twophase.c

Lines changed: 3 additions & 3 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.29 2007/04/03 16:34:35 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.30 2007/04/30 21:01:52 tgl Exp $
1111
*
1212
* NOTES
1313
* Each global transaction is associated with a global transaction
@@ -1675,7 +1675,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
16751675

16761676
/* Emit the XLOG commit record */
16771677
xlrec.xid = xid;
1678-
xlrec.crec.xtime = time(NULL);
1678+
xlrec.crec.xact_time = GetCurrentTimestamp();
16791679
xlrec.crec.nrels = nrels;
16801680
xlrec.crec.nsubxacts = nchildren;
16811681
rdata[0].data = (char *) (&xlrec);
@@ -1753,7 +1753,7 @@ RecordTransactionAbortPrepared(TransactionId xid,
17531753

17541754
/* Emit the XLOG abort record */
17551755
xlrec.xid = xid;
1756-
xlrec.arec.xtime = time(NULL);
1756+
xlrec.arec.xact_time = GetCurrentTimestamp();
17571757
xlrec.arec.nrels = nrels;
17581758
xlrec.arec.nsubxacts = nchildren;
17591759
rdata[0].data = (char *) (&xlrec);

src/backend/access/transam/xact.c

Lines changed: 6 additions & 12 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.241 2007/04/30 03:23:48 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.242 2007/04/30 21:01:52 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -773,7 +773,7 @@ RecordTransactionCommit(void)
773773
MyProc->inCommit = true;
774774

775775
SetCurrentTransactionStopTimestamp();
776-
xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
776+
xlrec.xact_time = xactStopTimestamp;
777777
xlrec.nrels = nrels;
778778
xlrec.nsubxacts = nchildren;
779779
rdata[0].data = (char *) (&xlrec);
@@ -1069,7 +1069,7 @@ RecordTransactionAbort(void)
10691069
XLogRecPtr recptr;
10701070

10711071
SetCurrentTransactionStopTimestamp();
1072-
xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
1072+
xlrec.xact_time = xactStopTimestamp;
10731073
xlrec.nrels = nrels;
10741074
xlrec.nsubxacts = nchildren;
10751075
rdata[0].data = (char *) (&xlrec);
@@ -1247,7 +1247,7 @@ RecordSubTransactionAbort(void)
12471247
xl_xact_abort xlrec;
12481248
XLogRecPtr recptr;
12491249

1250-
xlrec.xtime = time(NULL);
1250+
xlrec.xact_time = GetCurrentTimestamp();
12511251
xlrec.nrels = nrels;
12521252
xlrec.nsubxacts = nchildren;
12531253
rdata[0].data = (char *) (&xlrec);
@@ -4282,12 +4282,9 @@ xact_redo(XLogRecPtr lsn, XLogRecord *record)
42824282
static void
42834283
xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
42844284
{
4285-
struct tm *tm = localtime(&xlrec->xtime);
42864285
int i;
42874286

4288-
appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
4289-
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
4290-
tm->tm_hour, tm->tm_min, tm->tm_sec);
4287+
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
42914288
if (xlrec->nrels > 0)
42924289
{
42934290
appendStringInfo(buf, "; rels:");
@@ -4313,12 +4310,9 @@ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
43134310
static void
43144311
xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
43154312
{
4316-
struct tm *tm = localtime(&xlrec->xtime);
43174313
int i;
43184314

4319-
appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
4320-
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
4321-
tm->tm_hour, tm->tm_min, tm->tm_sec);
4315+
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
43224316
if (xlrec->nrels > 0)
43234317
{
43244318
appendStringInfo(buf, "; rels:");

src/backend/access/transam/xlog.c

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.267 2007/04/03 16:34:35 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.268 2007/04/30 21:01:52 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -47,7 +47,6 @@
4747
#include "storage/procarray.h"
4848
#include "storage/spin.h"
4949
#include "utils/builtins.h"
50-
#include "utils/nabstime.h"
5150
#include "utils/pg_locale.h"
5251

5352

@@ -114,11 +113,11 @@ static bool recoveryTarget = false;
114113
static bool recoveryTargetExact = false;
115114
static bool recoveryTargetInclusive = true;
116115
static TransactionId recoveryTargetXid;
117-
static time_t recoveryTargetTime;
116+
static TimestampTz recoveryTargetTime;
118117

119118
/* if recoveryStopsHere returns true, it saves actual stop xid/time here */
120119
static TransactionId recoveryStopXid;
121-
static time_t recoveryStopTime;
120+
static TimestampTz recoveryStopTime;
122121
static bool recoveryStopAfter;
123122

124123
/*
@@ -3536,7 +3535,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
35363535
xlogfname,
35373536
recoveryStopAfter ? "after" : "before",
35383537
recoveryStopXid,
3539-
str_time(recoveryStopTime));
3538+
timestamptz_to_str(recoveryStopTime));
35403539

35413540
nbytes = strlen(buffer);
35423541
errno = 0;
@@ -4276,17 +4275,16 @@ readRecoveryCommandFile(void)
42764275
recoveryTargetExact = false;
42774276

42784277
/*
4279-
* Convert the time string given by the user to the time_t format.
4280-
* We use type abstime's input converter because we know abstime
4281-
* has the same representation as time_t.
4278+
* Convert the time string given by the user to TimestampTz form.
42824279
*/
4283-
recoveryTargetTime = (time_t)
4284-
DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
4285-
CStringGetDatum(tok2)));
4280+
recoveryTargetTime =
4281+
DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
4282+
CStringGetDatum(tok2),
4283+
ObjectIdGetDatum(InvalidOid),
4284+
Int32GetDatum(-1)));
42864285
ereport(LOG,
42874286
(errmsg("recovery_target_time = %s",
4288-
DatumGetCString(DirectFunctionCall1(abstimeout,
4289-
AbsoluteTimeGetDatum((AbsoluteTime) recoveryTargetTime))))));
4287+
timestamptz_to_str(recoveryTargetTime))));
42904288
}
42914289
else if (strcmp(tok1, "recovery_target_inclusive") == 0)
42924290
{
@@ -4464,7 +4462,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
44644462
{
44654463
bool stopsHere;
44664464
uint8 record_info;
4467-
time_t recordXtime;
4465+
TimestampTz recordXtime;
44684466

44694467
/* Do we have a PITR target at all? */
44704468
if (!recoveryTarget)
@@ -4479,14 +4477,14 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
44794477
xl_xact_commit *recordXactCommitData;
44804478

44814479
recordXactCommitData = (xl_xact_commit *) XLogRecGetData(record);
4482-
recordXtime = recordXactCommitData->xtime;
4480+
recordXtime = recordXactCommitData->xact_time;
44834481
}
44844482
else if (record_info == XLOG_XACT_ABORT)
44854483
{
44864484
xl_xact_abort *recordXactAbortData;
44874485

44884486
recordXactAbortData = (xl_xact_abort *) XLogRecGetData(record);
4489-
recordXtime = recordXactAbortData->xtime;
4487+
recordXtime = recordXactAbortData->xact_time;
44904488
}
44914489
else
44924490
return false;
@@ -4532,22 +4530,26 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
45324530
if (recoveryStopAfter)
45334531
ereport(LOG,
45344532
(errmsg("recovery stopping after commit of transaction %u, time %s",
4535-
recoveryStopXid, str_time(recoveryStopTime))));
4533+
recoveryStopXid,
4534+
timestamptz_to_str(recoveryStopTime))));
45364535
else
45374536
ereport(LOG,
45384537
(errmsg("recovery stopping before commit of transaction %u, time %s",
4539-
recoveryStopXid, str_time(recoveryStopTime))));
4538+
recoveryStopXid,
4539+
timestamptz_to_str(recoveryStopTime))));
45404540
}
45414541
else
45424542
{
45434543
if (recoveryStopAfter)
45444544
ereport(LOG,
45454545
(errmsg("recovery stopping after abort of transaction %u, time %s",
4546-
recoveryStopXid, str_time(recoveryStopTime))));
4546+
recoveryStopXid,
4547+
timestamptz_to_str(recoveryStopTime))));
45474548
else
45484549
ereport(LOG,
45494550
(errmsg("recovery stopping before abort of transaction %u, time %s",
4550-
recoveryStopXid, str_time(recoveryStopTime))));
4551+
recoveryStopXid,
4552+
timestamptz_to_str(recoveryStopTime))));
45514553
}
45524554
}
45534555

src/backend/utils/adt/timestamp.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.175 2007/04/30 03:23:49 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.176 2007/04/30 21:01:52 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1301,6 +1301,33 @@ timestamptz_to_time_t(TimestampTz t)
13011301
return result;
13021302
}
13031303

1304+
/*
1305+
* Produce a C-string representation of a TimestampTz.
1306+
*
1307+
* This is mostly for use in emitting messages. The primary difference
1308+
* from timestamptz_out is that we force the output format to ISO. Note
1309+
* also that the result is in a static buffer, not pstrdup'd.
1310+
*/
1311+
const char *
1312+
timestamptz_to_str(TimestampTz t)
1313+
{
1314+
static char buf[MAXDATELEN + 1];
1315+
int tz;
1316+
struct pg_tm tt,
1317+
*tm = &tt;
1318+
fsec_t fsec;
1319+
char *tzn;
1320+
1321+
if (TIMESTAMP_NOT_FINITE(t))
1322+
EncodeSpecialTimestamp(t, buf);
1323+
else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1324+
EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
1325+
else
1326+
strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1327+
1328+
return buf;
1329+
}
1330+
13041331

13051332
void
13061333
dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)

src/include/access/xact.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.86 2007/04/30 03:23:49 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.87 2007/04/30 21:01:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -81,7 +81,7 @@ typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid,
8181

8282
typedef struct xl_xact_commit
8383
{
84-
time_t xtime;
84+
TimestampTz xact_time; /* time of commit */
8585
int nrels; /* number of RelFileNodes */
8686
int nsubxacts; /* number of subtransaction XIDs */
8787
/* Array of RelFileNode(s) to drop at commit */
@@ -93,7 +93,7 @@ typedef struct xl_xact_commit
9393

9494
typedef struct xl_xact_abort
9595
{
96-
time_t xtime;
96+
TimestampTz xact_time; /* time of abort */
9797
int nrels; /* number of RelFileNodes */
9898
int nsubxacts; /* number of subtransaction XIDs */
9999
/* Array of RelFileNode(s) to drop at abort */

src/include/access/xlog_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.19 2007/03/03 20:02:27 momjian Exp $
14+
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.20 2007/04/30 21:01:53 tgl Exp $
1515
*/
1616
#ifndef XLOG_INTERNAL_H
1717
#define XLOG_INTERNAL_H
@@ -71,7 +71,7 @@ typedef struct XLogContRecord
7171
/*
7272
* Each page of XLOG file has a header like this:
7373
*/
74-
#define XLOG_PAGE_MAGIC 0xD05F /* can be used as WAL version indicator */
74+
#define XLOG_PAGE_MAGIC 0xD061 /* can be used as WAL version indicator */
7575

7676
typedef struct XLogPageHeaderData
7777
{

src/include/utils/timestamp.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.68 2007/04/30 03:23:49 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.69 2007/04/30 21:01:53 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -318,6 +318,8 @@ extern bool TimestampDifferenceExceeds(TimestampTz start_time,
318318
extern TimestampTz time_t_to_timestamptz(time_t tm);
319319
extern time_t timestamptz_to_time_t(TimestampTz t);
320320

321+
extern const char *timestamptz_to_str(TimestampTz t);
322+
321323
extern int tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
322324
extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm,
323325
fsec_t *fsec, char **tzn, pg_tz *attimezone);

0 commit comments

Comments
 (0)