summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/.clang-format11
-rw-r--r--storage/innobase/btr/btr0bulk.cc30
-rw-r--r--storage/innobase/btr/btr0cur.cc24
-rw-r--r--storage/innobase/dict/dict0load.cc9
-rw-r--r--storage/innobase/fil/fil0crypt.cc25
-rw-r--r--storage/innobase/fts/fts0fts.cc8
-rw-r--r--storage/innobase/fts/fts0opt.cc170
-rw-r--r--storage/innobase/handler/ha_innodb.cc34
-rw-r--r--storage/innobase/handler/handler0alter.cc51
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc21
-rw-r--r--storage/innobase/include/data0data.h2
-rw-r--r--storage/innobase/include/data0data.ic2
-rw-r--r--storage/innobase/include/dict0types.h2
-rw-r--r--storage/innobase/include/fts0fts.h7
-rw-r--r--storage/innobase/include/fts0opt.h3
-rw-r--r--storage/innobase/include/mem0mem.h5
-rw-r--r--storage/innobase/include/rem0rec.h2
-rw-r--r--storage/innobase/include/row0ins.h5
-rw-r--r--storage/innobase/include/ut0mem.h23
-rw-r--r--storage/innobase/include/ut0wqueue.h29
-rw-r--r--storage/innobase/mem/mem0mem.cc13
-rw-r--r--storage/innobase/os/os0file.cc38
-rw-r--r--storage/innobase/row/row0ins.cc19
-rw-r--r--storage/innobase/row/row0merge.cc2
-rw-r--r--storage/innobase/row/row0uins.cc50
-rw-r--r--storage/innobase/row/row0upd.cc17
-rw-r--r--storage/innobase/trx/trx0rec.cc26
-rw-r--r--storage/innobase/trx/trx0trx.cc3
-rw-r--r--storage/innobase/ut/ut0mem.cc50
-rw-r--r--storage/innobase/ut/ut0wqueue.cc31
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);
+ }
}
/****************************************************************//**