diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-01-31 19:43:03 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-02-01 09:30:55 +0200 |
commit | 81b7fe9d383bdf68a622b95384f067ed68ba342c (patch) | |
tree | 465e0c611e9b6bdc81459eb7e79de3fa0311fae1 | |
parent | 774056c825c4e2496730eb4821170d15d54ce14b (diff) | |
download | mariadb-git-81b7fe9d383bdf68a622b95384f067ed68ba342c.tar.gz |
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.
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 5 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 8 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 6 | ||||
-rw-r--r-- | storage/innobase/include/que0que.h | 13 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 11 | ||||
-rw-r--r-- | storage/innobase/include/srv0start.h | 8 | ||||
-rw-r--r-- | storage/innobase/log/log0log.cc | 29 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 3 | ||||
-rw-r--r-- | storage/innobase/que/que0que.cc | 19 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 8 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 42 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 143 | ||||
-rw-r--r-- | storage/innobase/trx/trx0sys.cc | 13 |
13 files changed, 146 insertions, 162 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 0f1d170b172..90ddf473232 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2000,6 +2000,11 @@ buf_pool_free_instance( mutex_free(&buf_pool->zip_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); bpage != NULL; bpage = prev_bpage) { diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 18252b64a78..81ee2b5f53a 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -779,7 +779,8 @@ fil_node_close_file( ut_a(!node->being_extended); ut_a(node->modification_counter == node->flush_counter || node->space->purpose == FIL_TYPE_TEMPORARY - || srv_fast_shutdown == 2); + || srv_fast_shutdown == 2 + || !srv_was_started); ret = os_file_close(node->handle); ut_a(ret); @@ -1450,7 +1451,8 @@ fil_space_free_low( fil_space_t* space) { /* 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); node != NULL; ) { @@ -2059,6 +2061,7 @@ fil_close_all_files(void) /* At shutdown, we should not have any files in this list. */ ut_ad(srv_fast_shutdown == 2 + || !srv_was_started || UT_LIST_GET_LEN(fil_system->named_spaces) == 0); mutex_enter(&fil_system->mutex); @@ -2085,6 +2088,7 @@ fil_close_all_files(void) mutex_exit(&fil_system->mutex); ut_ad(srv_fast_shutdown == 2 + || !srv_was_started || UT_LIST_GET_LEN(fil_system->named_spaces) == 0); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d5ee8f1f82e..b353be635f5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4476,6 +4476,7 @@ innobase_change_buffering_inited_ok: } if (err != DB_SUCCESS) { + innodb_shutdown(); DBUG_RETURN(innobase_init_abort()); } else if (!srv_read_only_mode) { mysql_thread_create(thd_destructor_thread_key, @@ -4594,10 +4595,7 @@ innobase_end( mysql_cond_broadcast(thd_destructor_myvar->current_cond); } - if (innobase_shutdown_for_mysql() != DB_SUCCESS) { - err = 1; - } - + innodb_shutdown(); innobase_space_shutdown(); if (!srv_read_only_mode) { pthread_join(thd_destructor_thread, NULL); diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 3e90e0b25e3..574b7e6acee 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -1,6 +1,7 @@ /***************************************************************************** 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 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_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 */ enum que_thr_state_t { QUE_THR_RUNNING, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index b22487ca1ef..fee6ceaca4c 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -729,22 +729,11 @@ void srv_boot(void); /*==========*/ /*********************************************************************//** -Initializes the server. */ -void -srv_init(void); -/*==========*/ -/*********************************************************************//** Frees the data structures created in srv_init(). */ 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. */ void srv_set_io_thread_op_info( diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index d456806b86b..8de9e3457fc 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -67,11 +67,9 @@ are not found and the user wants. dberr_t innobase_start_or_create_for_mysql(void); /*====================================*/ -/****************************************************************//** -Shuts down the Innobase database. -@return DB_SUCCESS or error code */ -dberr_t -innobase_shutdown_for_mysql(void); +/** Shut down InnoDB. */ +void +innodb_shutdown(); /****************************************************************//** Shuts down background threads that can generate undo pages. */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 95e64784718..3c92e9572df 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -2097,7 +2097,6 @@ logs_empty_and_mark_files_at_shutdown(void) { lsn_t lsn; ulint count = 0; - ulint total_trx; ulint pending_io; ib::info() << "Starting shutdown..."; @@ -2120,7 +2119,11 @@ loop: os_event_set(srv_monitor_event); os_event_set(srv_buf_dump_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); @@ -2131,9 +2134,8 @@ loop: shutdown, because the InnoDB layer may have committed or prepared transactions and we don't want to lose them. */ - total_trx = trx_sys_any_active_transactions(); - - if (total_trx > 0) { + if (ulint total_trx = srv_was_started + ? trx_sys_any_active_transactions() : 0) { if (srv_print_verbose_log && count > 600) { ib::info() << "Waiting for " << total_trx << " active" @@ -2253,8 +2255,8 @@ wait_suspend_loop: goto loop; } - if (srv_fast_shutdown == 2) { - if (!srv_read_only_mode) { + if (srv_fast_shutdown == 2 || !srv_was_started) { + if (!srv_read_only_mode && srv_was_started) { ib::info() << "MySQL has requested a very fast" " shutdown without flushing the InnoDB buffer" " pool to data files. At the next mysqld" @@ -2318,8 +2320,7 @@ wait_suspend_loop: srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; /* Make some checks that the server really is quiet */ - srv_thread_type type = srv_get_active_thread_type(); - ut_a(type == SRV_NONE); + ut_a(srv_get_active_thread_type() == SRV_NONE); bool freed = buf_all_freed(); ut_a(freed); @@ -2327,9 +2328,8 @@ wait_suspend_loop: ut_a(lsn == log_sys->lsn); if (lsn < srv_start_lsn) { - ib::error() << "Log sequence number at shutdown " << lsn - << " is lower than at startup " << srv_start_lsn - << "!"; + ib::error() << "Shutdown LSN=" << lsn + << " is less than start LSN=" << srv_start_lsn; } srv_shutdown_lsn = lsn; @@ -2339,15 +2339,14 @@ wait_suspend_loop: if (err != DB_SUCCESS) { ib::error() << "Writing flushed lsn " << lsn - << " failed at shutdown error " << err; + << " failed; error=" << err; } } fil_close_all_files(); /* Make some checks that the server really is quiet */ - type = srv_get_active_thread_type(); - ut_a(type == SRV_NONE); + ut_a(srv_get_active_thread_type() == SRV_NONE); freed = buf_all_freed(); ut_a(freed); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index dc44ae3505d..78566d060cb 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -455,6 +455,8 @@ recv_sys_close(void) /*================*/ { if (recv_sys != NULL) { + recv_sys->dblwr.pages.clear(); + if (recv_sys->addr_hash != NULL) { hash_table_free(recv_sys->addr_hash); } @@ -3263,6 +3265,7 @@ recv_recovery_from_checkpoint_start( ut_ad(!recv_sys->found_corrupt_fs); if (srv_read_only_mode && recv_needed_recovery) { + log_mutex_exit(); return(DB_READ_ONLY); } diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index 8d3e8cfa115..9fd12686f57 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -1,6 +1,7 @@ /***************************************************************************** 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 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); } - -/*********************************************************************//** -Initialise the query sub-system. */ -void -que_init(void) -/*==========*/ -{ - /* No op */ -} - -/*********************************************************************//** -Close the query sub-system. */ -void -que_close(void) -/*===========*/ -{ - /* No op */ -} diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 9356f25bcb0..fbf49d8d3a0 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1,6 +1,7 @@ /***************************************************************************** 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 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); - mutex_free(&row_drop_list_mutex); - - row_mysql_drop_list_inited = FALSE; + if (row_mysql_drop_list_inited) { + mutex_free(&row_drop_list_mutex); + row_mysql_drop_list_inited = FALSE; + } } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index c2cf71a2f98..0fd5ff7afaf 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1007,11 +1007,10 @@ srv_free_slot( srv_sys_mutex_exit(); } -/*********************************************************************//** -Initializes the server. */ +/** Initialize the server. */ +static void -srv_init(void) -/*==========*/ +srv_init() { ulint n_sys_threads = 0; ulint srv_sys_sz = sizeof(*srv_sys); @@ -1097,6 +1096,10 @@ void srv_free(void) /*==========*/ { + if (!srv_sys) { + return; + } + mutex_free(&srv_innodb_monitor_mutex); mutex_free(&page_zip_stat_per_index_mutex); @@ -1131,22 +1134,6 @@ srv_free(void) } /*********************************************************************//** -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. */ static void @@ -1175,10 +1162,12 @@ srv_boot(void) srv_normalize_init_values(); - /* Initialize synchronization primitives, memory management, and thread - local storage */ - - srv_general_init(); + sync_check_init(); + os_thread_init(); + /* Reset the system variables in the recovery module. */ + recv_sys_var_init(); + trx_pool_init(); + row_mysql_init(); /* Initialize this module */ @@ -2013,14 +2002,15 @@ srv_get_active_thread_type(void) 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. */ switch (trx_purge_state()) { - case PURGE_STATE_INIT: case PURGE_STATE_RUN: case PURGE_STATE_STOP: ret = SRV_PURGE; break; + case PURGE_STATE_INIT: case PURGE_STATE_DISABLED: case PURGE_STATE_EXIT: break; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 408501f6f0d..1d17bff4782 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1281,7 +1281,6 @@ srv_shutdown_all_bg_threads() os_thread_sleep(100000); if (!active) { - srv_start_state = SRV_START_STATE_NONE; return; } } @@ -1419,7 +1418,7 @@ innobase_start_or_create_for_mysql(void) { bool create_new_db = false; lsn_t flushed_lsn; - dberr_t err; + dberr_t err = DB_SUCCESS; ulint srv_n_log_files_found = srv_n_log_files; mtr_t mtr; purge_pq_t* purge_queue; @@ -1566,7 +1565,7 @@ innobase_start_or_create_for_mysql(void) ib::error() << "Unrecognized value " << srv_file_flush_method_str << " for innodb_flush_method"; - return(srv_init_abort(DB_ERROR)); + err = DB_ERROR; } /* Note that the call srv_boot() also changes the values of @@ -1661,6 +1660,10 @@ innobase_start_or_create_for_mysql(void) srv_boot(); + if (err != DB_SUCCESS) { + return(srv_init_abort(err)); + } + ib::info() << ut_crc32_implementation; if (!srv_read_only_mode) { @@ -2589,23 +2592,6 @@ files_checked: << 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) { /* In the insert buffer we may have even bigger tablespace id's, because we may have dropped those tablespaces, but @@ -2641,6 +2627,21 @@ files_checked: } #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 */ dict_stats_thread_handle = os_thread_create( dict_stats_thread, NULL, NULL); @@ -2650,6 +2651,12 @@ files_checked: /* Create the thread that will optimize the FTS sub-system. */ 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); } @@ -2657,12 +2664,6 @@ files_checked: srv_buf_resize_thread_active = true; 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; return(DB_SUCCESS); } @@ -2703,27 +2704,18 @@ void srv_shutdown_bg_undo_sources(void) /*===========================*/ { - fts_optimize_shutdown(); - dict_stats_shutdown(); + if (srv_start_state_is_set(SRV_START_STATE_STAT)) { + ut_ad(!srv_read_only_mode); + fts_optimize_shutdown(); + dict_stats_shutdown(); + } } -/****************************************************************//** -Shuts down the InnoDB database. -@return DB_SUCCESS or error code */ -dberr_t -innobase_shutdown_for_mysql(void) -/*=============================*/ +/** Shut down InnoDB. */ +void +innodb_shutdown() { - if (!srv_was_started) { - 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) { + if (srv_fast_shutdown) { srv_shutdown_bg_undo_sources(); } @@ -2762,23 +2754,51 @@ innobase_shutdown_for_mysql(void) 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(); - fil_crypt_threads_cleanup(); } - /* Cleanup data for datafile scrubbing */ - btr_scrub_cleanup(); + if (srv_start_state_is_set(SRV_START_STATE_STAT)) { + 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 and closing the data dictionary. */ - btr_search_disable(true); - ibuf_close(); - log_shutdown(); - trx_sys_file_format_close(); - trx_sys_close(); - lock_sys_close(); + if (dict_sys) { + btr_search_disable(true); + } + if (ibuf) { + 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(); @@ -2790,13 +2810,17 @@ innobase_shutdown_for_mysql(void) mutex_free(&srv_misc_tmpfile_mutex); } - dict_close(); - btr_search_sys_free(); + if (dict_sys) { + dict_close(); + } + + if (btr_search_sys) { + btr_search_sys_free(); + } /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ os_aio_free(); - que_close(); row_mysql_close(); srv_free(); fil_close(); @@ -2817,15 +2841,14 @@ innobase_shutdown_for_mysql(void) 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 " << srv_shutdown_lsn; } + srv_start_state = SRV_START_STATE_NONE; srv_was_started = FALSE; srv_start_has_been_called = FALSE; - - return(DB_SUCCESS); } /******************************************************************** diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 724139461d3..bb29fb167b2 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -1086,13 +1086,14 @@ trx_sys_close(void) " shutdown: " << size << " read views open"; } - sess_close(trx_dummy_sess); - trx_dummy_sess = NULL; - - trx_purge_sys_close(); + if (trx_dummy_sess) { + sess_close(trx_dummy_sess); + trx_dummy_sess = NULL; + } - /* Free the double write data structures. */ - buf_dblwr_free(); + if (purge_sys) { + trx_purge_sys_close(); + } /* 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); |