Skip to content

Commit 573a71a

Browse files
committed
Nested transactions. There is still much left to do, especially on the
performance front, but with feature freeze upon us I think it's time to drive a stake in the ground and say that this will be in 7.5. Alvaro Herrera, with some help from Tom Lane.
1 parent 4c9aa57 commit 573a71a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+4521
-1149
lines changed

contrib/userlock/user_locks.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ user_write_unlock_oid(Oid oid)
7575
int
7676
user_unlock_all(void)
7777
{
78-
return LockReleaseAll(USER_LOCKMETHOD, MyProc, false,
79-
InvalidTransactionId);
78+
return LockReleaseAll(USER_LOCKMETHOD, MyProc, ReleaseAll, 0, NULL);
8079
}
8180

8281
/* end of file */

src/backend/access/gist/gistscan.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.51 2004/01/07 18:56:23 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.52 2004/07/01 00:49:27 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -41,6 +41,7 @@ static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
4141
typedef struct GISTScanListData
4242
{
4343
IndexScanDesc gsl_scan;
44+
TransactionId gsl_creatingXid;
4445
struct GISTScanListData *gsl_next;
4546
} GISTScanListData;
4647

@@ -223,6 +224,7 @@ gistregscan(IndexScanDesc s)
223224

224225
l = (GISTScanList) palloc(sizeof(GISTScanListData));
225226
l->gsl_scan = s;
227+
l->gsl_creatingXid = GetCurrentTransactionId();
226228
l->gsl_next = GISTScans;
227229
GISTScans = l;
228230
}
@@ -271,6 +273,46 @@ AtEOXact_gist(void)
271273
GISTScans = NULL;
272274
}
273275

276+
/*
277+
* AtEOSubXact_gist() --- clean up gist subsystem at subxact abort or commit.
278+
*
279+
* This is here because it needs to touch this module's static var GISTScans.
280+
*/
281+
void
282+
AtEOSubXact_gist(TransactionId childXid)
283+
{
284+
GISTScanList l;
285+
GISTScanList prev;
286+
GISTScanList next;
287+
288+
/*
289+
* Note: these actions should only be necessary during xact abort; but
290+
* they can't hurt during a commit.
291+
*/
292+
293+
/*
294+
* Forget active scans that were started in this subtransaction.
295+
*/
296+
prev = NULL;
297+
298+
for (l = GISTScans; l != NULL; l = next)
299+
{
300+
next = l->gsl_next;
301+
if (l->gsl_creatingXid == childXid)
302+
{
303+
if (prev == NULL)
304+
GISTScans = next;
305+
else
306+
prev->gsl_next = next;
307+
308+
pfree(l);
309+
/* prev does not change */
310+
}
311+
else
312+
prev = l;
313+
}
314+
}
315+
274316
void
275317
gistadjscans(Relation rel, int op, BlockNumber blkno, OffsetNumber offnum)
276318
{

src/backend/access/hash/hashscan.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.33 2004/01/07 18:56:23 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.34 2004/07/01 00:49:29 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -21,6 +21,7 @@
2121
typedef struct HashScanListData
2222
{
2323
IndexScanDesc hashsl_scan;
24+
TransactionId hashsl_creatingXid;
2425
struct HashScanListData *hashsl_next;
2526
} HashScanListData;
2627

@@ -50,6 +51,46 @@ AtEOXact_hash(void)
5051
HashScans = NULL;
5152
}
5253

54+
/*
55+
* AtEOSubXact_hash() --- clean up hash subsystem at subxact abort or commit.
56+
*
57+
* This is here because it needs to touch this module's static var HashScans.
58+
*/
59+
void
60+
AtEOSubXact_hash(TransactionId childXid)
61+
{
62+
HashScanList l;
63+
HashScanList prev;
64+
HashScanList next;
65+
66+
/*
67+
* Note: these actions should only be necessary during xact abort; but
68+
* they can't hurt during a commit.
69+
*/
70+
71+
/*
72+
* Forget active scans that were started in this subtransaction.
73+
*/
74+
prev = NULL;
75+
76+
for (l = HashScans; l != NULL; l = next)
77+
{
78+
next = l->hashsl_next;
79+
if (l->hashsl_creatingXid == childXid)
80+
{
81+
if (prev == NULL)
82+
HashScans = next;
83+
else
84+
prev->hashsl_next = next;
85+
86+
pfree(l);
87+
/* prev does not change */
88+
}
89+
else
90+
prev = l;
91+
}
92+
}
93+
5394
/*
5495
* _Hash_regscan() -- register a new scan.
5596
*/
@@ -60,6 +101,7 @@ _hash_regscan(IndexScanDesc scan)
60101

