mirror of https://github.com/postgres/postgres
First non-stub implementation of shared free space map. It's not super
useful as yet, since its primary source of information is (full) VACUUM, which makes a concerted effort to get rid of free space before telling the map about it ... next stop is concurrent VACUUM ...
This commit is contained in:
parent
755e367cb2
commit
42748087c1
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.75 2001/06/12 05:55:49 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.76 2001/07/02 20:50:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +30,8 @@
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "storage/sinval.h" /* for DatabaseHasActiveBackends */
|
#include "storage/freespace.h"
|
||||||
|
#include "storage/sinval.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
@ -372,6 +373,11 @@ dropdb(const char *dbname)
|
||||||
*/
|
*/
|
||||||
DropBuffers(db_id);
|
DropBuffers(db_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also, clean out any entries in the shared free space map.
|
||||||
|
*/
|
||||||
|
FreeSpaceMapForgetDatabase(db_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove the database's subdirectory and everything in it.
|
* Remove the database's subdirectory and everything in it.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.200 2001/06/29 20:14:27 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.201 2001/07/02 20:50:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/execnodes.h"
|
#include "nodes/execnodes.h"
|
||||||
|
#include "storage/freespace.h"
|
||||||
#include "storage/sinval.h"
|
#include "storage/sinval.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
|
@ -146,6 +147,8 @@ static void vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||||
double num_tuples, int keep_tuples);
|
double num_tuples, int keep_tuples);
|
||||||
static void scan_index(Relation indrel, double num_tuples);
|
static void scan_index(Relation indrel, double num_tuples);
|
||||||
static VacPage tid_reaped(ItemPointer itemptr, VacPageList vacpagelist);
|
static VacPage tid_reaped(ItemPointer itemptr, VacPageList vacpagelist);
|
||||||
|
static void vac_update_fsm(Relation onerel, VacPageList fraged_pages,
|
||||||
|
BlockNumber rel_pages);
|
||||||
static VacPage copy_vac_page(VacPage vacpage);
|
static VacPage copy_vac_page(VacPage vacpage);
|
||||||
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
|
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
|
||||||
static void get_indices(Relation relation, int *nindices, Relation **Irel);
|
static void get_indices(Relation relation, int *nindices, Relation **Irel);
|
||||||
|
@ -579,6 +582,9 @@ vacuum_rel(Oid relid)
|
||||||
activate_indexes_of_a_table(relid, true);
|
activate_indexes_of_a_table(relid, true);
|
||||||
#endif /* NOT_USED */
|
#endif /* NOT_USED */
|
||||||
|
|
||||||
|
/* update shared free space map with final free space info */
|
||||||
|
vac_update_fsm(onerel, &fraged_pages, vacrelstats->rel_pages);
|
||||||
|
|
||||||
/* all done with this class, but hold lock until commit */
|
/* all done with this class, but hold lock until commit */
|
||||||
heap_close(onerel, NoLock);
|
heap_close(onerel, NoLock);
|
||||||
|
|
||||||
|
@ -1157,6 +1163,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
* useful as move targets, since we only want to move down. Note
|
* useful as move targets, since we only want to move down. Note
|
||||||
* that since we stop the outer loop at last_move_dest_block, pages
|
* that since we stop the outer loop at last_move_dest_block, pages
|
||||||
* removed here cannot have had anything moved onto them already.
|
* removed here cannot have had anything moved onto them already.
|
||||||
|
*
|
||||||
|
* Also note that we don't change the stored fraged_pages list,
|
||||||
|
* only our local variable num_fraged_pages; so the forgotten pages
|
||||||
|
* are still available to be loaded into the free space map later.
|
||||||
*/
|
*/
|
||||||
while (num_fraged_pages > 0 &&
|
while (num_fraged_pages > 0 &&
|
||||||
fraged_pages->pagedesc[num_fraged_pages-1]->blkno >= blkno)
|
fraged_pages->pagedesc[num_fraged_pages-1]->blkno >= blkno)
|
||||||
|
@ -2080,6 +2090,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
if (blkno < nblocks)
|
if (blkno < nblocks)
|
||||||
{
|
{
|
||||||
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
|
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
|
||||||
|
onerel->rd_nblocks = blkno; /* update relcache immediately */
|
||||||
|
onerel->rd_targblock = InvalidBlockNumber;
|
||||||
vacrelstats->rel_pages = blkno; /* set new number of blocks */
|
vacrelstats->rel_pages = blkno; /* set new number of blocks */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2145,6 +2157,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
|
||||||
RelationGetRelationName(onerel),
|
RelationGetRelationName(onerel),
|
||||||
vacrelstats->rel_pages, relblocks);
|
vacrelstats->rel_pages, relblocks);
|
||||||
relblocks = smgrtruncate(DEFAULT_SMGR, onerel, relblocks);
|
relblocks = smgrtruncate(DEFAULT_SMGR, onerel, relblocks);
|
||||||
|
onerel->rd_nblocks = relblocks; /* update relcache immediately */
|
||||||
|
onerel->rd_targblock = InvalidBlockNumber;
|
||||||
vacrelstats->rel_pages = relblocks; /* set new number of
|
vacrelstats->rel_pages = relblocks; /* set new number of
|
||||||
* blocks */
|
* blocks */
|
||||||
}
|
}
|
||||||
|
@ -2414,6 +2428,45 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
|
||||||
heap_close(rd, RowExclusiveLock);
|
heap_close(rd, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the shared Free Space Map with the info we now have about
|
||||||
|
* free space in the relation, discarding any old info the map may have.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
vac_update_fsm(Relation onerel, VacPageList fraged_pages,
|
||||||
|
BlockNumber rel_pages)
|
||||||
|
{
|
||||||
|
int nPages = fraged_pages->num_pages;
|
||||||
|
int i;
|
||||||
|
BlockNumber *pages;
|
||||||
|
Size *spaceAvail;
|
||||||
|
|
||||||
|
/* +1 to avoid palloc(0) */
|
||||||
|
pages = (BlockNumber *) palloc((nPages + 1) * sizeof(BlockNumber));
|
||||||
|
spaceAvail = (Size *) palloc((nPages + 1) * sizeof(Size));
|
||||||
|
|
||||||
|
for (i = 0; i < nPages; i++)
|
||||||
|
{
|
||||||
|
pages[i] = fraged_pages->pagedesc[i]->blkno;
|
||||||
|
spaceAvail[i] = fraged_pages->pagedesc[i]->free;
|
||||||
|
/*
|
||||||
|
* fraged_pages may contain entries for pages that we later decided
|
||||||
|
* to truncate from the relation; don't enter them into the map!
|
||||||
|
*/
|
||||||
|
if (pages[i] >= rel_pages)
|
||||||
|
{
|
||||||
|
nPages = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiRecordFreeSpace(&onerel->rd_node,
|
||||||
|
0, MaxBlockNumber,
|
||||||
|
nPages, pages, spaceAvail);
|
||||||
|
pfree(pages);
|
||||||
|
pfree(spaceAvail);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy a VacPage structure */
|
/* Copy a VacPage structure */
|
||||||
static VacPage
|
static VacPage
|
||||||
copy_vac_page(VacPage vacpage)
|
copy_vac_page(VacPage vacpage)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.51 2001/06/29 21:08:24 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.52 2001/07/02 20:50:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -469,11 +469,13 @@ smgrtruncate(int16 which, Relation reln, BlockNumber nblocks)
|
||||||
if (smgrsw[which].smgr_truncate)
|
if (smgrsw[which].smgr_truncate)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Tell the free space map to forget this relation, so that it
|
* Tell the free space map to forget anything it may have stored
|
||||||
* stops caching info about the deleted blocks. XXX perhaps
|
* for the about-to-be-deleted blocks. We want to be sure it won't
|
||||||
* tell it to forget only info about blocks beyond nblocks?
|
* return bogus block numbers later on.
|
||||||
*/
|
*/
|
||||||
FreeSpaceMapForgetRel(&reln->rd_node);
|
MultiRecordFreeSpace(&reln->rd_node,
|
||||||
|
nblocks, MaxBlockNumber,
|
||||||
|
0, NULL, NULL);
|
||||||
|
|
||||||
newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks);
|
newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks);
|
||||||
if (newblks == InvalidBlockNumber)
|
if (newblks == InvalidBlockNumber)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: block.h,v 1.12 2001/01/24 19:43:27 momjian Exp $
|
* $Id: block.h,v 1.13 2001/07/02 20:50:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -32,6 +32,8 @@ typedef uint32 BlockNumber;
|
||||||
|
|
||||||
#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF)
|
#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF)
|
||||||
|
|
||||||
|
#define MaxBlockNumber ((BlockNumber) 0xFFFFFFFE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BlockId:
|
* BlockId:
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: freespace.h,v 1.1 2001/06/27 23:31:39 tgl Exp $
|
* $Id: freespace.h,v 1.2 2001/07/02 20:50:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +45,7 @@ extern void MultiRecordFreeSpace(RelFileNode *rel,
|
||||||
BlockNumber *pages,
|
BlockNumber *pages,
|
||||||
Size *spaceAvail);
|
Size *spaceAvail);
|
||||||
extern void FreeSpaceMapForgetRel(RelFileNode *rel);
|
extern void FreeSpaceMapForgetRel(RelFileNode *rel);
|
||||||
|
extern void FreeSpaceMapForgetDatabase(Oid dbid);
|
||||||
|
|
||||||
#ifdef FREESPACE_DEBUG
|
#ifdef FREESPACE_DEBUG
|
||||||
extern void DumpFreeSpace(void);
|
extern void DumpFreeSpace(void);
|
||||||
|
|
Loading…
Reference in New Issue