|
|
|
@ -84,12 +84,14 @@ struct log_bitmap_struct { |
|
|
|
both the correct type and the tree does |
|
|
|
not mind its overwrite during |
|
|
|
rbt_next() tree traversal. */ |
|
|
|
ib_mutex_t mutex; /*!< mutex protecting all the fields.*/ |
|
|
|
}; |
|
|
|
|
|
|
|
/* The log parsing and bitmap output struct instance */ |
|
|
|
static struct log_bitmap_struct* log_bmp_sys; |
|
|
|
|
|
|
|
/* Mutex protecting log_bmp_sys */ |
|
|
|
static ib_mutex_t log_bmp_sys_mutex; |
|
|
|
|
|
|
|
/** File name stem for bitmap files. */ |
|
|
|
static const char* bmp_file_name_stem = "ib_modified_log_"; |
|
|
|
|
|
|
|
@ -181,28 +183,24 @@ log_online_set_page_bit( |
|
|
|
ulint space, /*!<in: log record space id */ |
|
|
|
ulint page_no)/*!<in: log record page id */ |
|
|
|
{ |
|
|
|
ulint block_start_page; |
|
|
|
ulint block_pos; |
|
|
|
uint bit_pos; |
|
|
|
ib_rbt_bound_t tree_search_pos; |
|
|
|
byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; |
|
|
|
byte *page_ptr; |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
ut_a(space != ULINT_UNDEFINED); |
|
|
|
ut_a(page_no != ULINT_UNDEFINED); |
|
|
|
|
|
|
|
block_start_page = page_no / MODIFIED_PAGE_BLOCK_ID_COUNT |
|
|
|
ulint block_start_page = page_no / MODIFIED_PAGE_BLOCK_ID_COUNT |
|
|
|
* MODIFIED_PAGE_BLOCK_ID_COUNT; |
|
|
|
block_pos = block_start_page ? (page_no % block_start_page / 8) |
|
|
|
ulint block_pos = block_start_page ? (page_no % block_start_page / 8) |
|
|
|
: (page_no / 8); |
|
|
|
bit_pos = page_no % 8; |
|
|
|
uint bit_pos = page_no % 8; |
|
|
|
|
|
|
|
byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; |
|
|
|
mach_write_to_4(search_page + MODIFIED_PAGE_SPACE_ID, space); |
|
|
|
mach_write_to_4(search_page + MODIFIED_PAGE_1ST_PAGE_ID, |
|
|
|
block_start_page); |
|
|
|
|
|
|
|
byte *page_ptr; |
|
|
|
ib_rbt_bound_t tree_search_pos; |
|
|
|
if (!rbt_search(log_bmp_sys->modified_pages, &tree_search_pos, |
|
|
|
search_page)) { |
|
|
|
page_ptr = rbt_value(byte, tree_search_pos.last); |
|
|
|
@ -604,12 +602,19 @@ log_online_is_bitmap_file( |
|
|
|
&& (!strcmp(stem, bmp_file_name_stem))); |
|
|
|
} |
|
|
|
|
|
|
|
/*********************************************************************//**
|
|
|
|
Initialize the online log following subsytem. */ |
|
|
|
/** Initialize the constant part of the log tracking subsystem */ |
|
|
|
UNIV_INTERN |
|
|
|
void |
|
|
|
log_online_init(void) |
|
|
|
{ |
|
|
|
mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys_mutex, |
|
|
|
SYNC_LOG_ONLINE); |
|
|
|
} |
|
|
|
|
|
|
|
/** Initialize the dynamic part of the log tracking subsystem */ |
|
|
|
UNIV_INTERN |
|
|
|
void |
|
|
|
log_online_read_init(void) |
|
|
|
/*======================*/ |
|
|
|
{ |
|
|
|
ibool success; |
|
|
|
lsn_t tracking_start_lsn |
|
|
|
@ -633,9 +638,6 @@ log_online_read_init(void) |
|
|
|
log_bmp_sys->read_buf = static_cast<byte *> |
|
|
|
(ut_align(log_bmp_sys->read_buf_ptr, OS_FILE_LOG_BLOCK_SIZE)); |
|
|
|
|
|
|
|
mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys->mutex, |
|
|
|
SYNC_LOG_ONLINE); |
|
|
|
|
|
|
|
/* Initialize bitmap file directory from srv_data_home and add a path
|
|
|
|
separator if needed. */ |
|
|
|
srv_data_home_len = strlen(srv_data_home); |
|
|
|
@ -775,13 +777,15 @@ log_online_read_init(void) |
|
|
|
log_set_tracked_lsn(tracking_start_lsn); |
|
|
|
} |
|
|
|
|
|
|
|
/*********************************************************************//**
|
|
|
|
Shut down the online log following subsystem. */ |
|
|
|
/** Shut down the dynamic part of the log tracking subsystem */ |
|
|
|
UNIV_INTERN |
|
|
|
void |
|
|
|
log_online_read_shutdown(void) |
|
|
|
/*==========================*/ |
|
|
|
{ |
|
|
|
mutex_enter(&log_bmp_sys_mutex); |
|
|
|
|
|
|
|
srv_track_changed_pages = FALSE; |
|
|
|
|
|
|
|
ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list; |
|
|
|
|
|
|
|
if (log_bmp_sys->out.file != os_file_invalid) { |
|
|
|
@ -797,10 +801,21 @@ log_online_read_shutdown(void) |
|
|
|
free_list_node = next; |
|
|
|
} |
|
|
|
|
|
|
|
mutex_free(&log_bmp_sys->mutex); |
|
|
|
|
|
|
|
ut_free(log_bmp_sys->read_buf_ptr); |
|
|
|
ut_free(log_bmp_sys); |
|
|
|
log_bmp_sys = NULL; |
|
|
|
|
|
|
|
srv_redo_log_thread_started = false; |
|
|
|
|
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
} |
|
|
|
|
|
|
|
/** Shut down the constant part of the log tracking subsystem */ |
|
|
|
UNIV_INTERN |
|
|
|
void |
|
|
|
log_online_shutdown(void) |
|
|
|
{ |
|
|
|
mutex_free(&log_bmp_sys_mutex); |
|
|
|
} |
|
|
|
|
|
|
|
/*********************************************************************//**
|
|
|
|
@ -846,13 +861,12 @@ void |
|
|
|
log_online_parse_redo_log(void) |
|
|
|
/*===========================*/ |
|
|
|
{ |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
byte *ptr = log_bmp_sys->parse_buf; |
|
|
|
byte *end = log_bmp_sys->parse_buf_end; |
|
|
|
|
|
|
|
ulint len = 0; |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
|
|
|
|
while (ptr != end |
|
|
|
&& log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) { |
|
|
|
|
|
|
|
@ -934,6 +948,8 @@ log_online_add_to_parse_buf( |
|
|
|
ulint skip_len) /*!< in: how much of log data to
|
|
|
|
skip */ |
|
|
|
{ |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
ulint start_offset = skip_len ? skip_len : LOG_BLOCK_HDR_SIZE; |
|
|
|
ulint end_offset |
|
|
|
= (data_len == OS_FILE_LOG_BLOCK_SIZE) |
|
|
|
@ -942,8 +958,6 @@ log_online_add_to_parse_buf( |
|
|
|
ulint actual_data_len = (end_offset >= start_offset) |
|
|
|
? end_offset - start_offset : 0; |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
|
|
|
|
ut_memcpy(log_bmp_sys->parse_buf_end, log_block + start_offset, |
|
|
|
actual_data_len); |
|
|
|
|
|
|
|
@ -966,11 +980,9 @@ log_online_parse_redo_log_block( |
|
|
|
log data should be skipped as |
|
|
|
they were parsed before */ |
|
|
|
{ |
|
|
|
ulint block_data_len; |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
|
|
|
|
block_data_len = log_block_get_data_len(log_block); |
|
|
|
ulint block_data_len = log_block_get_data_len(log_block); |
|
|
|
|
|
|
|
ut_ad(block_data_len % OS_FILE_LOG_BLOCK_SIZE == 0 |
|
|
|
|| block_data_len < OS_FILE_LOG_BLOCK_SIZE); |
|
|
|
@ -990,14 +1002,14 @@ log_online_follow_log_seg( |
|
|
|
lsn_t block_start_lsn, /*!< in: the LSN to read from */ |
|
|
|
lsn_t block_end_lsn) /*!< in: the LSN to read to */ |
|
|
|
{ |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
/* Pointer to the current OS_FILE_LOG_BLOCK-sized chunk of the read log
|
|
|
|
data to parse */ |
|
|
|
byte* log_block = log_bmp_sys->read_buf; |
|
|
|
byte* log_block_end = log_bmp_sys->read_buf |
|
|
|
+ (block_end_lsn - block_start_lsn); |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
|
|
|
|
mutex_enter(&log_sys->mutex); |
|
|
|
log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf, |
|
|
|
group, block_start_lsn, block_end_lsn, TRUE); |
|
|
|
@ -1057,11 +1069,11 @@ log_online_follow_log_group( |
|
|
|
lsn_t contiguous_lsn) /*!< in: the LSN of log block start
|
|
|
|
containing the log_parse_start_lsn */ |
|
|
|
{ |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
lsn_t block_start_lsn = contiguous_lsn; |
|
|
|
lsn_t block_end_lsn; |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
|
|
|
|
log_bmp_sys->next_parse_lsn = log_bmp_sys->start_lsn; |
|
|
|
log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf; |
|
|
|
|
|
|
|
@ -1098,20 +1110,28 @@ log_online_write_bitmap_page( |
|
|
|
/*=========================*/ |
|
|
|
const byte *block) /*!< in: block to write */ |
|
|
|
{ |
|
|
|
ibool success; |
|
|
|
|
|
|
|
ut_ad(srv_track_changed_pages); |
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
/* Simulate a write error */ |
|
|
|
DBUG_EXECUTE_IF("bitmap_page_write_error", |
|
|
|
ib_logf(IB_LOG_LEVEL_ERROR, |
|
|
|
"simulating bitmap write error in " |
|
|
|
"log_online_write_bitmap_page"); |
|
|
|
return FALSE;); |
|
|
|
|
|
|
|
success = os_file_write(log_bmp_sys->out.name, log_bmp_sys->out.file, |
|
|
|
block, log_bmp_sys->out.offset, |
|
|
|
{ |
|
|
|
ulint space_id |
|
|
|
= mach_read_from_4(block |
|
|
|
+ MODIFIED_PAGE_SPACE_ID); |
|
|
|
if (space_id > 0) { |
|
|
|
ib_logf(IB_LOG_LEVEL_ERROR, |
|
|
|
"simulating bitmap write " |
|
|
|
"error in " |
|
|
|
"log_online_write_bitmap_page " |
|
|
|
"for space ID %lu", |
|
|
|
space_id); |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
ibool success = os_file_write(log_bmp_sys->out.name, |
|
|
|
log_bmp_sys->out.file, block, |
|
|
|
log_bmp_sys->out.offset, |
|
|
|
MODIFIED_PAGE_BLOCK_SIZE); |
|
|
|
if (UNIV_UNLIKELY(!success)) { |
|
|
|
|
|
|
|
@ -1151,11 +1171,7 @@ ibool |
|
|
|
log_online_write_bitmap(void) |
|
|
|
/*=========================*/ |
|
|
|
{ |
|
|
|
ib_rbt_node_t *bmp_tree_node; |
|
|
|
const ib_rbt_node_t *last_bmp_tree_node; |
|
|
|
ibool success = TRUE; |
|
|
|
|
|
|
|
ut_ad(mutex_own(&log_bmp_sys->mutex)); |
|
|
|
ut_ad(mutex_own(&log_bmp_sys_mutex)); |
|
|
|
|
|
|
|
if (log_bmp_sys->out.offset >= srv_max_bitmap_file_size) { |
|
|
|
if (!log_online_rotate_bitmap_file(log_bmp_sys->start_lsn)) { |
|
|
|
@ -1163,9 +1179,12 @@ log_online_write_bitmap(void) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bmp_tree_node = (ib_rbt_node_t *) |
|
|
|
rbt_first(log_bmp_sys->modified_pages); |
|
|
|
last_bmp_tree_node = rbt_last(log_bmp_sys->modified_pages); |
|
|
|
ib_rbt_node_t *bmp_tree_node |
|
|
|
= (ib_rbt_node_t *)rbt_first(log_bmp_sys->modified_pages); |
|
|
|
const ib_rbt_node_t * const last_bmp_tree_node |
|
|
|
= rbt_last(log_bmp_sys->modified_pages); |
|
|
|
|
|
|
|
ibool success = TRUE; |
|
|
|
|
|
|
|
while (bmp_tree_node) { |
|
|
|
|
|
|
|
@ -1198,9 +1217,11 @@ log_online_write_bitmap(void) |
|
|
|
rbt_next(log_bmp_sys->modified_pages, bmp_tree_node); |
|
|
|
|
|
|
|
DBUG_EXECUTE_IF("bitmap_page_2_write_error", |
|
|
|
ut_ad(bmp_tree_node); /* 2nd page must exist */ |
|
|
|
DBUG_SET("+d,bitmap_page_write_error"); |
|
|
|
DBUG_SET("-d,bitmap_page_2_write_error");); |
|
|
|
if (bmp_tree_node) |
|
|
|
{ |
|
|
|
DBUG_SET("+d,bitmap_page_write_error"); |
|
|
|
DBUG_SET("-d,bitmap_page_2_write_error"); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
rbt_reset(log_bmp_sys->modified_pages); |
|
|
|
@ -1221,10 +1242,19 @@ log_online_follow_redo_log(void) |
|
|
|
log_group_t* group; |
|
|
|
ibool result; |
|
|
|
|
|
|
|
ut_ad(srv_track_changed_pages); |
|
|
|
ut_ad(!srv_read_only_mode); |
|
|
|
|
|
|
|
mutex_enter(&log_bmp_sys->mutex); |
|
|
|
if (!srv_track_changed_pages) |
|
|
|
return TRUE; |
|
|
|
|
|
|
|
DEBUG_SYNC_C("log_online_follow_redo_log"); |
|
|
|
|
|
|
|
mutex_enter(&log_bmp_sys_mutex); |
|
|
|
|
|
|
|
if (!srv_track_changed_pages) { |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
/* Grab the LSN of the last checkpoint, we will parse up to it */ |
|
|
|
mutex_enter(&(log_sys->mutex)); |
|
|
|
@ -1232,7 +1262,7 @@ log_online_follow_redo_log(void) |
|
|
|
mutex_exit(&(log_sys->mutex)); |
|
|
|
|
|
|
|
if (log_bmp_sys->end_lsn == log_bmp_sys->start_lsn) { |
|
|
|
mutex_exit(&log_bmp_sys->mutex); |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1255,7 +1285,7 @@ log_online_follow_redo_log(void) |
|
|
|
log_bmp_sys->start_lsn = log_bmp_sys->end_lsn; |
|
|
|
log_set_tracked_lsn(log_bmp_sys->start_lsn); |
|
|
|
|
|
|
|
mutex_exit(&log_bmp_sys->mutex); |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1602,6 +1632,8 @@ log_online_bitmap_iterator_init( |
|
|
|
{ |
|
|
|
ut_a(i); |
|
|
|
|
|
|
|
i->max_lsn = max_lsn; |
|
|
|
|
|
|
|
if (UNIV_UNLIKELY(min_lsn > max_lsn)) { |
|
|
|
|
|
|
|
/* Empty range */ |
|
|
|
@ -1710,6 +1742,9 @@ log_online_bitmap_iterator_next( |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
if (i->end_lsn >= i->max_lsn && i->last_page_in_run) |
|
|
|
return FALSE; |
|
|
|
|
|
|
|
while (!checksum_ok) |
|
|
|
{ |
|
|
|
while (i->in.size < MODIFIED_PAGE_BLOCK_SIZE |
|
|
|
@ -1805,15 +1840,21 @@ log_online_purge_changed_page_bitmaps( |
|
|
|
lsn = LSN_MAX; |
|
|
|
} |
|
|
|
|
|
|
|
bool log_bmp_sys_inited = false; |
|
|
|
if (srv_redo_log_thread_started) { |
|
|
|
/* User requests might happen with both enabled and disabled
|
|
|
|
tracking */ |
|
|
|
mutex_enter(&log_bmp_sys->mutex); |
|
|
|
log_bmp_sys_inited = true; |
|
|
|
mutex_enter(&log_bmp_sys_mutex); |
|
|
|
if (!srv_redo_log_thread_started) { |
|
|
|
log_bmp_sys_inited = false; |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!log_online_setup_bitmap_file_range(&bitmap_files, 0, LSN_MAX)) { |
|
|
|
if (srv_redo_log_thread_started) { |
|
|
|
mutex_exit(&log_bmp_sys->mutex); |
|
|
|
if (log_bmp_sys_inited) { |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
} |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
@ -1851,7 +1892,7 @@ log_online_purge_changed_page_bitmaps( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (srv_redo_log_thread_started) { |
|
|
|
if (log_bmp_sys_inited) { |
|
|
|
if (lsn > log_bmp_sys->end_lsn) { |
|
|
|
lsn_t new_file_lsn; |
|
|
|
if (lsn == LSN_MAX) { |
|
|
|
@ -1867,7 +1908,7 @@ log_online_purge_changed_page_bitmaps( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
mutex_exit(&log_bmp_sys->mutex); |
|
|
|
mutex_exit(&log_bmp_sys_mutex); |
|
|
|
} |
|
|
|
|
|
|
|
free(bitmap_files.files); |
|
|
|
|