kill-autovacuum.patch
text/x-diff
Filename: kill-autovacuum.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/access/transam/twophase.c | 1 | 0 |
| src/backend/bootstrap/bootstrap.c | 1 | 1 |
| src/backend/postmaster/autovacuum.c | 2 | 2 |
| src/backend/postmaster/postmaster.c | 2 | 2 |
| src/backend/storage/ipc/procarray.c | 40 | 3 |
| src/backend/storage/lmgr/proc.c | 5 | 1 |
| src/backend/tcop/postgres.c | 2 | 2 |
| src/include/storage/proc.h | 2 | 1 |
Index: src/backend/access/transam/twophase.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/transam/twophase.c,v
retrieving revision 1.26
diff -c -p -r1.26 twophase.c
*** src/backend/access/transam/twophase.c 5 Jan 2007 22:19:23 -0000 1.26
--- src/backend/access/transam/twophase.c 15 Jan 2007 19:11:15 -0000
*************** MarkAsPreparing(TransactionId xid, const
*** 280,285 ****
--- 280,286 ----
gxact->proc.databaseId = databaseid;
gxact->proc.roleId = owner;
gxact->proc.inVacuum = false;
+ gxact->proc.isAutovacuum = false;
gxact->proc.lwWaiting = false;
gxact->proc.lwExclusive = false;
gxact->proc.lwWaitLink = NULL;
Index: src/backend/bootstrap/bootstrap.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.228
diff -c -p -r1.228 bootstrap.c
*** src/backend/bootstrap/bootstrap.c 5 Jan 2007 22:19:24 -0000 1.228
--- src/backend/bootstrap/bootstrap.c 15 Jan 2007 19:08:47 -0000
*************** BootstrapMain(int argc, char *argv[])
*** 446,452 ****
/*
* Do backend-like initialization for bootstrap mode
*/
! InitProcess();
(void) InitPostgres(dbname, NULL);
/*
--- 446,452 ----
/*
* Do backend-like initialization for bootstrap mode
*/
! InitProcess(false);
(void) InitPostgres(dbname, NULL);
/*
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.30
diff -c -p -r1.30 autovacuum.c
*** src/backend/postmaster/autovacuum.c 5 Jan 2007 22:19:36 -0000 1.30
--- src/backend/postmaster/autovacuum.c 15 Jan 2007 20:20:28 -0000
*************** AutoVacMain(int argc, char *argv[])
*** 290,296 ****
* had to do some stuff with LWLocks).
*/
#ifndef EXEC_BACKEND
! InitProcess();
#endif
/*
--- 290,296 ----
* had to do some stuff with LWLocks).
*/
#ifndef EXEC_BACKEND
! InitProcess(true);
#endif
/*
*************** AutoVacMain(int argc, char *argv[])
*** 307,313 ****
EmitErrorReport();
/*
! * We can now go away. Note that because we'll call InitProcess, a
* callback will be registered to do ProcKill, which will clean up
* necessary state.
*/
--- 307,313 ----
EmitErrorReport();
/*
! * We can now go away. Note that because we called InitProcess, a
* callback will be registered to do ProcKill, which will clean up
* necessary state.
*/
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.507
diff -c -p -r1.507 postmaster.c
*** src/backend/postmaster/postmaster.c 5 Jan 2007 22:19:36 -0000 1.507
--- src/backend/postmaster/postmaster.c 15 Jan 2007 19:09:29 -0000
*************** SubPostmasterMain(int argc, char *argv[]
*** 3347,3353 ****
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! InitProcess();
/*
* Attach process to shared data structures. If testing EXEC_BACKEND
--- 3347,3353 ----
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! InitProcess(false);
/*
* Attach process to shared data structures. If testing EXEC_BACKEND
*************** SubPostmasterMain(int argc, char *argv[]
*** 3391,3397 ****
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
--- 3391,3397 ----
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
! InitProcess(true);
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
Index: src/backend/storage/ipc/procarray.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/ipc/procarray.c,v
retrieving revision 1.20
diff -c -p -r1.20 procarray.c
*** src/backend/storage/ipc/procarray.c 5 Jan 2007 22:19:38 -0000 1.20
--- src/backend/storage/ipc/procarray.c 15 Jan 2007 20:21:41 -0000
***************
*** 29,34 ****
--- 29,36 ----
*/
#include "postgres.h"
+ #include <signal.h>
+
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/xact.h"
*************** GetSnapshotData(Snapshot snapshot, bool
*** 679,684 ****
--- 681,687 ----
/*
* DatabaseHasActiveBackends -- are there any backends running in the given DB
+ * If the only process running on the database is autovacuum, try to kill it.
*
* If 'ignoreMyself' is TRUE, ignore this particular backend while checking
* for backends in the target database.
*************** GetSnapshotData(Snapshot snapshot, bool
*** 693,701 ****
bool
DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
{
! bool result = false;
ProcArrayStruct *arrayP = procArray;
int index;
LWLockAcquire(ProcArrayLock, LW_SHARED);
--- 696,711 ----
bool
DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
{
! bool result;
ProcArrayStruct *arrayP = procArray;
int index;
+ int num;
+ pid_t autovacPid;
+
+ restart:
+ num = 0;
+ autovacPid = 0;
+ result = false;
LWLockAcquire(ProcArrayLock, LW_SHARED);
*************** DatabaseHasActiveBackends(Oid databaseId
*** 708,718 ****
if (ignoreMyself && proc == MyProc)
continue;
! result = true;
! break;
}
}
LWLockRelease(ProcArrayLock);
return result;
--- 718,755 ----
if (ignoreMyself && proc == MyProc)
continue;
! /*
! * We can't hope that only autovacuum is running if there's more than
! * one process.
! */
! if (++num > 1)
! break;
!
! if (proc->isAutovacuum)
! {
! Assert(autovacPid == 0);
! autovacPid = proc->pid;
! }
}
}
+ if (num == 0)
+ {
+ /* yipee, there's nobody here */
+ result = false;
+ }
+ else if (num == 1 && autovacPid != 0)
+ {
+ /* good, there's only an autovacuum -- kill it */
+ kill(autovacPid, SIGINT);
+ LWLockRelease(ProcArrayLock);
+ pg_usleep(100 * 1000); /* 100ms */
+ goto restart;
+ }
+ else
+ /* no luck; there's a different backend */
+ result = true;
+
LWLockRelease(ProcArrayLock);
return result;
Index: src/backend/storage/lmgr/proc.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/lmgr/proc.c,v
retrieving revision 1.182
diff -c -p -r1.182 proc.c
*** src/backend/storage/lmgr/proc.c 5 Jan 2007 22:19:38 -0000 1.182
--- src/backend/storage/lmgr/proc.c 15 Jan 2007 19:59:44 -0000
*************** InitProcGlobal(void)
*** 194,202 ****
/*
* InitProcess -- initialize a per-process data structure for this backend
*/
void
! InitProcess(void)
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
--- 194,204 ----
/*
* InitProcess -- initialize a per-process data structure for this backend
+ *
+ * "autovac" is used to initialize the "isAutovacuum" PGPROC member.
*/
void
! InitProcess(bool autovac)
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
*************** InitProcess(void)
*** 258,263 ****
--- 260,266 ----
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inVacuum = false;
+ MyProc->isAutovacuum = autovac;
MyProc->lwWaiting = false;
MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL;
*************** InitDummyProcess(void)
*** 390,395 ****
--- 393,399 ----
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inVacuum = false;
+ MyProc->isAutovacuum = false;
MyProc->lwWaiting = false;
MyProc->lwExclusive = false;
MyProc->lwWaitLink = NULL;
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/tcop/postgres.c,v
retrieving revision 1.521
diff -c -p -r1.521 postgres.c
*** src/backend/tcop/postgres.c 5 Jan 2007 22:19:39 -0000 1.521
--- src/backend/tcop/postgres.c 15 Jan 2007 19:10:28 -0000
*************** PostgresMain(int argc, char *argv[], con
*** 3125,3133 ****
*/
#ifdef EXEC_BACKEND
if (!IsUnderPostmaster)
! InitProcess();
#else
! InitProcess();
#endif
/*
--- 3125,3133 ----
*/
#ifdef EXEC_BACKEND
if (!IsUnderPostmaster)
! InitProcess(false);
#else
! InitProcess(false);
#endif
/*
Index: src/include/storage/proc.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/storage/proc.h,v
retrieving revision 1.92
diff -c -p -r1.92 proc.h
*** src/include/storage/proc.h 5 Jan 2007 22:19:58 -0000 1.92
--- src/include/storage/proc.h 15 Jan 2007 19:12:12 -0000
*************** struct PGPROC
*** 75,80 ****
--- 75,81 ----
Oid roleId; /* OID of role using this backend */
bool inVacuum; /* true if current xact is a LAZY VACUUM */
+ bool isAutovacuum; /* true if it's autovacuum */
/* Info about LWLock the process is currently waiting for, if any. */
bool lwWaiting; /* true if waiting for an LW lock */
*************** extern volatile bool cancel_from_timeout
*** 136,142 ****
extern int ProcGlobalSemas(void);
extern Size ProcGlobalShmemSize(void);
extern void InitProcGlobal(void);
! extern void InitProcess(void);
extern void InitProcessPhase2(void);
extern void InitDummyProcess(void);
extern bool HaveNFreeProcs(int n);
--- 137,143 ----
extern int ProcGlobalSemas(void);
extern Size ProcGlobalShmemSize(void);
extern void InitProcGlobal(void);
! extern void InitProcess(bool autovac);
extern void InitProcessPhase2(void);
extern void InitDummyProcess(void);
extern bool HaveNFreeProcs(int n);