@ -78,9 +78,9 @@
* that the potential for improvement was great enough to merit the cost of
* that the potential for improvement was great enough to merit the cost of
* supporting them .
* supporting them .
*/
*/
# define AUTO VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL 20 /* ms */
# define VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL 20 /* ms */
# define AUTO VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL 50 /* ms */
# define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL 50 /* ms */
# define AUTO VACUUM_TRUNCATE_LOCK_TIMEOUT 5000 /* ms */
# define VACUUM_TRUNCATE_LOCK_TIMEOUT 5000 /* ms */
/*
/*
* Guesstimation of number of dead tuples per page . This is used to
* Guesstimation of number of dead tuples per page . This is used to
@ -285,17 +285,10 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
new_frozen_xid ,
new_frozen_xid ,
new_min_multi ) ;
new_min_multi ) ;
/*
/* report results to the stats collector, too */
* Report results to the stats collector , too . An early terminated
pgstat_report_vacuum ( RelationGetRelid ( onerel ) ,
* lazy_truncate_heap attempt suppresses the message and also cancels the
onerel - > rd_rel - > relisshared ,
* execution of ANALYZE , if that was ordered .
new_rel_tuples ) ;
*/
if ( ! vacrelstats - > lock_waiter_detected )
pgstat_report_vacuum ( RelationGetRelid ( onerel ) ,
onerel - > rd_rel - > relisshared ,
new_rel_tuples ) ;
else
vacstmt - > options & = ~ VACOPT_ANALYZE ;
/* and log the action if appropriate */
/* and log the action if appropriate */
if ( IsAutoVacuumWorkerProcess ( ) & & Log_autovacuum_min_duration > = 0 )
if ( IsAutoVacuumWorkerProcess ( ) & & Log_autovacuum_min_duration > = 0 )
@ -1347,28 +1340,21 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
*/
*/
CHECK_FOR_INTERRUPTS ( ) ;
CHECK_FOR_INTERRUPTS ( ) ;
if ( + + lock_retry > ( AUTO VACUUM_TRUNCATE_LOCK_TIMEOUT /
if ( + + lock_retry > ( VACUUM_TRUNCATE_LOCK_TIMEOUT /
AUTO VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL) )
VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL ) )
{
{
/*
/*
* We failed to establish the lock in the specified number of
* We failed to establish the lock in the specified number of
* retries . This means we give up truncating . Suppress the
* retries . This means we give up truncating .
* ANALYZE step . Doing an ANALYZE at this point will reset the
* dead_tuple_count in the stats collector , so we will not get
* called by the autovacuum launcher again to do the truncate .
*/
*/
vacrelstats - > lock_waiter_detected = true ;
vacrelstats - > lock_waiter_detected = true ;
ereport ( LOG ,
ereport ( elevel ,
( errmsg ( " automatic vacuum of table \" %s.%s.%s \" : "
( errmsg ( " \" %s \" : stopping truncate due to conflicting lock request " ,
" could not (re)acquire exclusive "
" lock for truncate scan " ,
get_database_name ( MyDatabaseId ) ,
get_namespace_name ( RelationGetNamespace ( onerel ) ) ,
RelationGetRelationName ( onerel ) ) ) ) ;
RelationGetRelationName ( onerel ) ) ) ) ;
return ;
return ;
}
}
pg_usleep ( AUTO VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL) ;
pg_usleep ( VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL ) ;
}
}
/*
/*
@ -1448,8 +1434,6 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
{
{
BlockNumber blkno ;
BlockNumber blkno ;
instr_time starttime ;
instr_time starttime ;
instr_time currenttime ;
instr_time elapsed ;
/* Initialize the starttime if we check for conflicting lock requests */
/* Initialize the starttime if we check for conflicting lock requests */
INSTR_TIME_SET_CURRENT ( starttime ) ;
INSTR_TIME_SET_CURRENT ( starttime ) ;
@ -1467,24 +1451,26 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
/*
/*
* Check if another process requests a lock on our relation . We are
* Check if another process requests a lock on our relation . We are
* holding an AccessExclusiveLock here , so they will be waiting . We
* holding an AccessExclusiveLock here , so they will be waiting . We
* only do this in autovacuum_truncate_lock_check millisecond
* only do this once per VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL , and we
* intervals , and we only check if that interval has elapsed once
* only check if that interval has elapsed once every 32 blocks to
* every 32 blocks to keep the number of system calls and actual
* keep the number of system calls and actual shared lock table
* shared lock table lookups to a minimum .
* lookups to a minimum .
*/
*/
if ( ( blkno % 32 ) = = 0 )
if ( ( blkno % 32 ) = = 0 )
{
{
instr_time currenttime ;
instr_time elapsed ;
INSTR_TIME_SET_CURRENT ( currenttime ) ;
INSTR_TIME_SET_CURRENT ( currenttime ) ;
elapsed = currenttime ;
elapsed = currenttime ;
INSTR_TIME_SUBTRACT ( elapsed , starttime ) ;
INSTR_TIME_SUBTRACT ( elapsed , starttime ) ;
if ( ( INSTR_TIME_GET_MICROSEC ( elapsed ) / 1000 )
if ( ( INSTR_TIME_GET_MICROSEC ( elapsed ) / 1000 )
> = AUTO VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL)
> = VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL )
{
{
if ( LockHasWaitersRelation ( onerel , AccessExclusiveLock ) )
if ( LockHasWaitersRelation ( onerel , AccessExclusiveLock ) )
{
{
ereport ( elevel ,
ereport ( elevel ,
( errmsg ( " \" %s \" : suspending truncate "
( errmsg ( " \" %s \" : suspending truncate due to conflicting lock request " ,
" due to conflicting lock request " ,
RelationGetRelationName ( onerel ) ) ) ) ;
RelationGetRelationName ( onerel ) ) ) ) ;
vacrelstats - > lock_waiter_detected = true ;
vacrelstats - > lock_waiter_detected = true ;