Skip to content

Commit f425b60

Browse files
Jan WieckJan Wieck
authored andcommitted
Cost based vacuum delay feature.
Jan
1 parent 687d7cf commit f425b60

File tree

9 files changed

+189
-8
lines changed

9 files changed

+189
-8
lines changed

src/backend/access/nbtree/nbtree.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.110 2004/02/03 17:34:02 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.111 2004/02/06 19:36:17 wieck Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -586,6 +586,26 @@ btbulkdelete(PG_FUNCTION_ARGS)
586586

587587
CHECK_FOR_INTERRUPTS();
588588

589+
/*
590+
* If we're called by a cost based vacuum, do the
591+
* napping in case the balance exceeded the limit.
592+
*/
593+
if (VacuumCostActive && !InterruptPending &&
594+
VacuumCostBalance >= VacuumCostLimit)
595+
{
596+
int msec;
597+
598+
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
599+
if (msec < VacuumCostNaptime * 4)
600+
PG_MSLEEP(msec);
601+
else
602+
PG_MSLEEP(VacuumCostNaptime * 4);
603+
604+
VacuumCostBalance = 0;
605+
606+
CHECK_FOR_INTERRUPTS();
607+
}
608+
589609
ndeletable = 0;
590610
page = BufferGetPage(buf);
591611
opaque = (BTPageOpaque) PageGetSpecialPointer(page);

src/backend/commands/vacuumlazy.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
*
3232
*
3333
* IDENTIFICATION
34-
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.34 2004/02/03 17:34:02 tgl Exp $
34+
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.35 2004/02/06 19:36:17 wieck Exp $
3535
*
3636
*-------------------------------------------------------------------------
3737
*/
@@ -148,6 +148,11 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
148148
vac_open_indexes(onerel, &nindexes, &Irel);
149149
hasindex = (nindexes > 0);
150150

151+
/* Turn on vacuum cost accounting */
152+
if (VacuumCostNaptime > 0)
153+
VacuumCostActive = true;
154+
VacuumCostBalance = 0;
155+
151156
/* Do the vacuuming */
152157
lazy_scan_heap(onerel, vacrelstats, Irel, nindexes);
153158

@@ -168,6 +173,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
168173
/* Update shared free space map with final free space info */
169174
lazy_update_fsm(onerel, vacrelstats);
170175

176+
/* Turn off vacuum cost accounting */
177+
VacuumCostActive = false;
178+
171179
/* Update statistics in pg_class */
172180
vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages,
173181
vacrelstats->rel_tuples, hasindex);
@@ -228,6 +236,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
228236

229237
CHECK_FOR_INTERRUPTS();
230238

239+
/*
240+
* Do the napping in a cost based vacuum.
241+
*/
242+
if (VacuumCostActive && !InterruptPending &&
243+
VacuumCostBalance >= VacuumCostLimit)
244+
{
245+
int msec;
246+
247+
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
248+
if (msec < VacuumCostNaptime * 4)
249+
PG_MSLEEP(msec);
250+
else
251+
PG_MSLEEP(VacuumCostNaptime * 4);
252+
253+
VacuumCostBalance = 0;
254+
255+
CHECK_FOR_INTERRUPTS();
256+
}
257+
231258
/*
232259
* If we are close to overrunning the available space for
233260
* dead-tuple TIDs, pause and do a cycle of vacuuming before we
@@ -469,6 +496,25 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
469496

470497
CHECK_FOR_INTERRUPTS();
471498

499+
/*
500+
* Do the napping in a cost based vacuum.
501+
*/
502+
if (VacuumCostActive && !InterruptPending &&
503+
VacuumCostBalance >= VacuumCostLimit)
504+
{
505+
int msec;
506+
507+
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
508+
if (msec < VacuumCostNaptime * 4)
509+
PG_MSLEEP(msec);
510+
else
511+
PG_MSLEEP(VacuumCostNaptime * 4);
512+
513+
VacuumCostBalance = 0;
514+
515+
CHECK_FOR_INTERRUPTS();
516+
}
517+
472518
tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples[tupindex]);
473519
buf = ReadBuffer(onerel, tblk);
474520
LockBufferForCleanup(buf);
@@ -800,6 +846,25 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
800846

801847
CHECK_FOR_INTERRUPTS();
802848

