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

Commit92c2ecc

Browse files
committed
Modify snapshot definition so that lazy vacuums are ignored by other
vacuums. This allows a OLTP-like system with big tables to continueregular vacuuming on small-but-frequently-updated tables while thebig tables are being vacuumed.Original patch from Hannu Krossing, rewritten by Tom Lane and updatedby me.
1 parentd660379 commit92c2ecc

File tree

9 files changed

+99
-28
lines changed

9 files changed

+99
-28
lines changed

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

Lines changed: 2 additions & 1 deletion
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.21 2006/07/14 14:52:17 momjian Exp $
10+
*$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.22 2006/07/30 02:07:18 alvherre Exp $
1111
*
1212
* NOTES
1313
*Each global transaction is associated with a global transaction
@@ -279,6 +279,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
279279
gxact->proc.pid=0;
280280
gxact->proc.databaseId=databaseid;
281281
gxact->proc.roleId=owner;
282+
gxact->proc.inVacuum= false;
282283
gxact->proc.lwWaiting= false;
283284
gxact->proc.lwExclusive= false;
284285
gxact->proc.lwWaitLink=NULL;

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

Lines changed: 4 additions & 1 deletion
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.224 2006/07/24 16:32:44 petere Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.225 2006/07/30 02:07:18 alvherre Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1529,6 +1529,7 @@ CommitTransaction(void)
15291529
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
15301530
MyProc->xid=InvalidTransactionId;
15311531
MyProc->xmin=InvalidTransactionId;
1532+
MyProc->inVacuum= false;/* must be cleared with xid/xmin */
15321533

15331534
/* Clear the subtransaction-XID cache too while holding the lock */
15341535
MyProc->subxids.nxids=0;
@@ -1764,6 +1765,7 @@ PrepareTransaction(void)
17641765
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
17651766
MyProc->xid=InvalidTransactionId;
17661767
MyProc->xmin=InvalidTransactionId;
1768+
MyProc->inVacuum= false;/* must be cleared with xid/xmin */
17671769

17681770
/* Clear the subtransaction-XID cache too while holding the lock */
17691771
MyProc->subxids.nxids=0;
@@ -1927,6 +1929,7 @@ AbortTransaction(void)
19271929
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
19281930
MyProc->xid=InvalidTransactionId;
19291931
MyProc->xmin=InvalidTransactionId;
1932+
MyProc->inVacuum= false;/* must be cleared with xid/xmin */
19301933

19311934
/* Clear the subtransaction-XID cache too while holding the lock */
19321935
MyProc->subxids.nxids=0;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, 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.244 2006/07/14 14:52:17 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.245 2006/07/30 02:07:18 alvherre Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -5413,7 +5413,7 @@ CreateCheckPoint(bool shutdown, bool force)
54135413
* StartupSUBTRANS hasn't been called yet.
54145414
*/
54155415
if (!InRecovery)
5416-
TruncateSUBTRANS(GetOldestXmin(true));
5416+
TruncateSUBTRANS(GetOldestXmin(true, false));
54175417

