|
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) |
|