Commit 35248fed authored by Marko Mäkelä's avatar Marko Mäkelä

10.2 follow-up to MDEV-13039 innodb_fast_shutdown=0 crash due premature purge...

10.2 follow-up to MDEV-13039 innodb_fast_shutdown=0 crash due premature purge shutdown before fts_optimize_shutdown()

srv_start_state_t: Document the flags. Replace SRV_START_STATE_STAT
with SRV_START_STATE_REDO. The srv_bg_undo_sources replaces the
original use of SRV_START_STATE_STAT.

dict_stats_thread_started, buf_dump_thread_started,
buf_flush_page_cleaner_thread_started: Remove (unused).

srv_shutdown_all_bg_threads(): Always wait for the I/O threads
to exit, also in read-only mode.

os_thread_free(): Remove.
parent a78476d3
#
# Bug#21644827 - FTS, ASSERT !SRV_READ_ONLY_MODE || M_IMPL.M_LOG_MODE ==
# MTR_LOG_NO_REDO
#
create table t1 (a int not null, d varchar(15) not null, b create table t1 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156), varchar(198) not null, c char(156),
fulltext ftsic(c)) engine=InnoDB fulltext ftsic(c)) engine=InnoDB
...@@ -45,4 +49,26 @@ ERROR HY000: Table 't3' is read only ...@@ -45,4 +49,26 @@ ERROR HY000: Table 't3' is read only
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
TRUNCATE TABLE t2; TRUNCATE TABLE t2;
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
DROP TABLE t1,t2,t3; TRUNCATE TABLE t1;
ERROR 42S02: Table 'test.t1' doesn't exist in engine
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
SELECT COUNT(*) FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist in engine
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT COUNT(*) FROM t3;
COUNT(*)
0
RENAME TABLE t1 TO tee_one;
ERROR HY000: Error on rename of './test/t1' to './test/tee_one' (errno: 155 "The table does not exist in engine")
DROP TABLE t1;
Warnings:
Warning 1932 Table 'test.t1' doesn't exist in engine
NOT FOUND /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags. SYS_TABLES.MIX_LEN=255;/ in mysqld.1.err
FOUND 48 /\[ERROR\] InnoDB: InnoDB: Error: table unused flags are:255/ in mysqld.1.err
FOUND 1 /\[Warning\] InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found\./ in mysqld.1.err
NOT FOUND /"\[Warning\] InnoDB: Cannot open table test/t1 from the internal data dictionary of InnoDB though the \.frm file for the table exists.";/ in mysqld.1.err
FOUND 2 /\[ERROR\] InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (drop|rename)/ in mysqld.1.err
DROP TABLE t2,t3;
--source include/innodb_page_size.inc --source include/innodb_page_size.inc
--source include/have_debug.inc
# Embedded mode doesn't allow restarting # Embedded mode doesn't allow restarting
--source include/not_embedded.inc --source include/not_embedded.inc
# MDEV-13059 XtraDB hangs on Windows due to failing to release --echo #
# block->lock X-latch in innodb_read_only mode --echo # Bug#21644827 - FTS, ASSERT !SRV_READ_ONLY_MODE || M_IMPL.M_LOG_MODE ==
if (`SELECT count(*) FROM information_schema.plugins WHERE --echo # MTR_LOG_NO_REDO
plugin_name = 'innodb' AND plugin_status = 'active' AND --echo #
plugin_description LIKE '%xtradb%'`){
if (`SELECT @@version_compile_os IN ('Win32','Win64','Windows')`) {
skip MDEV-13059 XtraDB hangs on Windows in innodb_read_only mode;
}
}
create table t1 (a int not null, d varchar(15) not null, b create table t1 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156), varchar(198) not null, c char(156),
...@@ -70,6 +66,41 @@ TRUNCATE TABLE t1; ...@@ -70,6 +66,41 @@ TRUNCATE TABLE t1;
TRUNCATE TABLE t2; TRUNCATE TABLE t2;
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
# TODO: Shutdown, corrupt the SYS_TABLES.TYPE of the tables, restart --source include/shutdown_mysqld.inc
DROP TABLE t1,t2,t3; # FIXME: Corrupt the SYS_TABLES.TYPE of the tables, do not use --debug
--let $restart_parameters = --debug=d,ib_table_invalid_flags
--source include/start_mysqld.inc
--error ER_NO_SUCH_TABLE_IN_ENGINE
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT COUNT(*) FROM t1;
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t3;
--error ER_ERROR_ON_RENAME
RENAME TABLE t1 TO tee_one;
DROP TABLE t1;
--disable_query_log
call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.MIX_LEN=255");
call mtr.add_suppression("\\[ERROR\\] InnoDB: InnoDB: Error: table unused flags are:255");
call mtr.add_suppression("\\[Warning\\] InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found\\.");
call mtr.add_suppression("\\[Warning\\] InnoDB: Cannot open table test/t1 from the internal data dictionary of InnoDB though the \\.frm file for the table exists.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (drop|rename)");
--enable_query_log
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= \[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags. SYS_TABLES.MIX_LEN=255;
--source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= \[ERROR\] InnoDB: InnoDB: Error: table unused flags are:255
--source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= \[Warning\] InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found\.
--source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= "\\[Warning\\] InnoDB: Cannot open table test/t1 from the internal data dictionary of InnoDB though the \.frm file for the table exists.";
--source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= \[ERROR\] InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (drop|rename)
--source include/search_pattern_in_file.inc
DROP TABLE t2,t3;
...@@ -151,11 +151,6 @@ os_thread_sleep( ...@@ -151,11 +151,6 @@ os_thread_sleep(
/*============*/ /*============*/
ulint tm); /*!< in: time in microseconds */ ulint tm); /*!< in: time in microseconds */
/**
Frees OS thread management data structures. */
void
os_thread_free();
/*****************************************************************//** /*****************************************************************//**
Check if there are threads active. Check if there are threads active.
@return true if the thread count > 0. */ @return true if the thread count > 0. */
......
...@@ -49,8 +49,7 @@ innobase_start_or_create_for_mysql(); ...@@ -49,8 +49,7 @@ innobase_start_or_create_for_mysql();
void void
innodb_shutdown(); innodb_shutdown();
/****************************************************************//** /** Shut down background threads that can generate undo log. */
Shuts down background threads that can generate undo pages. */
void void
srv_shutdown_bg_undo_sources(); srv_shutdown_bg_undo_sources();
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
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
...@@ -254,14 +255,3 @@ os_thread_active() ...@@ -254,14 +255,3 @@ os_thread_active()
return(my_atomic_loadlint(&os_thread_count) > 0); return(my_atomic_loadlint(&os_thread_count) > 0);
} }
/**
Frees OS thread management data structures. */
void
os_thread_free()
{
if (ulint count = my_atomic_loadlint(&os_thread_count)) {
ib::warn() << "Some (" << count << ") threads are"
" still active";
}
}
...@@ -153,15 +153,23 @@ UNIV_INTERN uint srv_sys_space_size_debug; ...@@ -153,15 +153,23 @@ UNIV_INTERN uint srv_sys_space_size_debug;
determine which threads need to be stopped if we need to abort during determine which threads need to be stopped if we need to abort during
the initialisation step. */ the initialisation step. */
enum srv_start_state_t { enum srv_start_state_t {
/** No thread started */
SRV_START_STATE_NONE = 0, /*!< No thread started */ SRV_START_STATE_NONE = 0, /*!< No thread started */
/** lock_wait_timeout_thread started */
SRV_START_STATE_LOCK_SYS = 1, /*!< Started lock-timeout SRV_START_STATE_LOCK_SYS = 1, /*!< Started lock-timeout
thread. */ thread. */
SRV_START_STATE_IO = 2, /*!< Started IO threads */ /** buf_flush_page_cleaner_coordinator,
SRV_START_STATE_MONITOR = 4, /*!< Started montior thread */ buf_flush_page_cleaner_worker started */
SRV_START_STATE_MASTER = 8, /*!< Started master threadd. */ SRV_START_STATE_IO = 2,
SRV_START_STATE_PURGE = 16, /*!< Started purge thread(s) */ /** srv_error_monitor_thread, srv_monitor_thread started */
SRV_START_STATE_STAT = 32 /*!< Started bufdump + dict stat SRV_START_STATE_MONITOR = 4,
and FTS optimize thread. */ /** srv_master_thread started */
SRV_START_STATE_MASTER = 8,
/** srv_purge_coordinator_thread, srv_worker_thread started */
SRV_START_STATE_PURGE = 16,
/** fil_crypt_thread, btr_defragment_thread started
(all background threads that can generate redo log but not undo log */
SRV_START_STATE_REDO = 32
}; };
/** Track server thrd starting phases */ /** Track server thrd starting phases */
...@@ -189,9 +197,6 @@ static os_thread_t buf_dump_thread_handle; ...@@ -189,9 +197,6 @@ static os_thread_t buf_dump_thread_handle;
static os_thread_t dict_stats_thread_handle; static os_thread_t dict_stats_thread_handle;
/** Status variables, is thread started ?*/ /** Status variables, is thread started ?*/
static bool thread_started[SRV_MAX_N_IO_THREADS + 6 + 32] = {false}; static bool thread_started[SRV_MAX_N_IO_THREADS + 6 + 32] = {false};
static bool buf_dump_thread_started = false;
static bool dict_stats_thread_started = false;
static bool buf_flush_page_cleaner_thread_started = false;
/** Name of srv_monitor_file */ /** Name of srv_monitor_file */
static char* srv_monitor_file_name; static char* srv_monitor_file_name;
...@@ -1228,10 +1233,6 @@ srv_shutdown_all_bg_threads() ...@@ -1228,10 +1233,6 @@ srv_shutdown_all_bg_threads()
{ {
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
if (!srv_start_state) {
return;
}
/* All threads end up waiting for certain events. Put those events /* All threads end up waiting for certain events. Put those events
to the signaled state. Then the threads will exit themselves after to the signaled state. Then the threads will exit themselves after
os_event_wait(). */ os_event_wait(). */
...@@ -1841,7 +1842,6 @@ innobase_start_or_create_for_mysql() ...@@ -1841,7 +1842,6 @@ innobase_start_or_create_for_mysql()
recv_sys_create(); recv_sys_create();
recv_sys_init(buf_pool_get_curr_size()); recv_sys_init(buf_pool_get_curr_size());
lock_sys_create(srv_lock_table_size); lock_sys_create(srv_lock_table_size);
srv_start_state_set(SRV_START_STATE_LOCK_SYS);
/* Create i/o-handler threads: */ /* Create i/o-handler threads: */
...@@ -1860,8 +1860,6 @@ innobase_start_or_create_for_mysql() ...@@ -1860,8 +1860,6 @@ innobase_start_or_create_for_mysql()
os_thread_create(buf_flush_page_cleaner_coordinator, os_thread_create(buf_flush_page_cleaner_coordinator,
NULL, NULL); NULL, NULL);
buf_flush_page_cleaner_thread_started = true;
for (i = 1; i < srv_n_page_cleaners; ++i) { for (i = 1; i < srv_n_page_cleaners; ++i) {
os_thread_create(buf_flush_page_cleaner_worker, os_thread_create(buf_flush_page_cleaner_worker,
NULL, NULL); NULL, NULL);
...@@ -2559,7 +2557,8 @@ innobase_start_or_create_for_mysql() ...@@ -2559,7 +2557,8 @@ innobase_start_or_create_for_mysql()
srv_monitor_thread, srv_monitor_thread,
NULL, thread_ids + 4 + SRV_MAX_N_IO_THREADS); NULL, thread_ids + 4 + SRV_MAX_N_IO_THREADS);
thread_started[4 + SRV_MAX_N_IO_THREADS] = true; thread_started[4 + SRV_MAX_N_IO_THREADS] = true;
srv_start_state_set(SRV_START_STATE_MONITOR); srv_start_state |= SRV_START_STATE_LOCK_SYS
| SRV_START_STATE_MONITOR;
} }
/* Create the SYS_FOREIGN and SYS_FOREIGN_COLS system tables */ /* Create the SYS_FOREIGN and SYS_FOREIGN_COLS system tables */
...@@ -2615,7 +2614,6 @@ innobase_start_or_create_for_mysql() ...@@ -2615,7 +2614,6 @@ innobase_start_or_create_for_mysql()
srv_dict_stats_thread_active = true; srv_dict_stats_thread_active = true;
dict_stats_thread_handle = os_thread_create( dict_stats_thread_handle = os_thread_create(
dict_stats_thread, NULL, NULL); dict_stats_thread, NULL, NULL);
dict_stats_thread_started = true;
/* Create the thread that will optimize the FTS sub-system. */ /* Create the thread that will optimize the FTS sub-system. */
fts_optimize_init(); fts_optimize_init();
...@@ -2703,7 +2701,6 @@ innobase_start_or_create_for_mysql() ...@@ -2703,7 +2701,6 @@ innobase_start_or_create_for_mysql()
buf_dump_thread_handle= buf_dump_thread_handle=
os_thread_create(buf_dump_thread, NULL, NULL); os_thread_create(buf_dump_thread, NULL, NULL);
buf_dump_thread_started = true;
#ifdef WITH_WSREP #ifdef WITH_WSREP
} else { } else {
ib::warn() << ib::warn() <<
...@@ -2735,7 +2732,7 @@ innobase_start_or_create_for_mysql() ...@@ -2735,7 +2732,7 @@ innobase_start_or_create_for_mysql()
btr_defragment_thread_active = true; btr_defragment_thread_active = true;
os_thread_create(btr_defragment_thread, NULL, NULL); os_thread_create(btr_defragment_thread, NULL, NULL);
srv_start_state_set(SRV_START_STATE_STAT); srv_start_state |= SRV_START_STATE_REDO;
} }
/* Create the buffer pool resize thread */ /* Create the buffer pool resize thread */
...@@ -2775,8 +2772,7 @@ srv_fts_close(void) ...@@ -2775,8 +2772,7 @@ srv_fts_close(void)
} }
#endif #endif
/****************************************************************//** /** Shut down background threads that can generate undo log. */
Shuts down background threads that can generate undo pages. */
void void
srv_shutdown_bg_undo_sources() srv_shutdown_bg_undo_sources()
{ {
...@@ -2797,8 +2793,7 @@ void ...@@ -2797,8 +2793,7 @@ void
innodb_shutdown() innodb_shutdown()
{ {
ut_ad(!srv_running); ut_ad(!srv_running);
ut_ad(!srv_undo_sources);
srv_shutdown_bg_undo_sources();
/* 1. Flush the buffer pool to disk, write the current lsn to /* 1. Flush the buffer pool to disk, write the current lsn to
the tablespace header(s), and copy all log data to archive. the tablespace header(s), and copy all log data to archive.
...@@ -2851,7 +2846,7 @@ innodb_shutdown() ...@@ -2851,7 +2846,7 @@ innodb_shutdown()
dict_stats_thread_deinit(); dict_stats_thread_deinit();
} }
if (srv_start_state_is_set(SRV_START_STATE_STAT)) { if (srv_start_state_is_set(SRV_START_STATE_REDO)) {
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
/* srv_shutdown_bg_undo_sources() already invoked /* srv_shutdown_bg_undo_sources() already invoked
fts_optimize_shutdown(); dict_stats_shutdown(); */ fts_optimize_shutdown(); dict_stats_shutdown(); */
...@@ -2924,10 +2919,6 @@ innodb_shutdown() ...@@ -2924,10 +2919,6 @@ innodb_shutdown()
buf_pool_free(srv_buf_pool_instances); buf_pool_free(srv_buf_pool_instances);
} }
/* 6. Free the thread management resoruces. */
os_thread_free();
/* 7. Free the synchronisation infrastructure. */
sync_check_close(); sync_check_close();
if (dict_foreign_err_file) { if (dict_foreign_err_file) {
......
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