1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-01 17:39:21 +03:00

Shut down InnoDB after aborted startup.

This fixes memory leaks in tests that cause InnoDB startup to fail.

buf_pool_free_instance(): Also free buf_pool->flush_rbt, which would
normally be freed when crash recovery finishes.

fil_node_close_file(), fil_space_free_low(), fil_close_all_files():
Relax some debug assertions to tolerate !srv_was_started.

innodb_shutdown(): Renamed from innobase_shutdown_for_mysql().
Changed the return type to void. Do not assume that all subsystems
were started.

que_init(), que_close(): Remove (empty functions).

srv_init(), srv_general_init(): Remove as global functions.

srv_free(): Allow srv_sys=NULL.

srv_get_active_thread_type(): Only return SRV_PURGE if purge really
is running.

srv_shutdown_all_bg_threads(): Do not reset srv_start_state. It will
be needed by innodb_shutdown().

innobase_start_or_create_for_mysql(): Always call srv_boot() so that
innodb_shutdown() can assume that it was called. Make more subsystems
dependent on SRV_START_STATE_STAT.

srv_shutdown_bg_undo_sources(): Require SRV_START_STATE_STAT.

trx_sys_close(): Do not assume purge_sys!=NULL. Do not call
buf_dblwr_free(), because the doublewrite buffer can exist while
the transaction system does not.

logs_empty_and_mark_files_at_shutdown(): Do a faster shutdown if
!srv_was_started.

recv_sys_close(): Invoke dblwr.pages.clear() which would normally
be invoked by buf_dblwr_process().

recv_recovery_from_checkpoint_start(): Always release log_sys->mutex.

row_mysql_close(): Allow the subsystem not to exist.
This commit is contained in:
Marko Mäkelä
2017-01-31 19:43:03 +02:00
parent 774056c825
commit 81b7fe9d38
13 changed files with 146 additions and 162 deletions

View File

