diff options
author | Mikael Ronström <mikael@dator9> | 2011-04-15 15:46:11 +0200 |
---|---|---|
committer | Mikael Ronström <mikael@dator9> | 2011-04-15 15:46:11 +0200 |
commit | 70ed67e1ccf8b1696e0c11aa6fb1e5fdb28875fb (patch) | |
tree | a3b95707a820bf6af5adbb68c73f6f51dbf5b473 /storage | |
parent | 55557e223f6c89b16cbed2fecd90c26b519b6b92 (diff) | |
parent | 060541c02e6c332db0f08fa3b861cb2de305c71f (diff) | |
download | mariadb-git-70ed67e1ccf8b1696e0c11aa6fb1e5fdb28875fb.tar.gz |
Merge 5.5
Diffstat (limited to 'storage')
55 files changed, 965 insertions, 1084 deletions
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index fec41c12b81..a56cc3dd799 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -90,7 +90,7 @@ public: return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_STATS_RECORDS_IS_EXACT | - HA_HAS_RECORDS | + HA_HAS_RECORDS | HA_CAN_REPAIR | HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY); } ulong index_flags(uint idx, uint part, bool all_parts) const diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 845b50e3869..9fcaf2519c6 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -106,7 +106,8 @@ public: ulonglong table_flags() const { return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT | - HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE); + HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | + HA_CAN_REPAIR); } ulong index_flags(uint idx, uint part, bool all_parts) const { diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index e39bac525b5..6614b389b1f 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -149,7 +149,8 @@ public: HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | HA_NO_TRANSACTIONS /* until fixed by WL#2952 */ | - HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY); + HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY | + HA_CAN_REPAIR); } /* This is a bitmap of flags that says how the storage engine 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 e182840b1a0..c4034d0896a 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -4904,27 +4904,45 @@ btr_copy_blob_prefix( /*******************************************************************//** Copies the prefix of a compressed BLOB. The clustered index record -that points to this BLOB must be protected by a lock or a page latch. */ +that points to this BLOB must be protected by a lock or a page latch. +@return number of bytes written to buf */ static -void +ulint btr_copy_zblob_prefix( /*==================*/ - z_stream* d_stream,/*!< in/out: the decompressing stream */ + byte* buf, /*!< out: the externally stored part of + the field, or a prefix of it */ + ulint len, /*!< in: length of buf, in bytes */ ulint zip_size,/*!< in: compressed BLOB page size */ ulint space_id,/*!< in: space id of the BLOB pages */ ulint page_no,/*!< in: page number of the first BLOB page */ ulint offset) /*!< in: offset on the first BLOB page */ { - ulint page_type = FIL_PAGE_TYPE_ZBLOB; + ulint page_type = FIL_PAGE_TYPE_ZBLOB; + mem_heap_t* heap; + int err; + z_stream d_stream; + + d_stream.next_out = buf; + d_stream.avail_out = len; + d_stream.next_in = Z_NULL; + d_stream.avail_in = 0; + + /* Zlib inflate needs 32 kilobytes for the default + window size, plus a few kilobytes for small objects. */ + heap = mem_heap_create(40000); + page_zip_set_alloc(&d_stream, heap); ut_ad(ut_is_2pow(zip_size)); ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE); ut_ad(zip_size <= UNIV_PAGE_SIZE); ut_ad(space_id); + err = inflateInit(&d_stream); + ut_a(err == Z_OK); + for (;;) { buf_page_t* bpage; - int err; ulint next_page_no; /* There is no latch on bpage directly. Instead, @@ -4940,7 +4958,7 @@ btr_copy_zblob_prefix( " compressed BLOB" " page %lu space %lu\n", (ulong) page_no, (ulong) space_id); - return; + goto func_exit; } if (UNIV_UNLIKELY @@ -4966,13 +4984,13 @@ btr_copy_zblob_prefix( offset += 4; } - d_stream->next_in = bpage->zip.data + offset; - d_stream->avail_in = zip_size - offset; + d_stream.next_in = bpage->zip.data + offset; + d_stream.avail_in = zip_size - offset; - err = inflate(d_stream, Z_NO_FLUSH); + err = inflate(&d_stream, Z_NO_FLUSH); switch (err) { case Z_OK: - if (!d_stream->avail_out) { + if (!d_stream.avail_out) { goto end_of_blob; } break; @@ -4989,13 +5007,13 @@ inflate_error: " compressed BLOB" " page %lu space %lu returned %d (%s)\n", (ulong) page_no, (ulong) space_id, - err, d_stream->msg); + err, d_stream.msg); case Z_BUF_ERROR: goto end_of_blob; } if (next_page_no == FIL_NULL) { - if (!d_stream->avail_in) { + if (!d_stream.avail_in) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: unexpected end of" @@ -5004,7 +5022,7 @@ inflate_error: (ulong) page_no, (ulong) space_id); } else { - err = inflate(d_stream, Z_FINISH); + err = inflate(&d_stream, Z_FINISH); switch (err) { case Z_STREAM_END: case Z_BUF_ERROR: @@ -5016,7 +5034,7 @@ inflate_error: end_of_blob: buf_page_release_zip(bpage); - return; + goto func_exit; } buf_page_release_zip(bpage); @@ -5028,6 +5046,12 @@ end_of_blob: offset = FIL_PAGE_NEXT; page_type = FIL_PAGE_TYPE_ZBLOB2; } + +func_exit: + inflateEnd(&d_stream); + mem_heap_free(heap); + UNIV_MEM_ASSERT_RW(buf, d_stream.total_out); + return(d_stream.total_out); } /*******************************************************************//** @@ -5053,28 +5077,8 @@ btr_copy_externally_stored_field_prefix_low( } if (UNIV_UNLIKELY(zip_size)) { - int err; - z_stream d_stream; - mem_heap_t* heap; - - /* Zlib inflate needs 32 kilobytes for the default - window size, plus a few kilobytes for small objects. */ - heap = mem_heap_create(40000); - page_zip_set_alloc(&d_stream, heap); - - err = inflateInit(&d_stream); - ut_a(err == Z_OK); - - d_stream.next_out = buf; - d_stream.avail_out = len; - d_stream.avail_in = 0; - - btr_copy_zblob_prefix(&d_stream, zip_size, - space_id, page_no, offset); - inflateEnd(&d_stream); - mem_heap_free(heap); - UNIV_MEM_ASSERT_RW(buf, d_stream.total_out); - return(d_stream.total_out); + return(btr_copy_zblob_prefix(buf, len, zip_size, + space_id, page_no, offset)); } else { return(btr_copy_blob_prefix(buf, len, space_id, page_no, offset)); diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index d192ee7c132..93573a300e4 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -1213,8 +1213,8 @@ btr_search_drop_page_hash_when_freed( having to fear a deadlock. */ block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL, - BUF_GET_IF_IN_POOL, __FILE__, __LINE__, - &mtr); + BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__, + &mtr); /* Because the buffer pool mutex was released by buf_page_peek_if_search_hashed(), it is possible that the block was removed from the buffer pool by another thread diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 1ddf15ef8b9..cf5b90a2539 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1233,7 +1233,7 @@ buf_pool_init_instance( buf_pool->page_hash = hash_create(2 * buf_pool->curr_size); buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size); - + buf_pool->last_printout_time = ut_time(); } /* 2. Initialize flushing fields @@ -1365,11 +1365,11 @@ buf_pool_drop_hash_index_instance( /* block->is_hashed cannot be modified when we have an x-latch on btr_search_latch; see the comment in buf0buf.h */ - + if (!block->is_hashed) { continue; } - + /* To follow the latching order, we have to release btr_search_latch before acquiring block->latch. */ @@ -1378,14 +1378,14 @@ buf_pool_drop_hash_index_instance( we must rescan all blocks, because some may become hashed again. */ *released_search_latch = TRUE; - + rw_lock_x_lock(&block->lock); - + /* This should be guaranteed by the callers, which will be holding btr_search_enabled_mutex. */ ut_ad(!btr_search_enabled); - + /* Because we did not buffer-fix the block by calling buf_block_get_gen(), it is possible that the block has been @@ -1395,7 +1395,7 @@ buf_pool_drop_hash_index_instance( block is mapped to. All we want to do is to drop any hash entries referring to the page. */ - + /* It is possible that block->page.state != BUF_FILE_PAGE. Even that does not matter, because @@ -1403,18 +1403,18 @@ buf_pool_drop_hash_index_instance( check block->is_hashed before doing anything. block->is_hashed can only be set on uncompressed file pages. */ - + btr_search_drop_page_hash_index(block); - + rw_lock_x_unlock(&block->lock); - + rw_lock_x_lock(&btr_search_latch); - + ut_ad(!btr_search_enabled); } } } - + /********************************************************************//** Drops the adaptive hash index. To prevent a livelock, this function is only to be called while holding btr_search_latch and while @@ -1990,30 +1990,30 @@ buf_pool_resize(void) ulint min_change_size = 1048576 * srv_buf_pool_instances; buf_pool_mutex_enter_all(); - + if (srv_buf_pool_old_size == srv_buf_pool_size) { - + buf_pool_mutex_exit_all(); return; } else if (srv_buf_pool_curr_size + min_change_size > srv_buf_pool_size) { - + change_size = (srv_buf_pool_curr_size - srv_buf_pool_size) / UNIV_PAGE_SIZE; buf_pool_mutex_exit_all(); - + /* Disable adaptive hash indexes and empty the index in order to free up memory in the buffer pool chunks. */ buf_pool_shrink(change_size); } else if (srv_buf_pool_curr_size + min_change_size < srv_buf_pool_size) { - + /* Enlarge the buffer pool by at least one megabyte */ - + change_size = srv_buf_pool_size - srv_buf_pool_curr_size; buf_pool_mutex_exit_all(); @@ -2026,10 +2026,10 @@ buf_pool_resize(void) return; } - + buf_pool_page_hash_rebuild(); } - + /****************************************************************//** Remove the sentinel block for the watch before replacing it with a real block. buf_page_watch_clear() or buf_page_watch_occurred() will notice that @@ -2530,16 +2530,19 @@ buf_block_align_instance( /* TODO: protect buf_pool->chunks with a mutex (it will currently remain constant after buf_pool_init()) */ for (chunk = buf_pool->chunks, i = buf_pool->n_chunks; i--; chunk++) { - lint offs = ptr - chunk->blocks->frame; + ulint offs; - if (UNIV_UNLIKELY(offs < 0)) { + if (UNIV_UNLIKELY(ptr < chunk->blocks->frame)) { continue; } + /* else */ + + offs = ptr - chunk->blocks->frame; offs >>= UNIV_PAGE_SIZE_SHIFT; - if (UNIV_LIKELY((ulint) offs < chunk->size)) { + if (UNIV_LIKELY(offs < chunk->size)) { buf_block_t* block = &chunk->blocks[offs]; /* The function buf_chunk_init() invokes @@ -2716,7 +2719,7 @@ buf_page_get_gen( ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ buf_block_t* guess, /*!< in: guessed block or NULL */ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL, - BUF_GET_NO_LATCH, or + BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ @@ -2735,16 +2738,26 @@ buf_page_get_gen( ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH) || (rw_latch == RW_NO_LATCH)); - ut_ad((mode != BUF_GET_NO_LATCH) || (rw_latch == RW_NO_LATCH)); - ut_ad(mode == BUF_GET - || mode == BUF_GET_IF_IN_POOL - || mode == BUF_GET_NO_LATCH - || mode == BUF_GET_IF_IN_POOL_OR_WATCH); +#ifdef UNIV_DEBUG + switch (mode) { + case BUF_GET_NO_LATCH: + ut_ad(rw_latch == RW_NO_LATCH); + break; + case BUF_GET: + case BUF_GET_IF_IN_POOL: + case BUF_PEEK_IF_IN_POOL: + case BUF_GET_IF_IN_POOL_OR_WATCH: + break; + default: + ut_error; + } +#endif /* UNIV_DEBUG */ 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(mtr) || 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); @@ -2799,6 +2812,7 @@ loop2: buf_pool_mutex_exit(buf_pool); if (mode == BUF_GET_IF_IN_POOL + || mode == BUF_PEEK_IF_IN_POOL || mode == BUF_GET_IF_IN_POOL_OR_WATCH) { return(NULL); @@ -2839,7 +2853,8 @@ got_block: must_read = buf_block_get_io_fix(block) == BUF_IO_READ; - if (must_read && mode == BUF_GET_IF_IN_POOL) { + if (must_read && (mode == BUF_GET_IF_IN_POOL + || mode == BUF_PEEK_IF_IN_POOL)) { /* The page is being read to buffer pool, but we cannot wait around for the read to @@ -2873,7 +2888,7 @@ wait_until_unfixed: Try again later. */ buf_pool_mutex_exit(buf_pool); os_thread_sleep(WAIT_FOR_READ); - + goto loop; } @@ -2962,6 +2977,7 @@ wait_until_unfixed: mutex_exit(&buf_pool->zip_mutex); buf_pool->n_pend_unzip++; + bpage->state = BUF_BLOCK_ZIP_FREE; buf_buddy_free(buf_pool, bpage, sizeof *bpage); buf_pool_mutex_exit(buf_pool); @@ -3055,7 +3071,9 @@ wait_until_unfixed: buf_pool_mutex_exit(buf_pool); - buf_page_set_accessed_make_young(&block->page, access_time); + if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) { + buf_page_set_accessed_make_young(&block->page, access_time); + } #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(!block->page.file_page_was_freed); @@ -3108,11 +3126,12 @@ wait_until_unfixed: mtr_memo_push(mtr, block, fix_type); - if (!access_time) { + if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) { /* In the case of a first access, try to apply linear read-ahead */ - buf_read_ahead_linear(space, zip_size, offset, mtr); + buf_read_ahead_linear(space, zip_size, offset, + ibuf_inside(mtr)); } #ifdef UNIV_IBUF_COUNT_DEBUG @@ -3226,7 +3245,7 @@ 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), - mtr); + ibuf_inside(mtr)); } #ifdef UNIV_IBUF_COUNT_DEBUG @@ -3302,7 +3321,7 @@ buf_page_get_known_nowait( buf_pool_mutex_exit(buf_pool); } - ut_ad(!ibuf_inside(mtr) || (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), @@ -3568,13 +3587,12 @@ buf_page_init_for_read( ut_ad(!ibuf_bitmap_page(zip_size, offset)); - mtr_start(&mtr); - ibuf_enter(&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); } @@ -3698,6 +3716,7 @@ err_exit: /* The block was added by some other thread. */ watch_page = NULL; + bpage->state = BUF_BLOCK_ZIP_FREE; buf_buddy_free(buf_pool, bpage, sizeof *bpage); buf_buddy_free(buf_pool, data, zip_size); @@ -3758,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)); @@ -4786,7 +4805,7 @@ buf_get_modified_ratio_pct(void) buf_get_total_list_len(&lru_len, &free_len, &flush_list_len); ratio = (100 * flush_list_len) / (1 + lru_len + free_len); - + /* 1 + is there to avoid division by zero */ return(ratio); @@ -5169,7 +5188,7 @@ buf_all_freed(void) return(TRUE); } - + /*********************************************************************//** Checks that there currently are no pending i/o-operations for the buffer pool. diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 910e8386a71..64afcecfe3c 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -247,74 +247,78 @@ buf_LRU_drop_page_hash_for_tablespace( sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE); buf_pool_mutex_enter(buf_pool); + num_entries = 0; scan_again: - num_entries = 0; bpage = UT_LIST_GET_LAST(buf_pool->LRU); while (bpage != NULL) { - mutex_t* block_mutex = buf_page_get_mutex(bpage); buf_page_t* prev_bpage; + ibool is_fixed; - mutex_enter(block_mutex); prev_bpage = UT_LIST_GET_PREV(LRU, bpage); ut_a(buf_page_in_file(bpage)); if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE || bpage->space != id - || bpage->buf_fix_count > 0 || bpage->io_fix != BUF_IO_NONE) { - /* We leave the fixed pages as is in this scan. - To be dealt with later in the final scan. */ - mutex_exit(block_mutex); + /* Compressed pages are never hashed. + Skip blocks of other tablespaces. + Skip I/O-fixed blocks (to be dealt with later). */ +next_page: + bpage = prev_bpage; + continue; + } + + mutex_enter(&((buf_block_t*) bpage)->mutex); + is_fixed = bpage->buf_fix_count > 0 + || !((buf_block_t*) bpage)->is_hashed; + mutex_exit(&((buf_block_t*) bpage)->mutex); + + if (is_fixed) { goto next_page; } - if (((buf_block_t*) bpage)->is_hashed) { + /* Store the page number so that we can drop the hash + index in a batch later. */ + page_arr[num_entries] = bpage->offset; + ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE); + ++num_entries; - /* Store the offset(i.e.: page_no) in the array - so that we can drop hash index in a batch - later. */ - page_arr[num_entries] = bpage->offset; - mutex_exit(block_mutex); - ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE); - ++num_entries; + if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) { + goto next_page; + } - if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) { - goto next_page; - } + /* Array full. We release the buf_pool->mutex to obey + the latching order. */ + buf_pool_mutex_exit(buf_pool); - /* Array full. We release the buf_pool->mutex to - obey the latching order. */ - buf_pool_mutex_exit(buf_pool); + buf_LRU_drop_page_hash_batch( + id, zip_size, page_arr, num_entries); - buf_LRU_drop_page_hash_batch( - id, zip_size, page_arr, num_entries); + num_entries = 0; - num_entries = 0; + buf_pool_mutex_enter(buf_pool); - buf_pool_mutex_enter(buf_pool); - } else { - mutex_exit(block_mutex); - } + /* Note that we released the buf_pool mutex above + after reading the prev_bpage during processing of a + page_hash_batch (i.e.: when the array was full). + Because prev_bpage could belong to a compressed-only + block, it may have been relocated, and thus the + pointer cannot be trusted. Because bpage is of type + buf_block_t, it is safe to dereference. -next_page: - /* Note that we may have released the buf_pool mutex - above after reading the prev_bpage during processing - of a page_hash_batch (i.e.: when the array was full). - This means that prev_bpage can change in LRU list. - This is OK because this function is a 'best effort' - to drop as many search hash entries as possible and - it does not guarantee that ALL such entries will be - dropped. */ - bpage = prev_bpage; + bpage can change in the LRU list. This is OK because + this function is a 'best effort' to drop as many + search hash entries as possible and it does not + guarantee that ALL such entries will be dropped. */ /* If, however, bpage has been removed from LRU list to the free list then we should restart the scan. bpage->state is protected by buf_pool mutex. */ - if (bpage && !buf_page_in_file(bpage)) { - ut_a(num_entries == 0); + if (bpage + && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) { goto scan_again; } } @@ -1889,6 +1893,7 @@ buf_LRU_block_remove_hashed_page( buf_pool, bpage->zip.data, page_zip_get_size(&bpage->zip)); + bpage->state = BUF_BLOCK_ZIP_FREE; buf_buddy_free(buf_pool, bpage, sizeof(*bpage)); buf_pool_mutex_exit_allow(buf_pool); diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c index 3e36b707585..eeaa21ae9ef 100644 --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c @@ -236,12 +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) */ - mtr_t *mtr) /*!< in: mtr with knowledge if we're inside ibuf - routine */ + 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; @@ -431,11 +429,9 @@ buf_read_ahead_linear( /* If we got this far, read-ahead can be sensible: do it */ - if (ibuf_inside(mtr)) { - 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; @@ -452,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); diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 14490980bb6..37bf4a1ad59 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -2258,10 +2258,12 @@ loop: /* Since table names in SYS_FOREIGN are stored in a case-insensitive order, we have to check that the table name matches also in a binary string comparison. On Unix, MySQL allows table names that only differ - in character case. */ - - if (0 != ut_memcmp(field, table_name, len)) { + in character case. If lower_case_table_names=2 then what is stored + may not be the same case, but the previous comparison showed that they + match with no-case. */ + if ((srv_lower_case_table_names != 2) + && (0 != ut_memcmp(field, table_name, len))) { goto next_rec; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 14870b5ee63..74a33d05760 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -51,6 +51,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include <mysql/plugin.h> #include <mysql/innodb_priv.h> #include <mysql/psi/psi.h> +#include <my_sys.h> /** @file ha_innodb.cc */ @@ -81,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" @@ -279,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 */ @@ -1147,6 +1146,20 @@ innobase_strcasecmp( } /******************************************************************//** +Strip dir name from a full path name and return only the file name +@return file name or "null" if no file name */ +extern "C" UNIV_INTERN +const char* +innobase_basename( +/*==============*/ + const char* path_name) /*!< in: full path name */ +{ + const char* name = base_name(path_name); + + return((name) ? name : "null"); +} + +/******************************************************************//** Makes all characters in a NUL-terminated UTF-8 string lower case. */ extern "C" UNIV_INTERN void @@ -2594,7 +2607,6 @@ innobase_alter_table_flags( uint flags) { return(HA_INPLACE_ADD_INDEX_NO_READ_WRITE - | HA_INPLACE_ADD_INDEX_NO_WRITE | HA_INPLACE_DROP_INDEX_NO_READ_WRITE | HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE | HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE @@ -9261,7 +9273,8 @@ innodb_mutex_show_status( if (mutex->count_using > 0) { buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%s", - mutex->cmutex_name, mutex->cfile_name); + mutex->cmutex_name, + innobase_basename(mutex->cfile_name)); buf2len= my_snprintf(buf2, sizeof(buf2), "count=%lu, spin_waits=%lu," " spin_rounds=%lu, " @@ -9291,7 +9304,8 @@ innodb_mutex_show_status( } #else /* UNIV_DEBUG */ buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu", - mutex->cfile_name, (ulong) mutex->cline); + innobase_basename(mutex->cfile_name), + (ulong) mutex->cline); buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu", (ulong) mutex->count_os_wait); @@ -9307,7 +9321,8 @@ innodb_mutex_show_status( if (block_mutex) { buf1len = (uint) my_snprintf(buf1, sizeof buf1, "combined %s:%lu", - block_mutex->cfile_name, + innobase_basename( + block_mutex->cfile_name), (ulong) block_mutex->cline); buf2len = (uint) my_snprintf(buf2, sizeof buf2, "os_waits=%lu", @@ -9338,7 +9353,8 @@ innodb_mutex_show_status( } buf1len = my_snprintf(buf1, sizeof buf1, "%s:%lu", - lock->cfile_name, (ulong) lock->cline); + innobase_basename(lock->cfile_name), + (ulong) lock->cline); buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu", (ulong) lock->count_os_wait); @@ -9353,7 +9369,8 @@ innodb_mutex_show_status( if (block_lock) { buf1len = (uint) my_snprintf(buf1, sizeof buf1, "combined %s:%lu", - block_lock->cfile_name, + innobase_basename( + block_lock->cfile_name), (ulong) block_lock->cline); buf2len = (uint) my_snprintf(buf2, sizeof buf2, "os_waits=%lu", @@ -11357,7 +11374,7 @@ mysql_declare_plugin(innobase) MYSQL_STORAGE_ENGINE_PLUGIN, &innobase_storage_engine, innobase_hton_name, - "Innobase Oy", + plugin_author, "Supports transactions, row-level locking, and foreign keys", PLUGIN_LICENSE_GPL, innobase_init, /* Plugin Init */ diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 00aced180ce..de5cc682078 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -47,8 +47,6 @@ extern "C" { #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */ } -static const char plugin_author[] = "Innobase Oy"; - #define OK(expr) \ if ((expr) != 0) { \ DBUG_RETURN(1); \ @@ -1059,7 +1057,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits = /* plugin author (for SHOW PLUGINS) */ /* const char* */ - STRUCT_FLD(author, "Innobase Oy"), + STRUCT_FLD(author, plugin_author), /* general descriptive text (for SHOW PLUGINS) */ /* const char* */ diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h index 402c88bbedb..dc0deef119b 100644 --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -26,6 +26,8 @@ Created July 18, 2007 Vasil Dimov #ifndef i_s_h #define i_s_h +const char plugin_author[] = "Oracle Corporation"; + extern struct st_mysql_plugin i_s_innodb_trx; extern struct st_mysql_plugin i_s_innodb_locks; extern struct st_mysql_plugin i_s_innodb_lock_waits; diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 6b81e11b52e..6771ab219a4 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" @@ -329,10 +328,11 @@ inside an insert buffer routine. */ UNIV_INTERN void ibuf_enter( - mtr_t *mtr) /*!< in: mtr stores ibuf_inside info */ -/*============*/ +/*=======*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - mtr->ibuf_inside = TRUE; + ut_ad(!mtr->inside_ibuf); + mtr->inside_ibuf = TRUE; } /******************************************************************//** @@ -341,26 +341,25 @@ exiting an insert buffer routine. */ UNIV_INLINE void ibuf_exit( - mtr_t *mtr) /*!< in: mtr stores ibuf_inside info */ -/*===========*/ +/*======*/ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - mtr->ibuf_inside = 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( - mtr_t *mtr) /*!< in: mtr stores ibuf_inside info */ -/*=============*/ +/**************************************************************//** +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(mtr->ibuf_inside); + ut_d(ibuf_exit(mtr)); + btr_pcur_commit_specify_mtr(pcur, mtr); } /******************************************************************//** @@ -370,7 +369,7 @@ static page_t* ibuf_header_page_get( /*=================*/ - mtr_t* mtr) /*!< in: mtr */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { buf_block_t* block; @@ -559,7 +558,7 @@ ibuf_init_at_db_start(void) mutex_exit(&ibuf_mutex); ibuf->empty = (page_get_n_recs(root) == 0); - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); heap = mem_heap_create(450); @@ -1219,18 +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(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); @@ -1252,19 +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(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); @@ -1285,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 */ @@ -1309,6 +1342,9 @@ ibuf_rec_get_info( ulint info_len_local; ulint counter_local; + 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); @@ -1357,17 +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(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); @@ -1379,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); } @@ -1578,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 @@ -1596,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 @@ -1614,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) { @@ -1634,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); @@ -1721,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. @@ -1728,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; @@ -1740,6 +1812,9 @@ ibuf_rec_get_volume( ibool pre_4_1; ulint comp; + 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); @@ -1767,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 @@ -1784,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); @@ -2142,17 +2217,11 @@ 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); } @@ -2184,7 +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_mtr_commit(&mtr); return(TRUE); } @@ -2225,14 +2294,12 @@ ibuf_remove_free_page(void) mutex_exit(&ibuf_mutex); mutex_exit(&ibuf_pessimistic_insert_mutex); - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); return; } - ibuf_exit(&mtr); - mtr_start(&mtr2); - ibuf_enter(&mtr2); + ibuf_mtr_start(&mtr2); root = ibuf_tree_root_get(&mtr2); @@ -2245,7 +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_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 @@ -2305,7 +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_mtr_commit(&mtr); } /***********************************************************************//** @@ -2357,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 @@ -2393,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)) { @@ -2412,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; @@ -2424,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) @@ -2442,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 @@ -2463,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); } @@ -2475,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 @@ -2510,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 @@ -2563,9 +2645,7 @@ ibuf_contract_ext( return(0); } - mtr_start(&mtr); - - ibuf_enter(&mtr); + ibuf_mtr_start(&mtr); /* Open a cursor to a randomly chosen leaf of the tree, at a random position within the leaf */ @@ -2584,20 +2664,21 @@ ibuf_contract_ext( ut_ad(page_get_page_no(btr_pcur_get_page(&pcur)) == FSP_IBUF_TREE_ROOT_PAGE_NO); - 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 - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos, @@ -2737,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. @@ -2744,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 */ @@ -2755,8 +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(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; @@ -2841,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); @@ -2862,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 @@ -2872,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); @@ -2902,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)) { - - break; - } + for (; !page_rec_is_infimum(rec); + rec = page_rec_get_prev_const(rec)) { + ut_ad(page_align(rec) == page); - 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 */ @@ -2937,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); @@ -2947,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 @@ -2964,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 */ @@ -3015,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); @@ -3029,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 */ @@ -3039,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); } } @@ -3070,8 +3159,7 @@ ibuf_update_max_tablespace_id(void) ut_a(!dict_table_is_comp(ibuf->index->table)); - mtr_start(&mtr); - ibuf_enter(&mtr); + ibuf_mtr_start(&mtr); btr_pcur_open_at_index_side( FALSE, ibuf->index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr); @@ -3094,13 +3182,20 @@ ibuf_update_max_tablespace_id(void) max_space_id = mach_read_from_4(field); } - mtr_commit(&mtr); + 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. @@ -3108,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 */ @@ -3118,6 +3216,9 @@ ibuf_get_entry_counter_low( const byte* field; ulint len; + 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); @@ -3189,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. @@ -3250,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. @@ -3419,12 +3523,9 @@ ibuf_insert_low( return(DB_STRONG_FAIL); } } - mtr_start(&mtr); - } else { - mtr_start(&mtr); - ibuf_enter(&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)); @@ -3479,8 +3580,7 @@ fail_exit: #ifdef UNIV_IBUF_COUNT_DEBUG ut_a((buffered == 0) || ibuf_count_get(space, page_no)); #endif - mtr_start(&bitmap_mtr); - bitmap_mtr.ibuf_inside = mtr.ibuf_inside; + ibuf_mtr_start(&bitmap_mtr); bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &bitmap_mtr); @@ -3501,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; } @@ -3522,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; } @@ -3540,7 +3640,7 @@ bitmap_fail: &bitmap_mtr); } - mtr_commit(&bitmap_mtr); + ibuf_mtr_commit(&bitmap_mtr); cursor = btr_pcur_get_btr_cur(&pcur); @@ -3605,7 +3705,7 @@ func_exit: } #endif - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); mem_heap_free(heap); @@ -4156,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" @@ -4174,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)) { @@ -4198,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, @@ -4212,8 +4312,8 @@ ibuf_delete_rec( 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); @@ -4246,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; } @@ -4278,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); @@ -4372,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); @@ -4391,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) @@ -4402,7 +4505,7 @@ ibuf_merge_or_delete_for_page( 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 { @@ -4429,8 +4532,7 @@ ibuf_merge_or_delete_for_page( ut_print_timestamp(stderr); - mtr_start(&mtr); - ibuf_enter(&mtr); + ibuf_mtr_start(&mtr); fputs(" InnoDB: Dump of the ibuf bitmap page:\n", stderr); @@ -4438,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); @@ -4470,8 +4571,7 @@ ibuf_merge_or_delete_for_page( memset(dops, 0, sizeof(dops)); loop: - mtr_start(&mtr); - ibuf_enter(&mtr); + ibuf_mtr_start(&mtr); if (block) { ibool success; @@ -4505,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( @@ -4529,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, @@ -4538,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)); @@ -4571,14 +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_enter(&mtr); + ibuf_mtr_start(&mtr); success = buf_page_get_known_nowait( RW_X_LATCH, block, @@ -4593,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; @@ -4608,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 */ @@ -4619,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; @@ -4653,7 +4754,7 @@ reset_bit: } } - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); mem_heap_free(heap); @@ -4696,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. */ @@ -4713,8 +4813,7 @@ ibuf_delete_for_discarded_space( memset(dops, 0, sizeof(dops)); loop: - mtr_start(&mtr); - ibuf_enter(&mtr); + ibuf_mtr_start(&mtr); /* Position pcur in the insert buffer at the first entry for the space */ @@ -4734,19 +4833,18 @@ 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 */ @@ -4754,7 +4852,7 @@ loop: } if (btr_pcur_is_after_last_on_page(&pcur)) { - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); goto loop; @@ -4762,7 +4860,7 @@ loop: } leave_loop: - mtr_commit(&mtr); + ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); #ifdef HAVE_ATOMIC_BUILTINS @@ -4789,17 +4887,15 @@ ibuf_is_empty(void) const page_t* root; mtr_t mtr; - mtr_start(&mtr); - ibuf_enter(&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); - ut_a(is_empty == ibuf->empty); + ibuf_mtr_commit(&mtr); return(is_empty); } diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index 2334a266280..6c11c973fc9 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -150,7 +150,7 @@ UNIV_INLINE ulint btr_pcur_get_up_match( /*==================*/ - btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */ + const btr_pcur_t* cursor); /*!< in: persistent cursor */ /**************************************************************//** Gets the low_match value for a pcur after a search. @return number of matched fields at the cursor or to the right if @@ -159,7 +159,7 @@ UNIV_INLINE ulint btr_pcur_get_low_match( /*===================*/ - btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */ + const btr_pcur_t* cursor); /*!< in: persistent cursor */ /**************************************************************//** If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first user record satisfying the search condition, in the case PAGE_CUR_L or @@ -264,22 +264,6 @@ ulint btr_pcur_get_rel_pos( /*=================*/ const btr_pcur_t* cursor);/*!< in: persistent cursor */ -/*********************************************************//** -Sets the mtr field for a pcur. */ -UNIV_INLINE -void -btr_pcur_set_mtr( -/*=============*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr); /*!< in, own: mtr */ -/*********************************************************//** -Gets the mtr field for a pcur. -@return mtr */ -UNIV_INLINE -mtr_t* -btr_pcur_get_mtr( -/*=============*/ - btr_pcur_t* cursor); /*!< in: persistent cursor */ /**************************************************************//** Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES, that is, the cursor becomes detached. If there have been modifications @@ -387,10 +371,6 @@ page_cur_t* btr_pcur_get_page_cur( /*==================*/ const btr_pcur_t* cursor); /*!< in: persistent cursor */ -#else /* UNIV_DEBUG */ -# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur) -# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur) -#endif /* UNIV_DEBUG */ /*********************************************************//** Returns the page of a persistent cursor. @return pointer to the page */ @@ -398,7 +378,7 @@ UNIV_INLINE page_t* btr_pcur_get_page( /*==============*/ - btr_pcur_t* cursor);/*!< in: persistent cursor */ + const btr_pcur_t* cursor);/*!< in: persistent cursor */ /*********************************************************//** Returns the buffer block of a persistent cursor. @return pointer to the block */ @@ -406,7 +386,7 @@ UNIV_INLINE buf_block_t* btr_pcur_get_block( /*===============*/ - btr_pcur_t* cursor);/*!< in: persistent cursor */ + const btr_pcur_t* cursor);/*!< in: persistent cursor */ /*********************************************************//** Returns the record of a persistent cursor. @return pointer to the record */ @@ -414,7 +394,14 @@ UNIV_INLINE rec_t* btr_pcur_get_rec( /*=============*/ - btr_pcur_t* cursor);/*!< in: persistent cursor */ + const btr_pcur_t* cursor);/*!< in: persistent cursor */ +#else /* UNIV_DEBUG */ +# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur) +# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur) +# define btr_pcur_get_page(cursor) ((cursor)->btr_cur.page_cur.block->frame) +# define btr_pcur_get_block(cursor) ((cursor)->btr_cur.page_cur.block) +# define btr_pcur_get_rec(cursor) ((cursor)->btr_cur.page_cur.rec) +#endif /* UNIV_DEBUG */ /*********************************************************//** Checks if the persistent cursor is on a user record. */ UNIV_INLINE @@ -517,9 +504,6 @@ struct btr_pcur_struct{ /* NOTE that the following fields may possess dynamically allocated memory which should be freed if not needed anymore! */ - mtr_t* mtr; /*!< NULL, or this field may contain - a mini-transaction which holds the - latch on the cursor page */ byte* old_rec_buf; /*!< NULL, or a dynamically allocated buffer for old_rec */ ulint buf_size; /*!< old_rec_buf size if old_rec_buf diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 0c38797e6c5..59fdb21824b 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -42,34 +42,6 @@ btr_pcur_get_rel_pos( return(cursor->rel_pos); } -/*********************************************************//** -Sets the mtr field for a pcur. */ -UNIV_INLINE -void -btr_pcur_set_mtr( -/*=============*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr) /*!< in, own: mtr */ -{ - ut_ad(cursor); - - cursor->mtr = mtr; -} - -/*********************************************************//** -Gets the mtr field for a pcur. -@return mtr */ -UNIV_INLINE -mtr_t* -btr_pcur_get_mtr( -/*=============*/ - btr_pcur_t* cursor) /*!< in: persistent cursor */ -{ - ut_ad(cursor); - - return(cursor->mtr); -} - #ifdef UNIV_DEBUG /*********************************************************//** Returns the btr cursor component of a persistent cursor. @@ -95,7 +67,7 @@ btr_pcur_get_page_cur( { return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor))); } -#endif /* UNIV_DEBUG */ + /*********************************************************//** Returns the page of a persistent cursor. @return pointer to the page */ @@ -103,7 +75,7 @@ UNIV_INLINE page_t* btr_pcur_get_page( /*==============*/ - btr_pcur_t* cursor) /*!< in: persistent cursor */ + const btr_pcur_t* cursor) /*!< in: persistent cursor */ { ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); @@ -117,7 +89,7 @@ UNIV_INLINE buf_block_t* btr_pcur_get_block( /*===============*/ - btr_pcur_t* cursor) /*!< in: persistent cursor */ + const btr_pcur_t* cursor) /*!< in: persistent cursor */ { ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); @@ -131,13 +103,14 @@ UNIV_INLINE rec_t* btr_pcur_get_rec( /*=============*/ - btr_pcur_t* cursor) /*!< in: persistent cursor */ + const btr_pcur_t* cursor) /*!< in: persistent cursor */ { ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->latch_mode != BTR_NO_LATCHES); return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor))); } +#endif /* UNIV_DEBUG */ /**************************************************************//** Gets the up_match value for a pcur after a search. @@ -147,9 +120,9 @@ UNIV_INLINE ulint btr_pcur_get_up_match( /*==================*/ - btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */ + const btr_pcur_t* cursor) /*!< in: persistent cursor */ { - btr_cur_t* btr_cursor; + const btr_cur_t* btr_cursor; ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED) || (cursor->pos_state == BTR_PCUR_IS_POSITIONED)); @@ -169,9 +142,9 @@ UNIV_INLINE ulint btr_pcur_get_low_match( /*===================*/ - btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */ + const btr_pcur_t* cursor) /*!< in: persistent cursor */ { - btr_cur_t* btr_cursor; + const btr_cur_t* btr_cursor; ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED) || (cursor->pos_state == BTR_PCUR_IS_POSITIONED)); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index dbd5adee0cc..8fb008997ab 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -41,6 +41,8 @@ Created 11/5/1995 Heikki Tuuri /* @{ */ #define BUF_GET 10 /*!< get always */ #define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */ +#define BUF_PEEK_IF_IN_POOL 12 /*!< get if in pool, do not make + the block young in the LRU list */ #define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but set no latch; we have separated this case, because @@ -396,7 +398,7 @@ buf_page_get_gen( ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ buf_block_t* guess, /*!< in: guessed block or NULL */ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL, - BUF_GET_NO_LATCH or + BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH or BUF_GET_IF_IN_POOL_OR_WATCH */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index 6e1f832942a..9906981209a 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -71,11 +71,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) */ - mtr_t *mtr); /*!< in: mtr to get ibuf_inside indicator */ + 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/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index b75002944bd..dd9e8db82ee 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -174,6 +174,15 @@ innobase_strcasecmp( const char* b); /*!< in: second string to compare */ /******************************************************************//** +Strip dir name from a full path name and return only its file name. +@return file name or "null" if no file name */ +UNIV_INTERN +const char* +innobase_basename( +/*==============*/ + const char* path_name); /*!< in: full path name */ + +/******************************************************************//** Returns true if the thread is executing a SELECT statement. @return true if thd is executing SELECT */ diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 464571d1ff8..0f1cb0fe688 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,19 +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( - mtr_t* mtr);/*!< in: ibuf_inside stored on mtr */ -/*=============*/ -/***********************************************************************//** -Sets ibuf_inside indicator on current MTR. -*/ -UNIV_INTERN -void -ibuf_enter( - mtr_t* mtr);/*!< in: ibuf_inside stored on mtr */ -/*=============*/ +/*========*/ + 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 2aaad3322c3..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,8 +378,8 @@ struct mtr_struct{ #endif dyn_array_t memo; /*!< memo stack for locks etc. */ dyn_array_t log; /*!< mini-transaction log */ - ibool ibuf_inside; - /* TRUE if inside ibuf changes */ + 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 9baf2ae1d48..3d87eea2710 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -30,27 +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->ibuf_inside = 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/page0page.h b/storage/innobase/include/page0page.h index 826fd13125d..0a15dfbf2a1 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -952,7 +952,7 @@ UNIV_INTERN ibool page_rec_validate( /*==============*/ - rec_t* rec, /*!< in: physical record */ + const rec_t* rec, /*!< in: physical record */ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ /***************************************************************//** Checks that the first directory slot points to the infimum record and @@ -972,7 +972,7 @@ UNIV_INTERN ibool page_simple_validate_old( /*=====================*/ - page_t* page); /*!< in: old-style index page */ + const page_t* page); /*!< in: index page in ROW_FORMAT=REDUNDANT */ /***************************************************************//** This function checks the consistency of an index page when we do not know the index. This is also resilient so that this should never crash @@ -982,7 +982,7 @@ UNIV_INTERN ibool page_simple_validate_new( /*=====================*/ - page_t* block); /*!< in: new-style index page */ + const page_t* page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */ /***************************************************************//** This function checks the consistency of an index page. @return TRUE if ok */ @@ -990,7 +990,7 @@ UNIV_INTERN ibool page_validate( /*==========*/ - page_t* page, /*!< in: index page */ + const page_t* page, /*!< in: index page */ dict_index_t* index); /*!< in: data dictionary index containing the page record type definition */ /***************************************************************//** diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 9ffb5c7d9e5..3d157f1da95 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -600,6 +600,7 @@ ulint rec_offs_size( /*==========*/ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ +#ifdef UNIV_DEBUG /**********************************************************//** Returns a pointer to the start of the record. @return pointer to start */ @@ -607,7 +608,7 @@ UNIV_INLINE byte* rec_get_start( /*==========*/ - rec_t* rec, /*!< in: pointer to record */ + const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ /**********************************************************//** Returns a pointer to the end of the record. @@ -616,8 +617,12 @@ UNIV_INLINE byte* rec_get_end( /*========*/ - rec_t* rec, /*!< in: pointer to record */ + const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ +#else /* UNIV_DEBUG */ +# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets)) +# define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets)) +#endif /* UNIV_DEBUG */ /***************************************************************//** Copies a physical record to a buffer. @return pointer to the origin of the copy */ diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index ba306eaf27f..3d386710d7d 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -1462,6 +1462,7 @@ rec_offs_size( return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets)); } +#ifdef UNIV_DEBUG /**********************************************************//** Returns a pointer to the end of the record. @return pointer to end */ @@ -1469,11 +1470,11 @@ UNIV_INLINE byte* rec_get_end( /*========*/ - rec_t* rec, /*!< in: pointer to record */ + const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ { ut_ad(rec_offs_validate(rec, NULL, offsets)); - return(rec + rec_offs_data_size(offsets)); + return((rec_t*) rec + rec_offs_data_size(offsets)); } /**********************************************************//** @@ -1483,12 +1484,13 @@ UNIV_INLINE byte* rec_get_start( /*==========*/ - rec_t* rec, /*!< in: pointer to record */ + const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ { ut_ad(rec_offs_validate(rec, NULL, offsets)); - return(rec - rec_offs_extra_size(offsets)); + return((rec_t*) rec - rec_offs_extra_size(offsets)); } +#endif /* UNIV_DEBUG */ /***************************************************************//** Copies a physical record to a buffer. diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 252d1424c63..fb5bc56920a 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -442,16 +442,8 @@ typedef enum srv_stats_method_name_enum srv_stats_method_name_t; #ifndef UNIV_HOTBACKUP /** Types of threads existing in the system. */ enum srv_thread_type { - SRV_COM = 1, /**< threads serving communication and queries */ - SRV_CONSOLE, /**< thread serving console */ - SRV_WORKER, /**< threads serving parallelized queries and + SRV_WORKER = 0, /**< threads serving parallelized queries and queries released from lock wait */ -#if 0 - /* Utility threads */ - SRV_BUFFER, /**< thread flushing dirty buffer blocks */ - SRV_RECOVERY, /**< threads finishing a recovery */ - SRV_INSERT, /**< thread flushing the insert buffer to disk */ -#endif SRV_MASTER /**< the master thread, (whose type number must be biggest) */ }; @@ -490,13 +482,6 @@ ulint srv_get_n_threads(void); /*===================*/ /*********************************************************************//** -Returns the calling thread type. -@return SRV_COM, ... */ - -enum srv_thread_type -srv_get_thread_type(void); -/*=====================*/ -/*********************************************************************//** Check whether thread type has reserved a slot. @return slot number or UNDEFINED if not found*/ UNIV_INTERN diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h index 5f1280f5e28..6e931346238 100644 --- a/storage/innobase/include/sync0arr.h +++ b/storage/innobase/include/sync0arr.h @@ -115,8 +115,11 @@ Prints warnings of long semaphore waits to stderr. @return TRUE if fatal semaphore wait threshold was exceeded */ UNIV_INTERN ibool -sync_array_print_long_waits(void); -/*=============================*/ +sync_array_print_long_waits( +/*========================*/ + os_thread_id_t* waiter, /*!< out: longest waiting thread */ + const void** sema) /*!< out: longest-waited-for semaphore */ + __attribute__((nonnull)); /********************************************************************//** Validates the integrity of the wait array. Checks that the number of reserved cells equals the count variable. */ 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 14da8bffdd7..00000000000 --- a/storage/innobase/include/thr0loc.h +++ /dev/null @@ -1,82 +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 */ -/*******************************************************************//** -Gets the slot number in the thread table of a thread. -@return slot number */ -UNIV_INTERN -ulint -thr_local_get_slot_no( -/*==================*/ - os_thread_id_t id); /*!< in: thread id of the thread */ -/*******************************************************************//** -Sets in the local storage the slot number in the thread table of a thread. */ -UNIV_INTERN -void -thr_local_set_slot_no( -/*==================*/ - os_thread_id_t id, /*!< in: thread id of the thread */ - ulint slot_no);/*!< in: slot number */ - -#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/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c index d91e610a08a..ae43d6097a6 100644 --- a/storage/innobase/mem/mem0dbg.c +++ b/storage/innobase/mem/mem0dbg.c @@ -24,6 +24,8 @@ but is included in mem0mem.* ! Created 6/9/1994 Heikki Tuuri *************************************************************************/ +#include "ha_prototypes.h" + #ifdef UNIV_MEM_DEBUG # ifndef UNIV_HOTBACKUP /* The mutex which protects in the debug version the hash table @@ -400,7 +402,7 @@ mem_hash_remove( fprintf(stderr, "Memory heap or buffer freed in %s line %lu" " did not exist.\n", - file_name, (ulong) line); + innobase_basename(file_name), (ulong) line); ut_error; } @@ -419,8 +421,9 @@ mem_hash_remove( "in %s line %lu and tried to free in %s line %lu.\n" "Hex dump of 400 bytes around memory heap" " first block start:\n", - node->nth_heap, node->file_name, (ulong) node->line, - file_name, (ulong) line); + node->nth_heap, + innobase_basename(node->file_name), (ulong) node->line, + innobase_basename(file_name), (ulong) line); ut_print_buf(stderr, (byte*)node->heap - 200, 400); fputs("\nDump of the mem heap:\n", stderr); mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, @@ -763,7 +766,8 @@ mem_validate_no_assert(void) "Inconsistency in memory heap" " or buffer created\n" "in %s line %lu.\n", - node->file_name, node->line); + innobase_basename(node->file_name), + node->line); mutex_exit(&mem_hash_mutex); @@ -989,7 +993,8 @@ mem_print_info_low( fprintf(outfile, "%lu: file %s line %lu of size %lu phys.size %lu" " with %lu blocks, type %lu\n", - node->nth_heap, node->file_name, node->line, + node->nth_heap, + innobase_basename(node->file_name), node->line, allocated_mem, ph_size, n_blocks, (node->heap)->type); next_heap: diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c index 0b2100319c2..877cb93b926 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/page/page0page.c b/storage/innobase/page/page0page.c index 99182e85849..964d0e2abef 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -166,11 +166,11 @@ static ibool page_dir_slot_check( /*================*/ - page_dir_slot_t* slot) /*!< in: slot */ + const page_dir_slot_t* slot) /*!< in: slot */ { - page_t* page; - ulint n_slots; - ulint n_owned; + const page_t* page; + ulint n_slots; + ulint n_owned; ut_a(slot); @@ -1803,12 +1803,12 @@ UNIV_INTERN ibool page_rec_validate( /*==============*/ - rec_t* rec, /*!< in: physical record */ + const rec_t* rec, /*!< in: physical record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ { - ulint n_owned; - ulint heap_no; - page_t* page; + ulint n_owned; + ulint heap_no; + const page_t* page; page = page_align(rec); ut_a(!page_is_comp(page) == !rec_offs_comp(offsets)); @@ -1889,16 +1889,16 @@ UNIV_INTERN ibool page_simple_validate_old( /*=====================*/ - page_t* page) /*!< in: old-style index page */ + const page_t* page) /*!< in: index page in ROW_FORMAT=REDUNDANT */ { - page_dir_slot_t* slot; - ulint slot_no; - ulint n_slots; - rec_t* rec; - byte* rec_heap_top; - ulint count; - ulint own_count; - ibool ret = FALSE; + const page_dir_slot_t* slot; + ulint slot_no; + ulint n_slots; + const rec_t* rec; + const byte* rec_heap_top; + ulint count; + ulint own_count; + ibool ret = FALSE; ut_a(!page_is_comp(page)); @@ -2011,7 +2011,7 @@ page_simple_validate_old( goto func_exit; } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); own_count++; } @@ -2072,7 +2072,7 @@ page_simple_validate_old( goto func_exit; } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2099,16 +2099,16 @@ UNIV_INTERN ibool page_simple_validate_new( /*=====================*/ - page_t* page) /*!< in: new-style index page */ + const page_t* page) /*!< in: index page in ROW_FORMAT!=REDUNDANT */ { - page_dir_slot_t* slot; - ulint slot_no; - ulint n_slots; - rec_t* rec; - byte* rec_heap_top; - ulint count; - ulint own_count; - ibool ret = FALSE; + const page_dir_slot_t* slot; + ulint slot_no; + ulint n_slots; + const rec_t* rec; + const byte* rec_heap_top; + ulint count; + ulint own_count; + ibool ret = FALSE; ut_a(page_is_comp(page)); @@ -2221,7 +2221,7 @@ page_simple_validate_new( goto func_exit; } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); own_count++; } @@ -2283,7 +2283,7 @@ page_simple_validate_new( goto func_exit; } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2308,26 +2308,26 @@ UNIV_INTERN ibool page_validate( /*==========*/ - page_t* page, /*!< in: index page */ + const page_t* page, /*!< in: index page */ dict_index_t* index) /*!< in: data dictionary index containing the page record type definition */ { - page_dir_slot_t*slot; - mem_heap_t* heap; - byte* buf; - ulint count; - ulint own_count; - ulint rec_own_count; - ulint slot_no; - ulint data_size; - rec_t* rec; - rec_t* old_rec = NULL; - ulint offs; - ulint n_slots; - ibool ret = FALSE; - ulint i; - ulint* offsets = NULL; - ulint* old_offsets = NULL; + const page_dir_slot_t* slot; + mem_heap_t* heap; + byte* buf; + ulint count; + ulint own_count; + ulint rec_own_count; + ulint slot_no; + ulint data_size; + const rec_t* rec; + const rec_t* old_rec = NULL; + ulint offs; + ulint n_slots; + ibool ret = FALSE; + ulint i; + ulint* offsets = NULL; + ulint* old_offsets = NULL; if (UNIV_UNLIKELY((ibool) !!page_is_comp(page) != dict_table_is_comp(index->table))) { @@ -2482,7 +2482,7 @@ page_validate( count++; own_count++; old_rec = rec; - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); /* set old_offsets to offsets; recycle offsets */ { @@ -2556,7 +2556,7 @@ n_owned_zero: buf[offs + i] = 1; } - rec = page_rec_get_next(rec); + rec = page_rec_get_next_const(rec); } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c index 704b0c88e02..f077a56b087 100644 --- a/storage/innobase/page/page0zip.c +++ b/storage/innobase/page/page0zip.c @@ -653,13 +653,13 @@ page_zip_dir_encode( Allocate memory for zlib. */ static void* -page_zip_malloc( +page_zip_zalloc( /*============*/ void* opaque, /*!< in/out: memory heap */ uInt items, /*!< in: number of items to allocate */ uInt size) /*!< in: size of an item in bytes */ { - return(mem_heap_alloc(opaque, items * size)); + return(mem_heap_zalloc(opaque, items * size)); } /**********************************************************************//** @@ -684,7 +684,7 @@ page_zip_set_alloc( { z_stream* strm = stream; - strm->zalloc = page_zip_malloc; + strm->zalloc = page_zip_zalloc; strm->zfree = page_zip_free; strm->opaque = heap; } @@ -2912,19 +2912,18 @@ zlib_error: page_zip_set_alloc(&d_stream, heap); - if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT) - != Z_OK)) { - ut_error; - } - d_stream.next_in = page_zip->data + PAGE_DATA; /* Subtract the space reserved for the page header and the end marker of the modification log. */ d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1); - d_stream.next_out = page + PAGE_ZIP_START; d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START; + if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT) + != Z_OK)) { + ut_error; + } + /* Decode the zlib header and the index information. */ if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) { diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 3e10aa03096..dcf22656ad8 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" @@ -690,7 +689,7 @@ Unix.*/ struct srv_slot_struct{ os_thread_id_t id; /*!< thread id */ os_thread_t handle; /*!< thread handle */ - unsigned type:3; /*!< thread type: user, utility etc. */ + unsigned type:1; /*!< thread type: user, utility etc. */ unsigned in_use:1; /*!< TRUE if this slot is in use */ unsigned suspended:1; /*!< TRUE if the thread is waiting for the event of this slot */ @@ -797,6 +796,7 @@ srv_table_get_nth_slot( /*===================*/ ulint index) /*!< in: index of the slot */ { + ut_ad(mutex_own(&kernel_mutex)); ut_a(index < OS_THREAD_MAX_N); return(srv_sys->threads + index); @@ -815,7 +815,7 @@ srv_get_n_threads(void) mutex_enter(&kernel_mutex); - for (i = SRV_COM; i < SRV_MASTER + 1; i++) { + for (i = 0; i < SRV_MASTER + 1; i++) { n_threads += srv_n_threads[i]; } @@ -825,13 +825,46 @@ srv_get_n_threads(void) return(n_threads); } +#ifdef UNIV_DEBUG /*********************************************************************//** -Reserves a slot in the thread table for the current thread. Also creates the -thread local storage struct for the current thread. NOTE! The server mutex -has to be reserved by the caller! -@return reserved slot index */ +Validates the type of a thread table slot. +@return TRUE if ok */ static -ulint +ibool +srv_thread_type_validate( +/*=====================*/ + enum srv_thread_type type) /*!< in: thread type */ +{ + switch (type) { + case SRV_WORKER: + case SRV_MASTER: + return(TRUE); + } + ut_error; + return(FALSE); +} +#endif /* UNIV_DEBUG */ + +/*********************************************************************//** +Gets the type of a thread table slot. +@return thread type */ +static +enum srv_thread_type +srv_slot_get_type( +/*==============*/ + const srv_slot_t* slot) /*!< in: thread slot */ +{ + enum srv_thread_type type = (enum srv_thread_type) slot->type; + ut_ad(srv_thread_type_validate(type)); + return(type); +} + +/*********************************************************************//** +Reserves a slot in the thread table for the current thread. +NOTE! The server mutex has to be reserved by the caller! +@return reserved slot */ +static +srv_slot_t* srv_table_reserve_slot( /*===================*/ enum srv_thread_type type) /*!< in: type of the thread */ @@ -839,8 +872,7 @@ srv_table_reserve_slot( srv_slot_t* slot; ulint i; - ut_a(type > 0); - ut_a(type <= SRV_MASTER); + ut_ad(srv_thread_type_validate(type)); ut_ad(mutex_own(&kernel_mutex)); i = 0; @@ -851,53 +883,40 @@ srv_table_reserve_slot( slot = srv_table_get_nth_slot(i); } - ut_a(slot->in_use == FALSE); - slot->in_use = TRUE; slot->suspended = FALSE; slot->type = type; + ut_ad(srv_slot_get_type(slot) == type); slot->id = os_thread_get_curr_id(); slot->handle = os_thread_get_curr(); - thr_local_create(); - - thr_local_set_slot_no(os_thread_get_curr_id(), i); - - return(i); + return(slot); } /*********************************************************************//** Suspends the calling thread to wait for the event in its thread slot. -NOTE! The server mutex has to be reserved by the caller! -@return event for the calling thread to wait */ +NOTE! The server mutex has to be reserved by the caller! */ static -os_event_t -srv_suspend_thread(void) -/*====================*/ +void +srv_suspend_thread( +/*===============*/ + srv_slot_t* slot) /*!< in/out: thread slot */ { - srv_slot_t* slot; - os_event_t event; - ulint slot_no; enum srv_thread_type type; ut_ad(mutex_own(&kernel_mutex)); - - slot_no = thr_local_get_slot_no(os_thread_get_curr_id()); + ut_ad(slot->in_use); + ut_ad(!slot->suspended); + ut_ad(slot->id == os_thread_get_curr_id()); if (srv_print_thread_releases) { fprintf(stderr, "Suspending thread %lu to slot %lu\n", - (ulong) os_thread_get_curr_id(), (ulong) slot_no); + (ulong) os_thread_get_curr_id(), + (ulong) (slot - srv_sys->threads)); } - slot = srv_table_get_nth_slot(slot_no); - - type = slot->type; - - ut_ad(type >= SRV_WORKER); - ut_ad(type <= SRV_MASTER); - - event = slot->event; + type = srv_slot_get_type(slot); slot->suspended = TRUE; @@ -905,9 +924,7 @@ srv_suspend_thread(void) srv_n_threads_active[type]--; - os_event_reset(event); - - return(event); + os_event_reset(slot->event); } /*********************************************************************//** @@ -926,8 +943,7 @@ srv_release_threads( ulint i; ulint count = 0; - ut_ad(type >= SRV_WORKER); - ut_ad(type <= SRV_MASTER); + ut_ad(srv_thread_type_validate(type)); ut_ad(n > 0); ut_ad(mutex_own(&kernel_mutex)); @@ -935,7 +951,8 @@ srv_release_threads( slot = srv_table_get_nth_slot(i); - if (slot->in_use && slot->type == type && slot->suspended) { + if (slot->in_use && slot->suspended + && srv_slot_get_type(slot) == type) { slot->suspended = FALSE; @@ -963,34 +980,6 @@ srv_release_threads( } /*********************************************************************//** -Returns the calling thread type. -@return SRV_COM, ... */ -UNIV_INTERN -enum srv_thread_type -srv_get_thread_type(void) -/*=====================*/ -{ - ulint slot_no; - srv_slot_t* slot; - enum srv_thread_type type; - - mutex_enter(&kernel_mutex); - - slot_no = thr_local_get_slot_no(os_thread_get_curr_id()); - - slot = srv_table_get_nth_slot(slot_no); - - type = slot->type; - - ut_ad(type >= SRV_WORKER); - ut_ad(type <= SRV_MASTER); - - mutex_exit(&kernel_mutex); - - return(type); -} - -/*********************************************************************//** Check whether thread type has reserved a slot. Return the first slot that is found. This works because we currently have only 1 thread of each type. @return slot number or ULINT_UNDEFINED if not found*/ @@ -1003,6 +992,7 @@ srv_thread_has_reserved_slot( ulint i; ulint slot_no = ULINT_UNDEFINED; + ut_ad(srv_thread_type_validate(type)); mutex_enter(&kernel_mutex); for (i = 0; i < OS_THREAD_MAX_N; i++) { @@ -1040,22 +1030,18 @@ srv_init(void) mutex_create(srv_innodb_monitor_mutex_key, &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK); - srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); + srv_sys->threads = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); for (i = 0; i < OS_THREAD_MAX_N; i++) { - slot = srv_table_get_nth_slot(i); - slot->in_use = FALSE; - slot->type=0; /* Avoid purify errors */ + slot = srv_sys->threads + i; slot->event = os_event_create(NULL); ut_a(slot->event); } - srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); + srv_mysql_table = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_mysql_table + i; - slot->in_use = FALSE; - slot->type = 0; slot->event = os_event_create(NULL); ut_a(slot->event); } @@ -1142,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 =======================*/ @@ -1501,7 +1486,7 @@ srv_table_reserve_slot_for_mysql(void) while (slot->in_use) { i++; - if (i >= OS_THREAD_MAX_N) { + if (UNIV_UNLIKELY(i >= OS_THREAD_MAX_N)) { ut_print_timestamp(stderr); @@ -2382,6 +2367,12 @@ srv_error_monitor_thread( ib_uint64_t old_lsn; ib_uint64_t new_lsn; ib_int64_t sig_count; + /* longest waiting thread for a semaphore */ + os_thread_id_t waiter = os_thread_get_curr_id(); + os_thread_id_t old_waiter = waiter; + /* the semaphore that is being waited for */ + const void* sema = NULL; + const void* old_sema = NULL; old_lsn = srv_start_lsn; @@ -2435,7 +2426,8 @@ loop: sync_arr_wake_threads_if_sema_free(); - if (sync_array_print_long_waits()) { + if (sync_array_print_long_waits(&waiter, &sema) + && sema == old_sema && os_thread_eq(waiter, old_waiter)) { fatal_cnt++; if (fatal_cnt > 10) { @@ -2450,6 +2442,8 @@ loop: } } else { fatal_cnt = 0; + old_waiter = waiter; + old_sema = sema; } /* Flush stderr so that a database user gets the output @@ -2489,7 +2483,7 @@ srv_is_any_background_thread_active(void) mutex_enter(&kernel_mutex); - for (i = SRV_COM; i <= SRV_MASTER; ++i) { + for (i = 0; i <= SRV_MASTER; ++i) { if (srv_n_threads_active[i] != 0) { ret = TRUE; break; @@ -2643,7 +2637,7 @@ srv_master_thread( os_thread_create */ { buf_pool_stat_t buf_stat; - os_event_t event; + srv_slot_t* slot; ulint old_activity_count; ulint n_pages_purged = 0; ulint n_bytes_merged; @@ -2671,7 +2665,7 @@ srv_master_thread( mutex_enter(&kernel_mutex); - srv_table_reserve_slot(SRV_MASTER); + slot = srv_table_reserve_slot(SRV_MASTER); srv_n_threads_active[SRV_MASTER]++; @@ -3060,7 +3054,7 @@ suspend_thread: goto loop; } - event = srv_suspend_thread(); + srv_suspend_thread(slot); mutex_exit(&kernel_mutex); @@ -3070,7 +3064,7 @@ suspend_thread: manual also mentions this string in several places. */ srv_main_thread_op_info = "waiting for server activity"; - os_event_wait(event); + os_event_wait(slot->event); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { /* This is only extra safety, the thread should exit @@ -3084,8 +3078,6 @@ suspend_thread: main thread goes back to loop. */ goto loop; - - OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */ } /*********************************************************************//** @@ -3100,7 +3092,6 @@ srv_purge_thread( { srv_slot_t* slot; ulint retries = 0; - ulint slot_no = ULINT_UNDEFINED; ulint n_total_purged = ULINT_UNDEFINED; ut_a(srv_n_purge_threads == 1); @@ -3116,9 +3107,7 @@ srv_purge_thread( mutex_enter(&kernel_mutex); - slot_no = srv_table_reserve_slot(SRV_WORKER); - - slot = srv_table_get_nth_slot(slot_no); + slot = srv_table_reserve_slot(SRV_WORKER); ++srv_n_threads_active[SRV_WORKER]; @@ -3137,15 +3126,13 @@ srv_purge_thread( || (n_total_purged == 0 && retries >= TRX_SYS_N_RSEGS)) { - os_event_t event; - mutex_enter(&kernel_mutex); - event = srv_suspend_thread(); + srv_suspend_thread(slot); mutex_exit(&kernel_mutex); - os_event_wait(event); + os_event_wait(slot->event); retries = 0; } @@ -3179,16 +3166,11 @@ srv_purge_thread( mutex_enter(&kernel_mutex); - ut_ad(srv_table_get_nth_slot(slot_no) == slot); - /* Decrement the active count. */ - srv_suspend_thread(); + srv_suspend_thread(slot); slot->in_use = FALSE; - /* Free the thread local memory. */ - thr_local_free(os_thread_get_curr_id()); - mutex_exit(&kernel_mutex); #ifdef UNIV_DEBUG_THREAD_CREATION 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/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index 3ecbce72ebd..30caddccced 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -40,6 +40,7 @@ Created 9/5/1995 Heikki Tuuri #include "os0sync.h" #include "os0file.h" #include "srv0srv.h" +#include "ha_prototypes.h" /* WAIT ARRAY @@ -478,8 +479,8 @@ sync_array_cell_print( fprintf(file, "--Thread %lu has waited at %s line %lu" " for %.2f seconds the semaphore:\n", - (ulong) os_thread_pf(cell->thread), cell->file, - (ulong) cell->line, + (ulong) os_thread_pf(cell->thread), + innobase_basename(cell->file), (ulong) cell->line, difftime(time(NULL), cell->reservation_time)); if (type == SYNC_MUTEX) { @@ -493,7 +494,8 @@ sync_array_cell_print( "Last time reserved in file %s line %lu, " #endif /* UNIV_SYNC_DEBUG */ "waiters flag %lu\n", - (void*) mutex, mutex->cfile_name, (ulong) mutex->cline, + (void*) mutex, innobase_basename(mutex->cfile_name), + (ulong) mutex->cline, (ulong) mutex->lock_word, #ifdef UNIV_SYNC_DEBUG mutex->file_name, (ulong) mutex->line, @@ -512,7 +514,7 @@ sync_array_cell_print( fprintf(file, " RW-latch at %p created in file %s line %lu\n", - (void*) rwlock, rwlock->cfile_name, + (void*) rwlock, innobase_basename(rwlock->cfile_name), (ulong) rwlock->cline); writer = rw_lock_get_writer(rwlock); if (writer != RW_LOCK_NOT_LOCKED) { @@ -533,7 +535,7 @@ sync_array_cell_print( (ulong) rw_lock_get_reader_count(rwlock), (ulong) rwlock->waiters, rwlock->lock_word, - rwlock->last_s_file_name, + innobase_basename(rwlock->last_s_file_name), (ulong) rwlock->last_s_line, rwlock->last_x_file_name, (ulong) rwlock->last_x_line); @@ -913,8 +915,10 @@ Prints warnings of long semaphore waits to stderr. @return TRUE if fatal semaphore wait threshold was exceeded */ UNIV_INTERN ibool -sync_array_print_long_waits(void) -/*=============================*/ +sync_array_print_long_waits( +/*========================*/ + os_thread_id_t* waiter, /*!< out: longest waiting thread */ + const void** sema) /*!< out: longest-waited-for semaphore */ { sync_cell_t* cell; ibool old_val; @@ -922,6 +926,7 @@ sync_array_print_long_waits(void) ulint i; ulint fatal_timeout = srv_fatal_semaphore_wait_threshold; ibool fatal = FALSE; + double longest_diff = 0; #ifdef UNIV_DEBUG_VALGRIND /* Increase the timeouts if running under valgrind because it executes @@ -937,22 +942,36 @@ sync_array_print_long_waits(void) for (i = 0; i < sync_primary_wait_array->n_cells; i++) { + double diff; + void* wait_object; + cell = sync_array_get_nth_cell(sync_primary_wait_array, i); - if (cell->wait_object != NULL && cell->waiting - && difftime(time(NULL), cell->reservation_time) - > SYNC_ARRAY_TIMEOUT) { + wait_object = cell->wait_object; + + if (wait_object == NULL || !cell->waiting) { + + continue; + } + + diff = difftime(time(NULL), cell->reservation_time); + + if (diff > SYNC_ARRAY_TIMEOUT) { fputs("InnoDB: Warning: a long semaphore wait:\n", stderr); sync_array_cell_print(stderr, cell); noticed = TRUE; } - if (cell->wait_object != NULL && cell->waiting - && difftime(time(NULL), cell->reservation_time) - > fatal_timeout) { + if (diff > fatal_timeout) { fatal = TRUE; } + + if (diff > longest_diff) { + longest_diff = diff; + *sema = wait_object; + *waiter = cell->thread; + } } if (noticed) { diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index 73d1e3aa46e..397d505df50 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -39,6 +39,7 @@ Created 9/11/1995 Heikki Tuuri #include "mem0mem.h" #include "srv0srv.h" #include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */ +#include "ha_prototypes.h" /* IMPLEMENTATION OF THE RW_LOCK @@ -407,7 +408,8 @@ lock_loop: " cfile %s cline %lu rnds %lu\n", (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) lock, - lock->cfile_name, (ulong) lock->cline, (ulong) i); + innobase_basename(lock->cfile_name), + (ulong) lock->cline, (ulong) i); } /* We try once again to obtain the lock */ @@ -442,7 +444,8 @@ lock_loop: "Thread %lu OS wait rw-s-lock at %p" " cfile %s cline %lu\n", os_thread_pf(os_thread_get_curr_id()), - (void*) lock, lock->cfile_name, + (void*) lock, + innobase_basename(lock->cfile_name), (ulong) lock->cline); } @@ -664,7 +667,8 @@ lock_loop: "Thread %lu spin wait rw-x-lock at %p" " cfile %s cline %lu rnds %lu\n", os_thread_pf(os_thread_get_curr_id()), (void*) lock, - lock->cfile_name, (ulong) lock->cline, (ulong) i); + innobase_basename(lock->cfile_name), + (ulong) lock->cline, (ulong) i); } sync_array_reserve_cell(sync_primary_wait_array, @@ -687,7 +691,8 @@ lock_loop: "Thread %lu OS wait for rw-x-lock at %p" " cfile %s cline %lu\n", os_thread_pf(os_thread_get_curr_id()), (void*) lock, - lock->cfile_name, (ulong) lock->cline); + innobase_basename(lock->cfile_name), + (ulong) lock->cline); } /* these stats may not be accurate */ diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 0f6a60ca260..23fd64cc5ed 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -43,6 +43,7 @@ Created 9/5/1995 Heikki Tuuri #ifdef UNIV_SYNC_DEBUG # include "srv0start.h" /* srv_is_being_started */ #endif /* UNIV_SYNC_DEBUG */ +#include "ha_prototypes.h" /* REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX @@ -543,7 +544,8 @@ spin_loop: "Thread %lu spin wait mutex at %p" " cfile %s cline %lu rnds %lu\n", (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex, - mutex->cfile_name, (ulong) mutex->cline, (ulong) i); + innobase_basename(mutex->cfile_name), + (ulong) mutex->cline, (ulong) i); #endif mutex_spin_round_count += i; @@ -620,7 +622,8 @@ spin_loop: fprintf(stderr, "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n", (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex, - mutex->cfile_name, (ulong) mutex->cline, (ulong) i); + innobase_basename(mutex->cfile_name), + (ulong) mutex->cline, (ulong) i); #endif mutex_os_wait_count++; @@ -869,7 +872,8 @@ sync_print_warning( if (mutex->magic_n == MUTEX_MAGIC_N) { fprintf(stderr, "Mutex created at %s %lu\n", - mutex->cfile_name, (ulong) mutex->cline); + innobase_basename(mutex->cfile_name), + (ulong) mutex->cline); if (mutex_get_lock_word(mutex) != 0) { ulint line; diff --git a/storage/innobase/thr/thr0loc.c b/storage/innobase/thr/thr0loc.c deleted file mode 100644 index b7364afa166..00000000000 --- a/storage/innobase/thr/thr0loc.c +++ /dev/null @@ -1,287 +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 */ - ulint slot_no;/*!< the index of the slot in the thread table - for this 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->slot_no == ULINT_UNDEFINED - || local->slot_no < OS_THREAD_MAX_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); -} - -/*******************************************************************//** -Gets the slot number in the thread table of a thread. -@return slot number */ -UNIV_INTERN -ulint -thr_local_get_slot_no( -/*==================*/ - os_thread_id_t id) /*!< in: thread id of the thread */ -{ - ulint slot_no; - thr_local_t* local; - - mutex_enter(&thr_local_mutex); - - local = thr_local_get(id); - - slot_no = local->slot_no; - - mutex_exit(&thr_local_mutex); - - return(slot_no); -} - -/*******************************************************************//** -Sets the slot number in the thread table of a thread. */ -UNIV_INTERN -void -thr_local_set_slot_no( -/*==================*/ - os_thread_id_t id, /*!< in: thread id of the thread */ - ulint slot_no)/*!< in: slot number */ -{ - thr_local_t* local; - - mutex_enter(&thr_local_mutex); - - local = thr_local_get(id); - - local->slot_no = slot_no; - - mutex_exit(&thr_local_mutex); -} - -/*******************************************************************//** -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->slot_no = ULINT_UNDEFINED; - 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/trx0i_s.c b/storage/innobase/trx/trx0i_s.c index aff49e20726..c18b747da6d 100644 --- a/storage/innobase/trx/trx0i_s.c +++ b/storage/innobase/trx/trx0i_s.c @@ -518,7 +518,7 @@ fill_trx_row( query[stmt_len] = '\0'; row->trx_query = ha_storage_put_memlim( - cache->storage, stmt, stmt_len + 1, + cache->storage, query, stmt_len + 1, MAX_ALLOWED_FOR_STORAGE(cache)); row->trx_query_cs = innobase_get_charset(trx->mysql_thd); 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" diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c index 42ad8c03762..64fadd76d1c 100644 --- a/storage/innobase/ut/ut0dbg.c +++ b/storage/innobase/ut/ut0dbg.c @@ -25,6 +25,7 @@ Created 1/30/1994 Heikki Tuuri #include "univ.i" #include "ut0dbg.h" +#include "ha_prototypes.h" #if defined(__GNUC__) && (__GNUC__ > 2) #else @@ -55,12 +56,13 @@ ut_dbg_assertion_failed( ut_print_timestamp(stderr); #ifdef UNIV_HOTBACKUP fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n", - file, line); + innobase_basename(file), line); #else /* UNIV_HOTBACKUP */ fprintf(stderr, " InnoDB: Assertion failure in thread %lu" " in file %s line %lu\n", - os_thread_pf(os_thread_get_curr_id()), file, line); + os_thread_pf(os_thread_get_curr_id()), + innobase_basename(file), line); #endif /* UNIV_HOTBACKUP */ if (expr) { fprintf(stderr, @@ -93,7 +95,8 @@ ut_dbg_stop_thread( { #ifndef UNIV_HOTBACKUP fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n", - os_thread_pf(os_thread_get_curr_id()), file, line); + os_thread_pf(os_thread_get_curr_id()), + innobase_basename(file), line); os_thread_sleep(1000000000); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c index e8d81cbbbb1..a9814af220b 100644 --- a/storage/myisam/ft_stopwords.c +++ b/storage/myisam/ft_stopwords.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2005 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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 @@ -16,7 +16,7 @@ /* Written by Sergei A. Golubchik, who has a shared copyright to this code */ #include "ftdefs.h" -#include "my_handler.h" +#include "my_compare.h" static CHARSET_INFO *ft_stopword_cs= NULL; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index c7b6b2239ce..16457088f9c 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -639,7 +639,7 @@ ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg) HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS | HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | - HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT), + HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT | HA_CAN_REPAIR), can_enable_indexes(1) {} diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 5d8a7c3daef..af50ac27c96 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -80,6 +80,7 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks, uint buffer_length); static ha_checksum mi_byte_checksum(const uchar *buf, uint length); static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share); +static HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a); void myisamchk_init(MI_CHECK *param) { @@ -4729,3 +4730,92 @@ set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share) share->delete_record=tmp.delete_record; } } + +/* + Find the first NULL value in index-suffix values tuple + + SYNOPSIS + ha_find_null() + keyseg Array of keyparts for key suffix + a Key suffix value tuple + + DESCRIPTION + Find the first NULL value in index-suffix values tuple. + + TODO + Consider optimizing this function or its use so we don't search for + NULL values in completely NOT NULL index suffixes. + + RETURN + First key part that has NULL as value in values tuple, or the last key + part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain + NULLs. +*/ + +static HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a) +{ + for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++) + { + uchar *end; + if (keyseg->null_bit) + { + if (!*a++) + return keyseg; + } + end= a+ keyseg->length; + + switch ((enum ha_base_keytype) keyseg->type) { + case HA_KEYTYPE_TEXT: + case HA_KEYTYPE_BINARY: + case HA_KEYTYPE_BIT: + if (keyseg->flag & HA_SPACE_PACK) + { + int a_length; + get_key_length(a_length, a); + a += a_length; + break; + } + else + a= end; + break; + case HA_KEYTYPE_VARTEXT1: + case HA_KEYTYPE_VARTEXT2: + case HA_KEYTYPE_VARBINARY1: + case HA_KEYTYPE_VARBINARY2: + { + int a_length; + get_key_length(a_length, a); + a+= a_length; + break; + } + case HA_KEYTYPE_NUM: + if (keyseg->flag & HA_SPACE_PACK) + { + int alength= *a++; + end= a+alength; + } + a= end; + break; + case HA_KEYTYPE_INT8: + case HA_KEYTYPE_SHORT_INT: + case HA_KEYTYPE_USHORT_INT: + case HA_KEYTYPE_LONG_INT: + case HA_KEYTYPE_ULONG_INT: + case HA_KEYTYPE_INT24: + case HA_KEYTYPE_UINT24: +#ifdef HAVE_LONG_LONG + case HA_KEYTYPE_LONGLONG: + case HA_KEYTYPE_ULONGLONG: +#endif + case HA_KEYTYPE_FLOAT: + case HA_KEYTYPE_DOUBLE: + a= end; + break; + case HA_KEYTYPE_END: /* purecov: inspected */ + /* keep compiler happy */ + DBUG_ASSERT(0); + break; + } + } + return keyseg; +} diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 35b68fe00df..d56f1e18930 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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 @@ -673,7 +673,8 @@ get_one_option(int optid, int method; enum_mi_stats_method UNINIT_VAR(method_conv); myisam_stats_method_str= argument; - if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) + if ((method= find_type(argument, &myisam_stats_method_typelib, + FIND_TYPE_BASIC)) <= 0) { fprintf(stderr, "Invalid value of stats_method: %s.\n", argument); exit(1); diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index c545aff912f..533e5d13cdd 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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 @@ -77,7 +77,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { if (!strncmp(buff+1,"INSERT_METHOD=",14)) { /* Lookup insert method */ - int tmp=find_type(buff+15,&merge_insert_method,2); + int tmp= find_type(buff + 15, &merge_insert_method, FIND_TYPE_BASIC); found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); } continue; /* Skip comments */ @@ -271,7 +271,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, { /* Compare buffer with global methods list: merge_insert_method. */ insert_method= find_type(child_name_buff + 15, - &merge_insert_method, 2); + &merge_insert_method, FIND_TYPE_BASIC); } continue; } diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc index 20e736a546f..46e02306aca 100644 --- a/storage/perfschema/unittest/pfs-t.cc +++ b/storage/perfschema/unittest/pfs-t.cc @@ -1205,6 +1205,8 @@ void test_enabled() void do_all_tests() { + /* Using initialize_performance_schema(), no partial init needed. */ + test_bootstrap(); test_bad_registration(); test_init_disabled(); diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc index 13335326932..a00afe8b36a 100644 --- a/storage/perfschema/unittest/pfs_instr-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc @@ -199,7 +199,11 @@ void test_oom() void do_all_tests() { + PFS_atomic::init(); + test_oom(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc index 2ef9a5769ca..b13135aa615 100644 --- a/storage/perfschema/unittest/pfs_instr-t.cc +++ b/storage/perfschema/unittest/pfs_instr-t.cc @@ -400,10 +400,14 @@ void test_per_thread_wait() void do_all_tests() { + PFS_atomic::init(); + test_no_instruments(); test_no_instances(); test_with_instances(); test_per_thread_wait(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc index 9ccaf432ba2..95dccc420d7 100644 --- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc @@ -47,7 +47,11 @@ void test_oom() void do_all_tests() { + PFS_atomic::init(); + test_oom(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc index f9a1ee510b1..ac34f082fe8 100644 --- a/storage/perfschema/unittest/pfs_instr_class-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-t.cc @@ -554,6 +554,8 @@ void test_instruments_reset() void do_all_tests() { + PFS_atomic::init(); + test_no_registration(); test_mutex_registration(); test_rwlock_registration(); @@ -562,6 +564,8 @@ void do_all_tests() test_file_registration(); test_table_registration(); test_instruments_reset(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc index d8663c5ccda..69b554c7b31 100644 --- a/storage/perfschema/unittest/pfs_timer-t.cc +++ b/storage/perfschema/unittest/pfs_timer-t.cc @@ -105,7 +105,11 @@ void test_timers() void do_all_tests() { + PFS_atomic::init(); + test_timers(); + + PFS_atomic::cleanup(); } int main(int, char **) |