Commit e4957de4 authored by Sergei Golubchik's avatar Sergei Golubchik

Merge branch 'merge-xtradb-5.5' into 5.5

parents 02be50a5 6010a27c
...@@ -76,7 +76,7 @@ btr_corruption_report( ...@@ -76,7 +76,7 @@ btr_corruption_report(
buf_block_get_zip_size(block), buf_block_get_zip_size(block),
BUF_PAGE_PRINT_NO_CRASH); BUF_PAGE_PRINT_NO_CRASH);
} }
buf_page_print(buf_block_get_frame_fast(block), 0, 0); buf_page_print(buf_nonnull_block_get_frame(block), 0, 0);
} }
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
...@@ -1077,7 +1077,7 @@ btr_get_size( ...@@ -1077,7 +1077,7 @@ btr_get_size(
SRV_CORRUPT_TABLE_CHECK(root, SRV_CORRUPT_TABLE_CHECK(root,
{ {
mtr_commit(mtr); mtr_commit(mtr);
return(0); return(ULINT_UNDEFINED);
}); });
if (flag == BTR_N_LEAF_PAGES) { if (flag == BTR_N_LEAF_PAGES) {
......
...@@ -469,6 +469,19 @@ innobase_is_fake_change( ...@@ -469,6 +469,19 @@ innobase_is_fake_change(
THD* thd) __attribute__((unused)); /*!< in: MySQL thread handle of the user for THD* thd) __attribute__((unused)); /*!< in: MySQL thread handle of the user for
whom the transaction is being committed */ whom the transaction is being committed */
/** Get the list of foreign keys referencing a specified table
table.
@param thd The thread handle
@param path Path to the table
@param f_key_list[out] The list of foreign keys
@return error code or zero for success */
static
int
innobase_get_parent_fk_list(
THD* thd,
const char* path,
List<FOREIGN_KEY_INFO>* f_key_list);
/******************************************************************//** /******************************************************************//**
Maps a MySQL trx isolation level code to the InnoDB isolation level code Maps a MySQL trx isolation level code to the InnoDB isolation level code
...@@ -10008,7 +10021,14 @@ ha_innobase::check( ...@@ -10008,7 +10021,14 @@ ha_innobase::check(
prebuilt->select_lock_type = LOCK_NONE; prebuilt->select_lock_type = LOCK_NONE;
if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) { bool check_result
= row_check_index_for_mysql(prebuilt, index, &n_rows);
DBUG_EXECUTE_IF(
"dict_set_index_corrupted",
if (!(index->type & DICT_CLUSTERED)) {
check_result = false;
});
if (!check_result) {
innobase_format_name( innobase_format_name(
index_name, sizeof index_name, index_name, sizeof index_name,
index->name, TRUE); index->name, TRUE);
...@@ -10344,6 +10364,73 @@ get_foreign_key_info( ...@@ -10344,6 +10364,73 @@ get_foreign_key_info(
return(pf_key_info); return(pf_key_info);
} }
/** Get the list of foreign keys referencing a specified table
table.
@param thd The thread handle
@param path Path to the table
@param f_key_list[out] The list of foreign keys */
static
void
fill_foreign_key_list(THD* thd,
const dict_table_t* table,
List<FOREIGN_KEY_INFO>* f_key_list)
{
ut_ad(mutex_own(&dict_sys->mutex));
for (dict_foreign_t* foreign
= UT_LIST_GET_FIRST(table->referenced_list);
foreign != NULL;
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
FOREIGN_KEY_INFO* pf_key_info
= get_foreign_key_info(thd, foreign);
if (pf_key_info) {
f_key_list->push_back(pf_key_info);
}
}
}
/** Get the list of foreign keys referencing a specified table
table.
@param thd The thread handle
@param path Path to the table
@param f_key_list[out] The list of foreign keys
@return error code or zero for success */
static
int
innobase_get_parent_fk_list(
THD* thd,
const char* path,
List<FOREIGN_KEY_INFO>* f_key_list)
{
ut_a(strlen(path) <= FN_REFLEN);
char norm_name[FN_REFLEN + 1];
normalize_table_name(norm_name, path);
trx_t* parent_trx = check_trx_exists(thd);
parent_trx->op_info = "getting list of referencing foreign keys";
trx_search_latch_release_if_reserved(parent_trx);
mutex_enter(&dict_sys->mutex);
dict_table_t* table
= dict_table_get_low(norm_name,
static_cast<dict_err_ignore_t>(
DICT_ERR_IGNORE_INDEX_ROOT
| DICT_ERR_IGNORE_CORRUPT));
if (!table) {
mutex_exit(&dict_sys->mutex);
return(HA_ERR_NO_SUCH_TABLE);
}
fill_foreign_key_list(thd, table, f_key_list);
mutex_exit(&dict_sys->mutex);
parent_trx->op_info = "";
return(0);
}
/*******************************************************************//** /*******************************************************************//**
Gets the list of foreign keys in this table. Gets the list of foreign keys in this table.
@return always 0, that is, always succeeds */ @return always 0, that is, always succeeds */
...@@ -10392,9 +10479,6 @@ ha_innobase::get_parent_foreign_key_list( ...@@ -10392,9 +10479,6 @@ ha_innobase::get_parent_foreign_key_list(
THD* thd, /*!< in: user thread handle */ THD* thd, /*!< in: user thread handle */
List<FOREIGN_KEY_INFO>* f_key_list) /*!< out: foreign key list */ List<FOREIGN_KEY_INFO>* f_key_list) /*!< out: foreign key list */
{ {
FOREIGN_KEY_INFO* pf_key_info;
dict_foreign_t* foreign;
ut_a(prebuilt != NULL); ut_a(prebuilt != NULL);
update_thd(ha_thd()); update_thd(ha_thd());
...@@ -10403,16 +10487,7 @@ ha_innobase::get_parent_foreign_key_list( ...@@ -10403,16 +10487,7 @@ ha_innobase::get_parent_foreign_key_list(
trx_search_latch_release_if_reserved(prebuilt->trx); trx_search_latch_release_if_reserved(prebuilt->trx);
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
fill_foreign_key_list(thd, prebuilt->table, f_key_list);
for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list);
foreign != NULL;
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
pf_key_info = get_foreign_key_info(thd, foreign);
if (pf_key_info) {
f_key_list->push_back(pf_key_info);
}
}
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
prebuilt->trx->op_info = ""; prebuilt->trx->op_info = "";
...@@ -12817,7 +12892,6 @@ innodb_track_changed_pages_validate( ...@@ -12817,7 +12892,6 @@ innodb_track_changed_pages_validate(
for update function */ for update function */
struct st_mysql_value* value) /*!< in: incoming bool */ struct st_mysql_value* value) /*!< in: incoming bool */
{ {
static bool enabled_on_startup = false;
long long intbuf = 0; long long intbuf = 0;
if (value->val_int(value, &intbuf)) { if (value->val_int(value, &intbuf)) {
...@@ -12825,8 +12899,7 @@ innodb_track_changed_pages_validate( ...@@ -12825,8 +12899,7 @@ innodb_track_changed_pages_validate(
return 1; return 1;
} }
if (srv_track_changed_pages || enabled_on_startup) { if (srv_redo_log_thread_started) {
enabled_on_startup = true;
*reinterpret_cast<ulong*>(save) *reinterpret_cast<ulong*>(save)
= static_cast<ulong>(intbuf); = static_cast<ulong>(intbuf);
return 0; return 0;
......
...@@ -1110,10 +1110,20 @@ buf_block_get_frame( ...@@ -1110,10 +1110,20 @@ buf_block_get_frame(
/*================*/ /*================*/
const buf_block_t* block) /*!< in: pointer to the control block */ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure)); __attribute__((pure));
# define buf_block_get_frame_fast(block) buf_block_get_frame(block)
/*********************************************************************//**
Gets a pointer to the memory frame of a block, where block is known not to be
NULL.
@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_nonnull_block_get_frame(
const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
#else /* UNIV_DEBUG */ #else /* UNIV_DEBUG */
# define buf_block_get_frame(block) (block ? (block)->frame : 0) # define buf_block_get_frame(block) (block ? (block)->frame : 0)
# define buf_block_get_frame_fast(block) (block)->frame # define buf_nonnull_block_get_frame(block) ((block)->frame)
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
Gets the space id of a block. Gets the space id of a block.
......
...@@ -718,6 +718,19 @@ buf_block_get_frame( ...@@ -718,6 +718,19 @@ buf_block_get_frame(
{ {
SRV_CORRUPT_TABLE_CHECK(block, return(0);); SRV_CORRUPT_TABLE_CHECK(block, return(0););
return(buf_nonnull_block_get_frame(block));
}
/*********************************************************************//**
Gets a pointer to the memory frame of a block, where block is known not to be
NULL.
@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_nonnull_block_get_frame(
/*========================*/
const buf_block_t* block) /*!< in: pointer to the control block */
{
switch (buf_block_get_state(block)) { switch (buf_block_get_state(block)) {
case BUF_BLOCK_ZIP_FREE: case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_PAGE:
...@@ -739,6 +752,7 @@ buf_block_get_frame( ...@@ -739,6 +752,7 @@ buf_block_get_frame(
ok: ok:
return((buf_frame_t*) block->frame); return((buf_frame_t*) block->frame);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
......
...@@ -78,6 +78,11 @@ extern os_event_t srv_checkpoint_completed_event; ...@@ -78,6 +78,11 @@ extern os_event_t srv_checkpoint_completed_event;
that the (slow) shutdown may proceed */ that the (slow) shutdown may proceed */
extern os_event_t srv_redo_log_thread_finished_event; extern os_event_t srv_redo_log_thread_finished_event;
/** Whether the redo log tracker thread has been started. Does not take into
account whether the tracking is currently enabled (see srv_track_changed_pages
for that) */
extern my_bool srv_redo_log_thread_started;
/* If the last data file is auto-extended, we add this many pages to it /* If the last data file is auto-extended, we add this many pages to it
at a time */ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \ #define SRV_AUTO_EXTEND_INCREMENT \
...@@ -145,6 +150,9 @@ extern char* srv_doublewrite_file; ...@@ -145,6 +150,9 @@ extern char* srv_doublewrite_file;
extern ibool srv_recovery_stats; extern ibool srv_recovery_stats;
/** Whether the redo log tracking is currently enabled. Note that it is
possible for the log tracker thread to be running and the tracking to be
disabled */
extern my_bool srv_track_changed_pages; extern my_bool srv_track_changed_pages;
extern ib_uint64_t srv_max_bitmap_file_size; extern ib_uint64_t srv_max_bitmap_file_size;
......
...@@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */ ...@@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
#ifndef PERCONA_INNODB_VERSION #ifndef PERCONA_INNODB_VERSION
#define PERCONA_INNODB_VERSION 38.0 #define PERCONA_INNODB_VERSION 38.3
#endif #endif
#define INNODB_VERSION_STR "5.5.49-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) #define INNODB_VERSION_STR "5.5.52-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
#define REFMAN "http://dev.mysql.com/doc/refman/" \ #define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
......
...@@ -3420,7 +3420,8 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3420,7 +3420,8 @@ logs_empty_and_mark_files_at_shutdown(void)
algorithm only works if the server is idle at shutdown */ algorithm only works if the server is idle at shutdown */
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
os_event_set(srv_shutdown_event);
srv_wake_purge_thread();
loop: loop:
os_thread_sleep(100000); os_thread_sleep(100000);
...@@ -3594,7 +3595,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3594,7 +3595,7 @@ logs_empty_and_mark_files_at_shutdown(void)
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Wake the log tracking thread which will then immediatelly /* Wake the log tracking thread which will then immediatelly
quit because of srv_shutdown_state value */ quit because of srv_shutdown_state value */
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
os_event_set(srv_checkpoint_completed_event); os_event_set(srv_checkpoint_completed_event);
os_event_wait(srv_redo_log_thread_finished_event); os_event_wait(srv_redo_log_thread_finished_event);
} }
...@@ -3671,7 +3672,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3671,7 +3672,7 @@ logs_empty_and_mark_files_at_shutdown(void)
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Signal the log following thread to quit */ /* Signal the log following thread to quit */
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
os_event_set(srv_checkpoint_completed_event); os_event_set(srv_checkpoint_completed_event);
} }
...@@ -3695,7 +3696,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3695,7 +3696,7 @@ logs_empty_and_mark_files_at_shutdown(void)
fil_flush_file_spaces(FIL_TABLESPACE); fil_flush_file_spaces(FIL_TABLESPACE);
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
os_event_wait(srv_redo_log_thread_finished_event); os_event_wait(srv_redo_log_thread_finished_event);
} }
......
...@@ -1813,7 +1813,7 @@ log_online_purge_changed_page_bitmaps( ...@@ -1813,7 +1813,7 @@ log_online_purge_changed_page_bitmaps(
lsn = IB_ULONGLONG_MAX; lsn = IB_ULONGLONG_MAX;
} }
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
/* User requests might happen with both enabled and disabled /* User requests might happen with both enabled and disabled
tracking */ tracking */
mutex_enter(&log_bmp_sys->mutex); mutex_enter(&log_bmp_sys->mutex);
...@@ -1821,13 +1821,13 @@ log_online_purge_changed_page_bitmaps( ...@@ -1821,13 +1821,13 @@ log_online_purge_changed_page_bitmaps(
if (!log_online_setup_bitmap_file_range(&bitmap_files, 0, if (!log_online_setup_bitmap_file_range(&bitmap_files, 0,
IB_ULONGLONG_MAX)) { IB_ULONGLONG_MAX)) {
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
mutex_exit(&log_bmp_sys->mutex); mutex_exit(&log_bmp_sys->mutex);
} }
return TRUE; return TRUE;
} }
if (srv_track_changed_pages && lsn > log_bmp_sys->end_lsn) { if (srv_redo_log_thread_started && lsn > log_bmp_sys->end_lsn) {
/* If we have to delete the current output file, close it /* If we have to delete the current output file, close it
first. */ first. */
os_file_close(log_bmp_sys->out.file); os_file_close(log_bmp_sys->out.file);
...@@ -1858,7 +1858,7 @@ log_online_purge_changed_page_bitmaps( ...@@ -1858,7 +1858,7 @@ log_online_purge_changed_page_bitmaps(
} }
} }
if (srv_track_changed_pages) { if (srv_redo_log_thread_started) {
if (lsn > log_bmp_sys->end_lsn) { if (lsn > log_bmp_sys->end_lsn) {
ib_uint64_t new_file_lsn; ib_uint64_t new_file_lsn;
if (lsn == IB_ULONGLONG_MAX) { if (lsn == IB_ULONGLONG_MAX) {
...@@ -1869,9 +1869,7 @@ log_online_purge_changed_page_bitmaps( ...@@ -1869,9 +1869,7 @@ log_online_purge_changed_page_bitmaps(
new_file_lsn = log_bmp_sys->end_lsn; new_file_lsn = log_bmp_sys->end_lsn;
} }
if (!log_online_rotate_bitmap_file(new_file_lsn)) { if (!log_online_rotate_bitmap_file(new_file_lsn)) {
/* If file create failed, signal the log /* If file create failed, stop log tracking */
tracking thread to quit next time it wakes
up. */
srv_track_changed_pages = FALSE; srv_track_changed_pages = FALSE;
} }
} }
......
...@@ -3022,7 +3022,7 @@ recv_recovery_from_checkpoint_start_func( ...@@ -3022,7 +3022,7 @@ recv_recovery_from_checkpoint_start_func(
ib_uint64_t checkpoint_lsn; ib_uint64_t checkpoint_lsn;
ib_uint64_t checkpoint_no; ib_uint64_t checkpoint_no;
ib_uint64_t old_scanned_lsn; ib_uint64_t old_scanned_lsn;
ib_uint64_t group_scanned_lsn= 0; ib_uint64_t group_scanned_lsn = 0;
ib_uint64_t contiguous_lsn; ib_uint64_t contiguous_lsn;
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
ib_uint64_t archived_lsn; ib_uint64_t archived_lsn;
......
...@@ -56,7 +56,18 @@ mach_parse_compressed( ...@@ -56,7 +56,18 @@ mach_parse_compressed(
*val = flag; *val = flag;
return(ptr + 1); return(ptr + 1);
} else if (flag < 0xC0UL) { }
/* Workaround GCC bug
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
the compiler moves mach_read_from_4 right to the beginning of the
function, causing and out-of-bounds read if we are reading a short
integer close to the end of buffer. */
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
asm volatile("": : :"memory");
#endif
if (flag < 0xC0UL) {
if (end_ptr < ptr + 2) { if (end_ptr < ptr + 2) {
return(NULL); return(NULL);
} }
......
...@@ -180,6 +180,9 @@ UNIV_INTERN char* srv_doublewrite_file = NULL; ...@@ -180,6 +180,9 @@ UNIV_INTERN char* srv_doublewrite_file = NULL;
UNIV_INTERN ibool srv_recovery_stats = FALSE; UNIV_INTERN ibool srv_recovery_stats = FALSE;
/** Whether the redo log tracking is currently enabled. Note that it is
possible for the log tracker thread to be running and the tracking to be
disabled */
UNIV_INTERN my_bool srv_track_changed_pages = FALSE; UNIV_INTERN my_bool srv_track_changed_pages = FALSE;
UNIV_INTERN ib_uint64_t srv_max_bitmap_file_size = 100 * 1024 * 1024; UNIV_INTERN ib_uint64_t srv_max_bitmap_file_size = 100 * 1024 * 1024;
...@@ -830,6 +833,11 @@ UNIV_INTERN os_event_t srv_checkpoint_completed_event; ...@@ -830,6 +833,11 @@ UNIV_INTERN os_event_t srv_checkpoint_completed_event;
UNIV_INTERN os_event_t srv_redo_log_thread_finished_event; UNIV_INTERN os_event_t srv_redo_log_thread_finished_event;
/** Whether the redo log tracker thread has been started. Does not take into
account whether the tracking is currently enabled (see srv_track_changed_pages
for that) */
UNIV_INTERN my_bool srv_redo_log_thread_started = FALSE;
UNIV_INTERN srv_sys_t* srv_sys = NULL; UNIV_INTERN srv_sys_t* srv_sys = NULL;
/* padding to prevent other memory update hotspots from residing on /* padding to prevent other memory update hotspots from residing on
...@@ -3201,18 +3209,15 @@ srv_redo_log_follow_thread( ...@@ -3201,18 +3209,15 @@ srv_redo_log_follow_thread(
#endif #endif
my_thread_init(); my_thread_init();
srv_redo_log_thread_started = TRUE;
do { do {
os_event_wait(srv_checkpoint_completed_event); os_event_wait(srv_checkpoint_completed_event);
os_event_reset(srv_checkpoint_completed_event); os_event_reset(srv_checkpoint_completed_event);
#ifdef UNIV_DEBUG if (srv_track_changed_pages
if (!srv_track_changed_pages) { && srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
continue;
}
#endif
if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
if (!log_online_follow_redo_log()) { if (!log_online_follow_redo_log()) {
/* TODO: sync with I_S log tracking status? */ /* TODO: sync with I_S log tracking status? */
fprintf(stderr, fprintf(stderr,
...@@ -3228,6 +3233,7 @@ srv_redo_log_follow_thread( ...@@ -3228,6 +3233,7 @@ srv_redo_log_follow_thread(
srv_track_changed_pages = FALSE; srv_track_changed_pages = FALSE;
log_online_read_shutdown(); log_online_read_shutdown();
os_event_set(srv_redo_log_thread_finished_event); os_event_set(srv_redo_log_thread_finished_event);
srv_redo_log_thread_started = FALSE; /* Defensive, not required */
my_thread_end(); my_thread_end();
os_thread_exit(NULL); os_thread_exit(NULL);
...@@ -3349,7 +3355,7 @@ srv_master_do_purge(void) ...@@ -3349,7 +3355,7 @@ srv_master_do_purge(void)
ut_ad(!mutex_own(&kernel_mutex)); ut_ad(!mutex_own(&kernel_mutex));
ut_a(srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)); ut_a(srv_n_purge_threads == 0);
do { do {
/* Check for shutdown and change in purge config. */ /* Check for shutdown and change in purge config. */
...@@ -3875,7 +3881,7 @@ srv_master_thread( ...@@ -3875,7 +3881,7 @@ srv_master_thread(
/* Flush logs if needed */ /* Flush logs if needed */
srv_sync_log_buffer_in_background(); srv_sync_log_buffer_in_background();
if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) { if (srv_n_purge_threads == 0) {
srv_main_thread_op_info = "master purging"; srv_main_thread_op_info = "master purging";
srv_master_do_purge(); srv_master_do_purge();
...@@ -3953,7 +3959,7 @@ srv_master_thread( ...@@ -3953,7 +3959,7 @@ srv_master_thread(
} }
} }
if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) { if (srv_n_purge_threads == 0) {
srv_main_thread_op_info = "master purging"; srv_main_thread_op_info = "master purging";
srv_master_do_purge(); srv_master_do_purge();
...@@ -4170,9 +4176,10 @@ srv_purge_thread( ...@@ -4170,9 +4176,10 @@ srv_purge_thread(
We peek at the history len without holding any mutex We peek at the history len without holding any mutex
because in the worst case we will end up waiting for because in the worst case we will end up waiting for
the next purge event. */ the next purge event. */
if (trx_sys->rseg_history_len < srv_purge_batch_size if (srv_shutdown_state == SRV_SHUTDOWN_NONE
&& (trx_sys->rseg_history_len < srv_purge_batch_size
|| (n_total_purged == 0 || (n_total_purged == 0
&& retries >= TRX_SYS_N_RSEGS)) { && retries >= TRX_SYS_N_RSEGS))) {
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
...@@ -4187,8 +4194,12 @@ srv_purge_thread( ...@@ -4187,8 +4194,12 @@ srv_purge_thread(
/* Check for shutdown and whether we should do purge at all. */ /* Check for shutdown and whether we should do purge at all. */
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
|| srv_shutdown_state != 0 || (srv_shutdown_state != SRV_SHUTDOWN_NONE
|| srv_fast_shutdown) { && srv_fast_shutdown)
|| (srv_shutdown_state != SRV_SHUTDOWN_NONE
&& srv_fast_shutdown == 0
&& n_total_purged == 0
&& retries >= TRX_SYS_N_RSEGS)) {
break; break;
} }
...@@ -4211,6 +4222,9 @@ srv_purge_thread( ...@@ -4211,6 +4222,9 @@ srv_purge_thread(
srv_sync_log_buffer_in_background(); srv_sync_log_buffer_in_background();
if (srv_shutdown_state != SRV_SHUTDOWN_NONE)
continue;
cur_time = ut_time_ms(); cur_time = ut_time_ms();
sig_count = os_event_reset(srv_shutdown_event); sig_count = os_event_reset(srv_shutdown_event);
if (next_itr_time > cur_time) { if (next_itr_time > cur_time) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment