@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / commands / vacuum . c , v 1.389 .2 .1 2009 / 08 / 24 02 : 18 : 40 tgl Exp $
* $ PostgreSQL : pgsql / src / backend / commands / vacuum . c , v 1.389 .2 .2 2009 / 11 / 10 18 : 00 : 26 alvherre Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -218,10 +218,10 @@ static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
static void vac_truncate_clog ( TransactionId frozenXID ) ;
static void vacuum_rel ( Oid relid , VacuumStmt * vacstmt , bool do_toast ,
bool for_wraparound , bool * scanned_all ) ;
static void full_vacuum_rel ( Relation onerel , VacuumStmt * vacstmt ) ;
static bool full_vacuum_rel ( Relation onerel , VacuumStmt * vacstmt ) ;
static void scan_heap ( VRelStats * vacrelstats , Relation onerel ,
VacPageList vacuum_pages , VacPageList fraged_pages ) ;
static void repair_frag ( VRelStats * vacrelstats , Relation onerel ,
static bool repair_frag ( VRelStats * vacrelstats , Relation onerel ,
VacPageList vacuum_pages , VacPageList fraged_pages ,
int nindexes , Relation * Irel ) ;
static void move_chain_tuple ( Relation rel ,
@ -1023,6 +1023,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
Oid toast_relid ;
Oid save_userid ;
bool save_secdefcxt ;
bool heldoff ;
if ( scanned_all )
* scanned_all = false ;
@ -1189,9 +1190,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
* Do the actual work - - - either FULL or " lazy " vacuum
*/
if ( vacstmt - > full )
full_vacuum_rel ( onerel , vacstmt ) ;
heldoff = full_vacuum_rel ( onerel , vacstmt ) ;
else
lazy_vacuum_rel ( onerel , vacstmt , vac_strategy , scanned_all ) ;
heldoff = lazy_vacuum_rel ( onerel , vacstmt , vac_strategy , scanned_all ) ;
/* Restore userid */
SetUserIdAndContext ( save_userid , save_secdefcxt ) ;
@ -1205,6 +1206,10 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
PopActiveSnapshot ( ) ;
CommitTransactionCommand ( ) ;
/* now we can allow interrupts again, if disabled */
if ( heldoff )
RESUME_INTERRUPTS ( ) ;
/*
* If the relation has a secondary toast rel , vacuum that too while we
* still hold the session lock on the master table . Note however that
@ -1238,8 +1243,11 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
*
* At entry , we have already established a transaction and opened
* and locked the relation .
*
* The return value indicates whether this function has held off
* interrupts - - caller must RESUME_INTERRUPTS ( ) after commit if true .
*/
static void
static bool
full_vacuum_rel ( Relation onerel , VacuumStmt * vacstmt )
{
VacPageListData vacuum_pages ; /* List of pages to vacuum and/or
@ -1250,6 +1258,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
int nindexes ,
i ;
VRelStats * vacrelstats ;
bool heldoff = false ;
vacuum_set_xid_limits ( vacstmt - > freeze_min_age , vacstmt - > freeze_table_age ,
onerel - > rd_rel - > relisshared ,
@ -1301,7 +1310,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
if ( fraged_pages . num_pages > 0 )
{
/* Try to shrink heap */
repair_frag ( vacrelstats , onerel , & vacuum_pages , & fraged_pages ,
heldoff = repair_frag ( vacrelstats , onerel , & vacuum_pages , & fraged_pages ,
nindexes , Irel ) ;
vac_close_indexes ( nindexes , Irel , NoLock ) ;
}
@ -1327,6 +1336,8 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
/* report results to the stats collector, too */
pgstat_report_vacuum ( RelationGetRelid ( onerel ) , onerel - > rd_rel - > relisshared ,
true , vacstmt - > analyze , vacrelstats - > rel_tuples ) ;
return heldoff ;
}
@ -1877,8 +1888,11 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
* for them after committing ( in hack - manner - without losing locks
* and freeing memory ! ) current transaction . It truncates relation
* if some end - blocks are gone away .
*
* The return value indicates whether this function has held off
* interrupts - - caller must RESUME_INTERRUPTS ( ) after commit if true .
*/
static void
static bool
repair_frag ( VRelStats * vacrelstats , Relation onerel ,
VacPageList vacuum_pages , VacPageList fraged_pages ,
int nindexes , Relation * Irel )
@ -1903,6 +1917,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
int keep_tuples = 0 ;
int keep_indexed_tuples = 0 ;
PGRUsage ru0 ;
bool heldoff = false ;
pg_rusage_init ( & ru0 ) ;
@ -2708,8 +2723,12 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
*
* XXX This desperately needs to be revisited . Any failure after this
* point will result in a PANIC " cannot abort transaction nnn, it was
* already committed " !
* already committed " ! As a precaution, we prevent cancel interrupts
* after this point to mitigate this problem ; caller is responsible for
* re - enabling them after committing the transaction .
*/
HOLD_INTERRUPTS ( ) ;
heldoff = true ;
ForceSyncCommit ( ) ;
( void ) RecordTransactionCommit ( ) ;
}
@ -2909,6 +2928,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
pfree ( vacrelstats - > vtlinks ) ;
ExecContext_Finish ( & ec ) ;
return heldoff ;
}
/*