61102
new_el = (HashScanList) palloc(sizeof(HashScanListData));
62103
new_el->hashsl_scan = scan;
104+
new_el->hashsl_creatingXid = GetCurrentTransactionId();
63105
new_el->hashsl_next = HashScans;
64106
HashScans = new_el;
65107
}

src/backend/access/rtree/rtscan.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/rtree/rtscan.c,v 1.51 2004/01/07 18:56:24 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/rtree/rtscan.c,v 1.52 2004/07/01 00:49:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -42,6 +42,7 @@ static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
4242
typedef struct RTScanListData
4343
{
4444
IndexScanDesc rtsl_scan;
45+
TransactionId rtsl_creatingXid;
4546
struct RTScanListData *rtsl_next;
4647
} RTScanListData;
4748

@@ -240,6 +241,7 @@ rtregscan(IndexScanDesc s)
240241

241242
l = (RTScanList) palloc(sizeof(RTScanListData));
242243
l->rtsl_scan = s;
244+
l->rtsl_creatingXid = GetCurrentTransactionId();
243245
l->rtsl_next = RTScans;
244246
RTScans = l;
245247
}
@@ -290,6 +292,46 @@ AtEOXact_rtree(void)
290292
RTScans = NULL;
291293
}
292294

295+
/*
296+
* AtEOSubXact_rtree() --- clean up rtree subsystem at subxact abort or commit.
297+
*
298+
* This is here because it needs to touch this module's static var RTScans.
299+
*/
300+
void
301+
AtEOSubXact_rtree(TransactionId childXid)
302+
{
303+
RTScanList l;
304+
RTScanList prev;
305+
RTScanList next;
306+
307+
/*
308+
* Note: these actions should only be necessary during xact abort; but
309+
* they can't hurt during a commit.
310+
*/
311+
312+
/*
313+
* Forget active scans that were started in this subtransaction.
314+
*/
315+
prev = NULL;
316+
317+
for (l = RTScans; l != NULL; l = next)
318+
{
319+
next = l->rtsl_next;
320+
if (l->rtsl_creatingXid == childXid)
321+
{
322+
if (prev == NULL)
323+
RTScans = next;
324+
else
325+
prev->rtsl_next = next;
326+
327+
pfree(l);
328+
/* prev does not change */
329+
}
330+
else
331+
prev = l;
332+
}
333+
}
334+
293335
void
294336
rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
295337
{

src/backend/access/transam/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
# Makefile for access/transam
55
#
66
# IDENTIFICATION
7-
# $PostgreSQL: pgsql/src/backend/access/transam/Makefile,v 1.18 2003/11/29 19:51:40 pgsql Exp $
7+
# $PostgreSQL: pgsql/src/backend/access/transam/Makefile,v 1.19 2004/07/01 00:49:42 tgl Exp $
88
#
99
#-------------------------------------------------------------------------
1010

1111
subdir = src/backend/access/transam
1212
top_builddir = ../../../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
OBJS = clog.o transam.o varsup.o xact.o xlog.o xlogutils.o rmgr.o slru.o
15+
OBJS = clog.o transam.o varsup.o xact.o xlog.o xlogutils.o rmgr.o slru.o subtrans.o
1616

1717
all: SUBSYS.o
1818

src/backend/access/transam/clog.c

Lines changed: 21 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,21 @@
1313
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.20 2004/05/31 03:47:54 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.21 2004/07/01 00:49:42 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
2020
#include "postgres.h"
2121

2222
#include <fcntl.h>
2323
#include <dirent.h>
24-
#include <errno.h>
2524
#include <sys/stat.h>
2625
#include <unistd.h>
2726

2827
#include "access/clog.h"
2928
#include "access/slru.h"
30-
#include "storage/lwlock.h"
3129
#include "miscadmin.h"
30+
#include "storage/lwlock.h"
3231

3332

3433
/*
@@ -65,7 +64,7 @@
6564
* is guaranteed flushed through the XLOG commit record before we are called
6665
* to log a commit, so the WAL rule "write xlog before data" is satisfied
6766
* automatically for commits, and we don't really care for aborts. Therefore,
68-
* we don't need to mark XLOG pages with LSN information; we have enough
67+
* we don't need to mark CLOG pages with LSN information; we have enough
6968
* synchronization already.
7069
*----------
7170
*/
@@ -95,20 +94,22 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
9594
char *byteptr;
9695

9796
Assert(status == TRANSACTION_STATUS_COMMITTED ||
98-
status == TRANSACTION_STATUS_ABORTED);
97+
status == TRANSACTION_STATUS_ABORTED ||
98+
status == TRANSACTION_STATUS_SUB_COMMITTED);
9999

