@ -313,7 +313,7 @@ public:
if ( ! i - > second . created ) {
continue ;
}
if ( buf_block_t * block = buf_page_get_gen (
if ( buf_block_t * block = buf_page_get_low (
i - > first , univ_page_size , RW_X_LATCH , NULL ,
BUF_GET_IF_IN_POOL , __FILE__ , __LINE__ ,
& mtr , NULL ) ) {
@ -2293,6 +2293,99 @@ static void recv_read_in_area(const page_id_t page_id)
mutex_enter ( & recv_sys - > mutex ) ;
}
/** This is another low level function for the recovery system
to create a page which has buffered page intialization redo log records .
@ param [ in ] page_id page to be created using redo logs
@ param [ in , out ] recv_addr Hashed redo logs for the given page id
@ return whether the page creation successfully */
static buf_block_t * recv_recovery_create_page_low ( const page_id_t page_id ,
recv_addr_t * recv_addr )
{
mtr_t mtr ;
mlog_init_t : : init & i = mlog_init . last ( page_id ) ;
const lsn_t end_lsn = UT_LIST_GET_LAST ( recv_addr - > rec_list ) - > end_lsn ;
if ( end_lsn < i . lsn )
{
DBUG_LOG ( " ib_log " , " skip log for page "
< < page_id
< < " LSN " < < end_lsn
< < " < " < < i . lsn ) ;
recv_addr - > state = RECV_PROCESSED ;
ignore :
ut_a ( recv_sys - > n_addrs ) ;
recv_sys - > n_addrs - - ;
return NULL ;
}
fil_space_t * space = fil_space_acquire ( recv_addr - > space ) ;
if ( ! space )
{
recv_addr - > state = RECV_PROCESSED ;
goto ignore ;
}
if ( space - > enable_lsn )
{
init_fail :
fil_space_release ( space ) ;
recv_addr - > state = RECV_NOT_PROCESSED ;
return NULL ;
}
/* Determine if a tablespace could be for an internal table
for FULLTEXT INDEX . For those tables , no MLOG_INDEX_LOAD record
used to be written when redo logging was disabled . Hence , we
cannot optimize away page reads , because all the redo
log records for initializing and modifying the page in the
past could be older than the page in the data file .
The check is too broad , causing all
tables whose names start with FTS_ to skip the optimization . */
if ( strstr ( space - > name , " /FTS_ " ) )
goto init_fail ;
mtr . start ( ) ;
mtr . set_log_mode ( MTR_LOG_NONE ) ;
buf_block_t * block = buf_page_create ( page_id , page_size_t ( space - > flags ) ,
& mtr ) ;
if ( recv_addr - > state = = RECV_PROCESSED )
/* The page happened to exist in the buffer pool, or it was
just being read in . Before buf_page_get_with_no_latch ( ) returned ,
all changes must have been applied to the page already . */
mtr . commit ( ) ;
else
{
i . created = true ;
buf_block_dbg_add_level ( block , SYNC_NO_ORDER_CHECK ) ;
mtr . x_latch_at_savepoint ( 0 , block ) ;
recv_recover_page ( block , mtr , recv_addr , i . lsn ) ;
ut_ad ( mtr . has_committed ( ) ) ;
}
fil_space_release ( space ) ;
return block ;
}
/** This is a low level function for the recovery system
to create a page which has buffered intialized redo log records .
@ param [ in ] page_id page to be created using redo logs
@ return whether the page creation successfully */
buf_block_t * recv_recovery_create_page_low ( const page_id_t page_id )
{
buf_block_t * block = NULL ;
mutex_enter ( & recv_sys - > mutex ) ;
recv_addr_t * recv_addr = recv_get_fil_addr_struct ( page_id . space ( ) ,
page_id . page_no ( ) ) ;
if ( recv_addr & & recv_addr - > state = = RECV_WILL_NOT_READ )
{
block = recv_recovery_create_page_low ( page_id , recv_addr ) ;
}
mutex_exit ( & recv_sys - > mutex ) ;
return block ;
}
/** Apply the hash table of stored log records to persistent data pages.
@ param [ in ] last_batch whether the change buffer merge will be
performed as part of the operation */
@ -2384,7 +2477,7 @@ ignore:
apply :
mtr . start ( ) ;
mtr . set_log_mode ( MTR_LOG_NONE ) ;
if ( buf_block_t * block = buf_page_get_gen (
if ( buf_block_t * block = buf_page_get_low (
page_id , univ_page_size ,
RW_X_LATCH , NULL ,
BUF_GET_IF_IN_POOL ,
@ -2398,77 +2491,9 @@ apply:
mtr . commit ( ) ;
recv_read_in_area ( page_id ) ;
}
} else {
mlog_init_t : : init & i = mlog_init . last ( page_id ) ;
const lsn_t end_lsn = UT_LIST_GET_LAST (
recv_addr - > rec_list ) - > end_lsn ;
if ( end_lsn < i . lsn ) {
DBUG_LOG ( " ib_log " , " skip log for page "
< < page_id
< < " LSN " < < end_lsn
< < " < " < < i . lsn ) ;
skip :
recv_addr - > state = RECV_PROCESSED ;
goto ignore ;
}
fil_space_t * space = fil_space_acquire (
recv_addr - > space ) ;
if ( ! space ) {
goto skip ;
}
if ( space - > enable_lsn ) {
do_read :
fil_space_release ( space ) ;
recv_addr - > state = RECV_NOT_PROCESSED ;
goto apply ;
}
/* Determine if a tablespace could be
for an internal table for FULLTEXT INDEX .
For those tables , no MLOG_INDEX_LOAD record
used to be written when redo logging was
disabled . Hence , we cannot optimize
away page reads , because all the redo
log records for initializing and
modifying the page in the past could
be older than the page in the data
file .
The check is too broad , causing all
tables whose names start with FTS_ to
skip the optimization . */
if ( strstr ( space - > name , " /FTS_ " ) ) {
goto do_read ;
}
mtr . start ( ) ;
mtr . set_log_mode ( MTR_LOG_NONE ) ;
buf_block_t * block = buf_page_create (
page_id , page_size_t ( space - > flags ) ,
& mtr ) ;
if ( recv_addr - > state = = RECV_PROCESSED ) {
/* The page happened to exist
in the buffer pool , or it was
just being read in . Before
buf_page_get_with_no_latch ( )
returned , all changes must have
been applied to the page already . */
mtr . commit ( ) ;
} else {
i . created = true ;
buf_block_dbg_add_level (
block , SYNC_NO_ORDER_CHECK ) ;
mtr . x_latch_at_savepoint ( 0 , block ) ;
recv_recover_page ( block , mtr ,
recv_addr , i . lsn ) ;
ut_ad ( mtr . has_committed ( ) ) ;
}
fil_space_release ( space ) ;
} else if ( ! recv_recovery_create_page_low (
page_id , recv_addr ) ) {
goto apply ;
}
}
}