Cost based vacuum delay feature.

Jan
This commit is contained in:
Jan Wieck 2004-02-06 19:36:18 +00:00
parent 687d7cf355
commit f425b605f4
9 changed files with 189 additions and 8 deletions

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.110 2004/02/03 17:34:02 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.111 2004/02/06 19:36:17 wieck Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -586,6 +586,26 @@ btbulkdelete(PG_FUNCTION_ARGS)
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
/*
* If we're called by a cost based vacuum, do the
* napping in case the balance exceeded the limit.
*/
if (VacuumCostActive && !InterruptPending &&
VacuumCostBalance >= VacuumCostLimit)
{
int msec;
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
if (msec < VacuumCostNaptime * 4)
PG_MSLEEP(msec);
else
PG_MSLEEP(VacuumCostNaptime * 4);
VacuumCostBalance = 0;
CHECK_FOR_INTERRUPTS();
}
ndeletable = 0; ndeletable = 0;
page = BufferGetPage(buf); page = BufferGetPage(buf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page);

View File

@ -31,7 +31,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.34 2004/02/03 17:34:02 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.35 2004/02/06 19:36:17 wieck Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -148,6 +148,11 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
vac_open_indexes(onerel, &nindexes, &Irel); vac_open_indexes(onerel, &nindexes, &Irel);
hasindex = (nindexes > 0); hasindex = (nindexes > 0);
/* Turn on vacuum cost accounting */
if (VacuumCostNaptime > 0)
VacuumCostActive = true;
VacuumCostBalance = 0;
/* Do the vacuuming */ /* Do the vacuuming */
lazy_scan_heap(onerel, vacrelstats, Irel, nindexes); lazy_scan_heap(onerel, vacrelstats, Irel, nindexes);
@ -168,6 +173,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
/* Update shared free space map with final free space info */ /* Update shared free space map with final free space info */
lazy_update_fsm(onerel, vacrelstats); lazy_update_fsm(onerel, vacrelstats);
/* Turn off vacuum cost accounting */
VacuumCostActive = false;
/* Update statistics in pg_class */ /* Update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages, vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages,
vacrelstats->rel_tuples, hasindex); vacrelstats->rel_tuples, hasindex);
@ -228,6 +236,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
/*
* Do the napping in a cost based vacuum.
*/
if (VacuumCostActive && !InterruptPending &&
VacuumCostBalance >= VacuumCostLimit)
{
int msec;
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
if (msec < VacuumCostNaptime * 4)
PG_MSLEEP(msec);
else
PG_MSLEEP(VacuumCostNaptime * 4);
VacuumCostBalance = 0;
CHECK_FOR_INTERRUPTS();
}
/* /*
* If we are close to overrunning the available space for * If we are close to overrunning the available space for
* dead-tuple TIDs, pause and do a cycle of vacuuming before we * dead-tuple TIDs, pause and do a cycle of vacuuming before we
@ -469,6 +496,25 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
/*
* Do the napping in a cost based vacuum.
*/
if (VacuumCostActive && !InterruptPending &&
VacuumCostBalance >= VacuumCostLimit)
{
int msec;
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
if (msec < VacuumCostNaptime * 4)
PG_MSLEEP(msec);
else
PG_MSLEEP(VacuumCostNaptime * 4);
VacuumCostBalance = 0;
CHECK_FOR_INTERRUPTS();
}
tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples[tupindex]); tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples[tupindex]);
buf = ReadBuffer(onerel, tblk); buf = ReadBuffer(onerel, tblk);
LockBufferForCleanup(buf); LockBufferForCleanup(buf);
@ -800,6 +846,25 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
/*
* Do the napping in a cost based vacuum.
*/
if (VacuumCostActive && !InterruptPending &&
VacuumCostBalance >= VacuumCostLimit)
{
int msec;
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
if (msec < VacuumCostNaptime * 4)
PG_MSLEEP(msec);
else
PG_MSLEEP(VacuumCostNaptime * 4);
VacuumCostBalance = 0;
CHECK_FOR_INTERRUPTS();
}
blkno--; blkno--;
buf = ReadBuffer(onerel, blkno); buf = ReadBuffer(onerel, blkno);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.155 2004/02/04 01:24:53 wieck Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.156 2004/02/06 19:36:18 wieck Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -576,6 +576,12 @@ write_buffer(Buffer buffer, bool release)
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE); LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
Assert(bufHdr->refcount > 0); Assert(bufHdr->refcount > 0);
/*
* If the buffer is not dirty yet, do vacuum cost accounting.
*/
if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
VacuumCostBalance += VacuumCostPageDirty;
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED); bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
if (release) if (release)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.39 2004/01/15 16:14:26 wieck Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.40 2004/02/06 19:36:18 wieck Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -31,6 +31,7 @@
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/proc.h" #include "storage/proc.h"
#include "access/xact.h" #include "access/xact.h"
#include "miscadmin.h"
#ifndef MAX #ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b))
@ -237,6 +238,12 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck)
strategy_get_from = STRAT_LIST_T2; strategy_get_from = STRAT_LIST_T2;
} }
/*
* Do the cost accounting for vacuum
*/
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageMiss;
/* report cache miss */ /* report cache miss */
return NULL; return NULL;
} }
@ -250,6 +257,8 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck)
* Count hits * Count hits
*/ */
StrategyControl->num_hit[cdb->list]++; StrategyControl->num_hit[cdb->list]++;
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageHit;
/* /*
* If this is a T2 hit, we simply move the CDB to the * If this is a T2 hit, we simply move the CDB to the

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.388 2004/02/03 17:34:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.389 2004/02/06 19:36:18 wieck Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
@ -2707,6 +2707,11 @@ PostgresMain(int argc, char *argv[], const char *username)
InError = false; InError = false;
xact_started = false; xact_started = false;
/*
* Clear flag that causes accounting for cost based vacuum.
*/
VacuumCostActive = false;
/* /*
* If we were handling an extended-query-protocol message, * If we were handling an extended-query-protocol message,
* initiate skip till next Sync. This also causes us not to issue * initiate skip till next Sync. This also causes us not to issue

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.82 2004/02/03 17:34:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.83 2004/02/06 19:36:18 wieck Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
@ -81,3 +81,11 @@ bool allowSystemTableMods = false;
int work_mem = 1024; int work_mem = 1024;
int maintenance_work_mem = 16384; int maintenance_work_mem = 16384;
int NBuffers = 1000; int NBuffers = 1000;
int VacuumCostPageHit = 1;
int VacuumCostPageMiss = 10;
int VacuumCostPageDirty = 20;
int VacuumCostLimit = 200;
int VacuumCostBalance = 0;
int VacuumCostNaptime = 0;
bool VacuumCostActive = false;

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.185 2004/02/04 01:24:53 wieck Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.186 2004/02/06 19:36:18 wieck Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
@ -1047,6 +1047,51 @@ static struct config_int ConfigureNamesInt[] =
16384, 1024, INT_MAX / 1024, NULL, NULL 16384, 1024, INT_MAX / 1024, NULL, NULL
}, },
{
{"vacuum_cost_page_hit", PGC_USERSET, RESOURCES,
gettext_noop("Vacuum cost for a page found in the buffer cache."),
NULL
},
&VacuumCostPageHit,
1, 0, 10000, NULL, NULL
},
{
{"vacuum_cost_page_miss", PGC_USERSET, RESOURCES,
gettext_noop("Vacuum cost for a page not found in the buffer cache."),
NULL
},
&VacuumCostPageMiss,
10, 0, 10000, NULL, NULL
},
{
{"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES,
gettext_noop("Vacuum cost for a page dirtied by vacuum."),
NULL
},
&VacuumCostPageDirty,
20, 0, 10000, NULL, NULL
},
{
{"vacuum_cost_limit", PGC_USERSET, RESOURCES,
gettext_noop("Vacuum cost amount available before napping."),
NULL
},
&VacuumCostLimit,
200, 1, 10000, NULL, NULL
},
{
{"vacuum_cost_naptime", PGC_USERSET, RESOURCES,
gettext_noop("Vacuum cost naptime in milliseconds."),
NULL
},
&VacuumCostNaptime,
0, 0, 1000, NULL, NULL
},
{ {
{"max_files_per_process", PGC_BACKEND, RESOURCES_KERNEL, {"max_files_per_process", PGC_BACKEND, RESOURCES_KERNEL,
gettext_noop("Sets the maximum number of simultaneously open files for each server process."), gettext_noop("Sets the maximum number of simultaneously open files for each server process."),

View File

@ -60,6 +60,12 @@
#maintenance_work_mem = 16384 # min 1024, size in KB #maintenance_work_mem = 16384 # min 1024, size in KB
#debug_shared_buffers = 0 # 0-600 seconds #debug_shared_buffers = 0 # 0-600 seconds
#vacuum_cost_page_hit = 1 # 0-10000 credits
#vacuum_cost_page_miss = 10 # 0-10000 credits
#vacuum_cost_page_dirty = 20 # 0-10000 credits
#vacuum_cost_limit = 200 # 0-10000 credits
#vacuum_cost_naptime = 50 # 0-1000 milliseconds
# - Background writer - # - Background writer -
#bgwriter_delay = 200 # 10-5000 milliseconds #bgwriter_delay = 200 # 10-5000 milliseconds
#bgwriter_percent = 1 # 0-100% of dirty buffers #bgwriter_percent = 1 # 0-100% of dirty buffers

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.150 2004/02/03 17:34:03 tgl Exp $ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.151 2004/02/06 19:36:18 wieck Exp $
* *
* NOTES * NOTES
* some of the information in this file should be moved to * some of the information in this file should be moved to
@ -106,11 +106,19 @@ do { \
delay.tv_usec = ((_usec) % 1000000); \ delay.tv_usec = ((_usec) % 1000000); \
(void) select(0, NULL, NULL, NULL, &delay); \ (void) select(0, NULL, NULL, NULL, &delay); \
} while(0) } while(0)
#define PG_MSLEEP(_msec) \
do { \
struct timeval _delay; \
_delay.tv_sec = (_msec) / 1000; \
_delay.tv_usec = ((_msec) % 1000) * 1000; \
(void) select (0, NULL, NULL, NULL, &_delay); \
} while(0)
#else #else
#define PG_USLEEP(_usec) \ #define PG_USLEEP(_usec) \
do { \ do { \
SleepEx(((_usec) < 500 ? 1 : ((_usec) + 500) / 1000), TRUE); \ SleepEx(((_usec) < 500 ? 1 : ((_usec) + 500) / 1000), TRUE); \
} while(0) } while(0)
#define PG_MSLEEP(_msec) PG_USLEEP((_msec) * 1000)
#endif #endif
#ifdef WIN32 #ifdef WIN32
@ -209,6 +217,15 @@ extern bool enableFsync;
extern bool allowSystemTableMods; extern bool allowSystemTableMods;
extern DLLIMPORT int work_mem; extern DLLIMPORT int work_mem;
extern DLLIMPORT int maintenance_work_mem; extern DLLIMPORT int maintenance_work_mem;
extern int VacuumMem;
extern int VacuumCostPageHit;
extern int VacuumCostPageMiss;
extern int VacuumCostPageDirty;
extern int VacuumCostLimit;
extern int VacuumCostBalance;
extern int VacuumCostNaptime;
extern bool VacuumCostActive;
/* /*
* A few postmaster startup options are exported here so the * A few postmaster startup options are exported here so the