@ -53,7 +53,7 @@ ulong srv_max_purge_lag = 0;
ulong srv_max_purge_lag_delay = 0 ;
/** The global data structure coordinating a purge */
purge_sys_t * purge_sys ;
purge_sys_t purge_sys ;
/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
@ -67,7 +67,7 @@ my_bool srv_purge_view_update_only_debug;
static const TrxUndoRsegs NullElement ;
/** Default constructor */
inline TrxUndoRsegsIterator : : TrxUndoRsegsIterator ( )
TrxUndoRsegsIterator : : TrxUndoRsegsIterator ( )
: m_rsegs ( NullElement ) , m_iter ( m_rsegs . begin ( ) )
{
}
@ -77,7 +77,7 @@ Executed in the purge coordinator thread.
@ return whether anything is to be purged */
inline bool TrxUndoRsegsIterator : : set_next ( )
{
mutex_enter ( & purge_sys - > pq_mutex ) ;
mutex_enter ( & purge_sys . pq_mutex ) ;
/* Only purge consumes events from the priority queue, user
threads only produce the events . */
@ -90,41 +90,41 @@ inline bool TrxUndoRsegsIterator::set_next()
number shouldn ' t increase . Undo the increment of
expected commit done by caller assuming rollback
segments from given transaction are done . */
purge_sys - > tail . commit = ( * m_iter ) - > last_commit ;
} else if ( ! purge_sys - > purge_queue . empty ( ) ) {
m_rsegs = purge_sys - > purge_queue . top ( ) ;
purge_sys - > purge_queue . pop ( ) ;
ut_ad ( purge_sys - > purge_queue . empty ( )
| | purge_sys - > purge_queue . top ( ) ! = m_rsegs ) ;
purge_sys . tail . commit = ( * m_iter ) - > last_commit ;
} else if ( ! purge_sys . purge_queue . empty ( ) ) {
m_rsegs = purge_sys . purge_queue . top ( ) ;
purge_sys . purge_queue . pop ( ) ;
ut_ad ( purge_sys . purge_queue . empty ( )
| | purge_sys . purge_queue . top ( ) ! = m_rsegs ) ;
m_iter = m_rsegs . begin ( ) ;
} else {
/* Queue is empty, reset iterator. */
purge_sys - > rseg = NULL ;
mutex_exit ( & purge_sys - > pq_mutex ) ;
purge_sys . rseg = NULL ;
mutex_exit ( & purge_sys . pq_mutex ) ;
m_rsegs = NullElement ;
m_iter = m_rsegs . begin ( ) ;
return false ;
}
purge_sys - > rseg = * m_iter + + ;
mutex_exit ( & purge_sys - > pq_mutex ) ;
mutex_enter ( & purge_sys - > rseg - > mutex ) ;
purge_sys . rseg = * m_iter + + ;
mutex_exit ( & purge_sys . pq_mutex ) ;
mutex_enter ( & purge_sys . rseg - > mutex ) ;
ut_a ( purge_sys - > rseg - > last_page_no ! = FIL_NULL ) ;
ut_ad ( purge_sys - > rseg - > last_trx_no ( ) = = m_rsegs . trx_no ( ) ) ;
ut_a ( purge_sys . rseg - > last_page_no ! = FIL_NULL ) ;
ut_ad ( purge_sys . rseg - > last_trx_no ( ) = = m_rsegs . trx_no ( ) ) ;
/* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */
ut_a ( purge_sys - > rseg - > space = = TRX_SYS_SPACE
| | srv_is_undo_tablespace ( purge_sys - > rseg - > space ) ) ;
ut_a ( purge_sys . rseg - > space = = TRX_SYS_SPACE
| | srv_is_undo_tablespace ( purge_sys . rseg - > space ) ) ;
ut_a ( purge_sys - > tail . commit < = purge_sys - > rseg - > last_commit ) ;
ut_a ( purge_sys . tail . commit < = purge_sys . rseg - > last_commit ) ;
purge_sys - > tail . commit = purge_sys - > rseg - > last_commit ;
purge_sys - > hdr_offset = purge_sys - > rseg - > last_offset ;
purge_sys - > hdr_page_no = purge_sys - > rseg - > last_page_no ;
purge_sys . tail . commit = purge_sys . rseg - > last_commit ;
purge_sys . hdr_offset = purge_sys . rseg - > last_offset ;
purge_sys . hdr_page_no = purge_sys . rseg - > last_page_no ;
mutex_exit ( & purge_sys - > rseg - > mutex ) ;
mutex_exit ( & purge_sys . rseg - > mutex ) ;
return ( true ) ;
}
@ -157,27 +157,37 @@ purge_graph_build()
return ( fork ) ;
}
/** Construct the purge system. */
purge_sys_t : : purge_sys_t ( )
: latch ( ) , event ( os_event_create ( 0 ) ) ,
n_stop ( 0 ) , running ( false ) , state ( PURGE_STATE_INIT ) ,
query ( purge_graph_build ( ) ) ,
view ( ) , n_submitted ( 0 ) , n_completed ( 0 ) ,
tail ( ) , head ( ) ,
next_stored ( false ) , rseg ( NULL ) ,
page_no ( 0 ) , offset ( 0 ) , hdr_page_no ( 0 ) , hdr_offset ( 0 ) ,
rseg_iter ( ) , purge_queue ( ) , pq_mutex ( ) , undo_trunc ( )
/** Initialise the purge system. */
void purge_sys_t : : create ( )
{
ut_ad ( ! purge_sys ) ;
rw_lock_create ( trx_purge_latch_key , & latch , SYNC_PURGE_LATCH ) ;
mutex_create ( LATCH_ID_PURGE_SYS_PQ , & pq_mutex ) ;
ut_ad ( this = = & purge_sys ) ;
ut_ad ( ! is_initialised ( ) ) ;
event = os_event_create ( 0 ) ;
n_stop = 0 ;
running = false ;
state = PURGE_STATE_INIT ;
query = purge_graph_build ( ) ;
n_submitted = 0 ;
n_completed = 0 ;
next_stored = false ;
rseg = NULL ;
page_no = 0 ;
offset = 0 ;
hdr_page_no = 0 ;
hdr_offset = 0 ;
rw_lock_create ( trx_purge_latch_key , & latch , SYNC_PURGE_LATCH ) ;
mutex_create ( LATCH_ID_PURGE_SYS_PQ , & pq_mutex ) ;
undo_trunc . create ( ) ;
m_initialised = true ;
}
/** Destruct the purge system. */
purge_sys_t : : ~ purge_sys_t ( )
/** Close the purge subsystem on shutdown . */
void purge_sys_t : : close ( )
{
ut_ad ( this = = purge_sys ) ;
ut_ad ( this = = & purge_sys ) ;
if ( ! is_initialised ( ) ) return ;
m_initialised = false ;
trx_t * trx = query - > trx ;
que_graph_free ( query ) ;
ut_ad ( ! trx - > id ) ;
@ -268,9 +278,9 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
ut_ad ( srv_undo_sources
| | ( ( srv_startup_is_before_trx_rollback_phase
| | trx_rollback_is_active )
& & purge_sys - > state = = PURGE_STATE_INIT )
& & purge_sys . state = = PURGE_STATE_INIT )
| | ( srv_force_recovery > = SRV_FORCE_NO_BACKGROUND
& & purge_sys - > state = = PURGE_STATE_DISABLED )
& & purge_sys . state = = PURGE_STATE_DISABLED )
| | ( ( trx - > undo_no = = 0 | | trx - > in_mysql_trx_list
| | trx - > internal )
& & srv_fast_shutdown ) ) ;
@ -842,17 +852,17 @@ void
trx_purge_cleanse_purge_queue (
undo : : Truncate * undo_trunc )
{
mutex_enter ( & purge_sys - > pq_mutex ) ;
mutex_enter ( & purge_sys . pq_mutex ) ;
typedef std : : vector < TrxUndoRsegs > purge_elem_list_t ;
purge_elem_list_t purge_elem_list ;
/* Remove rseg instances that are in the purge queue before we start
truncate of corresponding UNDO truncate . */
while ( ! purge_sys - > purge_queue . empty ( ) ) {
purge_elem_list . push_back ( purge_sys - > purge_queue . top ( ) ) ;
purge_sys - > purge_queue . pop ( ) ;
while ( ! purge_sys . purge_queue . empty ( ) ) {
purge_elem_list . push_back ( purge_sys . purge_queue . top ( ) ) ;
purge_sys . purge_queue . pop ( ) ;
}
ut_ad ( purge_sys - > purge_queue . empty ( ) ) ;
ut_ad ( purge_sys . purge_queue . empty ( ) ) ;
for ( purge_elem_list_t : : iterator it = purge_elem_list . begin ( ) ;
it ! = purge_elem_list . end ( ) ;
@ -870,10 +880,10 @@ trx_purge_cleanse_purge_queue(
}
if ( ! it - > empty ( ) ) {
purge_sys - > purge_queue . push ( * it ) ;
purge_sys . purge_queue . push ( * it ) ;
}
}
mutex_exit ( & purge_sys - > pq_mutex ) ;
mutex_exit ( & purge_sys . pq_mutex ) ;
}
/** Iterate over selected UNDO tablespace and check if all the rsegs
@ -994,17 +1004,17 @@ trx_purge_initiate_truncate(
return ;
}
if ( purge_sys - > rseg ! = NULL
& & purge_sys - > rseg - > last_page_no = = FIL_NULL ) {
/* If purge_sys-> rseg is pointing to rseg that was recently
if ( purge_sys . rseg ! = NULL
& & purge_sys . rseg - > last_page_no = = FIL_NULL ) {
/* If purge_sys. rseg is pointing to rseg that was recently
truncated then move to next rseg element .
Note : Ideally purge_sys - > rseg should be NULL because purge
Note : Ideally purge_sys . rseg should be NULL because purge
should complete processing of all the records but there is
purge_batch_size that can force the purge loop to exit before
all the records are purged and in this case purge_sys - > rseg
all the records are purged and in this case purge_sys . rseg
could point to a valid rseg waiting for next purge cycle . */
purge_sys - > next_stored = false ;
purge_sys - > rseg = NULL ;
purge_sys . next_stored = false ;
purge_sys . rseg = NULL ;
}
DBUG_EXECUTE_IF ( " ib_undo_trunc_before_ddl_log_end " ,
@ -1037,13 +1047,13 @@ function is called, the caller must not have any latches on undo log pages!
*/
static void trx_purge_truncate_history ( )
{
ut_ad ( purge_sys - > head < = purge_sys - > tail ) ;
purge_sys_t : : iterator & head = purge_sys - > head . commit
? purge_sys - > head : purge_sys - > tail ;
ut_ad ( purge_sys . head < = purge_sys . tail ) ;
purge_sys_t : : iterator & head = purge_sys . head . commit
? purge_sys . head : purge_sys . tail ;
if ( head . trx_no ( ) > = purge_sys - > view . low_limit_no ( ) ) {
if ( head . trx_no ( ) > = purge_sys . view . low_limit_no ( ) ) {
/* This is sometimes necessary. TODO: find out why. */
head . reset_trx_no ( purge_sys - > view . low_limit_no ( ) ) ;
head . reset_trx_no ( purge_sys . view . low_limit_no ( ) ) ;
head . undo_no = 0 ;
}
@ -1058,14 +1068,14 @@ static void trx_purge_truncate_history()
can ( greedy approach ) . This will ensure when the server is idle we
try and truncate all the UNDO tablespaces . */
for ( ulint i = srv_undo_tablespaces_active ; i - - ; ) {
trx_purge_mark_undo_for_truncate ( & purge_sys - > undo_trunc ) ;
trx_purge_initiate_truncate ( head , & purge_sys - > undo_trunc ) ;
trx_purge_mark_undo_for_truncate ( & purge_sys . undo_trunc ) ;
trx_purge_initiate_truncate ( head , & purge_sys . undo_trunc ) ;
}
}
/***********************************************************************/ /**
Updates the last not yet purged history log info in rseg when we have purged
a whole undo log . Advances also purge_sys - > purge_trx_no past the purged log . */
a whole undo log . Advances also purge_sys . purge_trx_no past the purged log . */
static
void
trx_purge_rseg_get_next_history_log (
@ -1084,9 +1094,9 @@ trx_purge_rseg_get_next_history_log(
ut_a ( rseg - > last_page_no ! = FIL_NULL ) ;
purge_sys - > tail . commit = rseg - > last_commit + 1 ;
purge_sys - > tail . undo_no = 0 ;
purge_sys - > next_stored = false ;
purge_sys . tail . commit = rseg - > last_commit + 1 ;
purge_sys . tail . undo_no = 0 ;
purge_sys . next_stored = false ;
mtr_start ( & mtr ) ;
@ -1142,11 +1152,11 @@ trx_purge_rseg_get_next_history_log(
than the events that Purge produces . ie . Purge can never produce
events from an empty rollback segment . */
mutex_enter ( & purge_sys - > pq_mutex ) ;
mutex_enter ( & purge_sys . pq_mutex ) ;
purge_sys - > purge_queue . push ( * rseg ) ;
purge_sys . purge_queue . push ( * rseg ) ;
mutex_exit ( & purge_sys - > pq_mutex ) ;
mutex_exit ( & purge_sys . pq_mutex ) ;
mutex_exit ( & rseg - > mutex ) ;
}
@ -1160,15 +1170,15 @@ trx_purge_read_undo_rec()
ulint page_no ;
ib_uint64_t undo_no ;
purge_sys - > hdr_offset = purge_sys - > rseg - > last_offset ;
page_no = purge_sys - > hdr_page_no = purge_sys - > rseg - > last_page_no ;
purge_sys . hdr_offset = purge_sys . rseg - > last_offset ;
page_no = purge_sys . hdr_page_no = purge_sys . rseg - > last_page_no ;
if ( purge_sys - > rseg - > needs_purge ) {
if ( purge_sys . rseg - > needs_purge ) {
mtr_t mtr ;
mtr . start ( ) ;
if ( trx_undo_rec_t * undo_rec = trx_undo_get_first_rec (
purge_sys - > rseg - > space , purge_sys - > hdr_page_no ,
purge_sys - > hdr_offset , RW_S_LATCH , & mtr ) ) {
purge_sys . rseg - > space , purge_sys . hdr_page_no ,
purge_sys . hdr_offset , RW_S_LATCH , & mtr ) ) {
offset = page_offset ( undo_rec ) ;
undo_no = trx_undo_rec_get_undo_no ( undo_rec ) ;
@ -1184,11 +1194,11 @@ trx_purge_read_undo_rec()
undo_no = 0 ;
}
purge_sys - > offset = offset ;
purge_sys - > page_no = page_no ;
purge_sys - > tail . undo_no = undo_no ;
purge_sys . offset = offset ;
purge_sys . page_no = page_no ;
purge_sys . tail . undo_no = undo_no ;
purge_sys - > next_stored = true ;
purge_sys . next_stored = true ;
}
/***********************************************************************/ /**
@ -1201,9 +1211,9 @@ void
trx_purge_choose_next_log ( void )
/*===========================*/
{
ut_ad ( ! purge_sys - > next_stored ) ;
ut_ad ( ! purge_sys . next_stored ) ;
if ( purge_sys - > rseg_iter . set_next ( ) ) {
if ( purge_sys . rseg_iter . set_next ( ) ) {
trx_purge_read_undo_rec ( ) ;
} else {
/* There is nothing to do yet. */
@ -1232,19 +1242,19 @@ trx_purge_get_next_rec(
ulint space ;
mtr_t mtr ;
ut_ad ( purge_sys - > next_stored ) ;
ut_ad ( purge_sys - > tail . trx_no ( ) < purge_sys - > view . low_limit_no ( ) ) ;
ut_ad ( purge_sys . next_stored ) ;
ut_ad ( purge_sys . tail . trx_no ( ) < purge_sys . view . low_limit_no ( ) ) ;
space = purge_sys - > rseg - > space ;
page_no = purge_sys - > page_no ;
offset = purge_sys - > offset ;
space = purge_sys . rseg - > space ;
page_no = purge_sys . page_no ;
offset = purge_sys . offset ;
if ( offset = = 0 ) {
/* It is the dummy undo log record, which means that there is
no need to purge this undo log */
trx_purge_rseg_get_next_history_log (
purge_sys - > rseg , n_pages_handled ) ;
purge_sys . rseg , n_pages_handled ) ;
/* Look for the next undo log and record to purge */
@ -1260,19 +1270,19 @@ trx_purge_get_next_rec(
rec = undo_page + offset ;
rec2 = trx_undo_page_get_next_rec ( rec , purge_sys - > hdr_page_no ,
purge_sys - > hdr_offset ) ;
rec2 = trx_undo_page_get_next_rec ( rec , purge_sys . hdr_page_no ,
purge_sys . hdr_offset ) ;
if ( rec2 = = NULL ) {
rec2 = trx_undo_get_next_rec ( rec , purge_sys - > hdr_page_no ,
purge_sys - > hdr_offset , & mtr ) ;
rec2 = trx_undo_get_next_rec ( rec , purge_sys . hdr_page_no ,
purge_sys . hdr_offset , & mtr ) ;
}
if ( rec2 = = NULL ) {
mtr_commit ( & mtr ) ;
trx_purge_rseg_get_next_history_log (
purge_sys - > rseg , n_pages_handled ) ;
purge_sys . rseg , n_pages_handled ) ;
/* Look for the next undo log and record to purge */
@ -1287,9 +1297,9 @@ trx_purge_get_next_rec(
} else {
page = page_align ( rec2 ) ;
purge_sys - > offset = rec2 - page ;
purge_sys - > page_no = page_get_page_no ( page ) ;
purge_sys - > tail . undo_no = trx_undo_rec_get_undo_no ( rec2 ) ;
purge_sys . offset = rec2 - page ;
purge_sys . page_no = page_get_page_no ( page ) ;
purge_sys . tail . undo_no = trx_undo_rec_get_undo_no ( rec2 ) ;
if ( undo_page ! = page ) {
/* We advance to a new page of the undo log: */
@ -1318,17 +1328,17 @@ trx_purge_fetch_next_rec(
handled */
mem_heap_t * heap ) /*!< in: memory heap where copied */
{
if ( ! purge_sys - > next_stored ) {
if ( ! purge_sys . next_stored ) {
trx_purge_choose_next_log ( ) ;
if ( ! purge_sys - > next_stored ) {
if ( ! purge_sys . next_stored ) {
DBUG_PRINT ( " ib_purge " ,
( " no logs left in the history list " ) ) ;
return ( NULL ) ;
}
}
if ( purge_sys - > tail . trx_no ( ) > = purge_sys - > view . low_limit_no ( ) ) {
if ( purge_sys . tail . trx_no ( ) > = purge_sys . view . low_limit_no ( ) ) {
return ( NULL ) ;
}
@ -1340,8 +1350,8 @@ trx_purge_fetch_next_rec(
/* row_purge_record_func() will later set
ROLL_PTR_INSERT_FLAG for TRX_UNDO_INSERT_REC */
false ,
purge_sys - > rseg - > id ,
purge_sys - > page_no , purge_sys - > offset ) ;
purge_sys . rseg - > id ,
purge_sys . page_no , purge_sys . offset ) ;
/* The following call will advance the stored values of the
purge iterator . */
@ -1359,14 +1369,14 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
que_thr_t * thr ;
ulint i = 0 ;
ulint n_pages_handled = 0 ;
ulint n_thrs = UT_LIST_GET_LEN ( purge_sys - > query - > thrs ) ;
ulint n_thrs = UT_LIST_GET_LEN ( purge_sys . query - > thrs ) ;
ut_a ( n_purge_threads > 0 ) ;
purge_sys - > head = purge_sys - > tail ;
purge_sys . head = purge_sys . tail ;
/* Debug code to validate some pre-requisites and reset done flag. */
for ( thr = UT_LIST_GET_FIRST ( purge_sys - > query - > thrs ) ;
for ( thr = UT_LIST_GET_FIRST ( purge_sys . query - > thrs ) ;
thr ! = NULL & & i < n_purge_threads ;
thr = UT_LIST_GET_NEXT ( thrs , thr ) , + + i ) {
@ -1388,10 +1398,10 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
/* Fetch and parse the UNDO records. The UNDO records are added
to a per purge node vector . */
thr = UT_LIST_GET_FIRST ( purge_sys - > query - > thrs ) ;
thr = UT_LIST_GET_FIRST ( purge_sys . query - > thrs ) ;
ut_a ( n_thrs > 0 & & thr ! = NULL ) ;
ut_ad ( purge_sys - > head < = purge_sys - > tail ) ;
ut_ad ( purge_sys . head < = purge_sys . tail ) ;
i = 0 ;
@ -1413,11 +1423,11 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
/* Track the max {trx_id, undo_no} for truncating the
UNDO logs once we have purged the records . */
if ( purge_sys - > head < = purge_sys - > tail ) {
purge_sys - > head = purge_sys - > tail ;
if ( purge_sys . head < = purge_sys . tail ) {
purge_sys . head = purge_sys . tail ;
}
/* Fetch the next record, and advance the purge_sys-> tail. */
/* Fetch the next record, and advance the purge_sys. tail. */
purge_rec - > undo_rec = trx_purge_fetch_next_rec (
& purge_rec - > roll_ptr , & n_pages_handled , node - > heap ) ;
@ -1445,13 +1455,13 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
thr = UT_LIST_GET_NEXT ( thrs , thr ) ;
if ( ! ( + + i % n_purge_threads ) ) {
thr = UT_LIST_GET_FIRST ( purge_sys - > query - > thrs ) ;
thr = UT_LIST_GET_FIRST ( purge_sys . query - > thrs ) ;
}
ut_a ( thr ! = NULL ) ;
}
ut_ad ( purge_sys - > head < = purge_sys - > tail ) ;
ut_ad ( purge_sys . head < = purge_sys . tail ) ;
return ( n_pages_handled ) ;
}
@ -1501,10 +1511,10 @@ static
void
trx_purge_wait_for_workers_to_complete ( )
{
ulint n_submitted = purge_sys - > n_submitted ;
ulint n_submitted = purge_sys . n_submitted ;
/* Ensure that the work queue empties out. */
while ( ( ulint ) my_atomic_loadlint ( & purge_sys - > n_completed ) ! = n_submitted ) {
while ( ( ulint ) my_atomic_loadlint ( & purge_sys . n_completed ) ! = n_submitted ) {
if ( srv_get_task_queue_length ( ) > 0 ) {
srv_release_threads ( SRV_WORKER , 1 ) ;
@ -1514,7 +1524,7 @@ trx_purge_wait_for_workers_to_complete()
}
/* None of the worker threads should be doing any work. */
ut_a ( purge_sys - > n_submitted = = purge_sys - > n_completed ) ;
ut_a ( purge_sys . n_submitted = = purge_sys . n_completed ) ;
/* There should be no outstanding tasks as long
as the worker threads are active . */
@ -1539,11 +1549,11 @@ trx_purge(
srv_dml_needed_delay = trx_purge_dml_delay ( ) ;
/* The number of tasks submitted should be completed. */
ut_a ( purge_sys - > n_submitted = = purge_sys - > n_completed ) ;
ut_a ( purge_sys . n_submitted = = purge_sys . n_completed ) ;
rw_lock_x_lock ( & purge_sys - > latch ) ;
rw_lock_x_lock ( & purge_sys . latch ) ;
trx_sys . clone_oldest_view ( ) ;
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
# ifdef UNIV_DEBUG
if ( srv_purge_view_update_only_debug ) {
@ -1561,39 +1571,38 @@ trx_purge(
/* Submit the tasks to the work queue. */
for ( i = 0 ; i < n_purge_threads - 1 ; + + i ) {
thr = que_fork_scheduler_round_robin (
purge_sys - > query , thr ) ;
purge_sys . query , thr ) ;
ut_a ( thr ! = NULL ) ;
srv_que_task_enqueue_low ( thr ) ;
}
thr = que_fork_scheduler_round_robin ( purge_sys - > query , thr ) ;
thr = que_fork_scheduler_round_robin ( purge_sys . query , thr ) ;
ut_a ( thr ! = NULL ) ;
purge_sys - > n_submitted + = n_purge_threads - 1 ;
purge_sys . n_submitted + = n_purge_threads - 1 ;
goto run_synchronously ;
/* Do it synchronously. */
} else {
thr = que_fork_scheduler_round_robin ( purge_sys - > query , NULL ) ;
thr = que_fork_scheduler_round_robin ( purge_sys . query , NULL ) ;
ut_ad ( thr ) ;
run_synchronously :
+ + purge_sys - > n_submitted ;
+ + purge_sys . n_submitted ;
que_run_threads ( thr ) ;
my_atomic_addlint (
& purge_sys - > n_completed , 1 ) ;
my_atomic_addlint ( & purge_sys . n_completed , 1 ) ;
if ( n_purge_threads > 1 ) {
trx_purge_wait_for_workers_to_complete ( ) ;
}
}
ut_a ( purge_sys - > n_submitted = = purge_sys - > n_completed ) ;
ut_a ( purge_sys . n_submitted = = purge_sys . n_completed ) ;
if ( truncate ) {
trx_purge_truncate_history ( ) ;
@ -1614,11 +1623,11 @@ trx_purge_state(void)
{
purge_state_t state ;
rw_lock_x_lock ( & purge_sys - > latch ) ;
rw_lock_x_lock ( & purge_sys . latch ) ;
state = purge_sys - > state ;
state = purge_sys . state ;
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
return ( state ) ;
}
@ -1629,9 +1638,9 @@ void
trx_purge_stop ( void )
/*================*/
{
rw_lock_x_lock ( & purge_sys - > latch ) ;
rw_lock_x_lock ( & purge_sys . latch ) ;
switch ( purge_sys - > state ) {
switch ( purge_sys . state ) {
case PURGE_STATE_INIT :
case PURGE_STATE_DISABLED :
ut_error ;
@ -1640,37 +1649,37 @@ trx_purge_stop(void)
FLUSH TABLES FOR EXPORT . */
ut_ad ( ! srv_undo_sources ) ;
unlock :
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
break ;
case PURGE_STATE_STOP :
ut_ad ( srv_n_purge_threads > 0 ) ;
+ + purge_sys - > n_stop ;
purge_sys - > state = PURGE_STATE_STOP ;
if ( ! purge_sys - > running ) {
+ + purge_sys . n_stop ;
purge_sys . state = PURGE_STATE_STOP ;
if ( ! purge_sys . running ) {
goto unlock ;
}
ib : : info ( ) < < " Waiting for purge to stop " ;
do {
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
os_thread_sleep ( 10000 ) ;
rw_lock_x_lock ( & purge_sys - > latch ) ;
} while ( purge_sys - > running ) ;
rw_lock_x_lock ( & purge_sys . latch ) ;
} while ( purge_sys . running ) ;
goto unlock ;
case PURGE_STATE_RUN :
ut_ad ( srv_n_purge_threads > 0 ) ;
+ + purge_sys - > n_stop ;
+ + purge_sys . n_stop ;
ib : : info ( ) < < " Stopping purge " ;
/* We need to wakeup the purge thread in case it is suspended,
so that it can acknowledge the state change . */
const int64_t sig_count = os_event_reset ( purge_sys - > event ) ;
purge_sys - > state = PURGE_STATE_STOP ;
const int64_t sig_count = os_event_reset ( purge_sys . event ) ;
purge_sys . state = PURGE_STATE_STOP ;
srv_purge_wakeup ( ) ;
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
/* Wait for purge coordinator to signal that it
is suspended . */
os_event_wait_low ( purge_sys - > event , sig_count ) ;
os_event_wait_low ( purge_sys . event , sig_count ) ;
}
MONITOR_INC_VALUE ( MONITOR_PURGE_STOP_COUNT , 1 ) ;
@ -1682,9 +1691,9 @@ void
trx_purge_run ( void )
/*===============*/
{
rw_lock_x_lock ( & purge_sys - > latch ) ;
rw_lock_x_lock ( & purge_sys . latch ) ;
switch ( purge_sys - > state ) {
switch ( purge_sys . state ) {
case PURGE_STATE_EXIT :
/* Shutdown must have been initiated during
FLUSH TABLES FOR EXPORT . */
@ -1695,21 +1704,21 @@ trx_purge_run(void)
ut_error ;
case PURGE_STATE_RUN :
ut_a ( ! purge_sys - > n_stop ) ;
ut_a ( ! purge_sys . n_stop ) ;
break ;
case PURGE_STATE_STOP :
ut_a ( purge_sys - > n_stop ) ;
if ( - - purge_sys - > n_stop = = 0 ) {
ut_a ( purge_sys . n_stop ) ;
if ( - - purge_sys . n_stop = = 0 ) {
ib : : info ( ) < < " Resuming purge " ;
purge_sys - > state = PURGE_STATE_RUN ;
purge_sys . state = PURGE_STATE_RUN ;
}
MONITOR_INC_VALUE ( MONITOR_PURGE_RESUME_COUNT , 1 ) ;
}
rw_lock_x_unlock ( & purge_sys - > latch ) ;
rw_lock_x_unlock ( & purge_sys . latch ) ;
srv_purge_wakeup ( ) ;
}