mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
Merge 10.0 into 10.1
This commit is contained in:
commit
fa57479fcd
25 changed files with 373 additions and 447 deletions
|
|
@ -1899,8 +1899,8 @@ error:
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static my_bool
|
static void
|
||||||
innodb_end(void)
|
innodb_end()
|
||||||
{
|
{
|
||||||
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
|
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
|
||||||
innodb_inited = 0;
|
innodb_inited = 0;
|
||||||
|
|
@ -1908,9 +1908,7 @@ innodb_end(void)
|
||||||
msg("xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
|
msg("xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
|
||||||
srv_fast_shutdown);
|
srv_fast_shutdown);
|
||||||
|
|
||||||
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
|
innodb_shutdown();
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
free(internal_innobase_data_file_path);
|
free(internal_innobase_data_file_path);
|
||||||
internal_innobase_data_file_path = NULL;
|
internal_innobase_data_file_path = NULL;
|
||||||
|
|
||||||
|
|
@ -1921,12 +1919,6 @@ innodb_end(void)
|
||||||
// pthread_mutex_destroy(&commit_threads_m);
|
// pthread_mutex_destroy(&commit_threads_m);
|
||||||
// pthread_mutex_destroy(&commit_cond_m);
|
// pthread_mutex_destroy(&commit_cond_m);
|
||||||
// pthread_cond_destroy(&commit_cond);
|
// pthread_cond_destroy(&commit_cond);
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
error:
|
|
||||||
msg("xtrabackup: innodb_end(): Error occured.\n");
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================= common ================= */
|
/* ================= common ================= */
|
||||||
|
|
@ -4819,8 +4811,7 @@ end:
|
||||||
xb_filters_free();
|
xb_filters_free();
|
||||||
|
|
||||||
/* shutdown InnoDB */
|
/* shutdown InnoDB */
|
||||||
if(innodb_end())
|
innodb_end();
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================= prepare ================= */
|
/* ================= prepare ================= */
|
||||||
|
|
@ -6763,8 +6754,7 @@ next_node:
|
||||||
xb_write_galera_info(xtrabackup_incremental);
|
xb_write_galera_info(xtrabackup_incremental);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(innodb_end())
|
innodb_end();
|
||||||
goto error_cleanup;
|
|
||||||
|
|
||||||
innodb_free_param();
|
innodb_free_param();
|
||||||
|
|
||||||
|
|
@ -6850,9 +6840,7 @@ next_node:
|
||||||
if(innodb_init())
|
if(innodb_init())
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if(innodb_end())
|
innodb_end();
|
||||||
goto error;
|
|
||||||
|
|
||||||
innodb_free_param();
|
innodb_free_param();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
mysql-test/suite/innodb/r/row_format_redundant.result
Normal file
48
mysql-test/suite/innodb/r/row_format_redundant.result
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
create table t1 (a int not null, d varchar(15) not null, b
|
||||||
|
varchar(198) not null, c char(156),
|
||||||
|
fulltext ftsic(c)) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
insert into t1 values(123, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(456, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(789, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
SET GLOBAL innodb_file_per_table=OFF;
|
||||||
|
create table t2 (a int not null, d varchar(15) not null, b
|
||||||
|
varchar(198) not null, c char(156), fulltext ftsic(c)) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
insert into t2 select * from t1;
|
||||||
|
create table t3 (a int not null, d varchar(15) not null, b varchar(198),
|
||||||
|
c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
insert into t3 values(444, 'dddd', 'bbbbb', 'aaaaa');
|
||||||
|
insert into t3 values(555, 'eeee', 'ccccc', 'aaaaa');
|
||||||
|
SET GLOBAL innodb_fast_shutdown=0;
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
COUNT(*)
|
||||||
|
4096
|
||||||
|
SELECT COUNT(*) FROM t2;
|
||||||
|
COUNT(*)
|
||||||
|
4096
|
||||||
|
SELECT COUNT(*) FROM t3;
|
||||||
|
COUNT(*)
|
||||||
|
2
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
ERROR HY000: Table 't1' is read only
|
||||||
|
TRUNCATE TABLE t2;
|
||||||
|
ERROR HY000: Table 't2' is read only
|
||||||
|
TRUNCATE TABLE t3;
|
||||||
|
ERROR HY000: Table 't3' is read only
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
TRUNCATE TABLE t2;
|
||||||
|
TRUNCATE TABLE t3;
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
75
mysql-test/suite/innodb/t/row_format_redundant.test
Normal file
75
mysql-test/suite/innodb/t/row_format_redundant.test
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
--source include/innodb_page_size.inc
|
||||||
|
# Embedded mode doesn't allow restarting
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
# MDEV-13059 XtraDB hangs on Windows due to failing to release
|
||||||
|
# block->lock X-latch in innodb_read_only mode
|
||||||
|
if (`SELECT count(*) FROM information_schema.plugins WHERE
|
||||||
|
plugin_name = 'innodb' AND plugin_status = 'active' AND
|
||||||
|
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
|
||||||
|
varchar(198) not null, c char(156),
|
||||||
|
fulltext ftsic(c)) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
|
||||||
|
insert into t1 values(123, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(456, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(789, 'abcdef', 'jghikl', 'mnop');
|
||||||
|
insert into t1 values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
|
||||||
|
SET GLOBAL innodb_file_per_table=OFF;
|
||||||
|
create table t2 (a int not null, d varchar(15) not null, b
|
||||||
|
varchar(198) not null, c char(156), fulltext ftsic(c)) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
|
||||||
|
insert into t2 select * from t1;
|
||||||
|
|
||||||
|
create table t3 (a int not null, d varchar(15) not null, b varchar(198),
|
||||||
|
c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
|
||||||
|
row_format=redundant;
|
||||||
|
|
||||||
|
insert into t3 values(444, 'dddd', 'bbbbb', 'aaaaa');
|
||||||
|
insert into t3 values(555, 'eeee', 'ccccc', 'aaaaa');
|
||||||
|
|
||||||
|
# read-only restart requires the change buffer to be empty; therefore we
|
||||||
|
# do a slow shutdown.
|
||||||
|
SET GLOBAL innodb_fast_shutdown=0;
|
||||||
|
--let $restart_parameters = --innodb-read-only
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
SELECT COUNT(*) FROM t2;
|
||||||
|
SELECT COUNT(*) FROM t3;
|
||||||
|
|
||||||
|
--error ER_OPEN_AS_READONLY
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
--error ER_OPEN_AS_READONLY
|
||||||
|
TRUNCATE TABLE t2;
|
||||||
|
--error ER_OPEN_AS_READONLY
|
||||||
|
TRUNCATE TABLE t3;
|
||||||
|
|
||||||
|
--let $restart_parameters =
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
TRUNCATE TABLE t2;
|
||||||
|
TRUNCATE TABLE t3;
|
||||||
|
|
||||||
|
# TODO: Shutdown, corrupt the SYS_TABLES.TYPE of the tables, restart
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
SET @start_value = @@GLOBAL.innodb_sched_priority_cleaner;
|
SET GLOBAL innodb_sched_priority_cleaner=39;
|
||||||
SELECT @@GLOBAL.innodb_sched_priority_cleaner;
|
SELECT @@GLOBAL.innodb_sched_priority_cleaner;
|
||||||
@@GLOBAL.innodb_sched_priority_cleaner
|
@@GLOBAL.innodb_sched_priority_cleaner
|
||||||
19
|
19
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,15 @@
|
||||||
|
|
||||||
# A dynamic, global variable
|
# A dynamic, global variable
|
||||||
|
|
||||||
SET @start_value = @@GLOBAL.innodb_sched_priority_cleaner;
|
# Test in read-only mode
|
||||||
|
--let $restart_parameters= --innodb-read-only
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
--let $restart_parameters=
|
||||||
|
|
||||||
|
# This has no actual effect in innodb_read_only mode
|
||||||
|
SET GLOBAL innodb_sched_priority_cleaner=39;
|
||||||
|
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
# Default value
|
# Default value
|
||||||
SELECT @@GLOBAL.innodb_sched_priority_cleaner;
|
SELECT @@GLOBAL.innodb_sched_priority_cleaner;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ is set to TRUE by the page_cleaner thread when it is spawned and is set
|
||||||
back to FALSE at shutdown by the page_cleaner as well. Therefore no
|
back to FALSE at shutdown by the page_cleaner as well. Therefore no
|
||||||
need to protect it by a mutex. It is only ever read by the thread
|
need to protect it by a mutex. It is only ever read by the thread
|
||||||
doing the shutdown */
|
doing the shutdown */
|
||||||
UNIV_INTERN ibool buf_page_cleaner_is_active = FALSE;
|
UNIV_INTERN bool buf_page_cleaner_is_active;
|
||||||
|
|
||||||
#ifdef UNIV_PFS_THREAD
|
#ifdef UNIV_PFS_THREAD
|
||||||
UNIV_INTERN mysql_pfs_key_t buf_page_cleaner_thread_key;
|
UNIV_INTERN mysql_pfs_key_t buf_page_cleaner_thread_key;
|
||||||
|
|
@ -2326,7 +2326,6 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
|
||||||
fprintf(stderr, "InnoDB: page_cleaner thread running, id %lu\n",
|
fprintf(stderr, "InnoDB: page_cleaner thread running, id %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()));
|
os_thread_pf(os_thread_get_curr_id()));
|
||||||
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
||||||
buf_page_cleaner_is_active = TRUE;
|
|
||||||
|
|
||||||
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
|
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
|
||||||
|
|
||||||
|
|
@ -2422,7 +2421,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
|
||||||
/* We have lived our life. Time to die. */
|
/* We have lived our life. Time to die. */
|
||||||
|
|
||||||
thread_exit:
|
thread_exit:
|
||||||
buf_page_cleaner_is_active = FALSE;
|
buf_page_cleaner_is_active = false;
|
||||||
|
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
/* We count the number of threads in os_thread_exit(). A created
|
/* We count the number of threads in os_thread_exit(). A created
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, MariaDB Corporation. 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
|
||||||
|
|
@ -39,12 +39,18 @@ Created Apr 25, 2012 Vasil Dimov
|
||||||
/** Minimum time interval between stats recalc for a given table */
|
/** Minimum time interval between stats recalc for a given table */
|
||||||
#define MIN_RECALC_INTERVAL 10 /* seconds */
|
#define MIN_RECALC_INTERVAL 10 /* seconds */
|
||||||
|
|
||||||
#define SHUTTING_DOWN() (srv_shutdown_state != SRV_SHUTDOWN_NONE)
|
|
||||||
|
|
||||||
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
|
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
|
||||||
or shutdown. Not protected by any mutex. */
|
or shutdown. Not protected by any mutex. */
|
||||||
UNIV_INTERN os_event_t dict_stats_event;
|
UNIV_INTERN os_event_t dict_stats_event;
|
||||||
|
|
||||||
|
/** Variable to initiate shutdown the dict stats thread. Note we don't
|
||||||
|
use 'srv_shutdown_state' because we want to shutdown dict stats thread
|
||||||
|
before purge thread. */
|
||||||
|
static bool dict_stats_start_shutdown;
|
||||||
|
|
||||||
|
/** Event to wait for shutdown of the dict stats thread */
|
||||||
|
static os_event_t dict_stats_shutdown_event;
|
||||||
|
|
||||||
/** This mutex protects the "recalc_pool" variable. */
|
/** This mutex protects the "recalc_pool" variable. */
|
||||||
static ib_mutex_t recalc_pool_mutex;
|
static ib_mutex_t recalc_pool_mutex;
|
||||||
static ib_mutex_t defrag_pool_mutex;
|
static ib_mutex_t defrag_pool_mutex;
|
||||||
|
|
@ -340,11 +346,11 @@ Must be called before dict_stats_thread() is started. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
dict_stats_thread_init()
|
dict_stats_thread_init()
|
||||||
/*====================*/
|
|
||||||
{
|
{
|
||||||
ut_a(!srv_read_only_mode);
|
ut_a(!srv_read_only_mode);
|
||||||
|
|
||||||
dict_stats_event = os_event_create();
|
dict_stats_event = os_event_create();
|
||||||
|
dict_stats_shutdown_event = os_event_create();
|
||||||
|
|
||||||
/* The recalc_pool_mutex is acquired from:
|
/* The recalc_pool_mutex is acquired from:
|
||||||
1) the background stats gathering thread before any other latch
|
1) the background stats gathering thread before any other latch
|
||||||
|
|
@ -389,6 +395,9 @@ dict_stats_thread_deinit()
|
||||||
|
|
||||||
os_event_free(dict_stats_event);
|
os_event_free(dict_stats_event);
|
||||||
dict_stats_event = NULL;
|
dict_stats_event = NULL;
|
||||||
|
os_event_free(dict_stats_shutdown_event);
|
||||||
|
dict_stats_shutdown_event = NULL;
|
||||||
|
dict_stats_start_shutdown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
|
|
@ -532,7 +541,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
my_thread_init();
|
my_thread_init();
|
||||||
ut_a(!srv_read_only_mode);
|
ut_a(!srv_read_only_mode);
|
||||||
|
|
||||||
while (!SHUTTING_DOWN()) {
|
while (!dict_stats_start_shutdown) {
|
||||||
|
|
||||||
/* Wake up periodically even if not signaled. This is
|
/* Wake up periodically even if not signaled. This is
|
||||||
because we may lose an event - if the below call to
|
because we may lose an event - if the below call to
|
||||||
|
|
@ -542,7 +551,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
os_event_wait_time(
|
os_event_wait_time(
|
||||||
dict_stats_event, MIN_RECALC_INTERVAL * 1000000);
|
dict_stats_event, MIN_RECALC_INTERVAL * 1000000);
|
||||||
|
|
||||||
if (SHUTTING_DOWN()) {
|
if (dict_stats_start_shutdown) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,6 +565,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
|
|
||||||
srv_dict_stats_thread_active = false;
|
srv_dict_stats_thread_active = false;
|
||||||
|
|
||||||
|
os_event_set(dict_stats_shutdown_event);
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
/* We count the number of threads in os_thread_exit(). A created
|
/* We count the number of threads in os_thread_exit(). A created
|
||||||
thread should always use that to exit instead of return(). */
|
thread should always use that to exit instead of return(). */
|
||||||
|
|
@ -563,3 +573,12 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
|
|
||||||
OS_THREAD_DUMMY_RETURN;
|
OS_THREAD_DUMMY_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shut down the dict_stats_thread. */
|
||||||
|
void
|
||||||
|
dict_stats_shutdown()
|
||||||
|
{
|
||||||
|
dict_stats_start_shutdown = true;
|
||||||
|
os_event_set(dict_stats_event);
|
||||||
|
os_event_wait(dict_stats_shutdown_event);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2731,7 +2731,6 @@ fsp_reserve_free_extents(
|
||||||
ibool success;
|
ibool success;
|
||||||
ulint n_pages_added;
|
ulint n_pages_added;
|
||||||
size_t total_reserved = 0;
|
size_t total_reserved = 0;
|
||||||
ulint rounds = 0;
|
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
*n_reserved = n_ext;
|
*n_reserved = n_ext;
|
||||||
|
|
@ -2811,17 +2810,7 @@ try_to_extend:
|
||||||
space_header, mtr);
|
space_header, mtr);
|
||||||
|
|
||||||
if (success && n_pages_added > 0) {
|
if (success && n_pages_added > 0) {
|
||||||
|
|
||||||
rounds++;
|
|
||||||
total_reserved += n_pages_added;
|
total_reserved += n_pages_added;
|
||||||
|
|
||||||
if (rounds > 50) {
|
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
|
||||||
"Space id %lu trying to reserve %lu extents actually reserved %lu "
|
|
||||||
" reserve %lu free %lu size %lu rounds %lu total_reserved %llu",
|
|
||||||
space, n_ext, n_pages_added, reserve, n_free, size, rounds, (ullint) total_reserved);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1380,14 +1380,11 @@ innobase_drop_database(
|
||||||
the path is used as the database name:
|
the path is used as the database name:
|
||||||
for example, in 'mysql/data/test' the
|
for example, in 'mysql/data/test' the
|
||||||
database name is 'test' */
|
database name is 'test' */
|
||||||
/*******************************************************************//**
|
/** Shut down the InnoDB storage engine.
|
||||||
Closes an InnoDB database. */
|
@return 0 */
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
innobase_end(
|
innobase_end(handlerton*, ha_panic_function);
|
||||||
/*=========*/
|
|
||||||
handlerton* hton, /* in: Innodb handlerton */
|
|
||||||
ha_panic_function type);
|
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Creates an InnoDB transaction struct for the thd if it does not yet have one.
|
Creates an InnoDB transaction struct for the thd if it does not yet have one.
|
||||||
|
|
@ -4011,21 +4008,13 @@ error:
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/** Shut down the InnoDB storage engine.
|
||||||
Closes an InnoDB database.
|
@return 0 */
|
||||||
@return TRUE if error */
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
innobase_end(
|
innobase_end(handlerton*, ha_panic_function)
|
||||||
/*=========*/
|
|
||||||
handlerton* hton, /*!< in/out: InnoDB handlerton */
|
|
||||||
ha_panic_function type MY_ATTRIBUTE((unused)))
|
|
||||||
/*!< in: ha_panic() parameter */
|
|
||||||
{
|
{
|
||||||
int err= 0;
|
|
||||||
|
|
||||||
DBUG_ENTER("innobase_end");
|
DBUG_ENTER("innobase_end");
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
|
||||||
|
|
||||||
if (innodb_inited) {
|
if (innodb_inited) {
|
||||||
|
|
||||||
|
|
@ -4042,9 +4031,7 @@ innobase_end(
|
||||||
innodb_inited = 0;
|
innodb_inited = 0;
|
||||||
hash_table_free(innobase_open_tables);
|
hash_table_free(innobase_open_tables);
|
||||||
innobase_open_tables = NULL;
|
innobase_open_tables = NULL;
|
||||||
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
|
innodb_shutdown();
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
srv_free_paths_and_sizes();
|
srv_free_paths_and_sizes();
|
||||||
my_free(internal_innobase_data_file_path);
|
my_free(internal_innobase_data_file_path);
|
||||||
mysql_mutex_destroy(&innobase_share_mutex);
|
mysql_mutex_destroy(&innobase_share_mutex);
|
||||||
|
|
@ -4053,7 +4040,7 @@ innobase_end(
|
||||||
mysql_mutex_destroy(&pending_checkpoint_mutex);
|
mysql_mutex_destroy(&pending_checkpoint_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ Created 11/5/1995 Heikki Tuuri
|
||||||
#include "buf0types.h"
|
#include "buf0types.h"
|
||||||
|
|
||||||
/** Flag indicating if the page_cleaner is in active state. */
|
/** Flag indicating if the page_cleaner is in active state. */
|
||||||
extern ibool buf_page_cleaner_is_active;
|
extern bool buf_page_cleaner_is_active;
|
||||||
|
|
||||||
/** Event to synchronise with the flushing. */
|
/** Event to synchronise with the flushing. */
|
||||||
extern os_event_t buf_flush_event;
|
extern os_event_t buf_flush_event;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, MariaDB Corporation. 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
|
||||||
|
|
@ -144,6 +144,10 @@ DECLARE_THREAD(dict_stats_thread)(
|
||||||
void* arg); /*!< in: a dummy parameter
|
void* arg); /*!< in: a dummy parameter
|
||||||
required by os_thread_create */
|
required by os_thread_create */
|
||||||
|
|
||||||
|
/** Shut down the dict_stats_thread. */
|
||||||
|
void
|
||||||
|
dict_stats_shutdown();
|
||||||
|
|
||||||
# ifndef UNIV_NONINL
|
# ifndef UNIV_NONINL
|
||||||
# include "dict0stats_bg.ic"
|
# include "dict0stats_bg.ic"
|
||||||
# endif
|
# endif
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1995, 2017, 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
|
||||||
|
|
@ -76,22 +77,12 @@ are not found and the user wants.
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
innobase_start_or_create_for_mysql(void);
|
innobase_start_or_create_for_mysql();
|
||||||
/*====================================*/
|
|
||||||
/****************************************************************//**
|
|
||||||
Shuts down the Innobase database.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INTERN
|
|
||||||
dberr_t
|
|
||||||
innobase_shutdown_for_mysql(void);
|
|
||||||
|
|
||||||
/********************************************************************
|
/** Shut down InnoDB. */
|
||||||
Signal all per-table background threads to shutdown, and wait for them to do
|
|
||||||
so. */
|
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
srv_shutdown_table_bg_threads(void);
|
innodb_shutdown();
|
||||||
/*=============================*/
|
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Copy the file path component of the physical file to parameter. It will
|
Copy the file path component of the physical file to parameter. It will
|
||||||
|
|
@ -159,6 +150,9 @@ enum srv_shutdown_state {
|
||||||
SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
|
SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Whether any undo log records can be generated */
|
||||||
|
extern bool srv_undo_sources;
|
||||||
|
|
||||||
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
|
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
|
||||||
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
|
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
|
||||||
extern enum srv_shutdown_state srv_shutdown_state;
|
extern enum srv_shutdown_state srv_shutdown_state;
|
||||||
|
|
|
||||||
|
|
@ -2528,31 +2528,29 @@ suspend_thread:
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Check if purge should stop.
|
||||||
Check if purge should stop.
|
@param[in] n_purged pages purged in the last batch
|
||||||
@return true if it should shutdown. */
|
@return whether purge should exit */
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
srv_purge_should_exit(
|
srv_purge_should_exit(ulint n_purged)
|
||||||
/*==============*/
|
|
||||||
ulint n_purged) /*!< in: pages purged in last batch */
|
|
||||||
{
|
{
|
||||||
switch (srv_shutdown_state) {
|
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
case SRV_SHUTDOWN_NONE:
|
|| srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
|
||||||
/* Normal operation. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SRV_SHUTDOWN_CLEANUP:
|
if (srv_undo_sources) {
|
||||||
case SRV_SHUTDOWN_EXIT_THREADS:
|
return(false);
|
||||||
/* Exit unless slow shutdown requested or all done. */
|
|
||||||
return(srv_fast_shutdown != 0 || n_purged == 0);
|
|
||||||
|
|
||||||
case SRV_SHUTDOWN_LAST_PHASE:
|
|
||||||
case SRV_SHUTDOWN_FLUSH_PHASE:
|
|
||||||
ut_error;
|
|
||||||
}
|
}
|
||||||
|
if (srv_fast_shutdown) {
|
||||||
return(false);
|
return(true);
|
||||||
|
}
|
||||||
|
/* Slow shutdown was requested. */
|
||||||
|
if (n_purged) {
|
||||||
|
/* The previous round still did some work. */
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
/* Exit if there are no active transactions to roll back. */
|
||||||
|
return(trx_sys_any_active_transactions() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
|
@ -2813,7 +2811,7 @@ srv_purge_coordinator_suspend(
|
||||||
}
|
}
|
||||||
|
|
||||||
rw_lock_x_unlock(&purge_sys->latch);
|
rw_lock_x_unlock(&purge_sys->latch);
|
||||||
} while (stop);
|
} while (stop && srv_undo_sources);
|
||||||
|
|
||||||
srv_resume_thread(slot, 0, false);
|
srv_resume_thread(slot, 0, false);
|
||||||
}
|
}
|
||||||
|
|
@ -2864,6 +2862,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
|
||||||
purge didn't purge any records then wait for activity. */
|
purge didn't purge any records then wait for activity. */
|
||||||
|
|
||||||
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
|
&& srv_undo_sources
|
||||||
&& (purge_sys->state == PURGE_STATE_STOP
|
&& (purge_sys->state == PURGE_STATE_STOP
|
||||||
|| n_total_purged == 0)) {
|
|| n_total_purged == 0)) {
|
||||||
|
|
||||||
|
|
@ -2880,36 +2879,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
|
||||||
|
|
||||||
rseg_history_len = srv_do_purge(
|
rseg_history_len = srv_do_purge(
|
||||||
srv_n_purge_threads, &n_total_purged);
|
srv_n_purge_threads, &n_total_purged);
|
||||||
|
|
||||||
} while (!srv_purge_should_exit(n_total_purged));
|
} while (!srv_purge_should_exit(n_total_purged));
|
||||||
|
|
||||||
/* Ensure that we don't jump out of the loop unless the
|
|
||||||
exit condition is satisfied. */
|
|
||||||
|
|
||||||
ut_a(srv_purge_should_exit(n_total_purged));
|
|
||||||
|
|
||||||
ulint n_pages_purged = ULINT_MAX;
|
|
||||||
|
|
||||||
/* Ensure that all records are purged if it is not a fast shutdown.
|
|
||||||
This covers the case where a record can be added after we exit the
|
|
||||||
loop above. */
|
|
||||||
while (srv_fast_shutdown == 0 && n_pages_purged > 0) {
|
|
||||||
n_pages_purged = trx_purge(1, srv_purge_batch_size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This trx_purge is called to remove any undo records (added by
|
|
||||||
background threads) after completion of the above loop. When
|
|
||||||
srv_fast_shutdown != 0, a large batch size can cause significant
|
|
||||||
delay in shutdown ,so reducing the batch size to magic number 20
|
|
||||||
(which was default in 5.5), which we hope will be sufficient to
|
|
||||||
remove all the undo records */
|
|
||||||
const uint temp_batch_size = 20;
|
|
||||||
|
|
||||||
n_pages_purged = trx_purge(1, srv_purge_batch_size <= temp_batch_size
|
|
||||||
? srv_purge_batch_size : temp_batch_size,
|
|
||||||
true);
|
|
||||||
ut_a(n_pages_purged == 0 || srv_fast_shutdown != 0);
|
|
||||||
|
|
||||||
/* The task queue should always be empty, independent of fast
|
/* The task queue should always be empty, independent of fast
|
||||||
shutdown state. */
|
shutdown state. */
|
||||||
ut_a(srv_get_task_queue_length() == 0);
|
ut_a(srv_get_task_queue_length() == 0);
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,11 @@ UNIV_INTERN ibool srv_is_being_started = FALSE;
|
||||||
/** TRUE if the server was successfully started */
|
/** TRUE if the server was successfully started */
|
||||||
UNIV_INTERN ibool srv_was_started = FALSE;
|
UNIV_INTERN ibool srv_was_started = FALSE;
|
||||||
/** TRUE if innobase_start_or_create_for_mysql() has been called */
|
/** TRUE if innobase_start_or_create_for_mysql() has been called */
|
||||||
static ibool srv_start_has_been_called = FALSE;
|
static ibool srv_start_has_been_called;
|
||||||
|
|
||||||
|
/** Whether any undo log records can be generated */
|
||||||
|
UNIV_INTERN bool srv_undo_sources;
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
/** InnoDB system tablespace to set during recovery */
|
/** InnoDB system tablespace to set during recovery */
|
||||||
UNIV_INTERN uint srv_sys_space_size_debug;
|
UNIV_INTERN uint srv_sys_space_size_debug;
|
||||||
|
|
@ -1620,8 +1624,7 @@ are not found and the user wants.
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
innobase_start_or_create_for_mysql(void)
|
innobase_start_or_create_for_mysql()
|
||||||
/*====================================*/
|
|
||||||
{
|
{
|
||||||
bool create_new_db;
|
bool create_new_db;
|
||||||
lsn_t flushed_lsn;
|
lsn_t flushed_lsn;
|
||||||
|
|
@ -2776,8 +2779,8 @@ files_checked:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_startup_is_before_trx_rollback_phase = FALSE;
|
|
||||||
recv_recovery_rollback_active();
|
recv_recovery_rollback_active();
|
||||||
|
srv_startup_is_before_trx_rollback_phase = FALSE;
|
||||||
|
|
||||||
/* It is possible that file_format tag has never
|
/* It is possible that file_format tag has never
|
||||||
been set. In this case we initialize it to minimum
|
been set. In this case we initialize it to minimum
|
||||||
|
|
@ -2903,6 +2906,16 @@ files_checked:
|
||||||
srv_master_thread,
|
srv_master_thread,
|
||||||
NULL, thread_ids + (1 + SRV_MAX_N_IO_THREADS));
|
NULL, thread_ids + (1 + SRV_MAX_N_IO_THREADS));
|
||||||
thread_started[1 + SRV_MAX_N_IO_THREADS] = true;
|
thread_started[1 + SRV_MAX_N_IO_THREADS] = true;
|
||||||
|
|
||||||
|
srv_undo_sources = true;
|
||||||
|
/* Create the dict stats gathering thread */
|
||||||
|
srv_dict_stats_thread_active = true;
|
||||||
|
dict_stats_thread_handle = os_thread_create(
|
||||||
|
dict_stats_thread, NULL, NULL);
|
||||||
|
dict_stats_thread_started = true;
|
||||||
|
|
||||||
|
/* Create the thread that will optimize the FTS sub-system. */
|
||||||
|
fts_optimize_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv_read_only_mode
|
if (!srv_read_only_mode
|
||||||
|
|
@ -2946,6 +2959,7 @@ files_checked:
|
||||||
(thread_ids + 6 + 32));
|
(thread_ids + 6 + 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf_page_cleaner_is_active = true;
|
||||||
buf_flush_page_cleaner_thread_handle = os_thread_create(buf_flush_page_cleaner_thread, NULL, NULL);
|
buf_flush_page_cleaner_thread_handle = os_thread_create(buf_flush_page_cleaner_thread, NULL, NULL);
|
||||||
buf_flush_page_cleaner_thread_started = true;
|
buf_flush_page_cleaner_thread_started = true;
|
||||||
}
|
}
|
||||||
|
|
@ -2989,10 +3003,10 @@ files_checked:
|
||||||
if (!wsrep_recovery) {
|
if (!wsrep_recovery) {
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
/* Create the buffer pool dump/load thread */
|
/* Create the buffer pool dump/load thread */
|
||||||
|
srv_buf_dump_thread_active = true;
|
||||||
buf_dump_thread_handle=
|
buf_dump_thread_handle=
|
||||||
os_thread_create(buf_dump_thread, NULL, NULL);
|
os_thread_create(buf_dump_thread, NULL, NULL);
|
||||||
|
|
||||||
srv_buf_dump_thread_active = true;
|
|
||||||
buf_dump_thread_started = true;
|
buf_dump_thread_started = true;
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3002,15 +3016,6 @@ files_checked:
|
||||||
}
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
/* Create the dict stats gathering thread */
|
|
||||||
dict_stats_thread_handle = os_thread_create(
|
|
||||||
dict_stats_thread, NULL, NULL);
|
|
||||||
srv_dict_stats_thread_active = true;
|
|
||||||
dict_stats_thread_started = true;
|
|
||||||
|
|
||||||
/* Create the thread that will optimize the FTS sub-system. */
|
|
||||||
fts_optimize_init();
|
|
||||||
|
|
||||||
/* Create thread(s) that handles key rotation */
|
/* Create thread(s) that handles key rotation */
|
||||||
fil_system_enter();
|
fil_system_enter();
|
||||||
fil_crypt_threads_init();
|
fil_crypt_threads_init();
|
||||||
|
|
@ -3060,13 +3065,10 @@ srv_fts_close(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************//**
|
/** Shut down InnoDB. */
|
||||||
Shuts down the InnoDB database.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
void
|
||||||
innobase_shutdown_for_mysql(void)
|
innodb_shutdown()
|
||||||
/*=============================*/
|
|
||||||
{
|
{
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
|
|
@ -3076,15 +3078,20 @@ innobase_shutdown_for_mysql(void)
|
||||||
"Shutting down an improperly started, "
|
"Shutting down an improperly started, "
|
||||||
"or created database!");
|
"or created database!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv_read_only_mode) {
|
if (srv_undo_sources) {
|
||||||
|
ut_ad(!srv_read_only_mode);
|
||||||
/* Shutdown the FTS optimize sub system. */
|
/* Shutdown the FTS optimize sub system. */
|
||||||
fts_optimize_start_shutdown();
|
fts_optimize_start_shutdown();
|
||||||
|
|
||||||
fts_optimize_end();
|
fts_optimize_end();
|
||||||
|
dict_stats_shutdown();
|
||||||
|
while (row_get_background_drop_list_len_low()) {
|
||||||
|
srv_wake_master_thread();
|
||||||
|
os_thread_yield();
|
||||||
|
}
|
||||||
|
srv_undo_sources = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1. Flush the buffer pool to disk, write the current lsn to
|
/* 1. Flush the buffer pool to disk, write the current lsn to
|
||||||
|
|
@ -3297,89 +3304,9 @@ innobase_shutdown_for_mysql(void)
|
||||||
|
|
||||||
srv_was_started = FALSE;
|
srv_was_started = FALSE;
|
||||||
srv_start_has_been_called = FALSE;
|
srv_start_has_been_called = FALSE;
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
|
||||||
Signal all per-table background threads to shutdown, and wait for them to do
|
|
||||||
so. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
srv_shutdown_table_bg_threads(void)
|
|
||||||
/*===============================*/
|
|
||||||
{
|
|
||||||
dict_table_t* table;
|
|
||||||
dict_table_t* first;
|
|
||||||
dict_table_t* last = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&dict_sys->mutex);
|
|
||||||
|
|
||||||
/* Signal all threads that they should stop. */
|
|
||||||
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
|
|
||||||
first = table;
|
|
||||||
while (table) {
|
|
||||||
dict_table_t* next;
|
|
||||||
fts_t* fts = table->fts;
|
|
||||||
|
|
||||||
if (fts != NULL) {
|
|
||||||
fts_start_shutdown(table, fts);
|
|
||||||
}
|
|
||||||
|
|
||||||
next = UT_LIST_GET_NEXT(table_LRU, table);
|
|
||||||
|
|
||||||
if (!next) {
|
|
||||||
last = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
table = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We must release dict_sys->mutex here; if we hold on to it in the
|
|
||||||
loop below, we will deadlock if any of the background threads try to
|
|
||||||
acquire it (for example, the FTS thread by calling que_eval_sql).
|
|
||||||
|
|
||||||
Releasing it here and going through dict_sys->table_LRU without
|
|
||||||
holding it is safe because:
|
|
||||||
|
|
||||||
a) MySQL only starts the shutdown procedure after all client
|
|
||||||
threads have been disconnected and no new ones are accepted, so no
|
|
||||||
new tables are added or old ones dropped.
|
|
||||||
|
|
||||||
b) Despite its name, the list is not LRU, and the order stays
|
|
||||||
fixed.
|
|
||||||
|
|
||||||
To safeguard against the above assumptions ever changing, we store
|
|
||||||
the first and last items in the list above, and then check that
|
|
||||||
they've stayed the same below. */
|
|
||||||
|
|
||||||
mutex_exit(&dict_sys->mutex);
|
|
||||||
|
|
||||||
/* Wait for the threads of each table to stop. This is not inside
|
|
||||||
the above loop, because by signaling all the threads first we can
|
|
||||||
overlap their shutting down delays. */
|
|
||||||
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
|
|
||||||
ut_a(first == table);
|
|
||||||
while (table) {
|
|
||||||
dict_table_t* next;
|
|
||||||
fts_t* fts = table->fts;
|
|
||||||
|
|
||||||
if (fts != NULL) {
|
|
||||||
fts_shutdown(table, fts);
|
|
||||||
}
|
|
||||||
|
|
||||||
next = UT_LIST_GET_NEXT(table_LRU, table);
|
|
||||||
|
|
||||||
if (table == last) {
|
|
||||||
ut_a(!next);
|
|
||||||
}
|
|
||||||
|
|
||||||
table = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Get the meta-data filename from the table name. */
|
Get the meta-data filename from the table name. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,19 @@ trx_purge_add_update_undo_to_history(
|
||||||
hist_size + undo->size, MLOG_4BYTES, mtr);
|
hist_size + undo->size, MLOG_4BYTES, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Before any transaction-generating background threads or the
|
||||||
|
purge have been started, recv_recovery_rollback_active() can
|
||||||
|
start transactions in row_merge_drop_temp_indexes() and
|
||||||
|
fts_drop_orphaned_tables(), and roll back recovered transactions.
|
||||||
|
After the purge thread has been given permission to exit,
|
||||||
|
in fast shutdown, we may roll back transactions (trx->undo_no==0)
|
||||||
|
in THD::cleanup() invoked from unlink_thd(). */
|
||||||
|
ut_ad(srv_undo_sources
|
||||||
|
|| ((srv_startup_is_before_trx_rollback_phase
|
||||||
|
|| trx_rollback_or_clean_is_active)
|
||||||
|
&& purge_sys->state == PURGE_STATE_INIT)
|
||||||
|
|| (trx->undo_no == 0 && srv_fast_shutdown));
|
||||||
|
|
||||||
/* Add the log as the first in the history list */
|
/* Add the log as the first in the history list */
|
||||||
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
|
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
|
||||||
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
|
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,10 @@ is set to TRUE by the page_cleaner thread when it is spawned and is set
|
||||||
back to FALSE at shutdown by the page_cleaner as well. Therefore no
|
back to FALSE at shutdown by the page_cleaner as well. Therefore no
|
||||||
need to protect it by a mutex. It is only ever read by the thread
|
need to protect it by a mutex. It is only ever read by the thread
|
||||||
doing the shutdown */
|
doing the shutdown */
|
||||||
UNIV_INTERN ibool buf_page_cleaner_is_active = FALSE;
|
UNIV_INTERN bool buf_page_cleaner_is_active;
|
||||||
|
|
||||||
/** Flag indicating if the lru_manager is in active state. */
|
/** Flag indicating if the lru_manager is in active state. */
|
||||||
UNIV_INTERN bool buf_lru_manager_is_active = false;
|
UNIV_INTERN bool buf_lru_manager_is_active;
|
||||||
|
|
||||||
#ifdef UNIV_PFS_THREAD
|
#ifdef UNIV_PFS_THREAD
|
||||||
UNIV_INTERN mysql_pfs_key_t buf_page_cleaner_thread_key;
|
UNIV_INTERN mysql_pfs_key_t buf_page_cleaner_thread_key;
|
||||||
|
|
@ -2799,8 +2799,6 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
|
||||||
os_thread_pf(os_thread_get_curr_id()));
|
os_thread_pf(os_thread_get_curr_id()));
|
||||||
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
||||||
|
|
||||||
buf_page_cleaner_is_active = TRUE;
|
|
||||||
|
|
||||||
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
|
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
|
||||||
|
|
||||||
ulint page_cleaner_sleep_time;
|
ulint page_cleaner_sleep_time;
|
||||||
|
|
@ -2909,7 +2907,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
|
||||||
/* We have lived our life. Time to die. */
|
/* We have lived our life. Time to die. */
|
||||||
|
|
||||||
thread_exit:
|
thread_exit:
|
||||||
buf_page_cleaner_is_active = FALSE;
|
buf_page_cleaner_is_active = false;
|
||||||
|
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
/* We count the number of threads in os_thread_exit(). A created
|
/* We count the number of threads in os_thread_exit(). A created
|
||||||
|
|
@ -2950,8 +2948,6 @@ DECLARE_THREAD(buf_flush_lru_manager_thread)(
|
||||||
os_thread_pf(os_thread_get_curr_id()));
|
os_thread_pf(os_thread_get_curr_id()));
|
||||||
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
#endif /* UNIV_DEBUG_THREAD_CREATION */
|
||||||
|
|
||||||
buf_lru_manager_is_active = true;
|
|
||||||
|
|
||||||
/* On server shutdown, the LRU manager thread runs through cleanup
|
/* On server shutdown, the LRU manager thread runs through cleanup
|
||||||
phase to provide free pages for the master and purge threads. */
|
phase to provide free pages for the master and purge threads. */
|
||||||
while (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
while (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, MariaDB Corporation. 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
|
||||||
|
|
@ -39,12 +39,18 @@ Created Apr 25, 2012 Vasil Dimov
|
||||||
/** Minimum time interval between stats recalc for a given table */
|
/** Minimum time interval between stats recalc for a given table */
|
||||||
#define MIN_RECALC_INTERVAL 10 /* seconds */
|
#define MIN_RECALC_INTERVAL 10 /* seconds */
|
||||||
|
|
||||||
#define SHUTTING_DOWN() (srv_shutdown_state != SRV_SHUTDOWN_NONE)
|
|
||||||
|
|
||||||
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
|
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
|
||||||
or shutdown. Not protected by any mutex. */
|
or shutdown. Not protected by any mutex. */
|
||||||
UNIV_INTERN os_event_t dict_stats_event;
|
UNIV_INTERN os_event_t dict_stats_event;
|
||||||
|
|
||||||
|
/** Variable to initiate shutdown the dict stats thread. Note we don't
|
||||||
|
use 'srv_shutdown_state' because we want to shutdown dict stats thread
|
||||||
|
before purge thread. */
|
||||||
|
static bool dict_stats_start_shutdown;
|
||||||
|
|
||||||
|
/** Event to wait for shutdown of the dict stats thread */
|
||||||
|
static os_event_t dict_stats_shutdown_event;
|
||||||
|
|
||||||
/** This mutex protects the "recalc_pool" variable. */
|
/** This mutex protects the "recalc_pool" variable. */
|
||||||
static ib_mutex_t recalc_pool_mutex;
|
static ib_mutex_t recalc_pool_mutex;
|
||||||
static ib_mutex_t defrag_pool_mutex;
|
static ib_mutex_t defrag_pool_mutex;
|
||||||
|
|
@ -341,11 +347,11 @@ Must be called before dict_stats_thread() is started. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
dict_stats_thread_init()
|
dict_stats_thread_init()
|
||||||
/*====================*/
|
|
||||||
{
|
{
|
||||||
ut_a(!srv_read_only_mode);
|
ut_a(!srv_read_only_mode);
|
||||||
|
|
||||||
dict_stats_event = os_event_create();
|
dict_stats_event = os_event_create();
|
||||||
|
dict_stats_shutdown_event = os_event_create();
|
||||||
|
|
||||||
/* The recalc_pool_mutex is acquired from:
|
/* The recalc_pool_mutex is acquired from:
|
||||||
1) the background stats gathering thread before any other latch
|
1) the background stats gathering thread before any other latch
|
||||||
|
|
@ -390,6 +396,9 @@ dict_stats_thread_deinit()
|
||||||
|
|
||||||
os_event_free(dict_stats_event);
|
os_event_free(dict_stats_event);
|
||||||
dict_stats_event = NULL;
|
dict_stats_event = NULL;
|
||||||
|
os_event_free(dict_stats_shutdown_event);
|
||||||
|
dict_stats_shutdown_event = NULL;
|
||||||
|
dict_stats_start_shutdown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
|
|
@ -533,7 +542,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
my_thread_init();
|
my_thread_init();
|
||||||
ut_a(!srv_read_only_mode);
|
ut_a(!srv_read_only_mode);
|
||||||
|
|
||||||
while (!SHUTTING_DOWN()) {
|
while (!dict_stats_start_shutdown) {
|
||||||
|
|
||||||
/* Wake up periodically even if not signaled. This is
|
/* Wake up periodically even if not signaled. This is
|
||||||
because we may lose an event - if the below call to
|
because we may lose an event - if the below call to
|
||||||
|
|
@ -543,7 +552,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
os_event_wait_time(
|
os_event_wait_time(
|
||||||
dict_stats_event, MIN_RECALC_INTERVAL * 1000000);
|
dict_stats_event, MIN_RECALC_INTERVAL * 1000000);
|
||||||
|
|
||||||
if (SHUTTING_DOWN()) {
|
if (dict_stats_start_shutdown) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,6 +566,7 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
|
|
||||||
srv_dict_stats_thread_active = false;
|
srv_dict_stats_thread_active = false;
|
||||||
|
|
||||||
|
os_event_set(dict_stats_shutdown_event);
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
/* We count the number of threads in os_thread_exit(). A created
|
/* We count the number of threads in os_thread_exit(). A created
|
||||||
thread should always use that to exit instead of return(). */
|
thread should always use that to exit instead of return(). */
|
||||||
|
|
@ -564,3 +574,12 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
||||||
|
|
||||||
OS_THREAD_DUMMY_RETURN;
|
OS_THREAD_DUMMY_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shut down the dict_stats_thread. */
|
||||||
|
void
|
||||||
|
dict_stats_shutdown()
|
||||||
|
{
|
||||||
|
dict_stats_start_shutdown = true;
|
||||||
|
os_event_set(dict_stats_event);
|
||||||
|
os_event_wait(dict_stats_shutdown_event);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2740,7 +2740,6 @@ fsp_reserve_free_extents(
|
||||||
ibool success;
|
ibool success;
|
||||||
ulint n_pages_added;
|
ulint n_pages_added;
|
||||||
size_t total_reserved = 0;
|
size_t total_reserved = 0;
|
||||||
ulint rounds = 0;
|
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
*n_reserved = n_ext;
|
*n_reserved = n_ext;
|
||||||
|
|
@ -2819,17 +2818,7 @@ try_to_extend:
|
||||||
success = fsp_try_extend_data_file(&n_pages_added, space,
|
success = fsp_try_extend_data_file(&n_pages_added, space,
|
||||||
space_header, mtr);
|
space_header, mtr);
|
||||||
if (success && n_pages_added > 0) {
|
if (success && n_pages_added > 0) {
|
||||||
|
|
||||||
rounds++;
|
|
||||||
total_reserved += n_pages_added;
|
total_reserved += n_pages_added;
|
||||||
|
|
||||||
if (rounds > 50) {
|
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
|
||||||
"Space id %lu trying to reserve %lu extents actually reserved %lu "
|
|
||||||
" reserve %lu free %lu size %lu rounds %lu total_reserved %llu",
|
|
||||||
space, n_ext, n_pages_added, reserve, n_free, size, rounds, (ullint) total_reserved);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1610,14 +1610,11 @@ innobase_drop_database(
|
||||||
the path is used as the database name:
|
the path is used as the database name:
|
||||||
for example, in 'mysql/data/test' the
|
for example, in 'mysql/data/test' the
|
||||||
database name is 'test' */
|
database name is 'test' */
|
||||||
/*******************************************************************//**
|
/** Shut down the InnoDB storage engine.
|
||||||
Closes an InnoDB database. */
|
@return 0 */
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
innobase_end(
|
innobase_end(handlerton*, ha_panic_function);
|
||||||
/*=========*/
|
|
||||||
handlerton* hton, /* in: Innodb handlerton */
|
|
||||||
ha_panic_function type);
|
|
||||||
|
|
||||||
#if NOT_USED
|
#if NOT_USED
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
|
|
@ -4493,21 +4490,13 @@ error:
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/** Shut down the InnoDB storage engine.
|
||||||
Closes an InnoDB database.
|
@return 0 */
|
||||||
@return TRUE if error */
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
innobase_end(
|
innobase_end(handlerton*, ha_panic_function)
|
||||||
/*=========*/
|
|
||||||
handlerton* hton, /*!< in/out: InnoDB handlerton */
|
|
||||||
ha_panic_function type MY_ATTRIBUTE((unused)))
|
|
||||||
/*!< in: ha_panic() parameter */
|
|
||||||
{
|
{
|
||||||
int err= 0;
|
|
||||||
|
|
||||||
DBUG_ENTER("innobase_end");
|
DBUG_ENTER("innobase_end");
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
|
||||||
|
|
||||||
if (innodb_inited) {
|
if (innodb_inited) {
|
||||||
|
|
||||||
|
|
@ -4524,9 +4513,7 @@ innobase_end(
|
||||||
innodb_inited = 0;
|
innodb_inited = 0;
|
||||||
hash_table_free(innobase_open_tables);
|
hash_table_free(innobase_open_tables);
|
||||||
innobase_open_tables = NULL;
|
innobase_open_tables = NULL;
|
||||||
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
|
innodb_shutdown();
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
srv_free_paths_and_sizes();
|
srv_free_paths_and_sizes();
|
||||||
my_free(internal_innobase_data_file_path);
|
my_free(internal_innobase_data_file_path);
|
||||||
mysql_mutex_destroy(&innobase_share_mutex);
|
mysql_mutex_destroy(&innobase_share_mutex);
|
||||||
|
|
@ -4535,7 +4522,7 @@ innobase_end(
|
||||||
mysql_mutex_destroy(&pending_checkpoint_mutex);
|
mysql_mutex_destroy(&pending_checkpoint_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
|
|
@ -18818,6 +18805,10 @@ innodb_sched_priority_cleaner_update(
|
||||||
const void* save) /*!< in: immediate result
|
const void* save) /*!< in: immediate result
|
||||||
from check function */
|
from check function */
|
||||||
{
|
{
|
||||||
|
if (srv_read_only_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ulint priority = *static_cast<const ulint *>(save);
|
ulint priority = *static_cast<const ulint *>(save);
|
||||||
ulint actual_priority;
|
ulint actual_priority;
|
||||||
ulint nice = 0;
|
ulint nice = 0;
|
||||||
|
|
@ -18844,10 +18835,6 @@ innodb_sched_priority_cleaner_update(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the priority for the page cleaner thread */
|
/* Set the priority for the page cleaner thread */
|
||||||
if (srv_read_only_mode) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(buf_page_cleaner_is_active);
|
ut_ad(buf_page_cleaner_is_active);
|
||||||
nice = os_thread_get_priority(srv_cleaner_tid);
|
nice = os_thread_get_priority(srv_cleaner_tid);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ Created 11/5/1995 Heikki Tuuri
|
||||||
#include "buf0types.h"
|
#include "buf0types.h"
|
||||||
|
|
||||||
/** Flag indicating if the page_cleaner is in active state. */
|
/** Flag indicating if the page_cleaner is in active state. */
|
||||||
extern ibool buf_page_cleaner_is_active;
|
extern bool buf_page_cleaner_is_active;
|
||||||
|
|
||||||
/** Flag indicating if the lru_manager is in active state. */
|
/** Flag indicating if the lru_manager is in active state. */
|
||||||
extern bool buf_lru_manager_is_active;
|
extern bool buf_lru_manager_is_active;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, MariaDB Corporation. 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
|
||||||
|
|
@ -144,6 +144,10 @@ DECLARE_THREAD(dict_stats_thread)(
|
||||||
void* arg); /*!< in: a dummy parameter
|
void* arg); /*!< in: a dummy parameter
|
||||||
required by os_thread_create */
|
required by os_thread_create */
|
||||||
|
|
||||||
|
/** Shut down the dict_stats_thread. */
|
||||||
|
void
|
||||||
|
dict_stats_shutdown();
|
||||||
|
|
||||||
# ifndef UNIV_NONINL
|
# ifndef UNIV_NONINL
|
||||||
# include "dict0stats_bg.ic"
|
# include "dict0stats_bg.ic"
|
||||||
# endif
|
# endif
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1995, 2017, 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
|
||||||
|
|
@ -75,22 +76,12 @@ are not found and the user wants.
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
innobase_start_or_create_for_mysql(void);
|
innobase_start_or_create_for_mysql();
|
||||||
/*====================================*/
|
|
||||||
/****************************************************************//**
|
|
||||||
Shuts down the Innobase database.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INTERN
|
|
||||||
dberr_t
|
|
||||||
innobase_shutdown_for_mysql(void);
|
|
||||||
|
|
||||||
/********************************************************************
|
/** Shut down InnoDB. */
|
||||||
Signal all per-table background threads to shutdown, and wait for them to do
|
|
||||||
so. */
|
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
srv_shutdown_table_bg_threads(void);
|
innodb_shutdown();
|
||||||
/*=============================*/
|
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Copy the file path component of the physical file to parameter. It will
|
Copy the file path component of the physical file to parameter. It will
|
||||||
|
|
@ -158,6 +149,9 @@ enum srv_shutdown_state {
|
||||||
SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
|
SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Whether any undo log records can be generated */
|
||||||
|
extern bool srv_undo_sources;
|
||||||
|
|
||||||
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
|
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
|
||||||
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
|
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
|
||||||
extern enum srv_shutdown_state srv_shutdown_state;
|
extern enum srv_shutdown_state srv_shutdown_state;
|
||||||
|
|
|
||||||
|
|
@ -3214,31 +3214,29 @@ suspend_thread:
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Check if purge should stop.
|
||||||
Check if purge should stop.
|
@param[in] n_purged pages purged in the last batch
|
||||||
@return true if it should shutdown. */
|
@return whether purge should exit */
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
srv_purge_should_exit(
|
srv_purge_should_exit(ulint n_purged)
|
||||||
/*==============*/
|
|
||||||
ulint n_purged) /*!< in: pages purged in last batch */
|
|
||||||
{
|
{
|
||||||
switch (srv_shutdown_state) {
|
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
case SRV_SHUTDOWN_NONE:
|
|| srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
|
||||||
/* Normal operation. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SRV_SHUTDOWN_CLEANUP:
|
if (srv_undo_sources) {
|
||||||
case SRV_SHUTDOWN_EXIT_THREADS:
|
return(false);
|
||||||
/* Exit unless slow shutdown requested or all done. */
|
|
||||||
return(srv_fast_shutdown != 0 || n_purged == 0);
|
|
||||||
|
|
||||||
case SRV_SHUTDOWN_LAST_PHASE:
|
|
||||||
case SRV_SHUTDOWN_FLUSH_PHASE:
|
|
||||||
ut_error;
|
|
||||||
}
|
}
|
||||||
|
if (srv_fast_shutdown) {
|
||||||
return(false);
|
return(true);
|
||||||
|
}
|
||||||
|
/* Slow shutdown was requested. */
|
||||||
|
if (n_purged) {
|
||||||
|
/* The previous round still did some work. */
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
/* Exit if there are no active transactions to roll back. */
|
||||||
|
return(trx_sys_any_active_transactions() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
|
@ -3513,7 +3511,7 @@ srv_purge_coordinator_suspend(
|
||||||
}
|
}
|
||||||
|
|
||||||
rw_lock_x_unlock(&purge_sys->latch);
|
rw_lock_x_unlock(&purge_sys->latch);
|
||||||
} while (stop);
|
} while (stop && srv_undo_sources);
|
||||||
|
|
||||||
srv_resume_thread(slot, 0, false);
|
srv_resume_thread(slot, 0, false);
|
||||||
}
|
}
|
||||||
|
|
@ -3567,6 +3565,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
|
||||||
purge didn't purge any records then wait for activity. */
|
purge didn't purge any records then wait for activity. */
|
||||||
|
|
||||||
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
|
&& srv_undo_sources
|
||||||
&& (purge_sys->state == PURGE_STATE_STOP
|
&& (purge_sys->state == PURGE_STATE_STOP
|
||||||
|| n_total_purged == 0)) {
|
|| n_total_purged == 0)) {
|
||||||
|
|
||||||
|
|
@ -3587,36 +3586,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
|
||||||
srv_n_purge_threads, &n_total_purged);
|
srv_n_purge_threads, &n_total_purged);
|
||||||
|
|
||||||
srv_inc_activity_count();
|
srv_inc_activity_count();
|
||||||
|
|
||||||
} while (!srv_purge_should_exit(n_total_purged));
|
} while (!srv_purge_should_exit(n_total_purged));
|
||||||
|
|
||||||
/* Ensure that we don't jump out of the loop unless the
|
|
||||||
exit condition is satisfied. */
|
|
||||||
|
|
||||||
ut_a(srv_purge_should_exit(n_total_purged));
|
|
||||||
|
|
||||||
ulint n_pages_purged = ULINT_MAX;
|
|
||||||
|
|
||||||
/* Ensure that all records are purged if it is not a fast shutdown.
|
|
||||||
This covers the case where a record can be added after we exit the
|
|
||||||
loop above. */
|
|
||||||
while (srv_fast_shutdown == 0 && n_pages_purged > 0) {
|
|
||||||
n_pages_purged = trx_purge(1, srv_purge_batch_size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This trx_purge is called to remove any undo records (added by
|
|
||||||
background threads) after completion of the above loop. When
|
|
||||||
srv_fast_shutdown != 0, a large batch size can cause significant
|
|
||||||
delay in shutdown ,so reducing the batch size to magic number 20
|
|
||||||
(which was default in 5.5), which we hope will be sufficient to
|
|
||||||
remove all the undo records */
|
|
||||||
const uint temp_batch_size = 20;
|
|
||||||
|
|
||||||
n_pages_purged = trx_purge(1, srv_purge_batch_size <= temp_batch_size
|
|
||||||
? srv_purge_batch_size : temp_batch_size,
|
|
||||||
true);
|
|
||||||
ut_a(n_pages_purged == 0 || srv_fast_shutdown != 0);
|
|
||||||
|
|
||||||
/* The task queue should always be empty, independent of fast
|
/* The task queue should always be empty, independent of fast
|
||||||
shutdown state. */
|
shutdown state. */
|
||||||
ut_a(srv_get_task_queue_length() == 0);
|
ut_a(srv_get_task_queue_length() == 0);
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,11 @@ UNIV_INTERN ibool srv_is_being_started = FALSE;
|
||||||
/** TRUE if the server was successfully started */
|
/** TRUE if the server was successfully started */
|
||||||
UNIV_INTERN ibool srv_was_started = FALSE;
|
UNIV_INTERN ibool srv_was_started = FALSE;
|
||||||
/** TRUE if innobase_start_or_create_for_mysql() has been called */
|
/** TRUE if innobase_start_or_create_for_mysql() has been called */
|
||||||
static ibool srv_start_has_been_called = FALSE;
|
static ibool srv_start_has_been_called;
|
||||||
|
|
||||||
|
/** Whether any undo log records can be generated */
|
||||||
|
UNIV_INTERN bool srv_undo_sources;
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
/** InnoDB system tablespace to set during recovery */
|
/** InnoDB system tablespace to set during recovery */
|
||||||
UNIV_INTERN uint srv_sys_space_size_debug;
|
UNIV_INTERN uint srv_sys_space_size_debug;
|
||||||
|
|
@ -1684,8 +1688,7 @@ are not found and the user wants.
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
innobase_start_or_create_for_mysql(void)
|
innobase_start_or_create_for_mysql()
|
||||||
/*====================================*/
|
|
||||||
{
|
{
|
||||||
bool create_new_db;
|
bool create_new_db;
|
||||||
lsn_t flushed_lsn;
|
lsn_t flushed_lsn;
|
||||||
|
|
@ -2862,8 +2865,8 @@ files_checked:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_startup_is_before_trx_rollback_phase = FALSE;
|
|
||||||
recv_recovery_rollback_active();
|
recv_recovery_rollback_active();
|
||||||
|
srv_startup_is_before_trx_rollback_phase = FALSE;
|
||||||
|
|
||||||
/* It is possible that file_format tag has never
|
/* It is possible that file_format tag has never
|
||||||
been set. In this case we initialize it to minimum
|
been set. In this case we initialize it to minimum
|
||||||
|
|
@ -2995,6 +2998,16 @@ files_checked:
|
||||||
srv_master_thread,
|
srv_master_thread,
|
||||||
NULL, thread_ids + (1 + SRV_MAX_N_IO_THREADS));
|
NULL, thread_ids + (1 + SRV_MAX_N_IO_THREADS));
|
||||||
thread_started[1 + SRV_MAX_N_IO_THREADS] = true;
|
thread_started[1 + SRV_MAX_N_IO_THREADS] = true;
|
||||||
|
|
||||||
|
srv_undo_sources = true;
|
||||||
|
/* Create the dict stats gathering thread */
|
||||||
|
srv_dict_stats_thread_active = true;
|
||||||
|
dict_stats_thread_handle = os_thread_create(
|
||||||
|
dict_stats_thread, NULL, NULL);
|
||||||
|
dict_stats_thread_started = true;
|
||||||
|
|
||||||
|
/* Create the thread that will optimize the FTS sub-system. */
|
||||||
|
fts_optimize_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv_read_only_mode
|
if (!srv_read_only_mode
|
||||||
|
|
@ -3039,12 +3052,16 @@ files_checked:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
buf_flush_page_cleaner_thread_handle = os_thread_create(buf_flush_page_cleaner_thread, NULL, NULL);
|
buf_page_cleaner_is_active = true;
|
||||||
|
buf_flush_page_cleaner_thread_handle = os_thread_create(
|
||||||
|
buf_flush_page_cleaner_thread, NULL, NULL);
|
||||||
buf_flush_page_cleaner_thread_started = true;
|
buf_flush_page_cleaner_thread_started = true;
|
||||||
}
|
|
||||||
|
|
||||||
buf_flush_lru_manager_thread_handle = os_thread_create(buf_flush_lru_manager_thread, NULL, NULL);
|
buf_lru_manager_is_active = true;
|
||||||
buf_flush_lru_manager_thread_started = true;
|
buf_flush_lru_manager_thread_handle = os_thread_create(
|
||||||
|
buf_flush_lru_manager_thread, NULL, NULL);
|
||||||
|
buf_flush_lru_manager_thread_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!srv_file_per_table && srv_pass_corrupt_table) {
|
if (!srv_file_per_table && srv_pass_corrupt_table) {
|
||||||
fprintf(stderr, "InnoDB: Warning:"
|
fprintf(stderr, "InnoDB: Warning:"
|
||||||
|
|
@ -3092,10 +3109,10 @@ files_checked:
|
||||||
if (!wsrep_recovery) {
|
if (!wsrep_recovery) {
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
/* Create the buffer pool dump/load thread */
|
/* Create the buffer pool dump/load thread */
|
||||||
|
srv_buf_dump_thread_active = true;
|
||||||
buf_dump_thread_handle=
|
buf_dump_thread_handle=
|
||||||
os_thread_create(buf_dump_thread, NULL, NULL);
|
os_thread_create(buf_dump_thread, NULL, NULL);
|
||||||
|
|
||||||
srv_buf_dump_thread_active = true;
|
|
||||||
buf_dump_thread_started = true;
|
buf_dump_thread_started = true;
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3105,15 +3122,6 @@ files_checked:
|
||||||
}
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
/* Create the dict stats gathering thread */
|
|
||||||
dict_stats_thread_handle = os_thread_create(
|
|
||||||
dict_stats_thread, NULL, NULL);
|
|
||||||
srv_dict_stats_thread_active = true;
|
|
||||||
dict_stats_thread_started = true;
|
|
||||||
|
|
||||||
/* Create the thread that will optimize the FTS sub-system. */
|
|
||||||
fts_optimize_init();
|
|
||||||
|
|
||||||
/* Create thread(s) that handles key rotation */
|
/* Create thread(s) that handles key rotation */
|
||||||
fil_system_enter();
|
fil_system_enter();
|
||||||
fil_crypt_threads_init();
|
fil_crypt_threads_init();
|
||||||
|
|
@ -3163,13 +3171,10 @@ srv_fts_close(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************//**
|
/** Shut down InnoDB. */
|
||||||
Shuts down the InnoDB database.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
void
|
||||||
innobase_shutdown_for_mysql(void)
|
innodb_shutdown()
|
||||||
/*=============================*/
|
|
||||||
{
|
{
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
|
|
@ -3179,15 +3184,20 @@ innobase_shutdown_for_mysql(void)
|
||||||
"Shutting down an improperly started, "
|
"Shutting down an improperly started, "
|
||||||
"or created database!");
|
"or created database!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv_read_only_mode) {
|
if (srv_undo_sources) {
|
||||||
|
ut_ad(!srv_read_only_mode);
|
||||||
/* Shutdown the FTS optimize sub system. */
|
/* Shutdown the FTS optimize sub system. */
|
||||||
fts_optimize_start_shutdown();
|
fts_optimize_start_shutdown();
|
||||||
|
|
||||||
fts_optimize_end();
|
fts_optimize_end();
|
||||||
|
dict_stats_shutdown();
|
||||||
|
while (row_get_background_drop_list_len_low()) {
|
||||||
|
srv_wake_master_thread();
|
||||||
|
os_thread_yield();
|
||||||
|
}
|
||||||
|
srv_undo_sources = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1. Flush the buffer pool to disk, write the current lsn to
|
/* 1. Flush the buffer pool to disk, write the current lsn to
|
||||||
|
|
@ -3402,88 +3412,9 @@ innobase_shutdown_for_mysql(void)
|
||||||
srv_start_has_been_called = FALSE;
|
srv_start_has_been_called = FALSE;
|
||||||
/* reset io_tid_i, in case current process does second innodb start (xtrabackup might do that).*/
|
/* reset io_tid_i, in case current process does second innodb start (xtrabackup might do that).*/
|
||||||
io_tid_i = 0;
|
io_tid_i = 0;
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
|
||||||
Signal all per-table background threads to shutdown, and wait for them to do
|
|
||||||
so. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
srv_shutdown_table_bg_threads(void)
|
|
||||||
/*===============================*/
|
|
||||||
{
|
|
||||||
dict_table_t* table;
|
|
||||||
dict_table_t* first;
|
|
||||||
dict_table_t* last = NULL;
|
|
||||||
|
|
||||||
mutex_enter(&dict_sys->mutex);
|
|
||||||
|
|
||||||
/* Signal all threads that they should stop. */
|
|
||||||
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
|
|
||||||
first = table;
|
|
||||||
while (table) {
|
|
||||||
dict_table_t* next;
|
|
||||||
fts_t* fts = table->fts;
|
|
||||||
|
|
||||||
if (fts != NULL) {
|
|
||||||
fts_start_shutdown(table, fts);
|
|
||||||
}
|
|
||||||
|
|
||||||
next = UT_LIST_GET_NEXT(table_LRU, table);
|
|
||||||
|
|
||||||
if (!next) {
|
|
||||||
last = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
table = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We must release dict_sys->mutex here; if we hold on to it in the
|
|
||||||
loop below, we will deadlock if any of the background threads try to
|
|
||||||
acquire it (for example, the FTS thread by calling que_eval_sql).
|
|
||||||
|
|
||||||
Releasing it here and going through dict_sys->table_LRU without
|
|
||||||
holding it is safe because:
|
|
||||||
|
|
||||||
a) MySQL only starts the shutdown procedure after all client
|
|
||||||
threads have been disconnected and no new ones are accepted, so no
|
|
||||||
new tables are added or old ones dropped.
|
|
||||||
|
|
||||||
b) Despite its name, the list is not LRU, and the order stays
|
|
||||||
fixed.
|
|
||||||
|
|
||||||
To safeguard against the above assumptions ever changing, we store
|
|
||||||
the first and last items in the list above, and then check that
|
|
||||||
they've stayed the same below. */
|
|
||||||
|
|
||||||
mutex_exit(&dict_sys->mutex);
|
|
||||||
|
|
||||||
/* Wait for the threads of each table to stop. This is not inside
|
|
||||||
the above loop, because by signaling all the threads first we can
|
|
||||||
overlap their shutting down delays. */
|
|
||||||
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
|
|
||||||
ut_a(first == table);
|
|
||||||
while (table) {
|
|
||||||
dict_table_t* next;
|
|
||||||
fts_t* fts = table->fts;
|
|
||||||
|
|
||||||
if (fts != NULL) {
|
|
||||||
fts_shutdown(table, fts);
|
|
||||||
}
|
|
||||||
|
|
||||||
next = UT_LIST_GET_NEXT(table_LRU, table);
|
|
||||||
|
|
||||||
if (table == last) {
|
|
||||||
ut_a(!next);
|
|
||||||
}
|
|
||||||
|
|
||||||
table = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Get the meta-data filename from the table name. */
|
Get the meta-data filename from the table name. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,19 @@ trx_purge_add_update_undo_to_history(
|
||||||
hist_size + undo->size, MLOG_4BYTES, mtr);
|
hist_size + undo->size, MLOG_4BYTES, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Before any transaction-generating background threads or the
|
||||||
|
purge have been started, recv_recovery_rollback_active() can
|
||||||
|
start transactions in row_merge_drop_temp_indexes() and
|
||||||
|
fts_drop_orphaned_tables(), and roll back recovered transactions.
|
||||||
|
After the purge thread has been given permission to exit,
|
||||||
|
in fast shutdown, we may roll back transactions (trx->undo_no==0)
|
||||||
|
in THD::cleanup() invoked from unlink_thd(). */
|
||||||
|
ut_ad(srv_undo_sources
|
||||||
|
|| ((srv_startup_is_before_trx_rollback_phase
|
||||||
|
|| trx_rollback_or_clean_is_active)
|
||||||
|
&& purge_sys->state == PURGE_STATE_INIT)
|
||||||
|
|| (trx->undo_no == 0 && srv_fast_shutdown));
|
||||||
|
|
||||||
/* Add the log as the first in the history list */
|
/* Add the log as the first in the history list */
|
||||||
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
|
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
|
||||||
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
|
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue