You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
(28) |
Jun
(12) |
Jul
(11) |
Aug
(12) |
Sep
(5) |
Oct
(19) |
Nov
(14) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(18) |
Feb
(30) |
Mar
(115) |
Apr
(89) |
May
(50) |
Jun
(44) |
Jul
(22) |
Aug
(13) |
Sep
(11) |
Oct
(30) |
Nov
(28) |
Dec
(39) |
2012 |
Jan
(38) |
Feb
(18) |
Mar
(43) |
Apr
(91) |
May
(108) |
Jun
(46) |
Jul
(37) |
Aug
(44) |
Sep
(33) |
Oct
(29) |
Nov
(36) |
Dec
(15) |
2013 |
Jan
(35) |
Feb
(611) |
Mar
(5) |
Apr
(55) |
May
(30) |
Jun
(28) |
Jul
(458) |
Aug
(34) |
Sep
(9) |
Oct
(39) |
Nov
(22) |
Dec
(32) |
2014 |
Jan
(16) |
Feb
(16) |
Mar
(42) |
Apr
(179) |
May
(7) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(4) |
Oct
|
Nov
(3) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
1
(1) |
2
|
3
(1) |
4
(1) |
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
(2) |
15
(4) |
16
(2) |
17
|
18
(1) |
19
|
20
|
21
|
22
|
23
(2) |
24
|
25
|
26
|
27
|
28
|
29
|
30
|
|
|
|
|
From: mason_s <ma...@us...> - 2010-11-01 15:36:20
|
Project "Postgres-XC". The branch, master has been updated via d62381f6e17e57fd4b3d7b51afce3032fe35507a (commit) from d7d492eaeca181add193b4705de58637f5ba7c58 (commit) - Log ----------------------------------------------------------------- commit d62381f6e17e57fd4b3d7b51afce3032fe35507a Author: Mason Sharp <ma...@us...> Date: Mon Nov 1 11:27:00 2010 -0400 Special hanlding for ANALYZE on the data nodes. Before this commit, if autovacuum executed analyze, it would get the XID from GTM, and the XID would be included in all global snapshots, even though the XID will never be involved in a transaction on the other nodes. This commit adds special handling to track these separately. They are excluded from global snapshots, and when the data node receives a snapshot, it adds any of these XIDs to the snapshot. This helps to prevent any long-running auto-analyze on a single node slowing down execution on other nodes because of a low xmin value. diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 03e6d90..d87abed 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -25,6 +25,7 @@ #ifdef PGXC #include "pgxc/pgxc.h" #include "access/gtm.h" +#include "storage/procarray.h" #endif @@ -110,7 +111,10 @@ GetNewTransactionId(bool isSubXact) * block all other processes. * GXID can just be obtained from a remote Coordinator */ - xid = (TransactionId) BeginTranGTM(timestamp); + if (IsAutoVacuumWorkerProcess() && (MyProc->vacuumFlags & PROC_IN_VACUUM)) + xid = (TransactionId) BeginTranAutovacuumGTM(); + else + xid = (TransactionId) BeginTranGTM(timestamp); *timestamp_received = true; } #endif @@ -148,20 +152,22 @@ GetNewTransactionId(bool isSubXact) if (IsAutoVacuumWorkerProcess()) { if (MyProc->vacuumFlags & PROC_IN_VACUUM) - { elog (DEBUG1, "Getting XID for autovacuum"); - /* Try and get gxid directly from GTM. - * We use a different function so that GTM knows to - * exclude it from other snapshots. - */ - next_xid = (TransactionId) BeginTranAutovacuumGTM(); - } else { elog (DEBUG1, "Getting XID for autovacuum worker (analyze)"); - /* try and get gxid directly from GTM */ - next_xid = (TransactionId) BeginTranGTM(NULL); + /* + * Acquire the Analyze array lock. + * We track ANALYZE XIDs separately and add them only to local snapshots. + */ + LWLockAcquire(AnalyzeProcArrayLock, LW_EXCLUSIVE); } + /* + * Get gxid directly from GTM. + * We use a separate function so that GTM knows to exclude it from + * other snapshots. + */ + next_xid = (TransactionId) BeginTranAutovacuumGTM(); } else if (GetForceXidFromGTM()) { @@ -328,6 +334,15 @@ GetNewTransactionId(bool isSubXact) } } +#ifdef PGXC + /* If it is auto-analyze, we need to add it to the array and unlock */ + if(IS_PGXC_DATANODE && IsAutoVacuumAnalyzeWorker()) + { + AnalyzeProcArrayAdd(MyProc); + LWLockRelease(AnalyzeProcArrayLock); + } +#endif + LWLockRelease(XidGenLock); return xid; } diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index f51672e..604d48a 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -1835,7 +1835,18 @@ CommitTransaction(void) /* If we are autovacuum, commit on GTM */ if ((IsAutoVacuumWorkerProcess() || GetForceXidFromGTM()) && IsGTMConnected()) + { + if(IsAutoVacuumAnalyzeWorker()) + LWLockAcquire(AnalyzeProcArrayLock, LW_EXCLUSIVE); + CommitTranGTM((GlobalTransactionId) latestXid); + + if(IsAutoVacuumAnalyzeWorker()) + { + AnalyzeProcArrayRemove(MyProc, latestXid); + LWLockRelease(AnalyzeProcArrayLock); + } + } } #endif @@ -2300,10 +2311,19 @@ AbortTransaction(void) } else if (IS_PGXC_DATANODE || IsConnFromCoord()) { + if(IsAutoVacuumAnalyzeWorker()) + LWLockAcquire(AnalyzeProcArrayLock, LW_EXCLUSIVE); + /* If we are autovacuum, commit on GTM */ if ((IsAutoVacuumWorkerProcess() || GetForceXidFromGTM()) && IsGTMConnected()) RollbackTranGTM((GlobalTransactionId) latestXid); + + if(IsAutoVacuumAnalyzeWorker()) + { + AnalyzeProcArrayRemove(MyProc, latestXid); + LWLockRelease(AnalyzeProcArrayLock); + } } #endif /* diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 3022867..4e57082 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -109,6 +109,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) size = add_size(size, MultiXactShmemSize()); size = add_size(size, LWLockShmemSize()); size = add_size(size, ProcArrayShmemSize()); +#ifdef PGXC + size = add_size(size, AnalyzeProcArrayShmemSize()); +#endif size = add_size(size, BackendStatusShmemSize()); size = add_size(size, SInvalShmemSize()); size = add_size(size, PMSignalShmemSize()); @@ -197,6 +200,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) if (!IsUnderPostmaster) InitProcGlobal(); CreateSharedProcArray(); +#ifdef PGXC + CreateSharedAnalyzeProcArray(); +#endif CreateSharedBackendStatus(); /* diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 7551d95..6000fdb 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -17,6 +17,14 @@ * as are the myProcLocks lists. They can be distinguished from regular * backend PGPROCs at need by checking for pid == 0. * +#ifdef PGXC + * For Postgres-XC, there is some special handling for ANALYZE. + * An XID for a local ANALYZE command will never involve other nodes. + * Also, ANALYZE may run for a long time, affecting snapshot xmin values + * on other nodes unnecessarily. We want to exclude the XID + * in global snapshots, but include it in local ones. As a result, + * these are tracked in shared memory separately. +#endif * * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California @@ -42,6 +50,7 @@ #ifdef PGXC #include "pgxc/pgxc.h" #include "access/gtm.h" +#include "storage/ipc.h" /* PGXC_DATANODE */ #include "postmaster/autovacuum.h" #endif @@ -62,6 +71,10 @@ typedef struct ProcArrayStruct static ProcArrayStruct *procArray; +#ifdef PGXC +static ProcArrayStruct *analyzeProcArray; +#endif + #ifdef XIDCACHE_DEBUG @@ -1571,6 +1584,9 @@ GetSnapshotDataDataNode(Snapshot snapshot) if ((snapshot_source == SNAPSHOT_COORDINATOR || snapshot_source == SNAPSHOT_DIRECT) && TransactionIdIsValid(gxmin)) { + int index; + ProcArrayStruct *arrayP = analyzeProcArray; + snapshot->xmin = gxmin; snapshot->xmax = gxmax; snapshot->xcnt = gxcnt; @@ -1605,6 +1621,16 @@ GetSnapshotDataDataNode(Snapshot snapshot) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); } + else if (snapshot->max_xcnt < gxcnt) + { + snapshot->xip = (TransactionId *) + realloc(snapshot->xip, gxcnt * sizeof(TransactionId)); + if (snapshot->xip == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + snapshot->max_xcnt = gxcnt; + } memcpy(snapshot->xip, gxip, gxcnt * sizeof(TransactionId)); snapshot->curcid = GetCurrentCommandId(false); @@ -1631,6 +1657,72 @@ GetSnapshotDataDataNode(Snapshot snapshot) snapshot->regd_count = 0; snapshot->copied = false; + /* + * Start of handling for local ANALYZE + * Make adjustments for any running auto ANALYZE commands + */ + LWLockAcquire(AnalyzeProcArrayLock, LW_SHARED); + + /* + * Spin over analyzeProcArray and add these local analyze XIDs to the + * local snapshot. + */ + for (index = 0; index < arrayP->numProcs; index++) + { + volatile PGPROC *proc = arrayP->procs[index]; + TransactionId xid; + + + /* Update globalxmin to be the smallest valid xmin */ + xid = proc->xmin; /* fetch just once */ + + if (TransactionIdIsNormal(xid) && + TransactionIdPrecedes(xid, RecentGlobalXmin)) + RecentGlobalXmin = xid; + + /* Fetch xid just once - see GetNewTransactionId */ + xid = proc->xid; + + /* + * If the transaction has been assigned an xid < xmax we add it to the + * snapshot, and update xmin if necessary. There's no need to store + * XIDs >= xmax, since we'll treat them as running anyway. We don't + * bother to examine their subxids either. + * + * We don't include our own XID (if any) in the snapshot, but we must + * include it into xmin. + */ + if (TransactionIdIsNormal(xid)) + { + if (TransactionIdFollowsOrEquals(xid, snapshot->xmax)) + continue; + if (proc != MyProc) + { + if (snapshot->xcnt >= snapshot->max_xcnt) + { + snapshot->max_xcnt += arrayP->numProcs; + + snapshot->xip = (TransactionId *) + realloc(snapshot->xip, snapshot->max_xcnt * sizeof(TransactionId)); + if (snapshot->xip == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + } + snapshot->xip[snapshot->xcnt++] = xid; + elog(DEBUG1, "Adding Analyze for xid %d to snapshot", proc->xid); + } + if (TransactionIdPrecedes(xid, snapshot->xmin)) + snapshot->xmin = xid; + } + } + + if (!TransactionIdIsValid(MyProc->xmin)) + MyProc->xmin = snapshot->xmin; + + LWLockRelease(AnalyzeProcArrayLock); + /* End handling of local analyze XID in snapshots */ + return true; } return false; @@ -1745,4 +1837,101 @@ GetSnapshotDataCoordinator(Snapshot snapshot) } return false; } + + +/* + * Report shared-memory space needed by CreateSharedAnalyzeProcArray. + */ +Size +AnalyzeProcArrayShmemSize(void) +{ + Size size; + + size = offsetof(ProcArrayStruct, procs); + size = add_size(size, mul_size(sizeof(PGPROC *), autovacuum_max_workers)); + + return size; +} + +/* + * Initialize the shared ANALYZE PGPROC array during postmaster startup. + */ +void +CreateSharedAnalyzeProcArray(void) +{ + bool found; + + /* Create or attach to the ProcArray shared structure */ + analyzeProcArray = (ProcArrayStruct *) + ShmemInitStruct("Analyze Proc Array", AnalyzeProcArrayShmemSize(), &found); + + if (!found) + { + /* + * We're the first - initialize. + */ + analyzeProcArray->numProcs = 0; + analyzeProcArray->maxProcs = autovacuum_max_workers; + } +} + +/* + * Add the specified PGPROC to the shared ANALYZE array. + * + * It assumes that AnalyzeProcArrayLock is already held, + * and will be held at exit. + */ +void +AnalyzeProcArrayAdd(PGPROC *proc) +{ + ProcArrayStruct *arrayP = analyzeProcArray; + + if (arrayP->numProcs >= arrayP->maxProcs) + { + /* + * Ooops, no room. (This really shouldn't happen, since there is a + * fixed supply of PGPROC structs too, and so we should have failed + * earlier.) + */ + LWLockRelease(AnalyzeProcArrayLock); + ereport(FATAL, + (errcode(ERRCODE_TOO_MANY_CONNECTIONS), + errmsg("sorry, too many analyze clients already"))); + } + + arrayP->procs[arrayP->numProcs] = proc; + arrayP->numProcs++; + + elog(DEBUG1, "Added analyze proc %p for xid %d in AnalyzeProcArray", proc, proc->xid); +} + +/* + * Remove the specified PGPROC from the shared ANALYZE array. + * We assume that AnalyzeProcArrayLock is already held, + * and it will still be held at exit + */ +void +AnalyzeProcArrayRemove(PGPROC *proc, TransactionId latestXid) +{ + ProcArrayStruct *arrayP = analyzeProcArray; + int index; + +#ifdef XIDCACHE_DEBUG + /* dump stats at backend shutdown, but not prepared-xact end */ + if (proc->pid != 0) + DisplayXidCache(); +#endif + + for (index = 0; index < arrayP->numProcs; index++) + { + if (arrayP->procs[index] == proc) + { + arrayP->procs[index] = arrayP->procs[arrayP->numProcs - 1]; + arrayP->procs[arrayP->numProcs - 1] = NULL; /* for debugging */ + arrayP->numProcs--; + elog(DEBUG1, "Removed analyze proc %p for xid %d in AnalyzeProcArray", proc, proc->xid); + return; + } + } +} #endif /* PGXC */ diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 0b918cb..9b47ff6 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -39,6 +39,9 @@ #include "access/xact.h" #include "miscadmin.h" #include "postmaster/autovacuum.h" +#ifdef PGXC +#include "pgxc/pgxc.h" +#endif #include "storage/ipc.h" #include "storage/lmgr.h" #include "storage/pmsignal.h" @@ -580,6 +583,15 @@ RemoveProcFromArray(int code, Datum arg) { Assert(MyProc != NULL); ProcArrayRemove(MyProc, InvalidTransactionId); +#ifdef PGXC + /* Remove from the analyze array */ + if (IS_PGXC_DATANODE && IsAutoVacuumAnalyzeWorker()) + { + LWLockAcquire(AnalyzeProcArrayLock, LW_EXCLUSIVE); + AnalyzeProcArrayRemove(MyProc, InvalidTransactionId); + LWLockRelease(AnalyzeProcArrayLock); + } +#endif } /* diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h index 640e973..06be483 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -17,6 +17,11 @@ #include "storage/lock.h" + +#ifdef PGXC /* PGXC_DATANODE */ +#define IsAutoVacuumAnalyzeWorker() (IsAutoVacuumWorkerProcess() && !(MyProc->vacuumFlags & PROC_IN_VACUUM)) +#endif + /* GUC variables */ extern bool autovacuum_start_daemon; extern int autovacuum_max_workers; @@ -61,8 +66,4 @@ extern void AutovacuumLauncherIAm(void); extern Size AutoVacuumShmemSize(void); extern void AutoVacuumShmemInit(void); -#ifdef PGXC /* PGXC_DATANODE */ -bool IsAutoVacuumWorkerProcess(void); -#endif - #endif /* AUTOVACUUM_H */ diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index e389c61..0548159 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -67,6 +67,9 @@ typedef enum LWLockId AutovacuumLock, AutovacuumScheduleLock, SyncScanLock, +#ifdef PGXC + AnalyzeProcArrayLock, +#endif /* Individual lock IDs end here */ FirstBufMappingLock, FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS, diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 3cc1689..f872c48 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -28,6 +28,10 @@ extern void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid); extern void ProcArrayClearTransaction(PGPROC *proc); #ifdef PGXC /* PGXC_DATANODE */ +extern Size AnalyzeProcArrayShmemSize(void); +extern void AnalyzeProcArrayAdd(PGPROC *proc); +extern void CreateSharedAnalyzeProcArray(void); +extern void AnalyzeProcArrayRemove(PGPROC *proc, TransactionId latestXid); extern void SetGlobalSnapshotData(int xmin, int xmax, int xcnt, int *xip); extern void UnsetGlobalSnapshotData(void); #endif /* PGXC */ ----------------------------------------------------------------------- Summary of changes: src/backend/access/transam/varsup.c | 35 +++++-- src/backend/access/transam/xact.c | 20 ++++ src/backend/storage/ipc/ipci.c | 6 + src/backend/storage/ipc/procarray.c | 189 +++++++++++++++++++++++++++++++++++ src/backend/storage/lmgr/proc.c | 12 ++ src/include/postmaster/autovacuum.h | 9 +- src/include/storage/lwlock.h | 3 + src/include/storage/procarray.h | 4 + 8 files changed, 264 insertions(+), 14 deletions(-) hooks/post-receive -- Postgres-XC |