@@ -2000,6 +2000,11 @@ buf_pool_free_instance(
mutex_free(&buf_pool->zip_mutex); mutex_free(&buf_pool->zip_mutex);
mutex_free(&buf_pool->flush_list_mutex); mutex_free(&buf_pool->flush_list_mutex);
if (buf_pool->flush_rbt) {
rbt_free(buf_pool->flush_rbt);
buf_pool->flush_rbt = NULL;
}
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
bpage != NULL; bpage != NULL;
bpage = prev_bpage) { bpage = prev_bpage) {

View File

@@ -779,7 +779,8 @@ fil_node_close_file(
ut_a(!node->being_extended); ut_a(!node->being_extended);
ut_a(node->modification_counter == node->flush_counter ut_a(node->modification_counter == node->flush_counter
|| node->space->purpose == FIL_TYPE_TEMPORARY || node->space->purpose == FIL_TYPE_TEMPORARY
|| srv_fast_shutdown == 2); || srv_fast_shutdown == 2
|| !srv_was_started);
ret = os_file_close(node->handle); ret = os_file_close(node->handle);
ut_a(ret); ut_a(ret);
@@ -1450,7 +1451,8 @@ fil_space_free_low(
fil_space_t* space) fil_space_t* space)
{ {
/* The tablespace must not be in fil_system->named_spaces. */ /* The tablespace must not be in fil_system->named_spaces. */
ut_ad(srv_fast_shutdown == 2 || space->max_lsn == 0); ut_ad(srv_fast_shutdown == 2 || !srv_was_started
|| space->max_lsn == 0);
for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
node != NULL; ) { node != NULL; ) {
@@ -2059,6 +2061,7 @@ fil_close_all_files(void)
/* At shutdown, we should not have any files in this list. */ /* At shutdown, we should not have any files in this list. */
ut_ad(srv_fast_shutdown == 2 ut_ad(srv_fast_shutdown == 2
|| !srv_was_started
|| UT_LIST_GET_LEN(fil_system->named_spaces) == 0); || UT_LIST_GET_LEN(fil_system->named_spaces) == 0);
mutex_enter(&fil_system->mutex); mutex_enter(&fil_system->mutex);
@@ -2085,6 +2088,7 @@ fil_close_all_files(void)
mutex_exit(&fil_system->mutex); mutex_exit(&fil_system->mutex);
ut_ad(srv_fast_shutdown == 2 ut_ad(srv_fast_shutdown == 2
|| !srv_was_started
|| UT_LIST_GET_LEN(fil_system->named_spaces) == 0); || UT_LIST_GET_LEN(fil_system->named_spaces) == 0);
} }

View File

@@ -4476,6 +4476,7 @@ innobase_change_buffering_inited_ok:
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
innodb_shutdown();
DBUG_RETURN(innobase_init_abort()); DBUG_RETURN(innobase_init_abort());
} else if (!srv_read_only_mode) { } else if (!srv_read_only_mode) {
mysql_thread_create(thd_destructor_thread_key, mysql_thread_create(thd_destructor_thread_key,
@@ -4594,10 +4595,7 @@ innobase_end(
mysql_cond_broadcast(thd_destructor_myvar->current_cond); mysql_cond_broadcast(thd_destructor_myvar->current_cond);
} }
if (innobase_shutdown_for_mysql() != DB_SUCCESS) { innodb_shutdown();
err = 1;
}
innobase_space_shutdown(); innobase_space_shutdown();
if (!srv_read_only_mode) { if (!srv_read_only_mode) {
pthread_join(thd_destructor_thread, NULL); pthread_join(thd_destructor_thread, NULL);

View File

@@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2015, 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
@@ -315,18 +316,6 @@ que_fork_scheduler_round_robin(
que_fork_t* fork, /*!< in: a query fork */ que_fork_t* fork, /*!< in: a query fork */
que_thr_t* thr); /*!< in: current pos */ que_thr_t* thr); /*!< in: current pos */
/*********************************************************************//**
Initialise the query sub-system. */
void
que_init(void);
/*==========*/
/*********************************************************************//**
Close the query sub-system. */
void
que_close(void);
/*===========*/
/** Query thread states */ /** Query thread states */
enum que_thr_state_t { enum que_thr_state_t {
QUE_THR_RUNNING, QUE_THR_RUNNING,

View File

@@ -729,22 +729,11 @@ void
srv_boot(void); srv_boot(void);
/*==========*/ /*==========*/
/*********************************************************************//** /*********************************************************************//**
Initializes the server. */
void
srv_init(void);
/*==========*/
/*********************************************************************//**
Frees the data structures created in srv_init(). */ Frees the data structures created in srv_init(). */
void void
srv_free(void); srv_free(void);
/*==========*/ /*==========*/
/*********************************************************************//** /*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
void
srv_general_init(void);
/*==================*/
/*********************************************************************//**
Sets the info describing an i/o thread current state. */ Sets the info describing an i/o thread current state. */
void void
srv_set_io_thread_op_info( srv_set_io_thread_op_info(

View File

@@ -67,11 +67,9 @@ are not found and the user wants.
dberr_t dberr_t
innobase_start_or_create_for_mysql(void); innobase_start_or_create_for_mysql(void);
/*====================================*/ /*====================================*/
/****************************************************************//** /** Shut down InnoDB. */
Shuts down the Innobase database. void
@return DB_SUCCESS or error code */ innodb_shutdown();
dberr_t
innobase_shutdown_for_mysql(void);
/****************************************************************//** /****************************************************************//**
Shuts down background threads that can generate undo pages. */ Shuts down background threads that can generate undo pages. */

View File

@@ -2097,7 +2097,6 @@ logs_empty_and_mark_files_at_shutdown(void)
{ {
lsn_t lsn; lsn_t lsn;
ulint count = 0; ulint count = 0;
ulint total_trx;
ulint pending_io; ulint pending_io;
ib::info() << "Starting shutdown..."; ib::info() << "Starting shutdown...";
@@ -2120,7 +2119,11 @@ loop:
os_event_set(srv_monitor_event); os_event_set(srv_monitor_event);
os_event_set(srv_buf_dump_event); os_event_set(srv_buf_dump_event);
os_event_set(lock_sys->timeout_event); os_event_set(lock_sys->timeout_event);
os_event_set(dict_stats_event); if (dict_stats_event) {
os_event_set(dict_stats_event);
} else {
ut_ad(!srv_dict_stats_thread_active);
}
} }
os_thread_sleep(100000); os_thread_sleep(100000);
@@ -2131,9 +2134,8 @@ loop:
shutdown, because the InnoDB layer may have committed or shutdown, because the InnoDB layer may have committed or
prepared transactions and we don't want to lose them. */ prepared transactions and we don't want to lose them. */
total_trx = trx_sys_any_active_transactions(); if (ulint total_trx = srv_was_started
? trx_sys_any_active_transactions() : 0) {
if (total_trx > 0) {
if (srv_print_verbose_log && count > 600) { if (srv_print_verbose_log && count > 600) {
ib::info() << "Waiting for " << total_trx << " active" ib::info() << "Waiting for " << total_trx << " active"
@@ -2253,8 +2255,8 @@ wait_suspend_loop:
goto loop; goto loop;
} }
if (srv_fast_shutdown == 2) { if (srv_fast_shutdown == 2 || !srv_was_started) {
if (!srv_read_only_mode) { if (!srv_read_only_mode && srv_was_started) {
ib::info() << "MySQL has requested a very fast" ib::info() << "MySQL has requested a very fast"
" shutdown without flushing the InnoDB buffer" " shutdown without flushing the InnoDB buffer"
" pool to data files. At the next mysqld" " pool to data files. At the next mysqld"
@@ -2318,8 +2320,7 @@ wait_suspend_loop:
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Make some checks that the server really is quiet */ /* Make some checks that the server really is quiet */
srv_thread_type type = srv_get_active_thread_type(); ut_a(srv_get_active_thread_type() == SRV_NONE);
ut_a(type == SRV_NONE);
bool freed = buf_all_freed(); bool freed = buf_all_freed();
ut_a(freed); ut_a(freed);
@@ -2327,9 +2328,8 @@ wait_suspend_loop:
ut_a(lsn == log_sys->lsn); ut_a(lsn == log_sys->lsn);
if (lsn < srv_start_lsn) { if (lsn < srv_start_lsn) {
ib::error() << "Log sequence number at shutdown " << lsn ib::error() << "Shutdown LSN=" << lsn
<< " is lower than at startup " << srv_start_lsn << " is less than start LSN=" << srv_start_lsn;
<< "!";
} }
srv_shutdown_lsn = lsn; srv_shutdown_lsn = lsn;
@@ -2339,15 +2339,14 @@ wait_suspend_loop:
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
ib::error() << "Writing flushed lsn " << lsn ib::error() << "Writing flushed lsn " << lsn
<< " failed at shutdown error " << err; << " failed; error=" << err;
} }
} }
fil_close_all_files(); fil_close_all_files();
/* Make some checks that the server really is quiet */ /* Make some checks that the server really is quiet */
type = srv_get_active_thread_type(); ut_a(srv_get_active_thread_type() == SRV_NONE);
ut_a(type == SRV_NONE);
freed = buf_all_freed(); freed = buf_all_freed();
ut_a(freed); ut_a(freed);

View File

@@ -455,6 +455,8 @@ recv_sys_close(void)
/*================*/ /*================*/
{ {
if (recv_sys != NULL) { if (recv_sys != NULL) {
recv_sys->dblwr.pages.clear();
if (recv_sys->addr_hash != NULL) { if (recv_sys->addr_hash != NULL) {
hash_table_free(recv_sys->addr_hash); hash_table_free(recv_sys->addr_hash);
} }
@@ -3263,6 +3265,7 @@ recv_recovery_from_checkpoint_start(
ut_ad(!recv_sys->found_corrupt_fs); ut_ad(!recv_sys->found_corrupt_fs);
if (srv_read_only_mode && recv_needed_recovery) { if (srv_read_only_mode && recv_needed_recovery) {
log_mutex_exit();
return(DB_READ_ONLY); return(DB_READ_ONLY);
} }

View File

@@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 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
@@ -1248,21 +1249,3 @@ que_eval_sql(
DBUG_RETURN(trx->error_state); DBUG_RETURN(trx->error_state);
} }
/*********************************************************************//**
Initialise the query sub-system. */
void
que_init(void)
/*==========*/
{
/* No op */
}
/*********************************************************************//**
Close the query sub-system. */
void
que_close(void)
/*===========*/
{
/* No op */
}

View File

@@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2000, 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
@@ -5233,7 +5234,8 @@ row_mysql_close(void)
{ {
ut_a(UT_LIST_GET_LEN(row_mysql_drop_list) == 0); ut_a(UT_LIST_GET_LEN(row_mysql_drop_list) == 0);
mutex_free(&row_drop_list_mutex); if (row_mysql_drop_list_inited) {
mutex_free(&row_drop_list_mutex);
row_mysql_drop_list_inited = FALSE; row_mysql_drop_list_inited = FALSE;
}
} }

View File

@@ -1007,11 +1007,10 @@ srv_free_slot(
srv_sys_mutex_exit(); srv_sys_mutex_exit();
} }
/*********************************************************************//** /** Initialize the server. */
Initializes the server. */ static
void void
srv_init(void) srv_init()
/*==========*/
{ {
ulint n_sys_threads = 0; ulint n_sys_threads = 0;
ulint srv_sys_sz = sizeof(*srv_sys); ulint srv_sys_sz = sizeof(*srv_sys);
@@ -1097,6 +1096,10 @@ void
srv_free(void) srv_free(void)
/*==========*/ /*==========*/
{ {
if (!srv_sys) {
return;
}
mutex_free(&srv_innodb_monitor_mutex); mutex_free(&srv_innodb_monitor_mutex);
mutex_free(&page_zip_stat_per_index_mutex); mutex_free(&page_zip_stat_per_index_mutex);
@@ -1130,22 +1133,6 @@ srv_free(void)
srv_sys = 0; srv_sys = 0;
} }
/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
void
srv_general_init(void)
/*==================*/
{
sync_check_init();
/* Reset the system variables in the recovery module. */
recv_sys_var_init();
os_thread_init();
trx_pool_init();
que_init();
row_mysql_init();
}
/*********************************************************************//** /*********************************************************************//**
Normalizes init parameter values to use units we use inside InnoDB. */ Normalizes init parameter values to use units we use inside InnoDB. */
static static
@@ -1175,10 +1162,12 @@ srv_boot(void)
srv_normalize_init_values(); srv_normalize_init_values();
/* Initialize synchronization primitives, memory management, and thread sync_check_init();
local storage */ os_thread_init();
/* Reset the system variables in the recovery module. */
srv_general_init(); recv_sys_var_init();
trx_pool_init();
row_mysql_init();
/* Initialize this module */ /* Initialize this module */
@@ -2013,14 +2002,15 @@ srv_get_active_thread_type(void)
srv_sys_mutex_exit(); srv_sys_mutex_exit();
if (ret == SRV_NONE && srv_shutdown_state != SRV_SHUTDOWN_NONE) { if (ret == SRV_NONE && srv_shutdown_state != SRV_SHUTDOWN_NONE
&& purge_sys != NULL) {
/* Check only on shutdown. */ /* Check only on shutdown. */
switch (trx_purge_state()) { switch (trx_purge_state()) {
case PURGE_STATE_INIT:
case PURGE_STATE_RUN: case PURGE_STATE_RUN:
case PURGE_STATE_STOP: case PURGE_STATE_STOP:
ret = SRV_PURGE; ret = SRV_PURGE;
break; break;
case PURGE_STATE_INIT:
case PURGE_STATE_DISABLED: case PURGE_STATE_DISABLED:
case PURGE_STATE_EXIT: case PURGE_STATE_EXIT:
break; break;

View File

@@ -1281,7 +1281,6 @@ srv_shutdown_all_bg_threads()
os_thread_sleep(100000); os_thread_sleep(100000);
if (!active) { if (!active) {
srv_start_state = SRV_START_STATE_NONE;
return; return;
} }
} }
@@ -1419,7 +1418,7 @@ innobase_start_or_create_for_mysql(void)
{ {
bool create_new_db = false; bool create_new_db = false;
lsn_t flushed_lsn; lsn_t flushed_lsn;
dberr_t err; dberr_t err = DB_SUCCESS;
ulint srv_n_log_files_found = srv_n_log_files; ulint srv_n_log_files_found = srv_n_log_files;
mtr_t mtr; mtr_t mtr;
purge_pq_t* purge_queue; purge_pq_t* purge_queue;
@@ -1566,7 +1565,7 @@ innobase_start_or_create_for_mysql(void)
ib::error() << "Unrecognized value " ib::error() << "Unrecognized value "
<< srv_file_flush_method_str << srv_file_flush_method_str
<< " for innodb_flush_method"; << " for innodb_flush_method";
return(srv_init_abort(DB_ERROR)); err = DB_ERROR;
} }
/* Note that the call srv_boot() also changes the values of /* Note that the call srv_boot() also changes the values of
@@ -1661,6 +1660,10 @@ innobase_start_or_create_for_mysql(void)
srv_boot(); srv_boot();
if (err != DB_SUCCESS) {
return(srv_init_abort(err));
}
ib::info() << ut_crc32_implementation; ib::info() << ut_crc32_implementation;
if (!srv_read_only_mode) { if (!srv_read_only_mode) {
@@ -2589,23 +2592,6 @@ files_checked:
<< srv_force_recovery << " !!!"; << srv_force_recovery << " !!!";
} }
if (!srv_read_only_mode) {
/* Create thread(s) that handles key rotation. This is
needed already here as log_preflush_pool_modified_pages
will flush dirty pages and that might need e.g.
fil_crypt_threads_event. */
fil_system_enter();
fil_crypt_threads_init();
fil_system_exit();
/*
Create a checkpoint before logging anything new, so that
the current encryption key in use is definitely logged
before any log blocks encrypted with that key.
*/
log_make_checkpoint_at(LSN_MAX, TRUE);
}
if (srv_force_recovery == 0) { if (srv_force_recovery == 0) {
/* In the insert buffer we may have even bigger tablespace /* In the insert buffer we may have even bigger tablespace
id's, because we may have dropped those tablespaces, but id's, because we may have dropped those tablespaces, but
@@ -2641,6 +2627,21 @@ files_checked:
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
/* Create thread(s) that handles key rotation. This is
needed already here as log_preflush_pool_modified_pages
will flush dirty pages and that might need e.g.
fil_crypt_threads_event. */
fil_system_enter();
fil_crypt_threads_init();
fil_system_exit();
/*
Create a checkpoint before logging anything new, so that
the current encryption key in use is definitely logged
before any log blocks encrypted with that key.
*/
log_make_checkpoint_at(LSN_MAX, TRUE);
/* Create the dict stats gathering thread */ /* Create the dict stats gathering thread */
dict_stats_thread_handle = os_thread_create( dict_stats_thread_handle = os_thread_create(
dict_stats_thread, NULL, NULL); dict_stats_thread, NULL, NULL);
@@ -2650,6 +2651,12 @@ files_checked:
/* 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();
/* Init data for datafile scrub threads */
btr_scrub_init();
/* Initialize online defragmentation. */
btr_defragment_init();
srv_start_state_set(SRV_START_STATE_STAT); srv_start_state_set(SRV_START_STATE_STAT);
} }
@@ -2657,12 +2664,6 @@ files_checked:
srv_buf_resize_thread_active = true; srv_buf_resize_thread_active = true;
os_thread_create(buf_resize_thread, NULL, NULL); os_thread_create(buf_resize_thread, NULL, NULL);
/* Init data for datafile scrub threads */
btr_scrub_init();
/* Initialize online defragmentation. */
btr_defragment_init();
srv_was_started = TRUE; srv_was_started = TRUE;
return(DB_SUCCESS); return(DB_SUCCESS);
} }
@@ -2703,27 +2704,18 @@ void
srv_shutdown_bg_undo_sources(void) srv_shutdown_bg_undo_sources(void)
/*===========================*/ /*===========================*/
{ {
fts_optimize_shutdown(); if (srv_start_state_is_set(SRV_START_STATE_STAT)) {
dict_stats_shutdown(); ut_ad(!srv_read_only_mode);
fts_optimize_shutdown();
dict_stats_shutdown();
}
} }
/****************************************************************//** /** Shut down InnoDB. */
Shuts down the InnoDB database. void
@return DB_SUCCESS or error code */ innodb_shutdown()
dberr_t
innobase_shutdown_for_mysql(void)
/*=============================*/
{ {
if (!srv_was_started) { if (srv_fast_shutdown) {
if (srv_is_being_started) {
ib::warn() << "Shutting down an improperly started,"
" or created database!";
}
return(DB_SUCCESS);
}
if (!srv_read_only_mode && srv_fast_shutdown) {
srv_shutdown_bg_undo_sources(); srv_shutdown_bg_undo_sources();
} }
@@ -2762,23 +2754,51 @@ innobase_shutdown_for_mysql(void)
srv_misc_tmpfile = 0; srv_misc_tmpfile = 0;
} }
if (!srv_read_only_mode) { ut_ad(dict_stats_event || !srv_was_started || srv_read_only_mode);
ut_ad(dict_sys || !srv_was_started);
ut_ad(trx_sys || !srv_was_started);
ut_ad(buf_dblwr || !srv_was_started);
ut_ad(lock_sys || !srv_was_started);
ut_ad(btr_search_sys || !srv_was_started);
ut_ad(ibuf || !srv_was_started);
ut_ad(log_sys || !srv_was_started);
if (dict_stats_event) {
dict_stats_thread_deinit(); dict_stats_thread_deinit();
fil_crypt_threads_cleanup();
} }
/* Cleanup data for datafile scrubbing */ if (srv_start_state_is_set(SRV_START_STATE_STAT)) {
btr_scrub_cleanup(); ut_ad(!srv_read_only_mode);
/* srv_shutdown_bg_undo_sources() already invoked
fts_optimize_shutdown(); dict_stats_shutdown(); */
fil_crypt_threads_cleanup();
btr_scrub_cleanup();
/* FIXME: call btr_defragment_shutdown(); */
}
/* This must be disabled before closing the buffer pool /* This must be disabled before closing the buffer pool
and closing the data dictionary. */ and closing the data dictionary. */
btr_search_disable(true);
ibuf_close(); if (dict_sys) {
log_shutdown(); btr_search_disable(true);
trx_sys_file_format_close(); }
trx_sys_close(); if (ibuf) {
lock_sys_close(); ibuf_close();
}
if (log_sys) {
log_shutdown();
}
if (trx_sys) {
trx_sys_file_format_close();
trx_sys_close();
}
if (buf_dblwr) {
buf_dblwr_free();
}
if (lock_sys) {
lock_sys_close();
}
trx_pool_close(); trx_pool_close();
@@ -2790,13 +2810,17 @@ innobase_shutdown_for_mysql(void)
mutex_free(&srv_misc_tmpfile_mutex); mutex_free(&srv_misc_tmpfile_mutex);
} }
dict_close(); if (dict_sys) {
btr_search_sys_free(); dict_close();
}
if (btr_search_sys) {
btr_search_sys_free();
}
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */ them */
os_aio_free(); os_aio_free();
que_close();
row_mysql_close(); row_mysql_close();
srv_free(); srv_free();
fil_close(); fil_close();
@@ -2817,15 +2841,14 @@ innobase_shutdown_for_mysql(void)
fclose(dict_foreign_err_file); fclose(dict_foreign_err_file);
} }
if (srv_print_verbose_log) { if (srv_was_started && srv_print_verbose_log) {
ib::info() << "Shutdown completed; log sequence number " ib::info() << "Shutdown completed; log sequence number "
<< srv_shutdown_lsn; << srv_shutdown_lsn;
} }
srv_start_state = SRV_START_STATE_NONE;
srv_was_started = FALSE; srv_was_started = FALSE;
srv_start_has_been_called = FALSE; srv_start_has_been_called = FALSE;
return(DB_SUCCESS);
} }
/******************************************************************** /********************************************************************

View File

@@ -1086,13 +1086,14 @@ trx_sys_close(void)
" shutdown: " << size << " read views open"; " shutdown: " << size << " read views open";
} }
sess_close(trx_dummy_sess); if (trx_dummy_sess) {
trx_dummy_sess = NULL; sess_close(trx_dummy_sess);
trx_dummy_sess = NULL;
}
trx_purge_sys_close(); if (purge_sys) {
trx_purge_sys_close();
/* Free the double write data structures. */ }
buf_dblwr_free();
/* Only prepared transactions may be left in the system. Free them. */ /* Only prepared transactions may be left in the system. Free them. */
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx); ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx);