|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.200 2001/06/29 20:14:27 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.201 2001/07/02 20:50:46 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
37 | 37 | #include"commands/vacuum.h"
|
38 | 38 | #include"miscadmin.h"
|
39 | 39 | #include"nodes/execnodes.h"
|
| 40 | +#include"storage/freespace.h" |
40 | 41 | #include"storage/sinval.h"
|
41 | 42 | #include"storage/smgr.h"
|
42 | 43 | #include"tcop/tcopprot.h"
|
@@ -146,6 +147,8 @@ static void vacuum_index(VacPageList vacpagelist, Relation indrel,
|
146 | 147 | doublenum_tuples,intkeep_tuples);
|
147 | 148 | staticvoidscan_index(Relationindrel,doublenum_tuples);
|
148 | 149 | staticVacPagetid_reaped(ItemPointeritemptr,VacPageListvacpagelist);
|
| 150 | +staticvoidvac_update_fsm(Relationonerel,VacPageListfraged_pages, |
| 151 | +BlockNumberrel_pages); |
149 | 152 | staticVacPagecopy_vac_page(VacPagevacpage);
|
150 | 153 | staticvoidvpage_insert(VacPageListvacpagelist,VacPagevpnew);
|
151 | 154 | staticvoidget_indices(Relationrelation,int*nindices,Relation**Irel);
|
@@ -579,6 +582,9 @@ vacuum_rel(Oid relid)
|
579 | 582 | activate_indexes_of_a_table(relid, true);
|
580 | 583 | #endif/* NOT_USED */
|
581 | 584 |
|
| 585 | +/* update shared free space map with final free space info */ |
| 586 | +vac_update_fsm(onerel,&fraged_pages,vacrelstats->rel_pages); |
| 587 | + |
582 | 588 | /* all done with this class, but hold lock until commit */
|
583 | 589 | heap_close(onerel,NoLock);
|
584 | 590 |
|
@@ -1157,6 +1163,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
1157 | 1163 | * useful as move targets, since we only want to move down. Note
|
1158 | 1164 | * that since we stop the outer loop at last_move_dest_block, pages
|
1159 | 1165 | * removed here cannot have had anything moved onto them already.
|
| 1166 | + * |
| 1167 | + * Also note that we don't change the stored fraged_pages list, |
| 1168 | + * only our local variable num_fraged_pages; so the forgotten pages |
| 1169 | + * are still available to be loaded into the free space map later. |
1160 | 1170 | */
|
1161 | 1171 | while (num_fraged_pages>0&&
|
1162 | 1172 | fraged_pages->pagedesc[num_fraged_pages-1]->blkno >=blkno)
|
@@ -2080,6 +2090,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
2080 | 2090 | if (blkno<nblocks)
|
2081 | 2091 | {
|
2082 | 2092 | blkno=smgrtruncate(DEFAULT_SMGR,onerel,blkno);
|
| 2093 | +onerel->rd_nblocks=blkno;/* update relcache immediately */ |
| 2094 | +onerel->rd_targblock=InvalidBlockNumber; |
2083 | 2095 | vacrelstats->rel_pages=blkno;/* set new number of blocks */
|
2084 | 2096 | }
|
2085 | 2097 |
|
@@ -2145,6 +2157,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
|
2145 | 2157 | RelationGetRelationName(onerel),
|
2146 | 2158 | vacrelstats->rel_pages,relblocks);
|
2147 | 2159 | relblocks=smgrtruncate(DEFAULT_SMGR,onerel,relblocks);
|
| 2160 | +onerel->rd_nblocks=relblocks;/* update relcache immediately */ |
| 2161 | +onerel->rd_targblock=InvalidBlockNumber; |
2148 | 2162 | vacrelstats->rel_pages=relblocks;/* set new number of
|
2149 | 2163 | * blocks */
|
2150 | 2164 | }
|
@@ -2414,6 +2428,45 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
|
2414 | 2428 | heap_close(rd,RowExclusiveLock);
|
2415 | 2429 | }
|
2416 | 2430 |
|
| 2431 | +/* |
| 2432 | + * Update the shared Free Space Map with the info we now have about |
| 2433 | + * free space in the relation, discarding any old info the map may have. |
| 2434 | + */ |
| 2435 | +staticvoid |
| 2436 | +vac_update_fsm(Relationonerel,VacPageListfraged_pages, |
| 2437 | +BlockNumberrel_pages) |
| 2438 | +{ |
| 2439 | +intnPages=fraged_pages->num_pages; |
| 2440 | +inti; |
| 2441 | +BlockNumber*pages; |
| 2442 | +Size*spaceAvail; |
| 2443 | + |
| 2444 | +/* +1 to avoid palloc(0) */ |
| 2445 | +pages= (BlockNumber*)palloc((nPages+1)*sizeof(BlockNumber)); |
| 2446 | +spaceAvail= (Size*)palloc((nPages+1)*sizeof(Size)); |
| 2447 | + |
| 2448 | +for (i=0;i<nPages;i++) |
| 2449 | +{ |
| 2450 | +pages[i]=fraged_pages->pagedesc[i]->blkno; |
| 2451 | +spaceAvail[i]=fraged_pages->pagedesc[i]->free; |
| 2452 | +/* |
| 2453 | + * fraged_pages may contain entries for pages that we later decided |
| 2454 | + * to truncate from the relation; don't enter them into the map! |
| 2455 | + */ |
| 2456 | +if (pages[i] >=rel_pages) |
| 2457 | +{ |
| 2458 | +nPages=i; |
| 2459 | +break; |
| 2460 | +} |
| 2461 | +} |
| 2462 | + |
| 2463 | +MultiRecordFreeSpace(&onerel->rd_node, |
| 2464 | +0,MaxBlockNumber, |
| 2465 | +nPages,pages,spaceAvail); |
| 2466 | +pfree(pages); |
| 2467 | +pfree(spaceAvail); |
| 2468 | +} |
| 2469 | + |
2417 | 2470 | /* Copy a VacPage structure */
|
2418 | 2471 | staticVacPage
|
2419 | 2472 | copy_vac_page(VacPagevacpage)
|
|