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

Lines changed: 90 additions & 54 deletions
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

Lines changed: 3 additions & 3 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy