Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4dbb880

Browse files
committed
Rearrange pg_subtrans handling as per recent discussion. pg_subtrans
updates are no longer WAL-logged nor even fsync'd; we do not need to, since after a crash no old pg_subtrans data is needed again. We truncate pg_subtrans to RecentGlobalXmin at each checkpoint. slru.c's API is refactored a little bit to separate out the necessary decisions.
1 parent 059912c commit 4dbb880

File tree

13 files changed

+387
-436
lines changed

13 files changed

+387
-436
lines changed

src/backend/access/transam/clog.c

+90-54
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,34 @@
1010
* looked up again. Now we use specialized access code so that the commit
1111
* log can be broken into relatively small, independent segments.
1212
*
13+
* XLOG interactions: this module generates an XLOG record whenever a new
14+
* CLOG page is initialized to zeroes. Other writes of CLOG come from
15+
* recording of transaction commit or abort in xact.c, which generates its
16+
* own XLOG records for these events and will re-perform the status update
17+
* on redo; so we need make no additional XLOG entry here. Also, the XLOG
18+
* is guaranteed flushed through the XLOG commit record before we are called
19+
* to log a commit, so the WAL rule "write xlog before data" is satisfied
20+
* automatically for commits, and we don't really care for aborts. Therefore,
21+
* we don't need to mark CLOG pages with LSN information; we have enough
22+
* synchronization already.
23+
*
1324
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1425
* Portions Copyright (c) 1994, Regents of the University of California
1526
*
16-
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.22 2004/07/03 02:55:56 tgl Exp $
27+
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.23 2004/08/23 23:22:44 tgl Exp $
1728
*
1829
*-------------------------------------------------------------------------
1930
*/
2031
#include "postgres.h"
2132

22-
#include <fcntl.h>
23-
#include <dirent.h>
24-
#include <sys/stat.h>
25-
#include <unistd.h>
26-
2733
#include "access/clog.h"
2834
#include "access/slru.h"
29-
#include "miscadmin.h"
30-
#include "storage/lwlock.h"
35+
#include "postmaster/bgwriter.h"
3136

3237

3338
/*
34-
* Defines for CLOG page and segment sizes. A page is the same BLCKSZ
35-
* as is used everywhere else in Postgres.
39+
* Defines for CLOG page sizes. A page is the same BLCKSZ as is used
40+
* everywhere else in Postgres.
3641
*
3742
* Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF,
3843
* CLOG page numbering also wraps around at 0xFFFFFFFF/CLOG_XACTS_PER_PAGE,
@@ -53,25 +58,11 @@
5358
#define TransactionIdToBIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
5459

5560

56-
/*----------
57-
* Shared-memory data structures for CLOG control
58-
*
59-
* XLOG interactions: this module generates an XLOG record whenever a new
60-
* CLOG page is initialized to zeroes. Other writes of CLOG come from
61-
* recording of transaction commit or abort in xact.c, which generates its
62-
* own XLOG records for these events and will re-perform the status update
63-
* on redo; so we need make no additional XLOG entry here. Also, the XLOG
64-
* is guaranteed flushed through the XLOG commit record before we are called
65-
* to log a commit, so the WAL rule "write xlog before data" is satisfied
66-
* automatically for commits, and we don't really care for aborts. Therefore,
67-
* we don't need to mark CLOG pages with LSN information; we have enough
68-
* synchronization already.
69-
*----------
61+
/*
62+
* Link to shared-memory data structures for CLOG control
7063
*/
71-
72-
7364
static SlruCtlData ClogCtlData;
74-
static SlruCtl ClogCtl = &ClogCtlData;
65+
#define ClogCtl (&ClogCtlData)
7566

7667

7768
static int ZeroCLOGPage(int pageno, bool writeXlog);
@@ -91,17 +82,18 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
9182
int pageno = TransactionIdToPage(xid);
9283
int byteno = TransactionIdToByte(xid);
9384
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
85+
int slotno;
9486
char *byteptr;
9587
char byteval;
9688

9789
Assert(status == TRANSACTION_STATUS_COMMITTED ||
9890
status == TRANSACTION_STATUS_ABORTED ||
9991
status == TRANSACTION_STATUS_SUB_COMMITTED);
10092

101-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
93+
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
10294

