aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/dbcommands.c10
-rw-r--r--src/backend/commands/vacuum.c55
2 files changed, 62 insertions, 3 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 424c9665f74..dca75bd71d9 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -9,7 +9,7 @@
*
*
* 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/dbcommands.h"
#include "miscadmin.h"
-#include "storage/sinval.h" /* for DatabaseHasActiveBackends */
+#include "storage/freespace.h"
+#include "storage/sinval.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
@@ -373,6 +374,11 @@ dropdb(const char *dbname)
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_dbdirs(nominal_loc, alt_loc);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 9c5c8d9085d..df486de5120 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -8,7 +8,7 @@
*
*
* 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 "miscadmin.h"
#include "nodes/execnodes.h"
+#include "storage/freespace.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "tcop/tcopprot.h"
@@ -146,6 +147,8 @@ static void vacuum_index(VacPageList vacpagelist, Relation indrel,
double num_tuples, int keep_tuples);
static void scan_index(Relation indrel, double num_tuples);
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 void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
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);
#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 */
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
* that since we stop the outer loop at last_move_dest_block, pages
* 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 &&
fraged_pages->pagedesc[num_fraged_pages-1]->blkno >= blkno)
@@ -2080,6 +2090,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if (blkno < nblocks)
{
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 */
}
@@ -2145,6 +2157,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
RelationGetRelationName(onerel),
vacrelstats->rel_pages, 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
* blocks */
}
@@ -2414,6 +2428,45 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
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 */
static VacPage
copy_vac_page(VacPage vacpage)