849+
/*
850+
* Do the napping in a cost based vacuum.
851+
*/
852+
if (VacuumCostActive && !InterruptPending &&
853+
VacuumCostBalance >= VacuumCostLimit)
854+
{
855+
int msec;
856+
857+
msec = VacuumCostNaptime * VacuumCostBalance / VacuumCostLimit;
858+
if (msec < VacuumCostNaptime * 4)
859+
PG_MSLEEP(msec);
860+
else
861+
PG_MSLEEP(VacuumCostNaptime * 4);
862+
863+
VacuumCostBalance = 0;
864+
865+
CHECK_FOR_INTERRUPTS();
866+
}
867+
803868
blkno--;
804869

805870
buf = ReadBuffer(onerel, blkno);

src/backend/storage/buffer/bufmgr.c

Lines changed: 7 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/buffer/bufmgr.c,v 1.155 2004/02/04 01:24:53 wieck Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.156 2004/02/06 19:36:18 wieck Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -576,6 +576,12 @@ write_buffer(Buffer buffer, bool release)
576576
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
577577
Assert(bufHdr->refcount > 0);
578578

579+
/*
580+
* If the buffer is not dirty yet, do vacuum cost accounting.
581+
*/
582+
if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
583+
VacuumCostBalance += VacuumCostPageDirty;
584+
579585
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
580586

581587
if (release)

src/backend/storage/buffer/freelist.c

Lines changed: 10 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/buffer/freelist.c,v 1.39 2004/01/15 16:14:26 wieck Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.40 2004/02/06 19:36:18 wieck Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,6 +31,7 @@
3131
#include "storage/ipc.h"
3232
#include "storage/proc.h"
3333
#include "access/xact.h"
34+
#include "miscadmin.h"
3435

3536
#ifndef MAX
3637
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -237,6 +238,12 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck)
237238
strategy_get_from = STRAT_LIST_T2;
238239
}
239240

241+
/*
242+
* Do the cost accounting for vacuum
243+
*/
244+
if (VacuumCostActive)
245+
VacuumCostBalance += VacuumCostPageMiss;
246+
240247
/* report cache miss */
241248
return NULL;
242249
}
@@ -250,6 +257,8 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck)
250257
* Count hits
251258
*/
252259
StrategyControl->num_hit[cdb->list]++;
260+
if (VacuumCostActive)
261+
VacuumCostBalance += VacuumCostPageHit;
253262