103-
byteptr = SimpleLruReadPage(ClogCtl, pageno, xid, true);
104-
byteptr += byteno;
95+
slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
96+
byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
10597

10698
/* Current state should be 0, subcommitted or target state */
10799
Assert(((*byteptr >> bshift) & CLOG_XACT_BITMASK) == 0 ||
@@ -114,9 +106,9 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
114106
byteval |= (status << bshift);
115107
*byteptr = byteval;
116108

117-
/* ...->page_status[slotno] = SLRU_PAGE_DIRTY; already done */
109+
ClogCtl->shared->page_status[slotno] = SLRU_PAGE_DIRTY;
118110

119-
LWLockRelease(ClogCtl->ControlLock);
111+
LWLockRelease(CLogControlLock);
120112
}
121113

122114
/*
@@ -131,17 +123,18 @@ TransactionIdGetStatus(TransactionId xid)
131123
int pageno = TransactionIdToPage(xid);
132124
int byteno = TransactionIdToByte(xid);
133125
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
126+
int slotno;
134127
char *byteptr;
135128
XidStatus status;
136129

137-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
130+
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
138131

139-
byteptr = SimpleLruReadPage(ClogCtl, pageno, xid, false);
140-
byteptr += byteno;
132+
slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
133+
byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
141134

142135
status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
143136

144-
LWLockRelease(ClogCtl->ControlLock);
137+
LWLockRelease(CLogControlLock);
145138

146139
return status;
147140
}
@@ -160,8 +153,8 @@ CLOGShmemSize(void)
160153
void
161154
CLOGShmemInit(void)
162155
{
163-
SimpleLruInit(ClogCtl, "CLOG Ctl", "pg_clog");
164156
ClogCtl->PagePrecedes = CLOGPagePrecedes;
157+
SimpleLruInit(ClogCtl, "CLOG Ctl", CLogControlLock, "pg_clog");
165158
}
166159

167160
/*
@@ -175,16 +168,16 @@ BootStrapCLOG(void)
175168
{
176169
int slotno;
177170

178-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
171+
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
179172

180173
/* Create and zero the first page of the commit log */
181174
slotno = ZeroCLOGPage(0, false);
182175

183176
/* Make sure it's written out */
184177
SimpleLruWritePage(ClogCtl, slotno, NULL);
185-
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */
178+
Assert(ClogCtl->shared->page_status[slotno] == SLRU_PAGE_CLEAN);
186179

187-
LWLockRelease(ClogCtl->ControlLock);
180+
LWLockRelease(CLogControlLock);
188181
}
189182

190183
/*
@@ -199,7 +192,9 @@ BootStrapCLOG(void)
199192
static int
200193
ZeroCLOGPage(int pageno, bool writeXlog)
201194
{
202-
int slotno = SimpleLruZeroPage(ClogCtl, pageno);
195+
int slotno;
196+
197+
slotno = SimpleLruZeroPage(ClogCtl, pageno);
203198

204199
if (writeXlog)
205200
WriteZeroPageXlogRec(pageno);
@@ -217,8 +212,7 @@ StartupCLOG(void)
217212
/*
218213
* Initialize our idea of the latest page number.
219214
*/
220-
SimpleLruSetLatestPage(ClogCtl,
221-
TransactionIdToPage(ShmemVariableCache->nextXid));
215+
ClogCtl->shared->latest_page_number = TransactionIdToPage(ShmemVariableCache->nextXid);
222216
}
223217

224218
/*
@@ -227,6 +221,7 @@ StartupCLOG(void)
227221
void
228222
ShutdownCLOG(void)
229223
{
224+
/* Flush dirty CLOG pages to disk */
230225
SimpleLruFlush(ClogCtl, false);
231226
}
232227

@@ -236,6 +231,7 @@ ShutdownCLOG(void)
236231
void
237232
CheckPointCLOG(void)
238233
{
234+
/* Flush dirty CLOG pages to disk */
239235
SimpleLruFlush(ClogCtl, true);
240236
}
241237

@@ -263,12 +259,12 @@ ExtendCLOG(TransactionId newestXact)
263259

264260
pageno = TransactionIdToPage(newestXact);
265261

266-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
262+
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
267263

268264
/* Zero the page and make an XLOG entry about it */
269265
ZeroCLOGPage(pageno, true);
270266

