@ -1,6 +1,6 @@
/*****************************************************************************
/*****************************************************************************
Copyright ( c ) 1996 , 2009 , Innobase Oy . All Rights Reserved .
Copyright ( c ) 1996 , 2011 , Innobase Oy . All Rights Reserved .
This program is free software ; you can redistribute it and / or modify it under
This program is free software ; you can redistribute it and / or modify it under
the terms of the GNU General Public License as published by the Free Software
the terms of the GNU General Public License as published by the Free Software
@ -57,8 +57,8 @@ UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
# endif /* UNIV_PFS_RWLOCK */
# endif /* UNIV_PFS_RWLOCK */
# ifdef UNIV_PFS_MUTEX
# ifdef UNIV_PFS_MUTEX
/* Key to register purge_sys_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t purge_sys_mutex_key ;
/* Key to register purge_sys_bh_ mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t purge_sys_bh_ mutex_key ;
# endif /* UNIV_PFS_MUTEX */
# endif /* UNIV_PFS_MUTEX */
/*****************************************************************/ /**
/*****************************************************************/ /**
@ -219,13 +219,16 @@ Creates the global purge system control structure and inits the history
mutex . */
mutex . */
UNIV_INTERN
UNIV_INTERN
void
void
trx_purge_sys_create ( void )
/*======================*/
trx_purge_sys_create (
/*=================*/
ib_bh_t * ib_bh ) /*!< in, own: UNDO log min binary heap */
{
{
ut_ad ( mutex_own ( & kernel_mutex ) ) ;
ut_ad ( mutex_own ( & kernel_mutex ) ) ;
purge_sys = mem_alloc ( sizeof ( trx_purge_t ) ) ;
purge_sys = mem_z alloc ( sizeof ( trx_purge_t ) ) ;
/* Take ownership of ib_bh, we are responsible for freeing it. */
purge_sys - > ib_bh = ib_bh ;
purge_sys - > state = TRX_STOP_PURGE ;
purge_sys - > state = TRX_STOP_PURGE ;
purge_sys - > n_pages_handled = 0 ;
purge_sys - > n_pages_handled = 0 ;
@ -237,8 +240,9 @@ trx_purge_sys_create(void)
rw_lock_create ( trx_purge_latch_key ,
rw_lock_create ( trx_purge_latch_key ,
& purge_sys - > latch , SYNC_PURGE_LATCH ) ;
& purge_sys - > latch , SYNC_PURGE_LATCH ) ;
mutex_create ( purge_sys_mutex_key ,
& purge_sys - > mutex , SYNC_PURGE_SYS ) ;
mutex_create (
purge_sys_bh_mutex_key , & purge_sys - > bh_mutex ,
SYNC_PURGE_QUEUE ) ;
purge_sys - > heap = mem_heap_create ( 256 ) ;
purge_sys - > heap = mem_heap_create ( 256 ) ;
@ -288,9 +292,12 @@ trx_purge_sys_close(void)
trx_undo_arr_free ( purge_sys - > arr ) ;
trx_undo_arr_free ( purge_sys - > arr ) ;
rw_lock_free ( & purge_sys - > latch ) ;
rw_lock_free ( & purge_sys - > latch ) ;
mutex_free ( & purge_sys - > mutex ) ;
mutex_free ( & purge_sys - > bh_ mutex) ;
mem_heap_free ( purge_sys - > heap ) ;
mem_heap_free ( purge_sys - > heap ) ;
ib_bh_free ( purge_sys - > ib_bh ) ;
mem_free ( purge_sys ) ;
mem_free ( purge_sys ) ;
purge_sys = NULL ;
purge_sys = NULL ;
@ -311,34 +318,31 @@ trx_purge_add_update_undo_to_history(
mtr_t * mtr ) /*!< in: mtr */
mtr_t * mtr ) /*!< in: mtr */
{
{
trx_undo_t * undo ;
trx_undo_t * undo ;
trx_rseg_t * rseg ;
trx_rsegf_t * rseg_header ;
trx_rsegf_t * rseg_header ;
# ifdef UNIV_DEBUG
trx_usegf_t * seg_header ;
# endif /* UNIV_DEBUG */
trx_ulogf_t * undo_header ;
trx_ulogf_t * undo_header ;
ulint hist_size ;
undo = trx - > update_undo ;
undo = trx - > update_undo ;
ut_ad ( undo ) ;
ut_ad ( undo ) ;
rseg = undo - > rseg ;
ut_ad ( mutex_own ( & undo - > rseg - > mutex ) ) ;
ut_ad ( mutex_own ( & ( rseg - > mutex ) ) ) ;
rseg_header = trx_rsegf_get ( rseg - > space , rseg - > zip_size ,
rseg - > page_no , mtr ) ;
rseg_header = trx_rsegf_get (
undo - > rseg - > space , undo - > rseg - > zip_size , undo - > rseg - > page_no ,
mtr ) ;
undo_header = undo_page + undo - > hdr_offset ;
undo_header = undo_page + undo - > hdr_offset ;
/* Add the log as the first in the history list */
if ( undo - > state ! = TRX_UNDO_CACHED ) {
ulint hist_size ;
# ifdef UNIV_DEBUG
# ifdef UNIV_DEBUG
seg_header = undo_page + TRX_UNDO_SEG_HDR ;
trx_usegf_t * seg_header = undo_page + TRX_UNDO_SEG_HDR ;
# endif /* UNIV_DEBUG */
# endif /* UNIV_DEBUG */
if ( undo - > state ! = TRX_UNDO_CACHED ) {
/* The undo log segment will not be reused */
/* The undo log segment will not be reused */
if ( undo - > id > = TRX_RSEG_N_SLOTS ) {
if ( UNIV_UNLIKELY ( undo - > id > = TRX_RSEG_N_SLOTS ) ) {
fprintf ( stderr ,
fprintf ( stderr ,
" InnoDB: Error: undo->id is %lu \n " ,
" InnoDB: Error: undo->id is %lu \n " ,
( ulong ) undo - > id ) ;
( ulong ) undo - > id ) ;
@ -347,42 +351,50 @@ trx_purge_add_update_undo_to_history(
trx_rsegf_set_nth_undo ( rseg_header , undo - > id , FIL_NULL , mtr ) ;
trx_rsegf_set_nth_undo ( rseg_header , undo - > id , FIL_NULL , mtr ) ;
hist_size = mtr_read_ulint ( rseg_header + TRX_RSEG_HISTORY_SIZE ,
MLOG_4BYTES , mtr ) ;
hist_size = mtr_read_ulint (
rseg_header + TRX_RSEG_HISTORY_SIZE , MLOG_4BYTES , mtr ) ;
ut_ad ( undo - > size = = flst_get_len (
ut_ad ( undo - > size = = flst_get_len (
seg_header + TRX_UNDO_PAGE_LIST , mtr ) ) ;
seg_header + TRX_UNDO_PAGE_LIST , mtr ) ) ;
mlog_write_ulint ( rseg_header + TRX_RSEG_HISTORY_SIZE ,
hist_size + undo - > size , MLOG_4BYTES , mtr ) ;
mlog_write_ulint (
rseg_header + TRX_RSEG_HISTORY_SIZE ,
hist_size + undo - > size , MLOG_4BYTES , mtr ) ;
}
}
/* Add the log as the first in the history list */
flst_add_first ( rseg_header + TRX_RSEG_HISTORY ,
undo_header + TRX_UNDO_HISTORY_NODE , mtr ) ;
mutex_enter ( & kernel_mutex ) ;
trx_sys - > rseg_history_len + + ;
mutex_exit ( & kernel_mutex ) ;
if ( ! ( trx_sys - > rseg_history_len % srv_purge_batch_size ) ) {
/* Inform the purge thread that there is work to do. */
srv_wake_purge_thread_if_not_active ( ) ;
}
flst_add_first (
rseg_header + TRX_RSEG_HISTORY ,
undo_header + TRX_UNDO_HISTORY_NODE , mtr ) ;
/* Write the trx number to the undo log header */
/* Write the trx number to the undo log header */
mlog_write_ull ( undo_header + TRX_UNDO_TRX_NO , trx - > no , mtr ) ;
mlog_write_ull ( undo_header + TRX_UNDO_TRX_NO , trx - > no , mtr ) ;
/* Write information about delete markings to the undo log header */
/* Write information about delete markings to the undo log header */
if ( ! undo - > del_marks ) {
if ( ! undo - > del_marks ) {
mlog_write_ulint ( undo_header + TRX_UNDO_DEL_MARKS , FALSE ,
MLOG_2BYTES , mtr ) ;
mlog_write_ulint (
undo_header + TRX_UNDO_DEL_MARKS , FALSE ,
MLOG_2BYTES , mtr ) ;
}
}
if ( rseg - > last_page_no = = FIL_NULL ) {
if ( undo - > rseg - > last_page_no = = FIL_NULL ) {
undo - > rseg - > last_trx_no = trx - > no ;
undo - > rseg - > last_offset = undo - > hdr_offset ;
undo - > rseg - > last_page_no = undo - > hdr_page_no ;
undo - > rseg - > last_del_marks = undo - > del_marks ;
rseg - > last_page_no = undo - > hdr_page_no ;
rseg - > last_offset = undo - > hdr_offset ;
rseg - > last_trx_no = trx - > no ;
rseg - > last_del_marks = undo - > del_marks ;
/* FIXME: Add a bin heap validate function to check that
the rseg exists . */
}
mutex_enter ( & kernel_mutex ) ;
trx_sys - > rseg_history_len + + ;
mutex_exit ( & kernel_mutex ) ;
if ( ! ( trx_sys - > rseg_history_len % srv_purge_batch_size ) ) {
/* Inform the purge thread that there is work to do. */
srv_wake_purge_thread_if_not_active ( ) ;
}
}
}
}
@ -411,7 +423,6 @@ trx_purge_free_segment(
/* fputs("Freeing an update undo log segment\n", stderr); */
/* fputs("Freeing an update undo log segment\n", stderr); */
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
loop :
loop :
mtr_start ( & mtr ) ;
mtr_start ( & mtr ) ;
mutex_enter ( & ( rseg - > mutex ) ) ;
mutex_enter ( & ( rseg - > mutex ) ) ;
@ -515,8 +526,6 @@ trx_purge_truncate_rseg_history(
mtr_t mtr ;
mtr_t mtr ;
trx_id_t undo_trx_no ;
trx_id_t undo_trx_no ;
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
mtr_start ( & mtr ) ;
mtr_start ( & mtr ) ;
mutex_enter ( & ( rseg - > mutex ) ) ;
mutex_enter ( & ( rseg - > mutex ) ) ;
@ -609,10 +618,8 @@ trx_purge_truncate_history(void)
trx_id_t limit_trx_no ;
trx_id_t limit_trx_no ;
undo_no_t limit_undo_no ;
undo_no_t limit_undo_no ;
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
trx_purge_arr_get_biggest ( purge_sys - > arr , & limit_trx_no ,
& limit_undo_no ) ;
trx_purge_arr_get_biggest (
purge_sys - > arr , & limit_trx_no , & limit_undo_no ) ;
if ( limit_trx_no = = 0 ) {
if ( limit_trx_no = = 0 ) {
@ -630,34 +637,29 @@ trx_purge_truncate_history(void)
ut_ad ( limit_trx_no < = purge_sys - > view - > low_limit_no ) ;
ut_ad ( limit_trx_no < = purge_sys - > view - > low_limit_no ) ;
rseg = UT_LIST_GET_FIRST ( trx_sys - > rseg_list ) ;
for ( rseg = UT_LIST_GET_FIRST ( trx_sys - > rseg_list ) ;
rseg ! = NULL ;
rseg = UT_LIST_GET_NEXT ( rseg_list , rseg ) ) {
while ( rseg ) {
trx_purge_truncate_rseg_history ( rseg , limit_trx_no ,
limit_undo_no ) ;
rseg = UT_LIST_GET_NEXT ( rseg_list , rseg ) ;
trx_purge_truncate_rseg_history (
rseg , limit_trx_no , limit_undo_no ) ;
}
}
}
}
/********************************************************************/ /**
/********************************************************************/ /**
Does a truncate if the purge array is empty . NOTE that when this function is
Does a truncate if the purge array is empty . NOTE that when this function is
called , the caller must not have any latches on undo log pages !
@ return TRUE if array empty */
called , the caller must not have any latches on undo log pages ! */
UNIV_INLINE
UNIV_INLINE
ibool
void
trx_purge_truncate_if_arr_empty ( void )
trx_purge_truncate_if_arr_empty ( void )
/*=================================*/
/*=================================*/
{
{
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
static ulint count ;
if ( purge_sys - > arr - > n_used = = 0 ) {
if ( ! ( + + count % TRX_SYS_N_RSEGS ) & & purge_sys - > arr - > n_used = = 0 ) {
trx_purge_truncate_history ( ) ;
trx_purge_truncate_history ( ) ;
return ( TRUE ) ;
}
}
return ( FALSE ) ;
}
}
/***********************************************************************/ /**
/***********************************************************************/ /**
@ -675,8 +677,8 @@ trx_purge_rseg_get_next_history_log(
trx_id_t trx_no ;
trx_id_t trx_no ;
ibool del_marks ;
ibool del_marks ;
mtr_t mtr ;
mtr_t mtr ;
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
rseg_queue_t rseg_queue ;
const void * ptr ;
mutex_enter ( & ( rseg - > mutex ) ) ;
mutex_enter ( & ( rseg - > mutex ) ) ;
@ -688,8 +690,9 @@ trx_purge_rseg_get_next_history_log(
mtr_start ( & mtr ) ;
mtr_start ( & mtr ) ;
undo_page = trx_undo_page_get_s_latched ( rseg - > space , rseg - > zip_size ,
rseg - > last_page_no , & mtr ) ;
undo_page = trx_undo_page_get_s_latched (
rseg - > space , rseg - > zip_size , rseg - > last_page_no , & mtr ) ;
log_hdr = undo_page + rseg - > last_offset ;
log_hdr = undo_page + rseg - > last_offset ;
/* Increase the purge page count by one for every handled log */
/* Increase the purge page count by one for every handled log */
@ -698,6 +701,7 @@ trx_purge_rseg_get_next_history_log(
prev_log_addr = trx_purge_get_log_from_hist (
prev_log_addr = trx_purge_get_log_from_hist (
flst_get_prev_addr ( log_hdr + TRX_UNDO_HISTORY_NODE , & mtr ) ) ;
flst_get_prev_addr ( log_hdr + TRX_UNDO_HISTORY_NODE , & mtr ) ) ;
if ( prev_log_addr . page = = FIL_NULL ) {
if ( prev_log_addr . page = = FIL_NULL ) {
/* No logs left in the history list */
/* No logs left in the history list */
@ -712,11 +716,11 @@ trx_purge_rseg_get_next_history_log(
on the MySQL mailing list on Nov 9 , 2004. The fut0lst . c
on the MySQL mailing list on Nov 9 , 2004. The fut0lst . c
file - based list was corrupt . The prev node pointer was
file - based list was corrupt . The prev node pointer was
FIL_NULL , even though the list length was over 8 million nodes !
FIL_NULL , even though the list length was over 8 million nodes !
We assume that purge truncates the history list in moderat e
We assume that purge truncates the history list in larg e
size pieces , and if we here reach the head of the list , the
size pieces , and if we here reach the head of the list , the
list cannot be longer than 20 000 undo logs now . */
list cannot be longer than 2000 000 undo logs now . */
if ( trx_sys - > rseg_history_len > 20000 ) {
if ( trx_sys - > rseg_history_len > 2000000 ) {
ut_print_timestamp ( stderr ) ;
ut_print_timestamp ( stderr ) ;
fprintf ( stderr ,
fprintf ( stderr ,
" InnoDB: Warning: purge reached the "
" InnoDB: Warning: purge reached the "
@ -756,105 +760,150 @@ trx_purge_rseg_get_next_history_log(
rseg - > last_trx_no = trx_no ;
rseg - > last_trx_no = trx_no ;
rseg - > last_del_marks = del_marks ;
rseg - > last_del_marks = del_marks ;
rseg_queue . rseg = rseg ;
rseg_queue . trx_no = rseg - > last_trx_no ;
/* Purge can also produce events, however these are already ordered
in the rollback segment and any user generated event will be greater
than the events that Purge produces . ie . Purge can never produce
events from an empty rollback segment . */
mutex_enter ( & purge_sys - > bh_mutex ) ;
ptr = ib_bh_push ( purge_sys - > ib_bh , & rseg_queue ) ;
ut_a ( ptr ! = NULL ) ;
mutex_exit ( & purge_sys - > bh_mutex ) ;
mutex_exit ( & ( rseg - > mutex ) ) ;
mutex_exit ( & ( rseg - > mutex ) ) ;
}
}
/***********************************************************************/ /**
/***********************************************************************/ /**
Chooses the next undo log to purge and updates the info in purge_sys . This
function is used to initialize purge_sys when the next record to purge is
not known , and also to update the purge system info on the next record when
purge has handled the whole undo log for a transaction . */
Chooses the rollback segment with the smallest trx_id .
@ return zip_size if log is for a compressed table , ULINT_UNDEFINED if
no rollback segments to purge , 0 for non compressed tables . */
static
static
void
trx_purge_choose_next_log ( void )
/*===========================*/
ulint
trx_purge_get_rseg_with_min_trx_id (
/*===============================*/
trx_purge_t * purge_sys ) /*!< in/out: purge instance */
{
{
trx_undo_rec_t * rec ;
trx_rseg_t * rseg ;
trx_rseg_t * min_rseg ;
trx_id_t min_trx_no ;
ulint space = 0 ; /* remove warning (??? bug ???) */
ulint zip_size = 0 ;
ulint zip_size = 0 ;
ulint page_no = 0 ; /* remove warning (??? bug ???) */
ulint offset = 0 ; /* remove warning (??? bug ???) */
mtr_t mtr ;
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
ut_ad ( purge_sys - > next_stored = = FALSE ) ;
mutex_enter ( & purge_sys - > bh_mutex ) ;
rseg = UT_LIST_GET_FIRST ( trx_sys - > rseg_list ) ;
/* Only purge consumes events from the binary heap, user
threads only produce the events . */
min_trx_no = IB_ULONGLONG_MAX ;
if ( ! ib_bh_is_empty ( purge_sys - > ib_bh ) ) {
trx_rseg_t * rseg ;
min_rseg = NULL ;
rseg = ( ( rseg_queue_t * ) ib_bh_first ( purge_sys - > ib_bh ) ) - > rseg ;
ib_bh_pop ( purge_sys - > ib_bh ) ;
while ( rseg ) {
mutex_enter ( & ( rseg - > mutex ) ) ;
mutex_exit ( & purge_sys - > bh_mutex ) ;
if ( rseg - > last_page_no ! = FIL_NULL ) {
purge_sys - > rseg = rseg ;
} else {
mutex_exit ( & purge_sys - > bh_mutex ) ;
if ( min_rseg = = NULL
| | min_trx_no > rseg - > last_trx_no ) {
purge_sys - > rseg = NULL ;
min_rseg = rseg ;
min_trx_no = rseg - > last_trx_no ;
space = rseg - > space ;
zip_size = rseg - > zip_size ;
ut_a ( space = = 0 ) ; /* We assume in purge of
externally stored fields
that space id = = 0 */
page_no = rseg - > last_page_no ;
offset = rseg - > last_offset ;
}
}
return ( ULINT_UNDEFINED ) ;
}
mutex_exit ( & ( rseg - > mutex ) ) ;
ut_a ( purge_sys - > rseg ! = NULL ) ;
rseg = UT_LIST_GET_NEXT ( rseg_list , rseg ) ;
}
mutex_enter ( & purge_sys - > rseg - > mutex ) ;
if ( min_rseg = = NULL ) {
ut_a ( purge_sys - > rseg - > last_page_no ! = FIL_NULL ) ;
return ;
}
/* We assume in purge of externally stored fields
that space id = = 0 */
ut_a ( purge_sys - > rseg - > space = = 0 ) ;
mtr_start ( & mtr ) ;
zip_size = purge_sys - > rseg - > zip_size ;
if ( ! min_rseg - > last_del_marks ) {
/* No need to purge this log */
ut_a ( purge_sys - > purge_trx_no < = purge_sys - > rseg - > last_trx_no ) ;
rec = & trx_purge_dummy_rec ;
} else {
rec = trx_undo_get_first_rec ( space , zip_size , page_no , offset ,
RW_S_LATCH , & mtr ) ;
if ( rec = = NULL ) {
/* Undo log empty */
purge_sys - > purge_trx_no = purge_sys - > rseg - > last_trx_no ;
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 ) ;
return ( zip_size ) ;
}
/***********************************************************************/ /**
Position the purge sys " iterator " on the undo record to use for purging . */
static
void
trx_purge_read_undo_rec (
/*====================*/
trx_purge_t * purge_sys , /*!< in/out: purge instance */
ulint zip_size ) /*!< in: block size or 0 */
{
ulint page_no ;
ulint offset = 0 ;
ib_uint64_t undo_no = 0 ;
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 - > last_del_marks ) {
mtr_t mtr ;
trx_undo_rec_t * undo_rec ;
rec = & trx_purge_dummy_rec ;
mtr_start ( & mtr ) ;
undo_rec = trx_undo_get_first_rec (
0 /* System space id */ , zip_size ,
purge_sys - > hdr_page_no ,
purge_sys - > hdr_offset , RW_S_LATCH , & mtr ) ;
if ( undo_rec ! = NULL ) {
offset = page_offset ( undo_rec ) ;
undo_no = trx_undo_rec_get_undo_no ( undo_rec ) ;
page_no = page_get_page_no ( page_align ( undo_rec ) ) ;
}
}
mtr_commit ( & mtr ) ;
}
}
purge_sys - > offset = offset ;
purge_sys - > page_no = page_no ;
purge_sys - > purge_undo_no = undo_no ;
purge_sys - > next_stored = TRUE ;
purge_sys - > next_stored = TRUE ;
purge_sys - > rseg = min_rseg ;
}
purge_sys - > hdr_page_no = page_no ;
purge_sys - > hdr_offset = offset ;
/***********************************************************************/ /**
Chooses the next undo log to purge and updates the info in purge_sys . This
function is used to initialize purge_sys when the next record to purge is
not known , and also to update the purge system info on the next record when
purge has handled the whole undo log for a transaction . */
static
void
trx_purge_choose_next_log ( void )
/*===========================*/
{
ulint zip_size ;
purge_sys - > purge_trx_no = min_trx_no ;
ut_ad ( purge_sys - > next_stored = = FALSE ) ;
if ( rec = = & trx_purge_dummy_rec ) {
zip_size = trx_purge_get_rseg_with_min_trx_id ( purge_sys ) ;
purge_sys - > purge_undo_no = 0 ;
purge_sys - > page_no = page_no ;
purge_sys - > offset = 0 ;
} else {
purge_sys - > purge_undo_no = trx_undo_rec_get_undo_no ( rec ) ;
if ( purge_sys - > rseg ! = NULL ) {
purge_sys - > page_no = page_get_page_no ( page_align ( rec ) ) ;
purge_sys - > offset = page_offset ( rec ) ;
trx_purge_read_undo_rec ( purge_sys , zip_size ) ;
} else {
/* There is nothing to do yet. */
os_thread_yield ( ) ;
}
}
mtr_commit ( & mtr ) ;
}
}
/***********************************************************************/ /**
/***********************************************************************/ /**
@ -880,7 +929,6 @@ trx_purge_get_next_rec(
ulint cmpl_info ;
ulint cmpl_info ;
mtr_t mtr ;
mtr_t mtr ;
ut_ad ( mutex_own ( & ( purge_sys - > mutex ) ) ) ;
ut_ad ( purge_sys - > next_stored ) ;
ut_ad ( purge_sys - > next_stored ) ;
space = purge_sys - > rseg - > space ;
space = purge_sys - > rseg - > space ;
@ -903,8 +951,8 @@ trx_purge_get_next_rec(
mtr_start ( & mtr ) ;
mtr_start ( & mtr ) ;
undo_page = trx_undo_page_get_s_latched ( space , zip_size ,
page_no , & mtr ) ;
undo_page = trx_undo_page_get_s_latched ( space , zip_size , page_no , & mtr ) ;
rec = undo_page + offset ;
rec = undo_page + offset ;
rec2 = rec ;
rec2 = rec ;
@ -913,9 +961,9 @@ trx_purge_get_next_rec(
/* Try first to find the next record which requires a purge
/* Try first to find the next record which requires a purge
operation from the same page of the same undo log */
operation from the same page of the same undo log */
next_rec = trx_undo_page_get_next_rec ( rec2 ,
purge_sys - > hdr_page_no ,
purge_sys - > hdr_offset ) ;
next_rec = trx_undo_page_get_next_rec (
rec2 , purge_sys - > hdr_page_no , purge_sys - > hdr_offset ) ;
if ( next_rec = = NULL ) {
if ( next_rec = = NULL ) {
rec2 = trx_undo_get_next_rec (
rec2 = trx_undo_get_next_rec (
rec2 , purge_sys - > hdr_page_no ,
rec2 , purge_sys - > hdr_page_no ,
@ -995,17 +1043,12 @@ trx_purge_fetch_next_rec(
{
{
trx_undo_rec_t * undo_rec ;
trx_undo_rec_t * undo_rec ;
mutex_enter ( & ( purge_sys - > mutex ) ) ;
if ( purge_sys - > state = = TRX_STOP_PURGE ) {
if ( purge_sys - > state = = TRX_STOP_PURGE ) {
trx_purge_truncate_if_arr_empty ( ) ;
trx_purge_truncate_if_arr_empty ( ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
return ( NULL ) ;
return ( NULL ) ;
}
if ( ! purge_sys - > next_stored ) {
} else if ( ! purge_sys - > next_stored ) {
trx_purge_choose_next_log ( ) ;
trx_purge_choose_next_log ( ) ;
if ( ! purge_sys - > next_stored ) {
if ( ! purge_sys - > next_stored ) {
@ -1020,8 +1063,6 @@ trx_purge_fetch_next_rec(
( ulong ) purge_sys - > n_pages_handled ) ;
( ulong ) purge_sys - > n_pages_handled ) ;
}
}
mutex_exit ( & ( purge_sys - > mutex ) ) ;
return ( NULL ) ;
return ( NULL ) ;
}
}
}
}
@ -1032,18 +1073,12 @@ trx_purge_fetch_next_rec(
trx_purge_truncate_if_arr_empty ( ) ;
trx_purge_truncate_if_arr_empty ( ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
return ( NULL ) ;
return ( NULL ) ;
}
if ( purge_sys - > purge_trx_no > = purge_sys - > view - > low_limit_no ) {
} else if ( purge_sys - > purge_trx_no > = purge_sys - > view - > low_limit_no ) {
purge_sys - > state = TRX_STOP_PURGE ;
purge_sys - > state = TRX_STOP_PURGE ;
trx_purge_truncate_if_arr_empty ( ) ;
trx_purge_truncate_if_arr_empty ( ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
return ( NULL ) ;
return ( NULL ) ;
}
}
@ -1052,12 +1087,13 @@ trx_purge_fetch_next_rec(
( ullint ) purge_sys - > purge_trx_no ,
( ullint ) purge_sys - > purge_trx_no ,
( ullint ) purge_sys - > purge_undo_no ) ; */
( ullint ) purge_sys - > purge_undo_no ) ; */
* roll_ptr = trx_undo_build_roll_ptr ( FALSE , ( purge_sys - > rseg ) - > id ,
purge_sys - > page_no ,
purge_sys - > offset ) ;
* cell = trx_purge_arr_store_info ( purge_sys - > purge_trx_no ,
purge_sys - > purge_undo_no ) ;
* roll_ptr = trx_undo_build_roll_ptr (
FALSE , ( purge_sys - > rseg ) - > id , purge_sys - > page_no ,
purge_sys - > offset ) ;
* cell = trx_purge_arr_store_info (
purge_sys - > purge_trx_no , purge_sys - > purge_undo_no ) ;
ut_ad ( purge_sys - > purge_trx_no < purge_sys - > view - > low_limit_no ) ;
ut_ad ( purge_sys - > purge_trx_no < purge_sys - > view - > low_limit_no ) ;
@ -1066,8 +1102,6 @@ trx_purge_fetch_next_rec(
undo_rec = trx_purge_get_next_rec ( heap ) ;
undo_rec = trx_purge_get_next_rec ( heap ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
return ( undo_rec ) ;
return ( undo_rec ) ;
}
}
@ -1079,11 +1113,7 @@ trx_purge_rec_release(
/*==================*/
/*==================*/
trx_undo_inf_t * cell ) /*!< in: storage cell */
trx_undo_inf_t * cell ) /*!< in: storage cell */
{
{
mutex_enter ( & ( purge_sys - > mutex ) ) ;
trx_purge_arr_remove_info ( cell ) ;
trx_purge_arr_remove_info ( cell ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
}
}
/*******************************************************************/ /**
/*******************************************************************/ /**
@ -1097,23 +1127,11 @@ trx_purge(
purge in one batch */
purge in one batch */
{
{
que_thr_t * thr ;
que_thr_t * thr ;
/* que_thr_t* thr2; */
ulint old_pages_handled ;
ulint old_pages_handled ;
mutex_enter ( & ( purge_sys - > mutex ) ) ;
if ( purge_sys - > trx - > n_active_thrs > 0 ) {
ut_a ( purge_sys - > trx - > n_active_thrs = = 0 ) ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
/* Should not happen */
ut_error ;
return ( 0 ) ;
}
rw_lock_x_lock ( & ( purge_sys - > latch ) ) ;
rw_lock_x_lock ( & purge_sys - > latch ) ;
mutex_enter ( & kernel_mutex ) ;
mutex_enter ( & kernel_mutex ) ;
@ -1147,8 +1165,9 @@ trx_purge(
}
}
}
}
purge_sys - > view = read_view_oldest_copy_or_open_new ( 0 ,
purge_sys - > heap ) ;
purge_sys - > view = read_view_oldest_copy_or_open_new (
0 , purge_sys - > heap ) ;
mutex_exit ( & kernel_mutex ) ;
mutex_exit ( & kernel_mutex ) ;
rw_lock_x_unlock ( & ( purge_sys - > latch ) ) ;
rw_lock_x_unlock ( & ( purge_sys - > latch ) ) ;
@ -1159,7 +1178,6 @@ trx_purge(
old_pages_handled = purge_sys - > n_pages_handled ;
old_pages_handled = purge_sys - > n_pages_handled ;
mutex_exit ( & ( purge_sys - > mutex ) ) ;
mutex_enter ( & kernel_mutex ) ;
mutex_enter ( & kernel_mutex ) ;
@ -1167,15 +1185,8 @@ trx_purge(
ut_ad ( thr ) ;
ut_ad ( thr ) ;
/* thr2 = que_fork_start_command(purge_sys->query);
ut_ad ( thr2 ) ; */
mutex_exit ( & kernel_mutex ) ;
mutex_exit ( & kernel_mutex ) ;
/* srv_que_task_enqueue(thr2); */
if ( srv_print_thread_releases ) {
if ( srv_print_thread_releases ) {
fputs ( " Starting purge \n " , stderr ) ;
fputs ( " Starting purge \n " , stderr ) ;