100100
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
101101

102102
byteptr = SimpleLruReadPage(ClogCtl, pageno, xid, true);
103103
byteptr += byteno;
104104

105-
/* Current state should be 0 or target state */
105+
/* Current state should be 0, subcommitted or target state */
106106
Assert(((*byteptr >> bshift) & CLOG_XACT_BITMASK) == 0 ||
107+
((*byteptr >> bshift) & CLOG_XACT_BITMASK) == TRANSACTION_STATUS_SUB_COMMITTED ||
107108
((*byteptr >> bshift) & CLOG_XACT_BITMASK) == status);
108109

109110
*byteptr |= (status << bshift);
110111

111-
/* ...->page_status[slotno] = CLOG_PAGE_DIRTY; already done */
112+
/* ...->page_status[slotno] = SLRU_PAGE_DIRTY; already done */
112113

113114
LWLockRelease(ClogCtl->ControlLock);
114115
}
@@ -117,7 +118,7 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
117118
* Interrogate the state of a transaction in the commit log.
118119
*
119120
* NB: this is a low-level routine and is NOT the preferred entry point
120-
* for most uses; TransactionLogTest() in transam.c is the intended caller.
121+
* for most uses; TransactionLogFetch() in transam.c is the intended caller.
121122
*/
122123
XidStatus
123124
TransactionIdGetStatus(TransactionId xid)
@@ -176,7 +177,7 @@ BootStrapCLOG(void)
176177

177178
/* Make sure it's written out */
178179
SimpleLruWritePage(ClogCtl, slotno, NULL);
179-
/* Assert(ClogCtl->page_status[slotno] == CLOG_PAGE_CLEAN); */
180+
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */
180181

181182
LWLockRelease(ClogCtl->ControlLock);
182183
}
@@ -211,7 +212,8 @@ StartupCLOG(void)
211212
/*
212213
* Initialize our idea of the latest page number.
213214
*/
214-
SimpleLruSetLatestPage(ClogCtl, TransactionIdToPage(ShmemVariableCache->nextXid));
215+
SimpleLruSetLatestPage(ClogCtl,
216+
TransactionIdToPage(ShmemVariableCache->nextXid));
215217
}
216218

217219
/*
@@ -333,51 +335,20 @@ WriteZeroPageXlogRec(int pageno)
333335
rdata.data = (char *) (&pageno);
334336
rdata.len = sizeof(int);
335337
rdata.next = NULL;
336-
(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
337-
}
338-
339-
/*
340-
* CLOG resource manager's routines
341-
*/
342-
void
343-
clog_redo(XLogRecPtr lsn, XLogRecord *record)
344-
{
345-
uint8 info = record->xl_info & ~XLR_INFO_MASK;
346-
347-
if (info == CLOG_ZEROPAGE)
348-
{
349-
int pageno;
350-
int slotno;
351-
352-
memcpy(&pageno, XLogRecGetData(record), sizeof(int));
353-
354-
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
355-
356-
slotno = ZeroCLOGPage(pageno, false);
357-
SimpleLruWritePage(ClogCtl, slotno, NULL);
358-
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */
359-
360-
LWLockRelease(ClogCtl->ControlLock);
361-
}
338+
(void) XLogInsert(RM_SLRU_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
362339
}
363340

341+
/* Redo a ZEROPAGE action during WAL replay */
364342
void
365-
clog_undo(XLogRecPtr lsn, XLogRecord *record)
343+
clog_zeropage_redo(int pageno)
366344
{
367-
}
345+
int slotno;
368346

369-
void
370-
clog_desc(char *buf, uint8 xl_info, char *rec)
371-
{
372-
uint8 info = xl_info & ~XLR_INFO_MASK;
347+
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE);
373348

374-
if (info == CLOG_ZEROPAGE)
375-
{
376-
int pageno;
349+
slotno = ZeroCLOGPage(pageno, false);
350+
SimpleLruWritePage(ClogCtl, slotno, NULL);
351+
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */
377352

378-
memcpy(&pageno, rec, sizeof(int));
379-
sprintf(buf + strlen(buf), "zeropage: %d", pageno);
380-
}
381-
else
382-
strcat(buf, "UNKNOWN");
353+
LWLockRelease(ClogCtl->ControlLock);
383354
}

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