271-
LWLockRelease(ClogCtl->ControlLock);
267+
LWLockRelease(CLogControlLock);
272268
}
273269

274270

@@ -296,6 +292,15 @@ TruncateCLOG(TransactionId oldestXact)
296292
* We pass the *page* containing oldestXact to SimpleLruTruncate.
297293
*/
298294
cutoffPage = TransactionIdToPage(oldestXact);
295+
296+
/* Check to see if there's any files that could be removed */
297+
if (!SlruScanDirectory(ClogCtl, cutoffPage, false))
298+
return; /* nothing to remove */
299+
300+
/* Perform a CHECKPOINT */
301+
RequestCheckpoint(true);
302+
303+
/* Now we can remove the old CLOG segment(s) */
299304
SimpleLruTruncate(ClogCtl, cutoffPage);
300305
}
301306

@@ -340,20 +345,51 @@ WriteZeroPageXlogRec(int pageno)
340345
rdata.data = (char *) (&pageno);
341346
rdata.len = sizeof(int);
342347
rdata.next = NULL;
343-
(void) XLogInsert(RM_SLRU_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
348+
(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
344349
}
345350

346-
/* Redo a ZEROPAGE action during WAL replay */
351+
/*
352+
* CLOG resource manager's routines
353+
*/
347354
void
348-
clog_zeropage_redo(int pageno)
355+
clog_redo(XLogRecPtr lsn, XLogRecord *record)
349356
{
350-
int slotno;
357+
uint8 info = record->xl_info & ~XLR_INFO_MASK;
351358

352-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
359+
if (info == CLOG_ZEROPAGE)
360+
{
361+
int pageno;
362+
int slotno;
353363

354-
slotno = ZeroCLOGPage(pageno, false);
355-
SimpleLruWritePage(ClogCtl, slotno, NULL);
356-
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */
364+
memcpy(&pageno, XLogRecGetData(record), sizeof(int));
365+
366+
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
367+
368+
slotno = ZeroCLOGPage(pageno, false);
369+
SimpleLruWritePage(ClogCtl, slotno, NULL);
370+
Assert(ClogCtl->shared->page_status[slotno] == SLRU_PAGE_CLEAN);
371+
372+
LWLockRelease(CLogControlLock);
373+
}
374+
}
375+
376+
void
377+
clog_undo(XLogRecPtr lsn, XLogRecord *record)
378+
{
379+
}
380+
381+
void
382+
clog_desc(char *buf, uint8 xl_info, char *rec)
383+
{
384+
uint8 info = xl_info & ~XLR_INFO_MASK;
385+
386+
if (info == CLOG_ZEROPAGE)
387+
{
388+
int pageno;
357389

358-
LWLockRelease(ClogCtl->ControlLock);
390+
memcpy(&pageno, rec, sizeof(int));
391+
sprintf(buf + strlen(buf), "zeropage: %d", pageno);
392+
}
393+
else
394+
strcat(buf, "UNKNOWN");
359395
}

src/backend/access/transam/rmgr.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Resource managers definition
55
*
6-
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.14 2004/07/21 22:31:20 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.15 2004/08/23 23:22:44 tgl Exp $
77
*/
88
#include "postgres.h"
99

@@ -12,7 +12,7 @@
1212
#include "access/heapam.h"
1313
#include "access/nbtree.h"
1414
#include "access/rtree.h"
15-
#include "access/slru.h"
15+
#include "access/clog.h"
1616
#include "access/xact.h"
1717
#include "access/xlog_internal.h"
1818
#include "storage/smgr.h"
@@ -23,7 +23,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
2323
{"XLOG", xlog_redo, xlog_undo, xlog_desc, NULL, NULL},
2424
{"Transaction", xact_redo, xact_undo, xact_desc, NULL, NULL},
2525
{"Storage", smgr_redo, smgr_undo, smgr_desc, NULL, NULL},
26-
{"SLRU", slru_redo, slru_undo, slru_desc, NULL, NULL},
26+
{"CLOG", clog_redo, clog_undo, clog_desc, NULL, NULL},
2727
{"Reserved 4", NULL, NULL, NULL, NULL, NULL},
2828
{"Reserved 5", NULL, NULL, NULL, NULL, NULL},
2929
{"Reserved 6", NULL, NULL, NULL, NULL, NULL},

0 commit comments

Comments
 (0)