54185418
if (!shutdown)
54195419
ereport(DEBUG2,

‎src/backend/catalog/index.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.269 2006/07/13 16:49:13 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.270 2006/07/30 02:07:18 alvherre Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1367,7 +1367,8 @@ IndexBuildHeapScan(Relation heapRelation,
13671367
else
13681368
{
13691369
snapshot=SnapshotAny;
1370-
OldestXmin=GetOldestXmin(heapRelation->rd_rel->relisshared);
1370+
/* okay to ignore lazy VACUUMs here */
1371+
OldestXmin=GetOldestXmin(heapRelation->rd_rel->relisshared, true);
13711372
}
13721373

13731374
scan=heap_beginscan(heapRelation,/* relation */

‎src/backend/commands/vacuum.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.335 2006/07/14 14:52:18momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.336 2006/07/30 02:07:18alvherre Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -37,6 +37,7 @@
3737
#include"postmaster/autovacuum.h"
3838
#include"storage/freespace.h"
3939
#include"storage/pmsignal.h"
40+
#include"storage/proc.h"
4041
#include"storage/procarray.h"
4142
#include"utils/acl.h"
4243
#include"utils/builtins.h"
@@ -589,7 +590,16 @@ vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
589590
{
590591
TransactionIdlimit;
591592

592-
*oldestXmin=GetOldestXmin(sharedRel);
593+
/*
594+
* We can always ignore processes running lazy vacuum. This is because we
595+
* use these values only for deciding which tuples we must keep in the
596+
* tables. Since lazy vacuum doesn't write its xid to the table, it's
597+
* safe to ignore it. In theory it could be problematic to ignore lazy
598+
* vacuums on a full vacuum, but keep in mind that only one vacuum process
599+
* can be working on a particular table at any time, and that each vacuum
600+
* is always an independent transaction.
601+
*/
602+
*oldestXmin=GetOldestXmin(sharedRel, true);
593603

594604
Assert(TransactionIdIsNormal(*oldestXmin));
595605

@@ -645,6 +655,11 @@ vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
645655
*pg_class would've been obsoleted. Of course, this only works for
646656
*fixed-size never-null columns, but these are.
647657
*
658+
*Another reason for doing it this way is that when we are in a lazy
659+
*VACUUM and have inVacuum set, we mustn't do any updates --- somebody
660+
*vacuuming pg_class might think they could delete a tuple marked with
661+
*xmin = our xid.
662+
*
648663
*This routine is shared by full VACUUM, lazy VACUUM, and stand-alone
649664
*ANALYZE.
650665
*/
@@ -996,8 +1011,35 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
9961011

9971012
/* Begin a transaction for vacuuming this relation */
9981013
StartTransactionCommand();
999-
/* functions in indexes may want a snapshot set */
1000-
ActiveSnapshot=CopySnapshot(GetTransactionSnapshot());
1014+
1015+
if (vacstmt->full)
1016+
{
1017+
/* functions in indexes may want a snapshot set */
1018+
ActiveSnapshot=CopySnapshot(GetTransactionSnapshot());
1019+
}
1020+
else
1021+
{
1022+
/*
1023+
* During a lazy VACUUM we do not run any user-supplied functions,
1024+
* and so it should be safe to not create a transaction snapshot.
1025+
*
1026+
* We can furthermore set the inVacuum flag, which lets other
1027+
* concurrent VACUUMs know that they can ignore this one while
1028+
* determining their OldestXmin. (The reason we don't set inVacuum
1029+
* during a full VACUUM is exactly that we may have to run user-
1030+
* defined functions for functional indexes, and we want to make
1031+
* sure that if they use the snapshot set above, any tuples it
1032+
* requires can't get removed from other tables. An index function
1033+
* that depends on the contents of other tables is arguably broken,
1034+
* but we won't break it here by violating transaction semantics.)
1035+
*
1036+
* Note: the inVacuum flag remains set until CommitTransaction or
1037+
* AbortTransaction. We don't want to clear it until we reset
1038+
* MyProc->xid/xmin, else OldestXmin might appear to go backwards,
1039+
* which is probably Not Good.
1040+
*/
1041+
MyProc->inVacuum= true;
1042+
}
10011043

10021044
/*
10031045
* Tell the cache replacement strategy that vacuum is causing all

‎src/backend/storage/ipc/procarray.c

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
*
2525
* IDENTIFICATION
26-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.14 2006/07/14 14:52:22 momjian Exp $
26+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.15 2006/07/30 02:07:18 alvherre Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -388,20 +388,24 @@ TransactionIdIsActive(TransactionId xid)
388388
* If allDbs is TRUE then all backends are considered; if allDbs is FALSE
389389
* then only backends running in my own database are considered.
390390
*
391+
* If ignoreVacuum is TRUE then backends with inVacuum set are ignored.
392+
*
391393
* This is used by VACUUM to decide which deleted tuples must be preserved
392394
* in a table.allDbs = TRUE is needed for shared relations, but allDbs =
393395
* FALSE is sufficient for non-shared relations, since only backends in my
394-
* own database could ever see the tuples in them.
396+
* own database could ever see the tuples in them. Also, we can ignore
397+
* concurrently running lazy VACUUMs because (a) they must be working on other
398+
* tables, and (b) they don't need to do snapshot-based lookups.
395399
*
396400
* This is also used to determine where to truncate pg_subtrans. allDbs
397-
* must be TRUE for that case.
401+
* must be TRUE for that case, and ignoreVacuum FALSE.
398402
*
399403
* Note: we include the currently running xids in the set of considered xids.
400404
* This ensures that if a just-started xact has not yet set its snapshot,
401405
* when it does set the snapshot it cannot set xmin less than what we compute.
402406
*/
403407
TransactionId
404-
GetOldestXmin(boolallDbs)
408+
GetOldestXmin(boolallDbs,boolignoreVacuum)
405409
{
406410
ProcArrayStruct*arrayP=procArray;
407411
TransactionIdresult;
@@ -425,15 +429,28 @@ GetOldestXmin(bool allDbs)
425429
{
426430
PGPROC*proc=arrayP->procs[index];
427431

432+
if (ignoreVacuum&&proc->inVacuum)
433+
continue;
434+
428435
if (allDbs||proc->databaseId==MyDatabaseId)
429436
{
430437
/* Fetch xid just once - see GetNewTransactionId */
431438
TransactionIdxid=proc->xid;
432439

433440
if (TransactionIdIsNormal(xid))
434441
{
442+
/* First consider the transaction own's Xid */
435443
if (TransactionIdPrecedes(xid,result))
436444
result=xid;
445+
446+
/*
447+
* Also consider the transaction's Xmin, if set.
448+
*
449+
* Note that this Xmin may seem to be guaranteed to be always
450+
* lower than the transaction's Xid, but this is not so because
451+
* there is a time window on which the Xid is already assigned
452+
* but the Xmin has not being calculated yet.
453+
*/
437454
xid=proc->xmin;
438455
if (TransactionIdIsNormal(xid))
439456
if (TransactionIdPrecedes(xid,result))
@@ -471,8 +488,8 @@ GetOldestXmin(bool allDbs)
471488
*RecentXmin: the xmin computed for the most recent snapshot. XIDs
472489
*older than this are known not running any more.
473490
*RecentGlobalXmin: the global xmin (oldest TransactionXmin across all
474-
*running transactions).This is the same computation done by
475-
*GetOldestXmin(TRUE).
491+
*running transactions, except those running LAZY VACUUM). This is
492+
*the same computation done byGetOldestXmin(true, false).
476493
*----------
477494
*/
478495
Snapshot
@@ -561,15 +578,17 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
561578

562579
/*
563580
* Ignore my own proc (dealt with my xid above), procs not running a
564-
* transaction, and xacts started since we read the next transaction
565-
* ID.There's no need to store XIDs above what we got from
566-
* ReadNewTransactionId, since we'll treat them as running anyway. We
567-
* also assume that such xacts can't compute an xmin older than ours,
568-
* so they needn't be considered in computing globalxmin.
581+
* transaction, xacts started since we read the next transaction
582+
* ID, and xacts executing LAZY VACUUM.There's no need to store XIDs
583+
* above what we got from ReadNewTransactionId, since we'll treat them
584+
* as running anyway. We also assume that such xacts can't compute an
585+
* xmin older than ours, so they needn't be considered in computing
586+
* globalxmin.
569587
*/
570588
if (proc==MyProc||
571589
!TransactionIdIsNormal(xid)||
572-
TransactionIdFollowsOrEquals(xid,xmax))
590+
TransactionIdFollowsOrEquals(xid,xmax)||
591+
proc->inVacuum)
573592
continue;
574593

575594
if (TransactionIdPrecedes(xid,xmin))

‎src/backend/storage/lmgr/proc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.178 2006/07/23 23:08:46 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.179 2006/07/30 02:07:18 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -257,6 +257,7 @@ InitProcess(void)
257257
/* databaseId and roleId will be filled in later */
258258
MyProc->databaseId=InvalidOid;
259259
MyProc->roleId=InvalidOid;
260+
MyProc->inVacuum= false;
260261
MyProc->lwWaiting= false;
261262
MyProc->lwExclusive= false;
262263
MyProc->lwWaitLink=NULL;
@@ -388,6 +389,7 @@ InitDummyProcess(void)
388389
MyProc->xmin=InvalidTransactionId;
389390
MyProc->databaseId=InvalidOid;
390391
MyProc->roleId=InvalidOid;
392+
MyProc->inVacuum= false;
391393
MyProc->lwWaiting= false;
392394
MyProc->lwExclusive= false;
393395
MyProc->lwWaitLink=NULL;

‎src/include/storage/proc.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.89 2006/07/13 16:49:20 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.90 2006/07/30 02:07:18 alvherre Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -66,13 +66,16 @@ struct PGPROC
6666
* this proc */
6767

6868
TransactionIdxmin;/* minimal running XID as it was when we were
69-
* starting our xact: vacuum must not remove
70-
* tuples deleted by xid >= xmin ! */
69+
* starting our xact, excluding LAZY VACUUM:
70+
* vacuum must not remove tuples deleted by
71+
* xid >= xmin ! */
7172

7273
intpid;/* This backend's process id, or 0 */
7374
OiddatabaseId;/* OID of database this backend is using */
7475
OidroleId;/* OID of role using this backend */
7576

77+
boolinVacuum;/* true if current xact is a LAZY VACUUM */
78+
7679
/* Info about LWLock the process is currently waiting for, if any. */
7780
boollwWaiting;/* true if waiting for an LW lock */
7881
boollwExclusive;/* true if waiting for exclusive access */

‎src/include/storage/procarray.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.9 2006/06/19 01:51:22 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.10 2006/07/30 02:07:18 alvherre Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -24,7 +24,7 @@ extern void ProcArrayRemove(PGPROC *proc);
2424

2525
externboolTransactionIdIsInProgress(TransactionIdxid);
2626
externboolTransactionIdIsActive(TransactionIdxid);
27-
externTransactionIdGetOldestXmin(boolallDbs);
27+
externTransactionIdGetOldestXmin(boolallDbs,boolignoreVacuum);
2828

2929
externPGPROC*BackendPidGetProc(intpid);
3030
externintBackendXidGetPid(TransactionIdxid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp