diff options
Diffstat (limited to 'storage/innobase')
30 files changed, 335 insertions, 377 deletions
diff --git a/storage/innobase/.clang-format b/storage/innobase/.clang-format new file mode 100644 index 00000000000..54f7b47bc88 --- /dev/null +++ b/storage/innobase/.clang-format @@ -0,0 +1,11 @@ +UseTab: Always +TabWidth: 8 +IndentWidth: 8 +ContinuationIndentWidth: 8 +BreakBeforeBinaryOperators: All +PointerAlignment: Left +BreakBeforeBraces: Custom +ColumnLimit: 79 +BraceWrapping: + AfterFunction: true +AccessModifierOffset: -8 diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index f2ad31f3a5d..387dad8dca1 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -51,7 +51,7 @@ PageBulk::init() m_heap = mem_heap_create(1000); m_mtr.start(); - mtr_x_lock(&m_index->lock, &m_mtr); + if (m_flush_observer) { m_mtr.set_log_mode(MTR_LOG_NO_REDO); m_mtr.set_flush_observer(m_flush_observer); @@ -607,22 +607,20 @@ PageBulk::storeExt( btr_pcur.pos_state = BTR_PCUR_IS_POSITIONED; btr_pcur.latch_mode = BTR_MODIFY_LEAF; btr_pcur.btr_cur.index = m_index; - - page_cur_t* page_cur = &btr_pcur.btr_cur.page_cur; - page_cur->index = m_index; - page_cur->rec = m_cur_rec; - page_cur->offsets = offsets; - page_cur->block = m_block; + btr_pcur.btr_cur.page_cur.index = m_index; + btr_pcur.btr_cur.page_cur.rec = m_cur_rec; + btr_pcur.btr_cur.page_cur.offsets = offsets; + btr_pcur.btr_cur.page_cur.block = m_block; dberr_t err = btr_store_big_rec_extern_fields( &btr_pcur, offsets, big_rec, &m_mtr, BTR_STORE_INSERT_BULK); - ut_ad(page_offset(m_cur_rec) == page_offset(page_cur->rec)); - /* Reset m_block and m_cur_rec from page cursor, because - block may be changed during blob insert. */ - m_block = page_cur->block; - m_cur_rec = page_cur->rec; + block may be changed during blob insert. (FIXME: Can it really?) */ + ut_ad(m_block == btr_pcur.btr_cur.page_cur.block); + + m_block = btr_pcur.btr_cur.page_cur.block; + m_cur_rec = btr_pcur.btr_cur.page_cur.rec; m_page = buf_block_get_frame(m_block); return(err); @@ -649,7 +647,7 @@ dberr_t PageBulk::latch() { m_mtr.start(); - mtr_x_lock(&m_index->lock, &m_mtr); + if (m_flush_observer) { m_mtr.set_log_mode(MTR_LOG_NO_REDO); m_mtr.set_flush_observer(m_flush_observer); @@ -754,6 +752,10 @@ BtrBulk::pageCommit( page_bulk->setNext(FIL_NULL); } + ut_ad(!rw_lock_own_flagged(&m_index->lock, + RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX + | RW_LOCK_FLAG_S)); + /* Compress page if it's a compressed table. */ if (page_bulk->getPageZip() != NULL && !page_bulk->compress()) { return(pageSplit(page_bulk, next_page_bulk)); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index a1019e19cf6..8fc30796228 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -7415,7 +7415,7 @@ struct btr_blob_log_check_t { ulint page_no = ULINT_UNDEFINED; FlushObserver* observer = m_mtr->get_flush_observer(); - if (m_op == BTR_STORE_INSERT_BULK) { + if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) { offs = page_offset(*m_rec); page_no = page_get_page_no( buf_block_get_frame(*m_block)); @@ -7438,8 +7438,7 @@ struct btr_blob_log_check_t { index->set_modified(*m_mtr); m_mtr->set_flush_observer(observer); - if (m_op == BTR_STORE_INSERT_BULK) { - mtr_x_lock(dict_index_get_lock(index), m_mtr); + if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) { m_pcur->btr_cur.page_cur.block = btr_block_get( *index, page_no, RW_X_LATCH, false, m_mtr); m_pcur->btr_cur.page_cur.rec @@ -7466,9 +7465,10 @@ struct btr_blob_log_check_t { *m_rec, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); - ut_ad(mtr_memo_contains_flagged(m_mtr, - dict_index_get_lock(index), - MTR_MEMO_SX_LOCK | MTR_MEMO_X_LOCK)); + ut_ad((m_op == BTR_STORE_INSERT_BULK) + == !mtr_memo_contains_flagged(m_mtr, &index->lock, + MTR_MEMO_SX_LOCK + | MTR_MEMO_X_LOCK)); } }; @@ -7522,8 +7522,10 @@ btr_store_big_rec_extern_fields( ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_any_extern(offsets)); - ut_ad(mtr_memo_contains_flagged(btr_mtr, dict_index_get_lock(index), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); + ut_ad(op == BTR_STORE_INSERT_BULK + || mtr_memo_contains_flagged(btr_mtr, &index->lock, + MTR_MEMO_X_LOCK + | MTR_MEMO_SX_LOCK)); ut_ad(mtr_memo_contains(btr_mtr, rec_block, MTR_MEMO_PAGE_X_FIX)); ut_ad(buf_block_get_frame(rec_block) == page_align(rec)); ut_a(dict_index_is_clust(index)); @@ -7643,7 +7645,7 @@ btr_store_big_rec_extern_fields( mtr_t *alloc_mtr; - if (op == BTR_STORE_INSERT_BULK) { + if (UNIV_UNLIKELY(op == BTR_STORE_INSERT_BULK)) { mtr_bulk.start(); mtr_bulk.set_spaces(mtr); alloc_mtr = &mtr_bulk; @@ -7666,7 +7668,7 @@ btr_store_big_rec_extern_fields( index->table->space->release_free_extents(r_extents); - if (op == BTR_STORE_INSERT_BULK) { + if (UNIV_UNLIKELY(op == BTR_STORE_INSERT_BULK)) { mtr_bulk.commit(); } @@ -7826,7 +7828,7 @@ btr_store_big_rec_extern_fields( } /* We compress a page when finish bulk insert.*/ - if (op != BTR_STORE_INSERT_BULK) { + if (UNIV_LIKELY(op != BTR_STORE_INSERT_BULK)) { page_zip_write_blob_ptr( page_zip, rec, index, offsets, field_no, &mtr); diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index fcaf4b0ab3b..df4786a7e20 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -43,8 +43,7 @@ Created 4/24/1996 Heikki Tuuri #include "rem0cmp.h" #include "srv0start.h" #include "srv0srv.h" -#include <stack> -#include <set> +#include "fts0opt.h" /** Following are the InnoDB system tables. The positions in this array are referenced by enum dict_system_table_id. */ @@ -3079,8 +3078,12 @@ func_exit: FTS */ fts_optimize_remove_table(table); fts_free(table); - } else { + } else if (fts_optimize_wq) { fts_optimize_add_table(table); + } else { + /* fts_optimize_thread is not started yet. + So make the table as non-evictable from cache. */ + dict_sys.prevent_eviction(table); } } diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 3f2f25f2485..db9c747a3b9 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1987,8 +1987,6 @@ fil_crypt_rotate_page( return; } - ut_d(const bool was_free = fseg_page_is_free(space, (uint32_t)offset)); - mtr_t mtr; mtr.start(); if (buf_block_t* block = fil_crypt_get_page_throttle(state, @@ -2003,9 +2001,9 @@ fil_crypt_rotate_page( if (space->is_stopping()) { /* The tablespace is closing (in DROP TABLE or TRUNCATE TABLE or similar): avoid further access */ - } else if (!*reinterpret_cast<uint32_t*>(FIL_PAGE_OFFSET - + frame)) { - /* It looks like this page was never + } else if (!kv && !*reinterpret_cast<uint16_t*> + (&frame[FIL_PAGE_TYPE])) { + /* It looks like this page is not allocated. Because key rotation is accessing pages in a pattern that is unlike the normal B-tree and undo log access pattern, we cannot @@ -2015,9 +2013,20 @@ fil_crypt_rotate_page( tablespace latch before acquiring block->lock, then the fseg_page_is_free() information could be stale already. */ - ut_ad(was_free); - ut_ad(kv == 0); - ut_ad(page_get_space_id(frame) == 0); + + /* If the data file was originally created + before MariaDB 10.0 or MySQL 5.6, some + allocated data pages could carry 0 in + FIL_PAGE_TYPE. The FIL_PAGE_TYPE on those + pages will be updated in + buf_flush_init_for_writing() when the page + is modified the next time. + + Also, when the doublewrite buffer pages are + allocated on bootstrap in a non-debug build, + some dummy pages will be allocated, with 0 in + the FIL_PAGE_TYPE. Those pages should be + skipped from key rotation forever. */ } else if (fil_crypt_needs_rotation( crypt_data, kv, diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index c248726913a..79307c36b01 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2685,6 +2685,10 @@ retry: } if (read_only) { + /* InnoDB stores actual synced_doc_id value + 1 in + FTS_CONFIG table. Reduce the value by 1 while reading + after startup. */ + if (*doc_id) *doc_id -= 1; goto func_exit; } @@ -5316,11 +5320,11 @@ fts_t::fts_t( const dict_table_t* table, mem_heap_t* heap) : - in_queue(0), added_synced(0), dict_locked(0), + added_synced(0), dict_locked(0), bg_threads(0), add_wq(NULL), cache(NULL), - doc_col(ULINT_UNDEFINED), + doc_col(ULINT_UNDEFINED), in_queue(false), fts_heap(heap) { ut_a(table->fts == NULL); diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index a7204974f84..d21107b4728 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -35,9 +35,10 @@ Completed 2011/7/10 Sunny and Jimmy Yang #include "srv0start.h" #include "ut0list.h" #include "zlib.h" +#include "fts0opt.h" /** The FTS optimize thread's work queue. */ -static ib_wqueue_t* fts_optimize_wq; +ib_wqueue_t* fts_optimize_wq; /** The FTS vector to store fts_slot_t */ static ib_vector_t* fts_slots; @@ -168,8 +169,8 @@ struct fts_encode_t { /** We use this information to determine when to start the optimize cycle for a table. */ struct fts_slot_t { - /** table identifier, or 0 if the slot is empty */ - table_id_t table_id; + /** table, or NULL if the slot is unused */ + dict_table_t* table; /** whether this slot is being processed */ bool running; @@ -2391,14 +2392,7 @@ fts_optimize_table_bk( return(DB_SUCCESS); } - dict_table_t* table = dict_table_open_on_id( - slot->table_id, FALSE, DICT_TABLE_OP_NORMAL); - - if (!table) { - slot->last_run = now; - return DB_SUCCESS; - } - + dict_table_t* table = slot->table; dberr_t error; if (fil_table_accessible(table) @@ -2418,8 +2412,6 @@ fts_optimize_table_bk( error = DB_SUCCESS; } - dict_table_close(table, FALSE, FALSE); - return(error); } /*********************************************************************//** @@ -2564,11 +2556,13 @@ void fts_optimize_add_table(dict_table_t* table) msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table); - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + mutex_enter(&fts_optimize_wq->mutex); + + ib_wqueue_add(fts_optimize_wq, msg, msg->heap, true); - mutex_enter(&table->fts->bg_threads_mutex); table->fts->in_queue = true; - mutex_exit(&table->fts->bg_threads_mutex); + + mutex_exit(&fts_optimize_wq->mutex); } /**********************************************************************//** @@ -2595,12 +2589,10 @@ fts_optimize_remove_table( return; } - fts_t* fts = table->fts; - mutex_enter(&fts->bg_threads_mutex); - bool is_in_optimize_queue = fts->in_queue; - mutex_exit(&fts->bg_threads_mutex); + mutex_enter(&fts_optimize_wq->mutex); - if (!is_in_optimize_queue) { + if (!table->fts->in_queue) { + mutex_exit(&fts_optimize_wq->mutex); return; } @@ -2616,15 +2608,17 @@ fts_optimize_remove_table( remove->event = event; msg->ptr = remove; - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + ib_wqueue_add(fts_optimize_wq, msg, msg->heap, true); + + mutex_exit(&fts_optimize_wq->mutex); os_event_wait(event); os_event_destroy(event); - mutex_enter(&fts->bg_threads_mutex); - fts->in_queue = false; - mutex_exit(&fts->bg_threads_mutex); + ut_d(mutex_enter(&fts_optimize_wq->mutex)); + ut_ad(!table->fts->in_queue); + ut_d(mutex_exit(&fts_optimize_wq->mutex)); } /** Send sync fts cache for the table. @@ -2633,9 +2627,6 @@ void fts_optimize_request_sync_table( dict_table_t* table) { - fts_msg_t* msg; - table_id_t* table_id; - /* if the optimize system not yet initialized, return */ if (!fts_optimize_wq) { return; @@ -2648,39 +2639,36 @@ fts_optimize_request_sync_table( return; } - msg = fts_optimize_create_msg(FTS_MSG_SYNC_TABLE, NULL); + fts_msg_t* msg = fts_optimize_create_msg(FTS_MSG_SYNC_TABLE, table); - table_id = static_cast<table_id_t*>( - mem_heap_alloc(msg->heap, sizeof(table_id_t))); - *table_id = table->id; - msg->ptr = table_id; + mutex_enter(&fts_optimize_wq->mutex); - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + ib_wqueue_add(fts_optimize_wq, msg, msg->heap, true); - mutex_enter(&table->fts->bg_threads_mutex); table->fts->in_queue = true; - mutex_exit(&table->fts->bg_threads_mutex); + + mutex_exit(&fts_optimize_wq->mutex); } /** Add a table to fts_slots if it doesn't already exist. */ static bool fts_optimize_new_table(dict_table_t* table) { + ut_ad(table); + ulint i; fts_slot_t* slot; fts_slot_t* empty = NULL; - const table_id_t table_id = table->id; - ut_ad(table_id); /* Search for duplicates, also find a free slot if one exists. */ for (i = 0; i < ib_vector_size(fts_slots); ++i) { slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i)); - if (!slot->table_id) { + if (!slot->table) { empty = slot; - } else if (slot->table_id == table_id) { + } else if (slot->table == table) { /* Already exists in our optimize queue. */ - return(FALSE); + return false; } } @@ -2689,36 +2677,35 @@ static bool fts_optimize_new_table(dict_table_t* table) memset(slot, 0x0, sizeof(*slot)); - slot->table_id = table->id; - slot->running = false; - - return(TRUE); + slot->table = table; + return true; } /** Remove a table from fts_slots if it exists. @param[in,out] table table to be removed from fts_slots */ static bool fts_optimize_del_table(const dict_table_t* table) { - const table_id_t table_id = table->id; - ut_ad(table_id); - + ut_ad(table); for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { fts_slot_t* slot; slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i)); - if (slot->table_id == table_id) { + if (slot->table == table) { if (fts_enable_diag_print) { ib::info() << "FTS Optimize Removing table " << table->name; } - slot->table_id = 0; - return(TRUE); + mutex_enter(&fts_optimize_wq->mutex); + slot->table->fts->in_queue = false; + mutex_exit(&fts_optimize_wq->mutex); + slot->table = NULL; + return true; } } - return(FALSE); + return false; } /**********************************************************************//** @@ -2732,7 +2719,7 @@ static ulint fts_optimize_how_many() for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( ib_vector_get_const(fts_slots, i)); - if (slot->table_id == 0) { + if (!slot->table) { continue; } @@ -2768,22 +2755,14 @@ static bool fts_is_sync_needed() const fts_slot_t* slot = static_cast<const fts_slot_t*>( ib_vector_get_const(fts_slots, i)); - if (slot->table_id == 0) { - continue; - } - - dict_table_t* table = dict_table_open_on_id( - slot->table_id, FALSE, DICT_TABLE_OP_NORMAL); - if (!table) { + if (!slot->table) { continue; } - if (table->fts && table->fts->cache) { - total_memory += table->fts->cache->total_size; + if (slot->table->fts && slot->table->fts->cache) { + total_memory += slot->table->fts->cache->total_size; } - dict_table_close(table, FALSE, FALSE); - if (total_memory > fts_max_total_cache_size) { return(true); } @@ -2793,22 +2772,14 @@ static bool fts_is_sync_needed() } /** Sync fts cache of a table -@param[in] table_id table id */ -static void fts_optimize_sync_table(table_id_t table_id) +@param[in,out] table table to be synced */ +static void fts_optimize_sync_table(dict_table_t* table) { - if (dict_table_t* table = dict_table_open_on_id( - table_id, FALSE, DICT_TABLE_OP_NORMAL)) { - if (fil_table_accessible(table) - && table->fts && table->fts->cache) { - fts_sync_table(table, false); - } - - DBUG_EXECUTE_IF( - "ib_optimize_wq_hang", - os_thread_sleep(6000000);); - - dict_table_close(table, FALSE, FALSE); + if (table->fts && table->fts->cache && fil_table_accessible(table)) { + fts_sync_table(table, false); } + + DBUG_EXECUTE_IF("ib_optimize_wq_hang", os_thread_sleep(6000000);); } /**********************************************************************//** @@ -2847,7 +2818,7 @@ DECLARE_THREAD(fts_optimize_thread)( ib_vector_get(fts_slots, current)); /* Handle the case of empty slots. */ - if (slot->table_id) { + if (slot->table) { slot->running = true; fts_optimize_table_bk(slot); } @@ -2906,7 +2877,7 @@ DECLARE_THREAD(fts_optimize_thread)( os_thread_sleep(300000);); fts_optimize_sync_table( - *static_cast<table_id_t*>(msg->ptr)); + static_cast<dict_table_t*>(msg->ptr)); break; default: @@ -2925,8 +2896,8 @@ DECLARE_THREAD(fts_optimize_thread)( fts_slot_t* slot = static_cast<fts_slot_t*>( ib_vector_get(fts_slots, i)); - if (table_id_t table_id = slot->table_id) { - fts_optimize_sync_table(table_id); + if (slot->table) { + fts_optimize_sync_table(slot->table); } } } @@ -2954,7 +2925,6 @@ fts_optimize_init(void) { mem_heap_t* heap; ib_alloc_t* heap_alloc; - dict_table_t* table; ut_ad(!srv_read_only_mode); @@ -2970,31 +2940,25 @@ fts_optimize_init(void) heap_alloc = ib_heap_allocator_create(heap); fts_slots = ib_vector_create(heap_alloc, sizeof(fts_slot_t), 4); - /* Add fts tables to the fts_slots vector which were skipped during restart */ - std::vector<dict_table_t*> table_vector; - std::vector<dict_table_t*>::iterator it; - + /* Add fts tables to fts_slots which could be skipped + during dict_load_table_one() because fts_optimize_thread + wasn't even started. */ mutex_enter(&dict_sys.mutex); - for (table = UT_LIST_GET_FIRST(dict_sys.table_LRU); - table != NULL; - table = UT_LIST_GET_NEXT(table_LRU, table)) { - if (table->fts && - dict_table_has_fts_index(table)) { - if (fts_optimize_new_table(table)){ - table_vector.push_back(table); - } + for (dict_table_t* table = UT_LIST_GET_FIRST(dict_sys.table_LRU); + table != NULL; + table = UT_LIST_GET_NEXT(table_LRU, table)) { + if (!table->fts || !dict_table_has_fts_index(table)) { + continue; } - } - /* It is better to call dict_table_prevent_eviction() - outside the above loop because it operates on - dict_sys.table_LRU list.*/ - for (it=table_vector.begin();it!=table_vector.end();++it) { - dict_table_prevent_eviction(*it); + /* fts_optimize_thread is not started yet. So there is no + need to acquire fts_optimize_wq->mutex for adding the fts + table to the fts slots. */ + ut_ad(!table->can_be_evicted); + fts_optimize_new_table(table); + table->fts->in_queue = true; } - mutex_exit(&dict_sys.mutex); - table_vector.clear(); fts_opt_shutdown_event = os_event_create(0); last_check_sync_time = time(NULL); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2e5b3c50a87..90d2d904c0f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2464,11 +2464,10 @@ innobase_next_autoinc( if (next_value == 0) { ulonglong next; - if (current >= offset) { + if (current > offset) { next = (current - offset) / step; } else { - next = 0; - block -= step; + next = (offset - current) / step; } ut_a(max_value > next); @@ -16221,7 +16220,7 @@ ha_innobase::get_auto_increment( if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE && autoinc < col_max_value) { - ulonglong prev_auto_inc = autoinc; + ulonglong prev_auto_inc = autoinc; autoinc = ((autoinc - 1) + increment - offset)/ increment; @@ -16275,27 +16274,6 @@ ha_innobase::get_auto_increment( current = *first_value; - if (m_prebuilt->autoinc_increment != increment) { - - WSREP_DEBUG("autoinc decrease: %llu -> %llu\n" - "THD: %ld, current: %llu, autoinc: %llu", - m_prebuilt->autoinc_increment, - increment, - thd_get_thread_id(m_user_thd), - current, autoinc); - if (!wsrep_on(m_user_thd)) { - current = autoinc - - m_prebuilt->autoinc_increment; - current = innobase_next_autoinc( - current, 1, increment, offset, col_max_value); - } - - dict_table_autoinc_initialize( - m_prebuilt->table, current); - - *first_value = current; - } - /* Compute the last value in the interval */ next_value = innobase_next_autoinc( current, *nb_reserved_values, increment, offset, @@ -19255,6 +19233,11 @@ static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method, NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib); #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_BOOL(change_buffer_dump, ibuf_dump, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Dump the change buffer at startup.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, PLUGIN_VAR_RQCMDARG, "Debug flags for InnoDB change buffering (0=none, 1=try to buffer)", @@ -19729,6 +19712,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(change_buffering), MYSQL_SYSVAR(change_buffer_max_size), #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffer_dump), MYSQL_SYSVAR(change_buffering_debug), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ #ifdef WITH_INNODB_DISALLOW_WRITES diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cffbf692fe7..565171529af 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -8789,25 +8789,21 @@ innobase_drop_foreign_try( } /** Rename a column in the data dictionary tables. -@param[in] user_table InnoDB table that was being altered -@param[in] trx Data dictionary transaction +@param[in] ctx ALTER TABLE context +@param[in,out] trx Data dictionary transaction @param[in] table_name Table name in MySQL @param[in] from old column name @param[in] to new column name -@param[in] new_clustered whether the table has been rebuilt -@param[in] evict_fk_cache Evict the fk info from cache @retval true Failure @retval false Success */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_rename_column_try( - const dict_table_t* user_table, - trx_t* trx, - const char* table_name, - const char* from, - const char* to, - bool new_clustered, - bool evict_fk_cache) + const ha_innobase_inplace_ctx& ctx, + trx_t* trx, + const char* table_name, + const char* from, + const char* to) { dberr_t error; @@ -8817,7 +8813,7 @@ innobase_rename_column_try( ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_d(dict_sys.assert_locked()); - if (new_clustered) { + if (ctx.need_rebuild()) { goto rename_foreign; } @@ -8826,7 +8822,7 @@ innobase_rename_column_try( trx->op_info = "renaming column in SYS_FIELDS"; for (const dict_index_t* index = dict_table_get_first_index( - user_table); + ctx.old_table); index != NULL; index = dict_table_get_next_index(index)) { @@ -8886,8 +8882,8 @@ rename_foreign: std::set<dict_foreign_t*> fk_evict; bool foreign_modified; - for (dict_foreign_set::const_iterator it = user_table->foreign_set.begin(); - it != user_table->foreign_set.end(); + for (dict_foreign_set::const_iterator it = ctx.old_table->foreign_set.begin(); + it != ctx.old_table->foreign_set.end(); ++it) { dict_foreign_t* foreign = *it; @@ -8900,6 +8896,14 @@ rename_foreign: continue; } + /* Ignore the foreign key rename if fk info + is being dropped. */ + if (innobase_dropping_foreign( + foreign, ctx.drop_fk, + ctx.num_to_drop_fk)) { + continue; + } + pars_info_t* info = pars_info_create(); pars_info_add_str_literal(info, "id", foreign->id); @@ -8928,8 +8932,8 @@ rename_foreign: } for (dict_foreign_set::const_iterator it - = user_table->referenced_set.begin(); - it != user_table->referenced_set.end(); + = ctx.old_table->referenced_set.begin(); + it != ctx.old_table->referenced_set.end(); ++it) { foreign_modified = false; @@ -8970,7 +8974,7 @@ rename_foreign: } /* Reload the foreign key info for instant table too. */ - if (new_clustered || evict_fk_cache) { + if (ctx.need_rebuild() || ctx.is_instant()) { std::for_each(fk_evict.begin(), fk_evict.end(), dict_foreign_remove_from_cache); } @@ -9017,11 +9021,9 @@ innobase_rename_columns_try( while (Create_field* cf = cf_it++) { if (cf->field == *fp) { if (innobase_rename_column_try( - ctx->old_table, trx, table_name, + *ctx, trx, table_name, cf->field->field_name.str, - cf->field_name.str, - ctx->need_rebuild(), - ctx->is_instant())) { + cf->field_name.str)) { return(true); } goto processed_field; @@ -9150,9 +9152,8 @@ innobase_rename_or_enlarge_column_try( const bool same_name = !strcmp(col_name, f.field_name.str); if (!same_name - && innobase_rename_column_try(user_table, trx, table_name, - col_name, f.field_name.str, - false, ctx->is_instant())) { + && innobase_rename_column_try(*ctx, trx, table_name, + col_name, f.field_name.str)) { DBUG_RETURN(true); } diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 460359a96b4..55bcd331f27 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -181,6 +181,8 @@ access order rules. */ ulong innodb_change_buffering; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Dump the change buffer at startup */ +my_bool ibuf_dump; /** Flag to control insert buffer debugging. */ uint ibuf_debug; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ @@ -487,6 +489,25 @@ ibuf_init_at_db_start(void) #endif /* BTR_CUR_ADAPT */ ibuf.index->page = FSP_IBUF_TREE_ROOT_PAGE_NO; ut_d(ibuf.index->cached = TRUE); + +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (!ibuf_dump) { + return DB_SUCCESS; + } + ib::info() << "Dumping the change buffer"; + ibuf_mtr_start(&mtr); + btr_pcur_t pcur; + if (DB_SUCCESS == btr_pcur_open_at_index_side( + true, ibuf.index, BTR_SEARCH_LEAF, &pcur, + true, 0, &mtr)) { + while (btr_pcur_move_to_next_user_rec(&pcur, &mtr)) { + rec_print_old(stderr, btr_pcur_get_rec(&pcur)); + } + } + ibuf_mtr_commit(&mtr); + ib::info() << "Dumped the change buffer"; +#endif + return DB_SUCCESS; } diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index 0b20bfbe975..5e53dce8429 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -168,7 +168,7 @@ dfield_data_is_binary_equal( const dfield_t* field, /*!< in: field */ ulint len, /*!< in: data length or UNIV_SQL_NULL */ const byte* data) /*!< in: data */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /*********************************************************************//** Gets info bits in a data tuple. diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic index be0186d53fe..92be8f8c589 100644 --- a/storage/innobase/include/data0data.ic +++ b/storage/innobase/include/data0data.ic @@ -225,7 +225,7 @@ dfield_data_is_binary_equal( { ut_ad(len != UNIV_SQL_DEFAULT); return(len == dfield_get_len(field) - && (len == UNIV_SQL_NULL + && (!len || len == UNIV_SQL_NULL || !memcmp(dfield_get_data(field), data, len))); } diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index d0e1ddaa664..d0da45ab218 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -141,6 +141,8 @@ struct table_name_t }; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Dump the change buffer at startup */ +extern my_bool ibuf_dump; /** Flag to control insert buffer debugging. */ extern uint ibuf_debug; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 8643f0f79a3..74e0ee7b360 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -320,9 +320,6 @@ public: /** Mutex protecting bg_threads* and fts_add_wq. */ ib_mutex_t bg_threads_mutex; - /** Whether the table was added to fts_optimize_wq(); - protected by bg_threads_mutex */ - unsigned in_queue:1; /** Whether the ADDED table record sync-ed after crash recovery; protected by bg_threads_mutex */ unsigned added_synced:1; @@ -348,6 +345,10 @@ public: /** Vector of FTS indexes, this is mainly for caching purposes. */ ib_vector_t* indexes; + /** Whether the table exists in fts_optimize_wq; + protected by fts_optimize_wq mutex */ + bool in_queue; + /** Heap for fts_t allocation. */ mem_heap_t* fts_heap; }; diff --git a/storage/innobase/include/fts0opt.h b/storage/innobase/include/fts0opt.h index 4b4d1c4c84a..c527ad8e528 100644 --- a/storage/innobase/include/fts0opt.h +++ b/storage/innobase/include/fts0opt.h @@ -25,6 +25,9 @@ Created 2011-02-15 Jimmy Yang #ifndef INNODB_FTS0OPT_H #define INNODB_FTS0OPT_H +/** The FTS optimize thread's work queue. */ +extern ib_wqueue_t* fts_optimize_wq; + /******************************************************************** Callback function to fetch the rows in an FTS INDEX record. */ ibool diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index 6d0f95cba19..fa22b3d3086 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -237,7 +237,10 @@ inline void* mem_heap_dup(mem_heap_t* heap, const void* data, size_t len) { - return(memcpy(mem_heap_alloc(heap, len), data, len)); + ut_ad(data || !len); + return UNIV_LIKELY(data != NULL) + ? memcpy(mem_heap_alloc(heap, len), data, len) + : NULL; } /** Duplicate a NUL-terminated string, allocated from a memory heap. diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index eae636d6b7d..0aadf59bfb2 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -1024,7 +1024,7 @@ rec_init_offsets_temp( ulint n_core, const dict_col_t::def_t*def_val, rec_comp_status_t status = REC_STATUS_ORDINARY) - MY_ATTRIBUTE((nonnull)); + MY_ATTRIBUTE((nonnull(1,2,3))); /** Determine the offset to each field in temporary file. @param[in] rec temporary file record @param[in] index index of that the record belongs to diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 87a72d88eb6..9b6aac9c548 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -146,9 +146,8 @@ row_ins_sec_index_entry( dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr, /*!< in: query thread */ - bool check_ref) /*!< in: TRUE if we want to check that - the referenced table is ok, FALSE if we - want to check the foreign key table */ + bool check_foreign = true) /*!< in: true if check + foreign table is needed, false otherwise */ MY_ATTRIBUTE((warn_unused_result)); /***********************************************************//** Inserts a row to a table. This is a high-level function used in diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index 1a430e98a10..414c00dfae8 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -30,29 +30,6 @@ Created 5/30/1994 Heikki Tuuri #include "os0event.h" #include "ut0mutex.h" -/**********************************************************************//** -Copies up to size - 1 characters from the NUL-terminated string src to -dst, NUL-terminating the result. Returns strlen(src), so truncation -occurred if the return value >= size. -@return strlen(src) */ -ulint -ut_strlcpy( -/*=======*/ - char* dst, /*!< in: destination buffer */ - const char* src, /*!< in: source buffer */ - ulint size); /*!< in: size of destination buffer */ - -/**********************************************************************//** -Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last -(size - 1) bytes of src, not the first. -@return strlen(src) */ -ulint -ut_strlcpy_rev( -/*===========*/ - char* dst, /*!< in: destination buffer */ - const char* src, /*!< in: source buffer */ - ulint size); /*!< in: size of destination buffer */ - /******************************************************************** Concatenate 3 strings.*/ char* diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h index 6a096a36894..5a895f4ea3c 100644 --- a/storage/innobase/include/ut0wqueue.h +++ b/storage/innobase/include/ut0wqueue.h @@ -38,7 +38,18 @@ processing. // Forward declaration struct ib_list_t; -struct ib_wqueue_t; + +/** Work queue */ +struct ib_wqueue_t +{ + /** Mutex protecting everything */ + ib_mutex_t mutex; + /** Work item list */ + ib_list_t* items; + /** event we use to signal additions to list; + os_event_set() and os_event_reset() are protected by the mutex */ + os_event_t event; +}; /****************************************************************//** Create a new work queue. @@ -54,15 +65,14 @@ ib_wqueue_free( /*===========*/ ib_wqueue_t* wq); /*!< in: work queue */ -/****************************************************************//** -Add a work item to the queue. */ +/** Add a work item to the queue. +@param[in,out] wq work queue +@param[in] item work item +@param[in,out] heap memory heap to use for allocating list node +@param[in] wq_locked work queue mutex locked */ void -ib_wqueue_add( -/*==========*/ - ib_wqueue_t* wq, /*!< in: work queue */ - void* item, /*!< in: work item */ - mem_heap_t* heap); /*!< in: memory heap to use for - allocating the list node */ +ib_wqueue_add(ib_wqueue_t* wq, void* item, mem_heap_t* heap, + bool wq_locked = false); /** Check if queue is empty. @param wq wait queue @@ -101,5 +111,4 @@ ib_wqueue_len( /*==========*/ ib_wqueue_t* wq); /*<! in: work queue */ - #endif /* IB_WORK_QUEUE_H */ diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc index 929bffb881c..a298a7c0b2f 100644 --- a/storage/innobase/mem/mem0mem.cc +++ b/storage/innobase/mem/mem0mem.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -228,6 +228,17 @@ mem_heap_validate( ut_ad(size == heap->total_size); } + +/** Copy the tail of a string. +@param[in,out] dst destination buffer +@param[in] src string whose tail to copy +@param[in] size size of dst buffer, in bytes, including NUL terminator +@return strlen(src) */ +static void ut_strlcpy_rev(char* dst, const char* src, ulint size) +{ + size_t src_size = strlen(src), n = std::min(src_size, size - 1); + memcpy(dst, src + src_size - n, n + 1); +} #endif /* UNIV_DEBUG */ /***************************************************************//** diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 40d77fa50eb..f9028122f8d 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -4577,19 +4577,23 @@ os_file_get_status_win32( CloseHandle(fh); } } + stat_info->block_size = 0; + /* What follows, is calculation of FS block size, which is not important + (it is just shown in I_S innodb tables). The error to calculate it will be ignored.*/ char volname[MAX_PATH]; BOOL result = GetVolumePathName(path, volname, MAX_PATH); - + static bool warned_once = false; if (!result) { - - ib::error() - << "os_file_get_status_win32: " - << "Failed to get the volume path name for: " - << path - << "- OS error number " << GetLastError(); - - return(DB_FAIL); + if (!warned_once) { + ib::warn() + << "os_file_get_status_win32: " + << "Failed to get the volume path name for: " + << path + << "- OS error number " << GetLastError(); + warned_once = true; + } + return(DB_SUCCESS); } DWORD sectorsPerCluster; @@ -4605,15 +4609,15 @@ os_file_get_status_win32( &totalNumberOfClusters); if (!result) { - - ib::error() - << "GetDiskFreeSpace(" << volname << ",...) " - << "failed " - << "- OS error number " << GetLastError(); - - return(DB_FAIL); + if (!warned_once) { + ib::warn() + << "GetDiskFreeSpace(" << volname << ",...) " + << "failed " + << "- OS error number " << GetLastError(); + warned_once = true; + } + return(DB_SUCCESS); } - stat_info->block_size = bytesPerSector * sectorsPerCluster; } else { stat_info->type = OS_FILE_TYPE_UNKNOWN; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 5bb299193ed..b4b767df3e4 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1972,10 +1972,7 @@ row_ins_check_foreign_constraints( dict_index_t* index, /*!< in: index */ bool pk, /*!< in: index->is_primary() */ dtuple_t* entry, /*!< in: index entry for index */ - que_thr_t* thr, /*!< in: query thread */ - bool check_ref = true) /*!< in: TRUE if we want to check that - the referenced table is ok, FALSE if we - want to check the foreign key table */ + que_thr_t* thr) /*!< in: query thread */ { dict_foreign_t* foreign; dberr_t err; @@ -2024,7 +2021,7 @@ row_ins_check_foreign_constraints( table from being dropped while the check is running. */ err = row_ins_check_foreign_constraint( - check_ref, foreign, table, entry, thr); + TRUE, foreign, table, entry, thr); if (referenced_table) { foreign->foreign_table->dec_fk_checks(); @@ -3270,9 +3267,8 @@ row_ins_sec_index_entry( dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr, /*!< in: query thread */ - bool check_ref) /*!< in: true if we want to check that - the referenced table is ok, false if we - want to check the foreign key table */ + bool check_foreign) /*!< in: true if check + foreign table is needed, false otherwise */ { dberr_t err; mem_heap_t* offsets_heap; @@ -3283,10 +3279,9 @@ row_ins_sec_index_entry( DBUG_SET("-d,row_ins_sec_index_entry_timeout"); return(DB_LOCK_WAIT);}); - if (!index->table->foreign_set.empty()) { + if (check_foreign && !index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, - false, entry, thr, - check_ref); + false, entry, thr); if (err != DB_SUCCESS) { return(err); @@ -3361,7 +3356,7 @@ row_ins_index_entry( if (index->is_primary()) { return row_ins_clust_index_entry(index, entry, thr, 0); } else { - return(row_ins_sec_index_entry(index, entry, thr, true)); + return row_ins_sec_index_entry(index, entry, thr); } } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 180577ecdae..355f29acc08 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2694,7 +2694,7 @@ write_buffers: buf, fts_index, old_table, new_table, psort_info, row, ext, &doc_id, conv_heap, - &err, &v_heap, table, trx)))) { + &err, &v_heap, eval_table, trx)))) { /* An empty buffer should have enough room for at least one record. */ ut_error; diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 88dea6c7995..becca3600dc 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -249,10 +249,8 @@ row_undo_ins_remove_sec_low( que_thr_t* thr) /*!< in: query thread */ { btr_pcur_t pcur; - btr_cur_t* btr_cur; dberr_t err = DB_SUCCESS; mtr_t mtr; - enum row_search_result search_result; const bool modify_leaf = mode == BTR_MODIFY_LEAF; row_mtr_start(&mtr, index, !modify_leaf); @@ -277,12 +275,15 @@ row_undo_ins_remove_sec_low( mode |= BTR_RTREE_UNDO_INS; } - search_result = row_search_index_entry(index, entry, mode, - &pcur, &mtr); - - switch (search_result) { + switch (row_search_index_entry(index, entry, mode, &pcur, &mtr)) { + case ROW_BUFFERED: + case ROW_NOT_DELETED_REF: + /* These are invalid outcomes, because the mode passed + to row_search_index_entry() did not include any of the + flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */ + ut_error; case ROW_NOT_FOUND: - goto func_exit; + break; case ROW_FOUND: if (dict_index_is_spatial(index) && rec_get_deleted_flag( @@ -292,31 +293,22 @@ row_undo_ins_remove_sec_low( << " is deleted marked on insert rollback."; ut_ad(0); } - break; - case ROW_BUFFERED: - case ROW_NOT_DELETED_REF: - /* These are invalid outcomes, because the mode passed - to row_search_index_entry() did not include any of the - flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */ - ut_error; - } - - btr_cur = btr_pcur_get_btr_cur(&pcur); + btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); - if (modify_leaf) { - err = btr_cur_optimistic_delete(btr_cur, 0, &mtr) - ? DB_SUCCESS : DB_FAIL; - } else { - /* Passing rollback=false here, because we are - deleting a secondary index record: the distinction - only matters when deleting a record that contains - externally stored columns. */ - ut_ad(!dict_index_is_clust(index)); - btr_cur_pessimistic_delete(&err, FALSE, btr_cur, 0, - false, &mtr); + if (modify_leaf) { + err = btr_cur_optimistic_delete(btr_cur, 0, &mtr) + ? DB_SUCCESS : DB_FAIL; + } else { + /* Passing rollback=false here, because we are + deleting a secondary index record: the distinction + only matters when deleting a record that contains + externally stored columns. */ + btr_cur_pessimistic_delete(&err, FALSE, btr_cur, 0, + false, &mtr); + } } -func_exit: + btr_pcur_close(&pcur); func_exit_no_pcur: mtr_commit(&mtr); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 88d08f13c25..a3279a3c87b 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2457,17 +2457,27 @@ row_upd_sec_index_entry( case DB_NO_REFERENCED_ROW: err = DB_SUCCESS; break; + case DB_LOCK_WAIT: + if (wsrep_debug) { + ib::warn() << "WSREP: sec index FK lock wait" + << " index " << index->name + << " table " << index->table->name + << " query " << wsrep_thd_query(trx->mysql_thd); + } + break; case DB_DEADLOCK: if (wsrep_get_debug()) { ib::warn() << "WSREP: sec index FK check fail for deadlock" << " index " << index->name - << " table " << index->table->name; + << " table " << index->table->name + << " query " << wsrep_thd_query(trx->mysql_thd); } break; default: ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err) << " index " << index->name - << " table " << index->table->name; + << " table " << index->table->name + << " query " << wsrep_thd_query(trx->mysql_thd); break; } @@ -2509,8 +2519,7 @@ row_upd_sec_index_entry( ut_a(entry); /* Insert new index entry */ - err = row_ins_sec_index_entry(index, entry, thr, - node->is_delete != VERSIONED_DELETE); + err = row_ins_sec_index_entry(index, entry, thr, !node->is_delete); func_exit: mem_heap_free(heap); diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index f5d98e8f05a..2db1fee062c 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -418,9 +418,15 @@ trx_undo_report_insert_virtual( const dfield_t* vfield = dtuple_get_nth_v_field( row, col->v_pos); - ulint flen = vfield->len; + switch (ulint flen = vfield->len) { + case 0: case UNIV_SQL_NULL: + if (trx_undo_left(undo_block, *ptr) < 5) { + return(false); + } - if (flen != UNIV_SQL_NULL) { + *ptr += mach_write_compressed(*ptr, flen); + break; + default: ulint max_len = dict_max_v_field_len_store_undo( table, col_no); @@ -437,12 +443,6 @@ trx_undo_report_insert_virtual( memcpy(*ptr, vfield->data, flen); *ptr += flen; - } else { - if (trx_undo_left(undo_block, *ptr) < 5) { - return(false); - } - - *ptr += mach_write_compressed(*ptr, flen); } } } @@ -521,7 +521,10 @@ trx_undo_page_report_insert( ptr += mach_write_compressed(ptr, flen); - if (flen != UNIV_SQL_NULL) { + switch (flen) { + case 0: case UNIV_SQL_NULL: + break; + default: if (trx_undo_left(undo_block, ptr) < flen) { return(0); @@ -1447,7 +1450,10 @@ already_logged: ptr += mach_write_compressed(ptr, flen); - if (flen != UNIV_SQL_NULL) { + switch (flen) { + case 0: case UNIV_SQL_NULL: + break; + default: if (trx_undo_left(undo_block, ptr) < flen) { return(0); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 5d42650953b..bf26b5b20ef 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -79,7 +79,8 @@ trx_set_detailed_error( trx_t* trx, /*!< in: transaction struct */ const char* msg) /*!< in: detailed error message */ { - ut_strlcpy(trx->detailed_error, msg, MAX_DETAILED_ERROR_LEN); + strncpy(trx->detailed_error, msg, MAX_DETAILED_ERROR_LEN - 1); + trx->detailed_error[MAX_DETAILED_ERROR_LEN - 1] = '\0'; } /*************************************************************//** diff --git a/storage/innobase/ut/ut0mem.cc b/storage/innobase/ut/ut0mem.cc index 32a90accd21..faade827283 100644 --- a/storage/innobase/ut/ut0mem.cc +++ b/storage/innobase/ut/ut0mem.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -24,55 +25,6 @@ Created 5/11/1994 Heikki Tuuri *************************************************************************/ #include "ut0mem.h" -#include "os0thread.h" -#include "srv0srv.h" -#include <stdlib.h> - -/**********************************************************************//** -Copies up to size - 1 characters from the NUL-terminated string src to -dst, NUL-terminating the result. Returns strlen(src), so truncation -occurred if the return value >= size. -@return strlen(src) */ -ulint -ut_strlcpy( -/*=======*/ - char* dst, /*!< in: destination buffer */ - const char* src, /*!< in: source buffer */ - ulint size) /*!< in: size of destination buffer */ -{ - ulint src_size = strlen(src); - - if (size != 0) { - ulint n = ut_min(src_size, size - 1); - - memcpy(dst, src, n); - dst[n] = '\0'; - } - - return(src_size); -} - -/**********************************************************************//** -Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last -(size - 1) bytes of src, not the first. -@return strlen(src) */ -ulint -ut_strlcpy_rev( -/*===========*/ - char* dst, /*!< in: destination buffer */ - const char* src, /*!< in: source buffer */ - ulint size) /*!< in: size of destination buffer */ -{ - ulint src_size = strlen(src); - - if (size != 0) { - ulint n = ut_min(src_size, size - 1); - - memcpy(dst, src + src_size - n, n + 1); - } - - return(src_size); -} /******************************************************************** Concatenate 3 strings.*/ diff --git a/storage/innobase/ut/ut0wqueue.cc b/storage/innobase/ut/ut0wqueue.cc index 026431695ed..ae97009430e 100644 --- a/storage/innobase/ut/ut0wqueue.cc +++ b/storage/innobase/ut/ut0wqueue.cc @@ -28,15 +28,6 @@ A work queue Created 4/26/2006 Osku Salerma ************************************************************************/ -/* Work queue. */ -struct ib_wqueue_t { - ib_mutex_t mutex; /*!< mutex protecting everything */ - ib_list_t* items; /*!< work item list */ - os_event_t event; /*!< event we use to signal additions to list; - os_event_set() and os_event_reset() are - protected by ib_wqueue_t::mutex */ -}; - /****************************************************************//** Create a new work queue. @return work queue */ @@ -72,22 +63,24 @@ ib_wqueue_free( ut_free(wq); } -/****************************************************************//** -Add a work item to the queue. */ +/** Add a work item to the queue. +@param[in,out] wq work queue +@param[in] item work item +@param[in,out] heap memory heap to use for allocating list node +@param[in] wq_locked work queue mutex locked */ void -ib_wqueue_add( -/*==========*/ - ib_wqueue_t* wq, /*!< in: work queue */ - void* item, /*!< in: work item */ - mem_heap_t* heap) /*!< in: memory heap to use for allocating the - list node */ +ib_wqueue_add(ib_wqueue_t* wq, void* item, mem_heap_t* heap, bool wq_locked) { - mutex_enter(&wq->mutex); + if (!wq_locked) { + mutex_enter(&wq->mutex); + } ib_list_add_last(wq->items, item, heap); os_event_set(wq->event); - mutex_exit(&wq->mutex); + if (!wq_locked) { + mutex_exit(&wq->mutex); + } } /****************************************************************//** |