254263
/*
255264
* If this is a T2 hit, we simply move the CDB to the

src/backend/tcop/postgres.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.388 2004/02/03 17:34:03 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.389 2004/02/06 19:36:18 wieck Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -2707,6 +2707,11 @@ PostgresMain(int argc, char *argv[], const char *username)
27072707
InError = false;
27082708
xact_started = false;
27092709

2710+
/*
2711+
* Clear flag that causes accounting for cost based vacuum.
2712+
*/
2713+
VacuumCostActive = false;
2714+
27102715
/*
27112716
* If we were handling an extended-query-protocol message,
27122717
* initiate skip till next Sync. This also causes us not to issue

src/backend/utils/init/globals.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.82 2004/02/03 17:34:03 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.83 2004/02/06 19:36:18 wieck Exp $
1212
*
1313
* NOTES
1414
* Globals used all over the place should be declared here and not
@@ -81,3 +81,11 @@ bool allowSystemTableMods = false;
8181
int work_mem = 1024;
8282
int maintenance_work_mem = 16384;
8383
int NBuffers = 1000;
84+
85+
int VacuumCostPageHit = 1;
86+
int VacuumCostPageMiss = 10;
87+
int VacuumCostPageDirty = 20;
88+
int VacuumCostLimit = 200;
89+
int VacuumCostBalance = 0;
90+
int VacuumCostNaptime = 0;
91+
bool VacuumCostActive = false;

src/backend/utils/misc/guc.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.185 2004/02/04 01:24:53 wieck Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.186 2004/02/06 19:36:18 wieck Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -1047,6 +1047,51 @@ static struct config_int ConfigureNamesInt[] =
10471047
16384, 1024, INT_MAX / 1024, NULL, NULL
10481048
},
10491049

1050+
{
1051+
{"vacuum_cost_page_hit", PGC_USERSET, RESOURCES,
1052+
gettext_noop("Vacuum cost for a page found in the buffer cache."),
1053+
NULL
1054+
},
1055+
&VacuumCostPageHit,
1056+
1, 0, 10000, NULL, NULL
1057+
},
1058+
1059+
{
1060+
{"vacuum_cost_page_miss", PGC_USERSET, RESOURCES,
1061+
gettext_noop("Vacuum cost for a page not found in the buffer cache."),
1062+
NULL
1063+
},
1064+
&VacuumCostPageMiss,
1065+
10, 0, 10000, NULL, NULL
1066+
},
1067+
1068+
{
1069+
{"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES,
1070+
gettext_noop("Vacuum cost for a page dirtied by vacuum."),
1071+
NULL
1072+
},
1073+
&VacuumCostPageDirty,
1074+
20, 0, 10000, NULL, NULL
1075+
},
1076+
1077+
{
1078+
{"vacuum_cost_limit", PGC_USERSET, RESOURCES,
1079+
gettext_noop("Vacuum cost amount available before napping."),
1080+
NULL
1081+
},
1082+
&VacuumCostLimit,
1083+
200, 1, 10000, NULL, NULL
1084+
},
1085+
1086+
{
1087+
{"vacuum_cost_naptime", PGC_USERSET, RESOURCES,
1088+
gettext_noop("Vacuum cost naptime in milliseconds."),
1089+
NULL
1090+
},
1091+
&VacuumCostNaptime,
1092+
0, 0, 1000, NULL, NULL
1093+
},
1094+
10501095
{
10511096
{"max_files_per_process", PGC_BACKEND, RESOURCES_KERNEL,
10521097
gettext_noop("Sets the maximum number of simultaneously open files for each server process."),

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
#maintenance_work_mem = 16384 # min 1024, size in KB
6161
#debug_shared_buffers = 0 # 0-600 seconds
6262

63+
#vacuum_cost_page_hit = 1 # 0-10000 credits
64+
#vacuum_cost_page_miss = 10 # 0-10000 credits
65+
#vacuum_cost_page_dirty = 20 # 0-10000 credits
66+
#vacuum_cost_limit = 200 # 0-10000 credits
67+
#vacuum_cost_naptime = 50 # 0-1000 milliseconds
68+
6369
# - Background writer -
6470
#bgwriter_delay = 200 # 10-5000 milliseconds
6571
#bgwriter_percent = 1 # 0-100% of dirty buffers

src/include/miscadmin.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.150 2004/02/03 17:34:03 tgl Exp $
15+
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.151 2004/02/06 19:36:18 wieck Exp $
1616
*
1717
* NOTES
1818
* some of the information in this file should be moved to
@@ -106,11 +106,19 @@ do { \
106106
delay.tv_usec = ((_usec) % 1000000); \
107107
(void) select(0, NULL, NULL, NULL, &delay); \
108108
} while(0)
109+
#define PG_MSLEEP(_msec) \
110+
do { \
111+
struct timeval _delay; \
112+
_delay.tv_sec = (_msec) / 1000; \
113+
_delay.tv_usec = ((_msec) % 1000) * 1000; \
114+
(void) select (0, NULL, NULL, NULL, &_delay); \
115+
} while(0)
109116
#else
110117
#define PG_USLEEP(_usec) \
111118
do { \
112119
SleepEx(((_usec) < 500 ? 1 : ((_usec) + 500) / 1000), TRUE); \
113120
} while(0)
121+
#define PG_MSLEEP(_msec) PG_USLEEP((_msec) * 1000)
114122
#endif
115123

116124
#ifdef WIN32
@@ -209,6 +217,15 @@ extern bool enableFsync;
209217
extern bool allowSystemTableMods;
210218
extern DLLIMPORT int work_mem;
211219
extern DLLIMPORT int maintenance_work_mem;
220+
extern int VacuumMem;
221+
222+
extern int VacuumCostPageHit;
223+
extern int VacuumCostPageMiss;
224+
extern int VacuumCostPageDirty;
225+
extern int VacuumCostLimit;
226+
extern int VacuumCostBalance;
227+
extern int VacuumCostNaptime;
228+
extern bool VacuumCostActive;
212229

213230
/*
214231
* A few postmaster startup options are exported here so the

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