From 538e7d165524a72e10aa237897025cb02489d379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 24 Mar 2011 14:00:14 +0200 Subject: [PATCH] Bug#11766305 - 59392: Remove thr0loc.c and ibuf_inside() [part 4 of 4] ibuf_inside(), ibuf_enter(), ibuf_exit(): Add the parameter mtr. The flag is no longer kept in the thread-local storage but in the mini-transaction (mtr->inside_ibuf). mtr_start(): Clean up the comment and remove the unused return value. mtr_commit(): Assert !ibuf_inside(mtr) in debug builds. ibuf_mtr_start(): Like mtr_start(), but sets the flag. ibuf_mtr_commit(), ibuf_btr_pcur_commit_specify_mtr(): Wrappers that assert ibuf_inside(). buf_page_get_zip(), buf_page_init_for_read(), buf_read_ibuf_merge_pages(), fil_io(), ibuf_free_excess_pages(), ibuf_contract_ext(): Remove assertions on ibuf_inside(), because a mini-transaction is not available. buf_read_ahead_linear(): Add the parameter inside_ibuf. ibuf_restore_pos(): When this function returns FALSE, it commits mtr and must therefore do ibuf_exit(mtr). ibuf_delete_rec(): This function commits mtr and must therefore do ibuf_exit(mtr). ibuf_rec_get_page_no(), ibuf_rec_get_space(), ibuf_rec_get_info(), ibuf_rec_get_op_type(), ibuf_build_entry_from_ibuf_rec(), ibuf_rec_get_volume(), ibuf_get_merge_page_nos(), ibuf_get_volume_buffered_count(), ibuf_get_entry_counter_low(): Add the parameter mtr in debug builds, for asserting ibuf_inside(mtr). rb:585 approved by Sunny Bains --- storage/innobase/CMakeLists.txt | 1 - storage/innobase/btr/btr0cur.c | 2 +- storage/innobase/buf/buf0buf.c | 25 +- storage/innobase/buf/buf0rea.c | 19 +- storage/innobase/fil/fil0fil.c | 2 - storage/innobase/handler/ha_innodb.cc | 3 - storage/innobase/ibuf/ibuf0ibuf.c | 593 ++++++++++++++------------ storage/innobase/include/buf0rea.h | 8 +- storage/innobase/include/ibuf0ibuf.h | 24 +- storage/innobase/include/ibuf0ibuf.ic | 40 ++ storage/innobase/include/mtr0mtr.h | 14 +- storage/innobase/include/mtr0mtr.ic | 11 +- storage/innobase/include/sync0sync.h | 1 - storage/innobase/include/thr0loc.h | 74 ---- storage/innobase/include/thr0loc.ic | 24 -- storage/innobase/mtr/mtr0mtr.c | 1 + storage/innobase/srv/srv0srv.c | 4 - storage/innobase/srv/srv0start.c | 2 - storage/innobase/thr/thr0loc.c | 259 ----------- storage/innobase/trx/trx0trx.c | 1 - 20 files changed, 422 insertions(+), 686 deletions(-) delete mode 100644 storage/innobase/include/thr0loc.h delete mode 100644 storage/innobase/include/thr0loc.ic delete mode 100644 storage/innobase/thr/thr0loc.c diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index d4b98f2af0d..01034eede69 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -241,7 +241,6 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c srv/srv0srv.c srv/srv0start.c sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c - thr/thr0loc.c trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c usr/usr0sess.c diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index fce3e98e3fa..c4034d0896a 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -402,7 +402,7 @@ btr_cur_search_to_nth_level( ut_ad(level == 0 || mode == PAGE_CUR_LE); ut_ad(dict_index_check_search_tuple(index, tuple)); - ut_ad(!dict_index_is_ibuf(index) || ibuf_inside()); + ut_ad(!dict_index_is_ibuf(index) || ibuf_inside(mtr)); ut_ad(dtuple_check_typed(tuple)); #ifdef UNIV_DEBUG diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index aece9586fd2..cf5b90a2539 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -2316,9 +2316,6 @@ buf_page_get_zip( unsigned access_time; buf_pool_t* buf_pool = buf_pool_get(space, offset); -#ifndef UNIV_LOG_DEBUG - ut_ad(!ibuf_inside()); -#endif buf_pool->stat.n_page_gets++; for (;;) { @@ -2758,8 +2755,9 @@ buf_page_get_gen( ut_ad(zip_size == fil_space_get_zip_size(space)); ut_ad(ut_is_2pow(zip_size)); #ifndef UNIV_LOG_DEBUG - ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset, - FALSE, file, line, NULL)); + ut_ad(!ibuf_inside(mtr) + || ibuf_page_low(space, zip_size, offset, + FALSE, file, line, NULL)); #endif buf_pool->stat.n_page_gets++; fold = buf_page_address_fold(space, offset); @@ -3132,7 +3130,8 @@ wait_until_unfixed: /* In the case of a first access, try to apply linear read-ahead */ - buf_read_ahead_linear(space, zip_size, offset); + buf_read_ahead_linear(space, zip_size, offset, + ibuf_inside(mtr)); } #ifdef UNIV_IBUF_COUNT_DEBUG @@ -3189,7 +3188,7 @@ buf_page_optimistic_get( access_time = buf_page_is_accessed(&block->page); buf_page_set_accessed_make_young(&block->page, access_time); - ut_ad(!ibuf_inside() + ut_ad(!ibuf_inside(mtr) || ibuf_page(buf_block_get_space(block), buf_block_get_zip_size(block), buf_block_get_page_no(block), NULL)); @@ -3245,7 +3244,8 @@ buf_page_optimistic_get( buf_read_ahead_linear(buf_block_get_space(block), buf_block_get_zip_size(block), - buf_block_get_page_no(block)); + buf_block_get_page_no(block), + ibuf_inside(mtr)); } #ifdef UNIV_IBUF_COUNT_DEBUG @@ -3321,7 +3321,7 @@ buf_page_get_known_nowait( buf_pool_mutex_exit(buf_pool); } - ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); + ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD); if (rw_latch == RW_S_LATCH) { success = rw_lock_s_lock_nowait(&(block->lock), @@ -3586,14 +3586,13 @@ buf_page_init_for_read( /* It is a read-ahead within an ibuf routine */ ut_ad(!ibuf_bitmap_page(zip_size, offset)); - ut_ad(ibuf_inside()); - mtr_start(&mtr); + ibuf_mtr_start(&mtr); if (!recv_no_ibuf_operations && !ibuf_page(space, zip_size, offset, &mtr)) { - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); return(NULL); } @@ -3778,7 +3777,7 @@ func_exit: if (mode == BUF_READ_IBUF_PAGES_ONLY) { - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); } ut_ad(!bpage || buf_page_in_file(bpage)); diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c index 17704a4b65d..eeaa21ae9ef 100644 --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c @@ -236,10 +236,10 @@ UNIV_INTERN ulint buf_read_ahead_linear( /*==================*/ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ - ulint offset) /*!< in: page number of a page; NOTE: the current thread - must want access to this page (see NOTE 3 above) */ + ulint space, /*!< in: space id */ + ulint zip_size, /*!< in: compressed page size in bytes, or 0 */ + ulint offset, /*!< in: page number; see NOTE 3 above */ + ibool inside_ibuf) /*!< in: TRUE if we are inside ibuf routine */ { buf_pool_t* buf_pool = buf_pool_get(space, offset); ib_int64_t tablespace_version; @@ -429,11 +429,9 @@ buf_read_ahead_linear( /* If we got this far, read-ahead can be sensible: do it */ - if (ibuf_inside()) { - ibuf_mode = BUF_READ_IBUF_PAGES_ONLY; - } else { - ibuf_mode = BUF_READ_ANY_PAGE; - } + ibuf_mode = inside_ibuf + ? BUF_READ_IBUF_PAGES_ONLY | OS_AIO_SIMULATED_WAKE_LATER + : BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER; count = 0; @@ -450,7 +448,7 @@ buf_read_ahead_linear( if (!ibuf_bitmap_page(zip_size, i)) { count += buf_read_page_low( &err, FALSE, - ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, + ibuf_mode, space, zip_size, FALSE, tablespace_version, i); if (err == DB_TABLESPACE_DELETED) { ut_print_timestamp(stderr); @@ -520,7 +518,6 @@ buf_read_ibuf_merge_pages( { ulint i; - ut_ad(!ibuf_inside()); #ifdef UNIV_IBUF_DEBUG ut_a(n_stored < UNIV_PAGE_SIZE); #endif diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index d940bc70609..6c50b853187 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -4342,8 +4342,6 @@ fil_io( ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE) || !ibuf_bitmap_page(zip_size, block_offset) || sync || is_log); - ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE) - || ibuf_page(space_id, zip_size, block_offset, NULL)); # endif /* UNIV_LOG_DEBUG */ if (sync) { mode = OS_AIO_SYNC; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1a2bb77e27d..c5fc3693c11 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -82,7 +82,6 @@ extern "C" { #include "fil0fil.h" #include "trx0xa.h" #include "row0merge.h" -#include "thr0loc.h" #include "dict0boot.h" #include "ha_prototypes.h" #include "ut0mem.h" @@ -280,7 +279,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { {&sync_thread_mutex_key, "sync_thread_mutex", 0}, # endif /* UNIV_SYNC_DEBUG */ {&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0}, - {&thr_local_mutex_key, "thr_local_mutex", 0}, {&trx_undo_mutex_key, "trx_undo_mutex", 0} }; # endif /* UNIV_PFS_MUTEX */ @@ -3042,7 +3040,6 @@ innobase_close_connection( innobase_rollback_trx(trx); - thr_local_free(trx->mysql_thread_id); trx_free_for_mysql(trx); DBUG_RETURN(0); diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 93d152bfb74..8110bccc162 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -44,7 +44,6 @@ Created 7/19/1997 Heikki Tuuri #include "fsp0fsp.h" #include "trx0sys.h" #include "fil0fil.h" -#include "thr0loc.h" #include "rem0rec.h" #include "btr0cur.h" #include "btr0pcur.h" @@ -324,52 +323,43 @@ still physically like the index page even if the index would have been dropped! So, there seems to be no problem. */ /******************************************************************//** -Sets the flag in the current OS thread local storage denoting that it is +Sets the flag in the current mini-transaction record indicating we're inside an insert buffer routine. */ UNIV_INLINE void -ibuf_enter(void) -/*============*/ +ibuf_enter( +/*=======*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - ibool* ptr; - - ptr = thr_local_get_in_ibuf_field(); - - ut_ad(*ptr == FALSE); - - *ptr = TRUE; + ut_ad(!mtr->inside_ibuf); + mtr->inside_ibuf = TRUE; } /******************************************************************//** -Sets the flag in the current OS thread local storage denoting that it is +Sets the flag in the current mini-transaction record indicating we're exiting an insert buffer routine. */ UNIV_INLINE void -ibuf_exit(void) -/*===========*/ +ibuf_exit( +/*======*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - ibool* ptr; - - ptr = thr_local_get_in_ibuf_field(); - - ut_ad(*ptr == TRUE); - - *ptr = FALSE; + ut_ad(mtr->inside_ibuf); + mtr->inside_ibuf = FALSE; } -/******************************************************************//** -Returns TRUE if the current OS thread is performing an insert buffer -routine. - -For instance, a read-ahead of non-ibuf pages is forbidden by threads -that are executing an insert buffer routine. -@return TRUE if inside an insert buffer routine */ -UNIV_INTERN -ibool -ibuf_inside(void) -/*=============*/ +/**************************************************************//** +Commits an insert buffer mini-transaction and sets the persistent +cursor latch mode to BTR_NO_LATCHES, that is, detaches the cursor. */ +UNIV_INLINE +void +ibuf_btr_pcur_commit_specify_mtr( +/*=============================*/ + btr_pcur_t* pcur, /*!< in/out: persistent cursor */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - return(*thr_local_get_in_ibuf_field()); + ut_d(ibuf_exit(mtr)); + btr_pcur_commit_specify_mtr(pcur, mtr); } /******************************************************************//** @@ -379,11 +369,11 @@ static page_t* ibuf_header_page_get( /*=================*/ - mtr_t* mtr) /*!< in: mtr */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { buf_block_t* block; - ut_ad(!ibuf_inside()); + ut_ad(!ibuf_inside(mtr)); block = buf_page_get( IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr); @@ -404,7 +394,7 @@ ibuf_tree_root_get( buf_block_t* block; page_t* root; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); ut_ad(mutex_own(&ibuf_mutex)); mtr_x_lock(dict_index_get_lock(ibuf->index), mtr); @@ -547,7 +537,7 @@ ibuf_init_at_db_start(void) fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, &n_used, &mtr); - ibuf_enter(); + ibuf_enter(&mtr); ut_ad(n_used >= 2); @@ -568,9 +558,7 @@ ibuf_init_at_db_start(void) mutex_exit(&ibuf_mutex); ibuf->empty = (page_get_n_recs(root) == 0); - mtr_commit(&mtr); - - ibuf_exit(); + ibuf_mtr_commit(&mtr); heap = mem_heap_create(450); @@ -1230,19 +1218,30 @@ ibuf_page_low( return(ret); } +#ifdef UNIV_DEBUG +# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(mtr,rec) +#else /* UNIV_DEBUG */ +# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(rec) +#endif /* UNIV_DEBUG */ + /********************************************************************//** Returns the page number field of an ibuf record. @return page number */ static ulint -ibuf_rec_get_page_no( -/*=================*/ +ibuf_rec_get_page_no_func( +/*======================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec) /*!< in: ibuf record */ { const byte* field; ulint len; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); field = rec_get_nth_field_old(rec, 1, &len); @@ -1264,20 +1263,31 @@ ibuf_rec_get_page_no( return(mach_read_from_4(field)); } +#ifdef UNIV_DEBUG +# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(mtr,rec) +#else /* UNIV_DEBUG */ +# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(rec) +#endif /* UNIV_DEBUG */ + /********************************************************************//** Returns the space id field of an ibuf record. For < 4.1.x format records returns 0. @return space id */ static ulint -ibuf_rec_get_space( -/*===============*/ +ibuf_rec_get_space_func( +/*====================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec) /*!< in: ibuf record */ { const byte* field; ulint len; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); field = rec_get_nth_field_old(rec, 1, &len); @@ -1298,12 +1308,22 @@ ibuf_rec_get_space( return(0); } +#ifdef UNIV_DEBUG +# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \ + ibuf_rec_get_info_func(mtr,rec,op,comp,info_len,counter) +#else /* UNIV_DEBUG */ +# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \ + ibuf_rec_get_info_func(rec,op,comp,info_len,counter) +#endif /****************************************************************//** Get various information about an ibuf record in >= 4.1.x format. */ static void -ibuf_rec_get_info( -/*==============*/ +ibuf_rec_get_info_func( +/*===================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec, /*!< in: ibuf record */ ibuf_op_t* op, /*!< out: operation type, or NULL */ ibool* comp, /*!< out: compact flag, or NULL */ @@ -1322,7 +1342,9 @@ ibuf_rec_get_info( ulint info_len_local; ulint counter_local; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); fields = rec_get_n_fields_old(rec); ut_a(fields > 4); @@ -1371,18 +1393,29 @@ ibuf_rec_get_info( } } +#ifdef UNIV_DEBUG +# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(mtr,rec) +#else /* UNIV_DEBUG */ +# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(rec) +#endif + /****************************************************************//** Returns the operation type field of an ibuf record. @return operation type */ static ibuf_op_t -ibuf_rec_get_op_type( -/*=================*/ +ibuf_rec_get_op_type_func( +/*======================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec) /*!< in: ibuf record */ { ulint len; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); (void) rec_get_nth_field_old(rec, 1, &len); @@ -1394,7 +1427,7 @@ ibuf_rec_get_op_type( } else { ibuf_op_t op; - ibuf_rec_get_info(rec, &op, NULL, NULL, NULL); + ibuf_rec_get_info(mtr, rec, &op, NULL, NULL, NULL); return(op); } @@ -1593,6 +1626,14 @@ ibuf_build_entry_pre_4_1_x( return(tuple); } +#ifdef UNIV_DEBUG +# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \ + ibuf_build_entry_from_ibuf_rec_func(mtr,ibuf_rec,heap,pindex) +#else /* UNIV_DEBUG */ +# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \ + ibuf_build_entry_from_ibuf_rec_func(ibuf_rec,heap,pindex) +#endif + /*********************************************************************//** Builds the entry used to @@ -1611,8 +1652,11 @@ hold a latch to the ibuf_rec page as long as the entry is used! @return own: entry to insert to a non-clustered index */ static dtuple_t* -ibuf_build_entry_from_ibuf_rec( -/*===========================*/ +ibuf_build_entry_from_ibuf_rec_func( +/*================================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* ibuf_rec, /*!< in: record in an insert buffer */ mem_heap_t* heap, /*!< in: heap where built */ dict_index_t** pindex) /*!< out, own: dummy index that @@ -1629,6 +1673,10 @@ ibuf_build_entry_from_ibuf_rec( ulint comp; dict_index_t* index; + ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); + data = rec_get_nth_field_old(ibuf_rec, 1, &len); if (len > 1) { @@ -1649,7 +1697,7 @@ ibuf_build_entry_from_ibuf_rec( types = rec_get_nth_field_old(ibuf_rec, 3, &len); - ibuf_rec_get_info(ibuf_rec, NULL, &comp, &info_len, NULL); + ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL); index = ibuf_dummy_index_create(n_fields, comp); @@ -1736,6 +1784,12 @@ ibuf_rec_get_size( return(size); } +#ifdef UNIV_DEBUG +# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(mtr,rec) +#else /* UNIV_DEBUG */ +# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(rec) +#endif + /********************************************************************//** Returns the space taken by a stored non-clustered index entry if converted to an index record. @@ -1743,8 +1797,11 @@ an index record. taken in the page directory */ static ulint -ibuf_rec_get_volume( -/*================*/ +ibuf_rec_get_volume_func( +/*=====================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* ibuf_rec)/*!< in: ibuf record */ { ulint len; @@ -1755,7 +1812,9 @@ ibuf_rec_get_volume( ibool pre_4_1; ulint comp; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(ibuf_rec) > 2); data = rec_get_nth_field_old(ibuf_rec, 1, &len); @@ -1783,7 +1842,7 @@ ibuf_rec_get_volume( types = rec_get_nth_field_old(ibuf_rec, 3, &len); - ibuf_rec_get_info(ibuf_rec, &op, &comp, &info_len, NULL); + ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL); if (op == IBUF_OP_DELETE_MARK || op == IBUF_OP_DELETE) { /* Delete-marking a record doesn't take any @@ -1800,7 +1859,7 @@ ibuf_rec_get_volume( mem_heap_t* heap = mem_heap_create(500); entry = ibuf_build_entry_from_ibuf_rec( - ibuf_rec, heap, &dummy_index); + mtr, ibuf_rec, heap, &dummy_index); volume = rec_get_converted_size(dummy_index, entry, 0); @@ -2158,21 +2217,15 @@ ibuf_add_free_page(void) mtr_commit(&mtr); return(FALSE); - } - - { - buf_block_t* block; - - block = buf_page_get( + } else { + buf_block_t* block = buf_page_get( IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); - page = buf_block_get_frame(block); } - ibuf_enter(); + ibuf_enter(&mtr); mutex_enter(&ibuf_mutex); @@ -2200,9 +2253,7 @@ ibuf_add_free_page(void) ibuf_bitmap_page_set_bits( bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr); - mtr_commit(&mtr); - - ibuf_exit(); + ibuf_mtr_commit(&mtr); return(TRUE); } @@ -2234,7 +2285,7 @@ ibuf_remove_free_page(void) header_page = ibuf_header_page_get(&mtr); /* Prevent pessimistic inserts to insert buffer trees for a while */ - ibuf_enter(); + ibuf_enter(&mtr); mutex_enter(&ibuf_pessimistic_insert_mutex); mutex_enter(&ibuf_mutex); @@ -2243,14 +2294,12 @@ ibuf_remove_free_page(void) mutex_exit(&ibuf_mutex); mutex_exit(&ibuf_pessimistic_insert_mutex); - ibuf_exit(); - - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); return; } - mtr_start(&mtr2); + ibuf_mtr_start(&mtr2); root = ibuf_tree_root_get(&mtr2); @@ -2263,9 +2312,8 @@ ibuf_remove_free_page(void) because in fseg_free_page we access level 1 pages, and the root is a level 2 page. */ - mtr_commit(&mtr2); - - ibuf_exit(); + ibuf_mtr_commit(&mtr2); + ibuf_exit(&mtr); /* Since pessimistic inserts were prevented, we know that the page is still in the free list. NOTE that also deletes may take @@ -2280,7 +2328,7 @@ ibuf_remove_free_page(void) buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no); #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ - ibuf_enter(); + ibuf_enter(&mtr); mutex_enter(&ibuf_mutex); @@ -2325,9 +2373,7 @@ ibuf_remove_free_page(void) #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no); #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ - mtr_commit(&mtr); - - ibuf_exit(); + ibuf_mtr_commit(&mtr); } /***********************************************************************//** @@ -2349,8 +2395,6 @@ ibuf_free_excess_pages(void) ut_ad(rw_lock_get_x_lock_count( fil_space_get_latch(IBUF_SPACE_ID, NULL)) == 1); - ut_ad(!ibuf_inside()); - /* NOTE: We require that the thread did not own the latch before, because then we know that we can obey the correct latching order for ibuf latches */ @@ -2381,20 +2425,30 @@ ibuf_free_excess_pages(void) } } +#ifdef UNIV_DEBUG +# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \ + ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,vers,pages,n_stored) +#else /* UNIV_DEBUG */ +# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \ + ibuf_get_merge_page_nos_func(contract,rec,ids,vers,pages,n_stored) +#endif /* UNIV_DEBUG */ + /*********************************************************************//** Reads page numbers from a leaf in an ibuf tree. @return a lower limit for the combined volume of records which will be merged */ static ulint -ibuf_get_merge_page_nos( -/*====================*/ +ibuf_get_merge_page_nos_func( +/*=========================*/ ibool contract,/*!< in: TRUE if this function is called to contract the tree, FALSE if this is called when a single page becomes full and we look if it pays to read also nearby pages */ - rec_t* rec, /*!< in: record from which we read up and down - in the chain of records */ + const rec_t* rec, /*!< in: insert buffer record */ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction holding rec */ +#endif /* UNIV_DEBUG */ ulint* space_ids,/*!< in/out: space id's of the pages */ ib_int64_t* space_versions,/*!< in/out: tablespace version timestamps; used to prevent reading in old @@ -2417,18 +2471,22 @@ ibuf_get_merge_page_nos( ulint limit; ulint n_pages; + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); + *n_stored = 0; limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool_get_curr_size() / 4); if (page_rec_is_supremum(rec)) { - rec = page_rec_get_prev(rec); + rec = page_rec_get_prev_const(rec); } if (page_rec_is_infimum(rec)) { - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } if (page_rec_is_supremum(rec)) { @@ -2436,8 +2494,8 @@ ibuf_get_merge_page_nos( return(0); } - first_page_no = ibuf_rec_get_page_no(rec); - first_space_id = ibuf_rec_get_space(rec); + first_page_no = ibuf_rec_get_page_no(mtr, rec); + first_space_id = ibuf_rec_get_space(mtr, rec); n_pages = 0; prev_page_no = 0; prev_space_id = 0; @@ -2448,8 +2506,8 @@ ibuf_get_merge_page_nos( while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) { - rec_page_no = ibuf_rec_get_page_no(rec); - rec_space_id = ibuf_rec_get_space(rec); + rec_page_no = ibuf_rec_get_page_no(mtr, rec); + rec_space_id = ibuf_rec_get_space(mtr, rec); if (rec_space_id != first_space_id || (rec_page_no / IBUF_MERGE_AREA) @@ -2466,10 +2524,10 @@ ibuf_get_merge_page_nos( prev_page_no = rec_page_no; prev_space_id = rec_space_id; - rec = page_rec_get_prev(rec); + rec = page_rec_get_prev_const(rec); } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); /* At the loop start there is no prev page; we mark this with a pair of space id, page no (0, 0) for which there can never be entries in @@ -2487,8 +2545,8 @@ ibuf_get_merge_page_nos( rec_page_no = 1; rec_space_id = 0; } else { - rec_page_no = ibuf_rec_get_page_no(rec); - rec_space_id = ibuf_rec_get_space(rec); + rec_page_no = ibuf_rec_get_page_no(mtr, rec); + rec_space_id = ibuf_rec_get_space(mtr, rec); ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO); } @@ -2499,9 +2557,9 @@ ibuf_get_merge_page_nos( || rec_page_no != prev_page_no) && (prev_space_id != 0 || prev_page_no != 0)) { - if ((prev_page_no == first_page_no - && prev_space_id == first_space_id) - || contract + if (contract + || (prev_page_no == first_page_no + && prev_space_id == first_space_id) || (volume_for_page > ((IBUF_MERGE_THRESHOLD - 1) * 4 * UNIV_PAGE_SIZE @@ -2534,14 +2592,14 @@ ibuf_get_merge_page_nos( break; } - rec_volume = ibuf_rec_get_volume(rec); + rec_volume = ibuf_rec_get_volume(mtr, rec); volume_for_page += rec_volume; prev_page_no = rec_page_no; prev_space_id = rec_space_id; - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } #ifdef UNIV_IBUF_DEBUG @@ -2576,7 +2634,6 @@ ibuf_contract_ext( mtr_t mtr; *n_pages = 0; - ut_ad(!ibuf_inside()); /* We perform a dirty read of ibuf->empty, without latching the insert buffer root page. We trust this dirty read except @@ -2588,9 +2645,7 @@ ibuf_contract_ext( return(0); } - mtr_start(&mtr); - - ibuf_enter(); + ibuf_mtr_start(&mtr); /* Open a cursor to a randomly chosen leaf of the tree, at a random position within the leaf */ @@ -2609,24 +2664,21 @@ ibuf_contract_ext( ut_ad(page_get_page_no(btr_pcur_get_page(&pcur)) == FSP_IBUF_TREE_ROOT_PAGE_NO); - ibuf_exit(); - - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); return(0); } - sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur), + sum_sizes = ibuf_get_merge_page_nos(TRUE, + btr_pcur_get_rec(&pcur), &mtr, space_ids, space_versions, page_nos, n_pages); #if 0 /* defined UNIV_IBUF_DEBUG */ fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n", sync, *n_pages, sum_sizes); #endif - ibuf_exit(); - - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos, @@ -2766,6 +2818,13 @@ ibuf_get_volume_buffered_hash( return(TRUE); } +#ifdef UNIV_DEBUG +# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \ + ibuf_get_volume_buffered_count_func(mtr,rec,hash,size,n_recs) +#else /* UNIV_DEBUG */ +# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \ + ibuf_get_volume_buffered_count_func(rec,hash,size,n_recs) +#endif /*********************************************************************//** Update the estimate of the number of records on a page, and get the space taken by merging the buffered record to the index page. @@ -2773,8 +2832,11 @@ get the space taken by merging the buffered record to the index page. taken in the page directory */ static ulint -ibuf_get_volume_buffered_count( -/*===========================*/ +ibuf_get_volume_buffered_count_func( +/*================================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction owning rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec, /*!< in: insert buffer record */ ulint* hash, /*!< in/out: hash array */ ulint size, /*!< in: number of elements in hash array */ @@ -2784,9 +2846,13 @@ ibuf_get_volume_buffered_count( ulint len; ibuf_op_t ibuf_op; const byte* types; - ulint n_fields = rec_get_n_fields_old(rec); + ulint n_fields; - ut_ad(ibuf_inside()); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); + ut_ad(ibuf_inside(mtr)); + + n_fields = rec_get_n_fields_old(rec); ut_ad(n_fields > 4); n_fields -= 4; @@ -2871,7 +2937,7 @@ get_volume_comp: mem_heap_t* heap = mem_heap_create(500); entry = ibuf_build_entry_from_ibuf_rec( - rec, heap, &dummy_index); + mtr, rec, heap, &dummy_index); volume = rec_get_converted_size(dummy_index, entry, 0); @@ -2892,7 +2958,7 @@ static ulint ibuf_get_volume_buffered( /*=====================*/ - btr_pcur_t* pcur, /*!< in: pcur positioned at a place in an + const btr_pcur_t*pcur, /*!< in: pcur positioned at a place in an insert buffer tree where we would insert an entry for the index page whose number is page_no, latch mode has to be BTR_MODIFY_PREV @@ -2902,16 +2968,17 @@ ibuf_get_volume_buffered( lint* n_recs, /*!< in/out: minimum number of records on the page after the buffered changes have been applied, or NULL to disable the counting */ - mtr_t* mtr) /*!< in: mtr */ + mtr_t* mtr) /*!< in: mini-transaction of pcur */ { - ulint volume; - rec_t* rec; - page_t* page; - ulint prev_page_no; - page_t* prev_page; - ulint next_page_no; - page_t* next_page; - ulint hash_bitmap[128 / sizeof(ulint)]; /* bitmap of buffered recs */ + ulint volume; + const rec_t* rec; + const page_t* page; + ulint prev_page_no; + const page_t* prev_page; + ulint next_page_no; + const page_t* next_page; + /* bitmap of buffered recs */ + ulint hash_bitmap[128 / sizeof(ulint)]; ut_a(trx_sys_multiple_tablespace_format); @@ -2932,26 +2999,22 @@ ibuf_get_volume_buffered( ut_ad(page_validate(page, ibuf->index)); if (page_rec_is_supremum(rec)) { - rec = page_rec_get_prev(rec); + rec = page_rec_get_prev_const(rec); } - for (;;) { - if (page_rec_is_infimum(rec)) { + for (; !page_rec_is_infimum(rec); + rec = page_rec_get_prev_const(rec)) { + ut_ad(page_align(rec) == page); - break; - } - - if (page_no != ibuf_rec_get_page_no(rec) - || space != ibuf_rec_get_space(rec)) { + if (page_no != ibuf_rec_get_page_no(mtr, rec) + || space != ibuf_rec_get_space(mtr, rec)) { goto count_later; } volume += ibuf_get_volume_buffered_count( - rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); - - rec = page_rec_get_prev(rec); - ut_ad(page_align(rec) == page); + mtr, rec, + hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); } /* Look at the previous page */ @@ -2967,7 +3030,8 @@ ibuf_get_volume_buffered( buf_block_t* block; block = buf_page_get( - IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr); + IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, + mtr); buf_block_dbg_add_level(block, SYNC_TREE_NODE); @@ -2977,14 +3041,15 @@ ibuf_get_volume_buffered( } #ifdef UNIV_BTR_DEBUG - ut_a(btr_page_get_next(prev_page, mtr) - == page_get_page_no(page)); + ut_a(btr_page_get_next(prev_page, mtr) == page_get_page_no(page)); #endif /* UNIV_BTR_DEBUG */ rec = page_get_supremum_rec(prev_page); - rec = page_rec_get_prev(rec); + rec = page_rec_get_prev_const(rec); + + for (;; rec = page_rec_get_prev_const(rec)) { + ut_ad(page_align(rec) == prev_page); - for (;;) { if (page_rec_is_infimum(rec)) { /* We cannot go to yet a previous page, because we @@ -2994,42 +3059,35 @@ ibuf_get_volume_buffered( return(UNIV_PAGE_SIZE); } - if (page_no != ibuf_rec_get_page_no(rec) - || space != ibuf_rec_get_space(rec)) { + if (page_no != ibuf_rec_get_page_no(mtr, rec) + || space != ibuf_rec_get_space(mtr, rec)) { goto count_later; } volume += ibuf_get_volume_buffered_count( - rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); - - rec = page_rec_get_prev(rec); - ut_ad(page_align(rec) == prev_page); + mtr, rec, + hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); } count_later: rec = btr_pcur_get_rec(pcur); if (!page_rec_is_supremum(rec)) { - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } - for (;;) { - if (page_rec_is_supremum(rec)) { - - break; - } - - if (page_no != ibuf_rec_get_page_no(rec) - || space != ibuf_rec_get_space(rec)) { + for (; !page_rec_is_supremum(rec); + rec = page_rec_get_next_const(rec)) { + if (page_no != ibuf_rec_get_page_no(mtr, rec) + || space != ibuf_rec_get_space(mtr, rec)) { return(volume); } volume += ibuf_get_volume_buffered_count( - rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); - - rec = page_rec_get_next(rec); + mtr, rec, + hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); } /* Look at the next page */ @@ -3045,7 +3103,8 @@ count_later: buf_block_t* block; block = buf_page_get( - IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr); + IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, + mtr); buf_block_dbg_add_level(block, SYNC_TREE_NODE); @@ -3059,9 +3118,11 @@ count_later: #endif /* UNIV_BTR_DEBUG */ rec = page_get_infimum_rec(next_page); - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); + + for (;; rec = page_rec_get_next_const(rec)) { + ut_ad(page_align(rec) == next_page); - for (;;) { if (page_rec_is_supremum(rec)) { /* We give up */ @@ -3069,17 +3130,15 @@ count_later: return(UNIV_PAGE_SIZE); } - if (page_no != ibuf_rec_get_page_no(rec) - || space != ibuf_rec_get_space(rec)) { + if (page_no != ibuf_rec_get_page_no(mtr, rec) + || space != ibuf_rec_get_space(mtr, rec)) { return(volume); } volume += ibuf_get_volume_buffered_count( - rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); - - rec = page_rec_get_next(rec); - ut_ad(page_align(rec) == next_page); + mtr, rec, + hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs); } } @@ -3100,9 +3159,7 @@ ibuf_update_max_tablespace_id(void) ut_a(!dict_table_is_comp(ibuf->index->table)); - ibuf_enter(); - - mtr_start(&mtr); + ibuf_mtr_start(&mtr); btr_pcur_open_at_index_side( FALSE, ibuf->index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr); @@ -3125,14 +3182,20 @@ ibuf_update_max_tablespace_id(void) max_space_id = mach_read_from_4(field); } - mtr_commit(&mtr); - ibuf_exit(); + ibuf_mtr_commit(&mtr); /* printf("Maximum space id in insert buffer %lu\n", max_space_id); */ fil_set_max_space_id_if_bigger(max_space_id); } +#ifdef UNIV_DEBUG +# define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \ + ibuf_get_entry_counter_low_func(mtr,rec,space,page_no) +#else /* UNIV_DEBUG */ +# define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \ + ibuf_get_entry_counter_low_func(rec,space,page_no) +#endif /****************************************************************//** Helper function for ibuf_set_entry_counter. Checks if rec is for (space, page_no), and if so, reads counter value from it and returns that + 1. @@ -3140,8 +3203,11 @@ Otherwise, returns 0. @return new counter value, or 0 */ static ulint -ibuf_get_entry_counter_low( -/*=======================*/ +ibuf_get_entry_counter_low_func( +/*============================*/ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction of rec */ +#endif /* UNIV_DEBUG */ const rec_t* rec, /*!< in: insert buffer record */ ulint space, /*!< in: space id */ ulint page_no) /*!< in: page number */ @@ -3150,7 +3216,9 @@ ibuf_get_entry_counter_low( const byte* field; ulint len; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) + || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); ut_ad(rec_get_n_fields_old(rec) > 2); field = rec_get_nth_field_old(rec, 1, &len); @@ -3222,12 +3290,15 @@ ibuf_set_entry_counter( ulint counter = 0; /* pcur points to either a user rec or to a page's infimum record. */ + ut_ad(ibuf_inside(mtr)); + ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur), + MTR_MEMO_PAGE_X_FIX)); ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index)); if (btr_pcur_is_on_user_rec(pcur)) { counter = ibuf_get_entry_counter_low( - btr_pcur_get_rec(pcur), space, page_no); + mtr, btr_pcur_get_rec(pcur), space, page_no); if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) { /* The record lacks a counter field. @@ -3283,7 +3354,7 @@ ibuf_set_entry_counter( ut_ad(page_rec_is_user_rec(rec)); counter = ibuf_get_entry_counter_low( - rec, space, page_no); + mtr, rec, space, page_no); if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) { /* The record lacks a counter field. @@ -3435,7 +3506,6 @@ ibuf_insert_low( if (mode == BTR_MODIFY_TREE) { for (;;) { - ibuf_enter(); mutex_enter(&ibuf_pessimistic_insert_mutex); mutex_enter(&ibuf_mutex); @@ -3446,7 +3516,6 @@ ibuf_insert_low( mutex_exit(&ibuf_mutex); mutex_exit(&ibuf_pessimistic_insert_mutex); - ibuf_exit(); if (UNIV_UNLIKELY(!ibuf_add_free_page())) { @@ -3454,11 +3523,9 @@ ibuf_insert_low( return(DB_STRONG_FAIL); } } - } else { - ibuf_enter(); } - mtr_start(&mtr); + ibuf_mtr_start(&mtr); btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr); ut_ad(page_validate(btr_pcur_get_page(&pcur), ibuf->index)); @@ -3513,7 +3580,7 @@ fail_exit: #ifdef UNIV_IBUF_COUNT_DEBUG ut_a((buffered == 0) || ibuf_count_get(space, page_no)); #endif - mtr_start(&bitmap_mtr); + ibuf_mtr_start(&bitmap_mtr); bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &bitmap_mtr); @@ -3534,15 +3601,15 @@ fail_exit: if (buffered + entry_size + page_dir_calc_reserved_space(1) > ibuf_index_page_calc_free_from_bits(zip_size, bits)) { /* Release the bitmap page latch early. */ - mtr_commit(&bitmap_mtr); + ibuf_mtr_commit(&bitmap_mtr); /* It may not fit */ do_merge = TRUE; - ibuf_get_merge_page_nos( - FALSE, btr_pcur_get_rec(&pcur), - space_ids, space_versions, - page_nos, &n_stored); + ibuf_get_merge_page_nos(FALSE, + btr_pcur_get_rec(&pcur), &mtr, + space_ids, space_versions, + page_nos, &n_stored); goto fail_exit; } @@ -3555,7 +3622,7 @@ fail_exit: && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur, mode == BTR_MODIFY_PREV, &mtr)) { bitmap_fail: - mtr_commit(&bitmap_mtr); + ibuf_mtr_commit(&bitmap_mtr); goto fail_exit; } @@ -3573,7 +3640,7 @@ bitmap_fail: &bitmap_mtr); } - mtr_commit(&bitmap_mtr); + ibuf_mtr_commit(&bitmap_mtr); cursor = btr_pcur_get_btr_cur(&pcur); @@ -3638,9 +3705,8 @@ func_exit: } #endif - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); - ibuf_exit(); mem_heap_free(heap); @@ -3898,7 +3964,7 @@ ibuf_insert_to_index_page( page_t* page = buf_block_get_frame(block); rec_t* rec; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); ut_ad(!buf_block_align(page)->is_hashed); @@ -4045,7 +4111,7 @@ ibuf_set_del_mark( page_cur_t page_cur; ulint low_match; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); low_match = page_cur_search( @@ -4102,7 +4168,7 @@ ibuf_delete( page_cur_t page_cur; ulint low_match; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); low_match = page_cur_search( @@ -4190,7 +4256,7 @@ ibuf_restore_pos( /* The tablespace has been dropped. It is possible that another thread has deleted the insert buffer entry. Do not complain. */ - btr_pcur_commit_specify_mtr(pcur, mtr); + ibuf_btr_pcur_commit_specify_mtr(pcur, mtr); } else { fprintf(stderr, "InnoDB: ERROR: Submit the output to" @@ -4208,7 +4274,7 @@ ibuf_restore_pos( page_rec_get_next(btr_pcur_get_rec(pcur))); fflush(stderr); - btr_pcur_commit_specify_mtr(pcur, mtr); + ibuf_btr_pcur_commit_specify_mtr(pcur, mtr); fputs("InnoDB: Validating insert buffer tree:\n", stderr); if (!btr_validate_index(ibuf->index, NULL)) { @@ -4232,8 +4298,8 @@ ibool ibuf_delete_rec( /*============*/ ulint space, /*!< in: space id */ - ulint page_no,/*!< in: index page number where the record - should belong */ + ulint page_no,/*!< in: index page number that the record + should belong to */ btr_pcur_t* pcur, /*!< in: pcur positioned on the record to delete, having latch mode BTR_MODIFY_LEAF */ const dtuple_t* search_tuple, @@ -4244,10 +4310,10 @@ ibuf_delete_rec( page_t* root; ulint err; - ut_ad(ibuf_inside()); + ut_ad(ibuf_inside(mtr)); ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur))); - ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no); - ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space); + ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no); + ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space); success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr); @@ -4280,22 +4346,22 @@ ibuf_delete_rec( } ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur))); - ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no); - ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space); + ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no); + ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space); /* We have to resort to a pessimistic delete from ibuf */ btr_pcur_store_position(pcur, mtr); + ibuf_btr_pcur_commit_specify_mtr(pcur, mtr); - btr_pcur_commit_specify_mtr(pcur, mtr); - + ibuf_mtr_start(mtr); mutex_enter(&ibuf_mutex); - mtr_start(mtr); - if (!ibuf_restore_pos(space, page_no, search_tuple, BTR_MODIFY_TREE, pcur, mtr)) { mutex_exit(&ibuf_mutex); + ut_ad(!ibuf_inside(mtr)); + ut_ad(mtr->state == MTR_COMMITTED); goto func_exit; } @@ -4312,9 +4378,11 @@ ibuf_delete_rec( mutex_exit(&ibuf_mutex); ibuf->empty = (page_get_n_recs(root) == 0); - btr_pcur_commit_specify_mtr(pcur, mtr); + ibuf_btr_pcur_commit_specify_mtr(pcur, mtr); func_exit: + ut_ad(!ibuf_inside(mtr)); + ut_ad(mtr->state == MTR_COMMITTED); btr_pcur_close(pcur); return(TRUE); @@ -4406,18 +4474,20 @@ ibuf_merge_or_delete_for_page( update_ibuf_bitmap = FALSE; } else { page_t* bitmap_page; + ulint bitmap_bits; - mtr_start(&mtr); + ibuf_mtr_start(&mtr); bitmap_page = ibuf_bitmap_get_map_page( space, page_no, zip_size, &mtr); + bitmap_bits = ibuf_bitmap_page_get_bits( + bitmap_page, page_no, zip_size, + IBUF_BITMAP_BUFFERED, &mtr); - if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no, - zip_size, - IBUF_BITMAP_BUFFERED, - &mtr)) { + ibuf_mtr_commit(&mtr); + + if (!bitmap_bits) { /* No inserts buffered for this page */ - mtr_commit(&mtr); if (!tablespace_being_deleted) { fil_decr_pending_ibuf_merges(space); @@ -4425,7 +4495,6 @@ ibuf_merge_or_delete_for_page( return; } - mtr_commit(&mtr); } } else if (block && (ibuf_fixed_addr_page(space, zip_size, page_no) @@ -4434,11 +4503,9 @@ ibuf_merge_or_delete_for_page( return; } - ibuf_enter(); - heap = mem_heap_create(512); - if (!trx_sys_multiple_tablespace_format) { + if (UNIV_UNLIKELY(!trx_sys_multiple_tablespace_format)) { ut_a(trx_doublewrite_must_reset_space_ids); search_tuple = ibuf_search_tuple_build(space, page_no, heap); } else { @@ -4465,7 +4532,7 @@ ibuf_merge_or_delete_for_page( ut_print_timestamp(stderr); - mtr_start(&mtr); + ibuf_mtr_start(&mtr); fputs(" InnoDB: Dump of the ibuf bitmap page:\n", stderr); @@ -4473,8 +4540,7 @@ ibuf_merge_or_delete_for_page( bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr); buf_page_print(bitmap_page, 0); - - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); fputs("\nInnoDB: Dump of the page:\n", stderr); @@ -4505,7 +4571,7 @@ ibuf_merge_or_delete_for_page( memset(dops, 0, sizeof(dops)); loop: - mtr_start(&mtr); + ibuf_mtr_start(&mtr); if (block) { ibool success; @@ -4539,8 +4605,8 @@ loop: rec = btr_pcur_get_rec(&pcur); /* Check if the entry is for this index page */ - if (ibuf_rec_get_page_no(rec) != page_no - || ibuf_rec_get_space(rec) != space) { + if (ibuf_rec_get_page_no(&mtr, rec) != page_no + || ibuf_rec_get_space(&mtr, rec) != space) { if (block) { page_header_reset_last_insert( @@ -4563,7 +4629,7 @@ loop: dtuple_t* entry; trx_id_t max_trx_id; dict_index_t* dummy_index; - ibuf_op_t op = ibuf_rec_get_op_type(rec); + ibuf_op_t op = ibuf_rec_get_op_type(&mtr, rec); max_trx_id = page_get_max_trx_id(page_align(rec)); page_update_max_trx_id(block, page_zip, max_trx_id, @@ -4572,7 +4638,7 @@ loop: ut_ad(page_validate(page_align(rec), ibuf->index)); entry = ibuf_build_entry_from_ibuf_rec( - rec, heap, &dummy_index); + &mtr, rec, heap, &dummy_index); ut_ad(page_validate(block->frame, dummy_index)); @@ -4605,13 +4671,14 @@ loop: Store and restore the cursor position. */ ut_ad(rec == btr_pcur_get_rec(&pcur)); ut_ad(page_rec_is_user_rec(rec)); - ut_ad(ibuf_rec_get_page_no(rec) == page_no); - ut_ad(ibuf_rec_get_space(rec) == space); + ut_ad(ibuf_rec_get_page_no(&mtr, rec) + == page_no); + ut_ad(ibuf_rec_get_space(&mtr, rec) == space); btr_pcur_store_position(&pcur, &mtr); - btr_pcur_commit_specify_mtr(&pcur, &mtr); + ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr); - mtr_start(&mtr); + ibuf_mtr_start(&mtr); success = buf_page_get_known_nowait( RW_X_LATCH, block, @@ -4626,7 +4693,8 @@ loop: BTR_MODIFY_LEAF, &pcur, &mtr)) { - mtr_commit(&mtr); + ut_ad(!ibuf_inside(&mtr)); + ut_ad(mtr.state == MTR_COMMITTED); mops[op]++; ibuf_dummy_index_free(dummy_index); goto loop; @@ -4641,7 +4709,7 @@ loop: ibuf_dummy_index_free(dummy_index); } else { - dops[ibuf_rec_get_op_type(rec)]++; + dops[ibuf_rec_get_op_type(&mtr, rec)]++; } /* Delete the record from ibuf */ @@ -4652,7 +4720,7 @@ loop: goto loop; } else if (btr_pcur_is_after_last_on_page(&pcur)) { - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); goto loop; @@ -4686,7 +4754,7 @@ reset_bit: } } - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); mem_heap_free(heap); @@ -4710,8 +4778,6 @@ reset_bit: fil_decr_pending_ibuf_merges(space); } - ibuf_exit(); - #ifdef UNIV_IBUF_COUNT_DEBUG ut_a(ibuf_count_get(space, page_no) == 0); #endif @@ -4731,9 +4797,8 @@ ibuf_delete_for_discarded_space( mem_heap_t* heap; btr_pcur_t pcur; dtuple_t* search_tuple; - rec_t* ibuf_rec; + const rec_t* ibuf_rec; ulint page_no; - ibool closed; mtr_t mtr; /* Counts for discarded operations. */ @@ -4748,9 +4813,7 @@ ibuf_delete_for_discarded_space( memset(dops, 0, sizeof(dops)); loop: - ibuf_enter(); - - mtr_start(&mtr); + ibuf_mtr_start(&mtr); /* Position pcur in the insert buffer at the first entry for the space */ @@ -4770,39 +4833,34 @@ loop: ibuf_rec = btr_pcur_get_rec(&pcur); /* Check if the entry is for this space */ - if (ibuf_rec_get_space(ibuf_rec) != space) { + if (ibuf_rec_get_space(&mtr, ibuf_rec) != space) { goto leave_loop; } - page_no = ibuf_rec_get_page_no(ibuf_rec); + page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec); - dops[ibuf_rec_get_op_type(ibuf_rec)]++; + dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++; /* Delete the record from ibuf */ - closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple, - &mtr); - if (closed) { + if (ibuf_delete_rec(space, page_no, &pcur, search_tuple, + &mtr)) { /* Deletion was pessimistic and mtr was committed: we start from the beginning again */ - ibuf_exit(); - goto loop; } if (btr_pcur_is_after_last_on_page(&pcur)) { - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); - ibuf_exit(); - goto loop; } } leave_loop: - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); #ifdef HAVE_ATOMIC_BUILTINS @@ -4814,8 +4872,6 @@ leave_loop: mutex_exit(&ibuf_mutex); #endif /* HAVE_ATOMIC_BUILTINS */ - ibuf_exit(); - mem_heap_free(heap); } @@ -4831,18 +4887,15 @@ ibuf_is_empty(void) const page_t* root; mtr_t mtr; - ibuf_enter(); - mtr_start(&mtr); + ibuf_mtr_start(&mtr); mutex_enter(&ibuf_mutex); root = ibuf_tree_root_get(&mtr); mutex_exit(&ibuf_mutex); is_empty = (page_get_n_recs(root) == 0); - mtr_commit(&mtr); - ibuf_exit(); - ut_a(is_empty == ibuf->empty); + ibuf_mtr_commit(&mtr); return(is_empty); } diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index 4a52f9dcd8d..cdf6cdba3d1 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -70,10 +70,10 @@ UNIV_INTERN ulint buf_read_ahead_linear( /*==================*/ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ - ulint offset);/*!< in: page number of a page; NOTE: the current thread - must want access to this page (see NOTE 3 above) */ + ulint space, /*!< in: space id */ + ulint zip_size, /*!< in: compressed page size in bytes, or 0 */ + ulint offset, /*!< in: page number; see NOTE 3 above */ + ibool inside_ibuf); /*!< in: TRUE if we are inside ibuf routine */ /********************************************************************//** Issues read requests for pages which the ibuf module wants to read in, in order to contract the insert buffer tree. Technically, this function is like diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 330efae780c..28c97fd609f 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -104,6 +104,22 @@ UNIV_INTERN void ibuf_update_max_tablespace_id(void); /*===============================*/ +/***************************************************************//** +Starts an insert buffer mini-transaction. */ +UNIV_INLINE +void +ibuf_mtr_start( +/*===========*/ + mtr_t* mtr) /*!< out: mini-transaction */ + __attribute__((nonnull)); +/***************************************************************//** +Commits an insert buffer mini-transaction. */ +UNIV_INLINE +void +ibuf_mtr_commit( +/*============*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ + __attribute__((nonnull)); /*********************************************************************//** Initializes an ibuf bitmap page. */ UNIV_INTERN @@ -224,10 +240,12 @@ routine. For instance, a read-ahead of non-ibuf pages is forbidden by threads that are executing an insert buffer routine. @return TRUE if inside an insert buffer routine */ -UNIV_INTERN +UNIV_INLINE ibool -ibuf_inside(void); -/*=============*/ +ibuf_inside( +/*========*/ + const mtr_t* mtr) /*!< in: mini-transaction */ + __attribute__((nonnull, pure)); /***********************************************************************//** Checks if a page address is an ibuf bitmap page (level 3 page) address. @return TRUE if a bitmap page */ diff --git a/storage/innobase/include/ibuf0ibuf.ic b/storage/innobase/include/ibuf0ibuf.ic index e3fa6e3e929..0a22667a260 100644 --- a/storage/innobase/include/ibuf0ibuf.ic +++ b/storage/innobase/include/ibuf0ibuf.ic @@ -37,6 +37,30 @@ buffer inserts to this page. If there is this much of free space, the corresponding bits are set in the ibuf bitmap. */ #define IBUF_PAGE_SIZE_PER_FREE_SPACE 32 +/***************************************************************//** +Starts an insert buffer mini-transaction. */ +UNIV_INLINE +void +ibuf_mtr_start( +/*===========*/ + mtr_t* mtr) /*!< out: mini-transaction */ +{ + mtr_start(mtr); + mtr->inside_ibuf = TRUE; +} +/***************************************************************//** +Commits an insert buffer mini-transaction. */ +UNIV_INLINE +void +ibuf_mtr_commit( +/*============*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ +{ + ut_ad(mtr->inside_ibuf); + ut_d(mtr->inside_ibuf = FALSE); + mtr_commit(mtr); +} + /** Insert buffer struct */ struct ibuf_struct{ ulint size; /*!< current size of the ibuf index @@ -120,6 +144,22 @@ ibuf_should_try( return(FALSE); } +/******************************************************************//** +Returns TRUE if the current OS thread is performing an insert buffer +routine. + +For instance, a read-ahead of non-ibuf pages is forbidden by threads +that are executing an insert buffer routine. +@return TRUE if inside an insert buffer routine */ +UNIV_INLINE +ibool +ibuf_inside( +/*========*/ + const mtr_t* mtr) /*!< in: mini-transaction */ +{ + return(mtr->inside_ibuf); +} + /***********************************************************************//** Checks if a page address is an ibuf bitmap page address. @return TRUE if a bitmap page */ diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 8abca093548..5582ad63039 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -190,21 +190,21 @@ functions). The page number parameter was originally written as 0. @{ */ /* @} */ /***************************************************************//** -Starts a mini-transaction and creates a mini-transaction handle -and buffer in the memory buffer given by the caller. -@return mtr buffer which also acts as the mtr handle */ +Starts a mini-transaction. */ UNIV_INLINE -mtr_t* +void mtr_start( /*======*/ - mtr_t* mtr); /*!< in: memory buffer for the mtr buffer */ + mtr_t* mtr) /*!< out: mini-transaction */ + __attribute__((nonnull)); /***************************************************************//** Commits a mini-transaction. */ UNIV_INTERN void mtr_commit( /*=======*/ - mtr_t* mtr); /*!< in: mini-transaction */ + mtr_t* mtr) /*!< in/out: mini-transaction */ + __attribute__((nonnull)); /**********************************************************//** Sets and returns a savepoint in mtr. @return savepoint */ @@ -378,6 +378,8 @@ struct mtr_struct{ #endif dyn_array_t memo; /*!< memo stack for locks etc. */ dyn_array_t log; /*!< mini-transaction log */ + ibool inside_ibuf; + /*!< TRUE if inside ibuf changes */ ibool modifications; /* TRUE if the mtr made modifications to buffer pool pages */ diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index 55f3cf7f147..3d87eea2710 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -30,26 +30,23 @@ Created 11/26/1995 Heikki Tuuri #include "mach0data.h" /***************************************************************//** -Starts a mini-transaction and creates a mini-transaction handle -and a buffer in the memory buffer given by the caller. -@return mtr buffer which also acts as the mtr handle */ +Starts a mini-transaction. */ UNIV_INLINE -mtr_t* +void mtr_start( /*======*/ - mtr_t* mtr) /*!< in: memory buffer for the mtr buffer */ + mtr_t* mtr) /*!< out: mini-transaction */ { dyn_array_create(&(mtr->memo)); dyn_array_create(&(mtr->log)); mtr->log_mode = MTR_LOG_ALL; mtr->modifications = FALSE; + mtr->inside_ibuf = FALSE; mtr->n_log_recs = 0; ut_d(mtr->state = MTR_ACTIVE); ut_d(mtr->magic_n = MTR_MAGIC_N); - - return(mtr); } /***************************************************//** diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index b4f9e21933f..a24c2106033 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -110,7 +110,6 @@ extern mysql_pfs_key_t syn_arr_mutex_key; extern mysql_pfs_key_t sync_thread_mutex_key; # endif /* UNIV_SYNC_DEBUG */ extern mysql_pfs_key_t trx_doublewrite_mutex_key; -extern mysql_pfs_key_t thr_local_mutex_key; extern mysql_pfs_key_t trx_undo_mutex_key; #endif /* UNIV_PFS_MUTEX */ diff --git a/storage/innobase/include/thr0loc.h b/storage/innobase/include/thr0loc.h deleted file mode 100644 index bc54f9693b3..00000000000 --- a/storage/innobase/include/thr0loc.h +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. - -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 -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/thr0loc.h -The thread local storage - -Created 10/5/1995 Heikki Tuuri -*******************************************************/ - -/* This module implements storage private to each thread, -a capability useful in some situations like storing the -OS handle to the current thread, or its priority. */ - -#ifndef thr0loc_h -#define thr0loc_h - -#include "univ.i" -#include "os0thread.h" - -/****************************************************************//** -Initializes the thread local storage module. */ -UNIV_INTERN -void -thr_local_init(void); -/*================*/ - /****************************************************************//** -Close the thread local storage module. */ -UNIV_INTERN -void -thr_local_close(void); -/*=================*/ -/*******************************************************************//** -Creates a local storage struct for the calling new thread. */ -UNIV_INTERN -void -thr_local_create(void); -/*==================*/ -/*******************************************************************//** -Frees the local storage struct for the specified thread. */ -UNIV_INTERN -void -thr_local_free( -/*===========*/ - os_thread_id_t id); /*!< in: thread id */ -/*******************************************************************//** -Returns pointer to the 'in_ibuf' field within the current thread local -storage. -@return pointer to the in_ibuf field */ -UNIV_INTERN -ibool* -thr_local_get_in_ibuf_field(void); -/*=============================*/ - -#ifndef UNIV_NONINL -#include "thr0loc.ic" -#endif - -#endif diff --git a/storage/innobase/include/thr0loc.ic b/storage/innobase/include/thr0loc.ic deleted file mode 100644 index ce44e512320..00000000000 --- a/storage/innobase/include/thr0loc.ic +++ /dev/null @@ -1,24 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. - -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 -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/thr0loc.ic -Thread local storage - -Created 10/4/1995 Heikki Tuuri -*******************************************************/ diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c index 74d04a22b86..88e698ed818 100644 --- a/storage/innobase/mtr/mtr0mtr.c +++ b/storage/innobase/mtr/mtr0mtr.c @@ -251,6 +251,7 @@ mtr_commit( ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->state == MTR_ACTIVE); + ut_ad(!mtr->inside_ibuf); ut_d(mtr->state = MTR_COMMITTING); #ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 59a2bc90052..99af0b23a04 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -66,7 +66,6 @@ Created 10/8/1995 Heikki Tuuri #include "mem0mem.h" #include "mem0pool.h" #include "sync0sync.h" -#include "thr0loc.h" #include "que0que.h" #include "log0recv.h" #include "pars0pars.h" @@ -1129,7 +1128,6 @@ srv_general_init(void) os_sync_init(); sync_init(); mem_init(srv_mem_pool_size); - thr_local_init(); } /*======================= InnoDB Server FIFO queue =======================*/ @@ -3071,8 +3069,6 @@ suspend_thread: main thread goes back to loop. */ goto loop; - - OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */ } /*********************************************************************//** diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 050fe460652..79eae610a05 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -85,7 +85,6 @@ Created 2/16/1996 Heikki Tuuri # include "row0row.h" # include "row0mysql.h" # include "btr0pcur.h" -# include "thr0loc.h" # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */ # include "zlib.h" /* for ZLIB_VERSION */ @@ -2210,7 +2209,6 @@ innobase_shutdown_for_mysql(void) ibuf_close(); log_shutdown(); lock_sys_close(); - thr_local_close(); trx_sys_file_format_close(); trx_sys_close(); diff --git a/storage/innobase/thr/thr0loc.c b/storage/innobase/thr/thr0loc.c deleted file mode 100644 index 0fa93922bb1..00000000000 --- a/storage/innobase/thr/thr0loc.c +++ /dev/null @@ -1,259 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. - -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 -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file thr/thr0loc.c -The thread local storage - -Created 10/5/1995 Heikki Tuuri -*******************************************************/ - -#include "thr0loc.h" -#ifdef UNIV_NONINL -#include "thr0loc.ic" -#endif - -#include "sync0sync.h" -#include "hash0hash.h" -#include "mem0mem.h" -#include "srv0srv.h" - -/* - IMPLEMENTATION OF THREAD LOCAL STORAGE - ====================================== - -The threads sometimes need private data which depends on the thread id. -This is implemented as a hash table, where the hash value is calculated -from the thread id, to prepare for a large number of threads. The hash table -is protected by a mutex. If you need modify the program and put new data to -the thread local storage, just add it to struct thr_local_struct in the -header file. */ - -/** Mutex protecting thr_local_hash */ -static mutex_t thr_local_mutex; - -/** The hash table. The module is not yet initialized when it is NULL. */ -static hash_table_t* thr_local_hash = NULL; - -/** Thread local data */ -typedef struct thr_local_struct thr_local_t; - -#ifdef UNIV_PFS_MUTEX -/* Key to register the mutex with performance schema */ -UNIV_INTERN mysql_pfs_key_t thr_local_mutex_key; -#endif /* UNIV_PFS_MUTEX */ - -/** @brief Thread local data. -The private data for each thread should be put to -the structure below and the accessor functions written -for the field. */ -struct thr_local_struct{ - os_thread_id_t id; /*!< id of the thread which owns this struct */ - os_thread_t handle; /*!< operating system handle to the thread */ - ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf - operation */ - hash_node_t hash; /*!< hash chain node */ - ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */ -}; - -/** The value of thr_local_struct::magic_n */ -#define THR_LOCAL_MAGIC_N 1231234 - -#ifdef UNIV_DEBUG -/*******************************************************************//** -Validates thread local data. -@return TRUE if valid */ -static -ibool -thr_local_validate( -/*===============*/ - const thr_local_t* local) /*!< in: data to validate */ -{ - ut_ad(local->magic_n == THR_LOCAL_MAGIC_N); - ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE); - return(TRUE); -} -#endif /* UNIV_DEBUG */ - -/*******************************************************************//** -Returns the local storage struct for a thread. -@return local storage */ -static -thr_local_t* -thr_local_get( -/*==========*/ - os_thread_id_t id) /*!< in: thread id of the thread */ -{ - thr_local_t* local; - -try_again: - ut_ad(thr_local_hash); - ut_ad(mutex_own(&thr_local_mutex)); - - /* Look for the local struct in the hash table */ - - local = NULL; - - HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id), - thr_local_t*, local, ut_ad(thr_local_validate(local)), - os_thread_eq(local->id, id)); - if (local == NULL) { - mutex_exit(&thr_local_mutex); - - thr_local_create(); - - mutex_enter(&thr_local_mutex); - - goto try_again; - } - - ut_ad(thr_local_validate(local)); - - return(local); -} - -/*******************************************************************//** -Returns pointer to the 'in_ibuf' field within the current thread local -storage. -@return pointer to the in_ibuf field */ -UNIV_INTERN -ibool* -thr_local_get_in_ibuf_field(void) -/*=============================*/ -{ - thr_local_t* local; - - mutex_enter(&thr_local_mutex); - - local = thr_local_get(os_thread_get_curr_id()); - - mutex_exit(&thr_local_mutex); - - return(&(local->in_ibuf)); -} - -/*******************************************************************//** -Creates a local storage struct for the calling new thread. */ -UNIV_INTERN -void -thr_local_create(void) -/*==================*/ -{ - thr_local_t* local; - - if (thr_local_hash == NULL) { - thr_local_init(); - } - - local = mem_alloc(sizeof(thr_local_t)); - - local->id = os_thread_get_curr_id(); - local->handle = os_thread_get_curr(); - local->magic_n = THR_LOCAL_MAGIC_N; - local->in_ibuf = FALSE; - - mutex_enter(&thr_local_mutex); - - HASH_INSERT(thr_local_t, hash, thr_local_hash, - os_thread_pf(os_thread_get_curr_id()), - local); - - mutex_exit(&thr_local_mutex); -} - -/*******************************************************************//** -Frees the local storage struct for the specified thread. */ -UNIV_INTERN -void -thr_local_free( -/*===========*/ - os_thread_id_t id) /*!< in: thread id */ -{ - thr_local_t* local; - - mutex_enter(&thr_local_mutex); - - /* Look for the local struct in the hash table */ - - HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id), - thr_local_t*, local, ut_ad(thr_local_validate(local)), - os_thread_eq(local->id, id)); - if (local == NULL) { - mutex_exit(&thr_local_mutex); - - return; - } - - HASH_DELETE(thr_local_t, hash, thr_local_hash, - os_thread_pf(id), local); - - mutex_exit(&thr_local_mutex); - - ut_a(local->magic_n == THR_LOCAL_MAGIC_N); - ut_ad(thr_local_validate(local)); - - mem_free(local); -} - -/****************************************************************//** -Initializes the thread local storage module. */ -UNIV_INTERN -void -thr_local_init(void) -/*================*/ -{ - - ut_a(thr_local_hash == NULL); - - thr_local_hash = hash_create(OS_THREAD_MAX_N + 100); - - mutex_create(thr_local_mutex_key, - &thr_local_mutex, SYNC_THR_LOCAL); -} - -/******************************************************************** -Close the thread local storage module. */ -UNIV_INTERN -void -thr_local_close(void) -/*=================*/ -{ - ulint i; - - ut_a(thr_local_hash != NULL); - - /* Free the hash elements. We don't remove them from the table - because we are going to destroy the table anyway. */ - for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) { - thr_local_t* local; - - local = HASH_GET_FIRST(thr_local_hash, i); - - while (local) { - thr_local_t* prev_local = local; - - local = HASH_GET_NEXT(hash, prev_local); - ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N); - ut_ad(thr_local_validate(prev_local)); - mem_free(prev_local); - } - } - - hash_table_free(thr_local_hash); - thr_local_hash = NULL; -} diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 820c40fe857..0d01bedc4fb 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri #include "usr0sess.h" #include "read0read.h" #include "srv0srv.h" -#include "thr0loc.h" #include "btr0sea.h" #include "os0proc.h" #include "trx0xa.h"