summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0cur.cc31
-rw-r--r--storage/innobase/btr/btr0sea.cc11
-rw-r--r--storage/innobase/buf/buf0buddy.cc2
-rw-r--r--storage/innobase/dict/dict0dict.cc1
-rw-r--r--storage/innobase/dict/dict0mem.cc19
-rw-r--r--storage/innobase/fil/fil0fil.cc22
-rw-r--r--storage/innobase/fts/fts0fts.cc5
-rw-r--r--storage/innobase/fts/fts0opt.cc5
-rw-r--r--storage/innobase/fts/fts0que.cc15
-rw-r--r--storage/innobase/handler/ha_innodb.cc47
-rw-r--r--storage/innobase/handler/handler0alter.cc15
-rw-r--r--storage/innobase/include/dict0mem.h13
-rw-r--r--storage/innobase/include/fts0ast.h2
-rw-r--r--storage/innobase/include/fts0fts.h12
-rw-r--r--storage/innobase/include/os0file.h1
-rw-r--r--storage/innobase/include/que0que.h3
-rw-r--r--storage/innobase/include/sync0sync.h1
-rw-r--r--storage/innobase/include/sync0types.h11
-rw-r--r--storage/innobase/include/ut0mutex.h14
-rw-r--r--storage/innobase/lock/lock0lock.cc7
-rw-r--r--storage/innobase/os/os0file.cc6
-rw-r--r--storage/innobase/row/row0ins.cc47
-rw-r--r--storage/innobase/row/row0sel.cc27
-rw-r--r--storage/innobase/row/row0uins.cc6
-rw-r--r--storage/innobase/row/row0umod.cc56
-rw-r--r--storage/innobase/row/row0undo.cc6
-rw-r--r--storage/innobase/sync/sync0debug.cc15
-rw-r--r--storage/innobase/sync/sync0sync.cc1
-rw-r--r--storage/innobase/trx/trx0rec.cc26
29 files changed, 248 insertions, 179 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 8fec8a8a824..81a04701da1 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -5451,7 +5451,6 @@ btr_cur_optimistic_delete_func(
mem_heap_t* heap = NULL;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_;
- ibool no_compress_needed;
rec_offs_init(offsets_);
ut_ad(flags == 0 || flags == BTR_CREATE_FLAG);
@@ -5472,6 +5471,20 @@ btr_cur_optimistic_delete_func(
rec = btr_cur_get_rec(cursor);
+ offsets = rec_get_offsets(rec, cursor->index, offsets, true,
+ ULINT_UNDEFINED, &heap);
+
+ const ibool no_compress_needed = !rec_offs_any_extern(offsets)
+ && btr_cur_can_delete_without_compress(
+ cursor, rec_offs_size(offsets), mtr);
+
+ if (!no_compress_needed) {
+ /* prefetch siblings of the leaf for the pessimistic
+ operation. */
+ btr_cur_prefetch_siblings(block);
+ goto func_exit;
+ }
+
if (UNIV_UNLIKELY(block->page.id().page_no() == cursor->index->page
&& page_get_n_recs(block->frame) == 1
+ (cursor->index->is_instant()
@@ -5509,19 +5522,11 @@ btr_cur_optimistic_delete_func(
}
page_cur_set_after_last(block,
btr_cur_get_page_cur(cursor));
- return true;
+ goto func_exit;
}
}
- offsets = rec_get_offsets(rec, cursor->index, offsets, true,
- ULINT_UNDEFINED, &heap);
-
- no_compress_needed = !rec_offs_any_extern(offsets)
- && btr_cur_can_delete_without_compress(
- cursor, rec_offs_size(offsets), mtr);
-
- if (no_compress_needed) {
-
+ {
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip= buf_block_get_page_zip(block);
@@ -5581,10 +5586,6 @@ btr_cur_optimistic_delete_func(
ibuf_update_free_bits_low(block, max_ins, mtr);
}
}
- } else {
- /* prefetch siblings of the leaf for the pessimistic
- operation. */
- btr_cur_prefetch_siblings(block);
}
func_exit:
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 238551783db..68d946aa79d 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1981,8 +1981,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
n_bytes, index->id);
}
- btr_search_sys_t::partition* const part
- = btr_search_sys.get_part(*index);
+ /* We must not look up "part" before acquiring ahi_latch. */
+ btr_search_sys_t::partition* part= nullptr;
bool locked = false;
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, *index)) {
@@ -1999,6 +1999,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
goto function_exit;
}
+ part = btr_search_sys.get_part(*index);
ha_insert_for_fold(&part->table, part->heap,
ins_fold, block, ins_rec);
MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED);
@@ -2016,6 +2017,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ part = btr_search_sys.get_part(*index);
}
if (!left_side) {
@@ -2039,6 +2042,8 @@ check_next_rec:
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ part = btr_search_sys.get_part(*index);
}
ha_insert_for_fold(&part->table, part->heap,
@@ -2057,6 +2062,8 @@ check_next_rec:
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ part = btr_search_sys.get_part(*index);
}
if (!left_side) {
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index b8ed7bb3f36..f822adc3389 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -319,7 +319,7 @@ static buf_buddy_free_t* buf_buddy_alloc_zip(ulint i)
if (buf) {
buf_buddy_free_t* buddy =
reinterpret_cast<buf_buddy_free_t*>(
- buf->stamp.bytes
+ reinterpret_cast<byte*>(buf)
+ (BUF_BUDDY_LOW << i));
ut_ad(!buf_pool.contains_zip(buddy));
buf_buddy_add_to_free(buddy, i);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index d9338af1327..52b77fd93a5 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2353,7 +2353,6 @@ dict_index_add_col(
if (col->is_virtual()) {
dict_v_col_t* v_col = reinterpret_cast<dict_v_col_t*>(col);
/* Register the index with the virtual column index list */
- v_col->n_v_indexes++;
v_col->v_indexes.push_front(dict_v_idx_t(index, index->n_def));
col_name = dict_table_get_v_col_name_mysql(
table, dict_col_get_no(col));
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 5b79406fb18..c27ea57e68d 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -440,7 +440,6 @@ dict_mem_table_add_v_col(
/* Initialize the index list for virtual columns */
ut_ad(v_col->v_indexes.empty());
- v_col->n_v_indexes = 0;
return(v_col);
}
@@ -1211,6 +1210,24 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set)
return(out);
}
+/** Check whether fulltext index gets affected by foreign
+key constraint. */
+bool dict_foreign_t::affects_fulltext() const
+{
+ if (foreign_table == referenced_table || !foreign_table->fts)
+ return false;
+
+ for (ulint i= 0; i < n_fields; i++)
+ {
+ const dict_col_t *col= dict_index_get_nth_col(foreign_index, i);
+ if (dict_table_is_fts_column(foreign_table->fts->indexes, col->ind,
+ col->is_virtual()) != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
+}
+
/** Reconstruct the clustered index fields. */
inline void dict_index_t::reconstruct_fields()
{
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 56476edbfa0..021f2f15e3b 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -412,6 +412,14 @@ static bool fil_node_open_file(fil_node_t* node)
const bool first_time_open = node->size == 0;
+ bool o_direct_possible = !FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags);
+ if (const ulint ssize = FSP_FLAGS_GET_ZIP_SSIZE(space->flags)) {
+ compile_time_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096);
+ if (ssize < 3) {
+ o_direct_possible = false;
+ }
+ }
+
if (first_time_open
|| (space->purpose == FIL_TYPE_TABLESPACE
&& node == UT_LIST_GET_FIRST(space->chain)
@@ -429,7 +437,12 @@ retry:
node->is_raw_disk
? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
: OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
+ OS_FILE_AIO,
+ o_direct_possible
+ ? OS_DATA_FILE
+ : OS_DATA_FILE_NO_O_DIRECT,
+ read_only_mode,
+ &success);
if (!success) {
/* The following call prints an error message */
@@ -462,7 +475,12 @@ fail:
node->is_raw_disk
? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
: OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
+ OS_FILE_AIO,
+ o_direct_possible
+ ? OS_DATA_FILE
+ : OS_DATA_FILE_NO_O_DIRECT,
+ read_only_mode,
+ &success);
}
ut_a(success);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 552832200e7..a5945fea791 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -5266,7 +5266,6 @@ fts_t::fts_t(
mem_heap_t* heap)
:
added_synced(0), dict_locked(0),
- bg_threads(0),
add_wq(NULL),
cache(NULL),
doc_col(ULINT_UNDEFINED), in_queue(false), sync_message(false),
@@ -5274,8 +5273,6 @@ fts_t::fts_t(
{
ut_a(table->fts == NULL);
- mutex_create(LATCH_ID_FTS_BG_THREADS, &bg_threads_mutex);
-
ib_alloc_t* heap_alloc = ib_heap_allocator_create(fts_heap);
indexes = ib_vector_create(heap_alloc, sizeof(dict_index_t*), 4);
@@ -5286,8 +5283,6 @@ fts_t::fts_t(
/** fts_t destructor. */
fts_t::~fts_t()
{
- mutex_free(&bg_threads_mutex);
-
ut_ad(add_wq == NULL);
if (cache != NULL) {
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 01c35ba280c..20ba44a8d73 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -2590,6 +2590,11 @@ fts_optimize_remove_table(
if (fts_opt_start_shutdown) {
ib::info() << "Try to remove table " << table->name
<< " after FTS optimize thread exiting.";
+ /* If the table can't be removed then wait till
+ fts optimize thread shuts down */
+ while (fts_optimize_wq) {
+ os_thread_sleep(10000);
+ }
return;
}
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 4baba419ff7..dd74aad4de7 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -144,6 +144,8 @@ struct fts_query_t {
ib_rbt_t* wildcard_words; /*!< words with wildcard */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
st_mysql_ftparser* parser; /*!< fts plugin parser */
};
@@ -2964,6 +2966,8 @@ fts_query_get_token(
return(new_ptr);
}
+static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*);
+
/*****************************************************************//**
Visit every node of the AST. */
static
@@ -3088,6 +3092,14 @@ fts_ast_visit_sub_exp(
ut_a(node->type == FTS_AST_SUBEXP_LIST);
+ /* To avoid stack overflow, we limit the mutual recursion
+ depth between fts_ast_visit(), fts_query_visitor() and
+ fts_ast_visit_sub_exp(). */
+ if (query->visiting_sub_exp++ > 31) {
+ query->error = DB_OUT_OF_MEMORY;
+ DBUG_RETURN(query->error);
+ }
+
cur_oper = query->oper;
/* Save current result set */
@@ -3110,6 +3122,7 @@ fts_ast_visit_sub_exp(
/* Reinstate parent node state */
query->multi_exist = multi_exist;
query->oper = cur_oper;
+ query->visiting_sub_exp--;
/* Merge the sub-expression result with the parent result set. */
subexpr_doc_ids = query->doc_ids;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 546957f8800..d6f28192893 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -514,7 +514,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(recalc_pool_mutex),
PSI_KEY(fil_system_mutex),
PSI_KEY(flush_list_mutex),
- PSI_KEY(fts_bg_threads_mutex),
PSI_KEY(fts_delete_mutex),
PSI_KEY(fts_doc_id_mutex),
PSI_KEY(log_flush_order_mutex),
@@ -2275,6 +2274,12 @@ innobase_trx_init(
DBUG_ENTER("innobase_trx_init");
DBUG_ASSERT(thd == trx->mysql_thd);
+ /* Ensure that thd_lock_wait_timeout(), which may be called
+ while holding lock_sys.mutex, by lock_rec_enqueue_waiting(),
+ will not end up acquiring LOCK_global_system_variables in
+ intern_sys_var_ptr(). */
+ THDVAR(thd, lock_wait_timeout);
+
trx->check_foreigns = !thd_test_options(
thd, OPTION_NO_FOREIGN_KEY_CHECKS);
@@ -3407,12 +3412,30 @@ static int innodb_init_params()
DBUG_RETURN(HA_ERR_INITIALIZATION);
}
+ if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS) {
+ ib::warn() << "The parameter innodb_lock_schedule_algorithm"
+ " is deprecated, and the setting"
+ " innodb_lock_schedule_algorithm=vats"
+ " may cause corruption. The parameter may be removed"
+ " in future releases.";
+
#ifdef WITH_WSREP
- /* Currently, Galera does not support VATS lock schedule algorithm. */
- if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
- && global_system_variables.wsrep_on) {
- ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
- innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ /* Currently, Galera does not support VATS lock schedule algorithm. */
+ if (global_system_variables.wsrep_on) {
+ ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
+ innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ }
+#endif /* WITH_WSREP */
+ }
+
+#ifdef WITH_WSREP
+ /* Print deprecation info if xtrabackup is used for SST method */
+ if (global_system_variables.wsrep_on
+ && wsrep_sst_method
+ && (!strcmp(wsrep_sst_method, "xtrabackup")
+ || !strcmp(wsrep_sst_method, "xtrabackup-v2"))) {
+ ib::info() << "Galera SST method xtrabackup is deprecated and the "
+ " support for it may be removed in future releases.";
}
#endif /* WITH_WSREP */
@@ -15961,8 +15984,7 @@ struct ShowStatus {
/** Collect the latch metrics. Ignore entries where the
spins and waits are zero.
@param[in] count The latch metrics */
- void operator()(Count* count)
- UNIV_NOTHROW
+ void operator()(Count* count) const UNIV_NOTHROW
{
if (count->m_spins > 0 || count->m_waits > 0) {
@@ -15990,13 +16012,8 @@ struct ShowStatus {
bool operator()(latch_meta_t& latch_meta)
UNIV_NOTHROW
{
- latch_meta_t::CounterType* counter;
-
- counter = latch_meta.get_counter();
-
- GetCount get_count(latch_meta.get_name(), &m_values);
-
- counter->iterate(get_count);
+ latch_meta.get_counter()->iterate(
+ GetCount(latch_meta.get_name(), &m_values));
return(true);
}
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index d5486567e44..9343ca7fe45 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -553,8 +553,10 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
mem_heap_dup(heap, table.v_col_names,
ulint(end - table.v_col_names)));
v_cols = static_cast<dict_v_col_t*>(
- mem_heap_dup(heap, table.v_cols,
- table.n_v_cols * sizeof *v_cols));
+ mem_heap_alloc(heap, table.n_v_cols * sizeof(*v_cols)));
+ for (ulint i = table.n_v_cols; i--; ) {
+ new (&v_cols[i]) dict_v_col_t(table.v_cols[i]);
+ }
} else {
ut_ad(table.n_v_cols == 0);
v_col_names = NULL;
@@ -570,7 +572,6 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
for (unsigned i = 0; i < n_v_def; i++) {
dict_v_col_t& v = v_cols[i];
DBUG_ASSERT(v.v_indexes.empty());
- v.n_v_indexes = 0;
v.base_col = static_cast<dict_col_t**>(
mem_heap_dup(heap, v.base_col,
v.num_base * sizeof *v.base_col));
@@ -680,7 +681,6 @@ dup_dropped:
<dict_v_col_t*>(f.col);
v_col->v_indexes.push_front(
dict_v_idx_t(index, i));
- v_col->n_v_indexes++;
}
}
}
@@ -4963,7 +4963,6 @@ prepare_inplace_add_virtual(
- ctx->num_to_drop_vcol + j)
& dict_index_t::MAX_N_FIELDS;
- ctx->add_vcol[j].n_v_indexes = 0;
/* MDEV-17468: Do this on ctx->instant_table later */
innodb_base_col_setup(ctx->old_table, field, &ctx->add_vcol[j]);
j++;
@@ -10805,11 +10804,11 @@ ha_innobase::commit_inplace_alter_table(
/* Exclusively lock the table, to ensure that no other
transaction is holding locks on the table while we
- change the table definition. The meta-data lock (MDL)
+ change the table definition. The MySQL meta-data lock
should normally guarantee that no conflicting locks
exist. However, FOREIGN KEY constraints checks and any
transactions collected during crash recovery could be
- holding InnoDB locks only, not MDL. */
+ holding InnoDB locks only, not MySQL locks. */
dberr_t error = row_merge_lock_table(
m_prebuilt->trx, ctx->old_table, LOCK_X);
@@ -11163,7 +11162,7 @@ foreign_fail:
}
dict_sys.remove(m_prebuilt->table);
m_prebuilt->table = dict_table_open_on_name(
- tb_name, TRUE, TRUE, DICT_ERR_IGNORE_NONE);
+ tb_name, TRUE, TRUE, DICT_ERR_IGNORE_FK_NOKEY);
/* Drop outdated table stats. */
char errstr[1024];
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 0c42c5ffe6f..1ae52dfbf5d 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -766,9 +766,6 @@ struct dict_v_col_t{
/** column pos in table */
unsigned v_pos:10;
- /** number of indexes */
- unsigned n_v_indexes:12;
-
/** Virtual index list, and column position in the index */
std::forward_list<dict_v_idx_t, ut_allocator<dict_v_idx_t> >
v_indexes;
@@ -777,21 +774,17 @@ struct dict_v_col_t{
@param index index to be detached from */
void detach(const dict_index_t &index)
{
- if (!n_v_indexes) return;
+ if (v_indexes.empty()) return;
auto i= v_indexes.before_begin();
- ut_d(unsigned n= 0);
do {
auto prev = i++;
if (i == v_indexes.end())
{
- ut_ad(n == n_v_indexes);
return;
}
- ut_ad(++n <= n_v_indexes);
if (i->index == &index)
{
v_indexes.erase_after(prev);
- n_v_indexes--;
return;
}
}
@@ -1450,6 +1443,10 @@ struct dict_foreign_t{
dict_vcol_set* v_cols; /*!< set of virtual columns affected
by foreign key constraint. */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index 3dca92235c7..15bf30bc5d5 100644
--- a/storage/innobase/include/fts0ast.h
+++ b/storage/innobase/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2020, 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
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 5c35e5dac4f..5e0381ccd56 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -316,19 +316,11 @@ public:
/** fts_t destructor. */
~fts_t();
- /** Mutex protecting bg_threads* and fts_add_wq. */
- ib_mutex_t bg_threads_mutex;
-
- /** Whether the ADDED table record sync-ed after
- crash recovery; protected by bg_threads_mutex */
+ /** Whether the ADDED table record sync-ed after crash recovery */
unsigned added_synced:1;
- /** Whether the table holds dict_sys.mutex;
- protected by bg_threads_mutex */
+ /** Whether the table holds dict_sys.mutex */
unsigned dict_locked:1;
- /** Number of background threads accessing this table. */
- ulint bg_threads;
-
/** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL
if the thread has not yet been created. Each work item is a
fts_trx_doc_ids_t*. */
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 4be5e5341ba..def091c9771 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -160,6 +160,7 @@ static const ulint OS_FILE_NORMAL = 62;
static const ulint OS_DATA_FILE = 100;
static const ulint OS_LOG_FILE = 101;
static const ulint OS_DATA_TEMP_FILE = 102;
+static const ulint OS_DATA_FILE_NO_O_DIRECT = 103;
/* @} */
/** Error codes from os_file_get_last_error @{ */
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 651fcb1aa36..af282b378ca 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -35,9 +35,6 @@ Created 5/27/1996 Heikki Tuuri
#include "row0types.h"
#include "pars0types.h"
-/** Mutex protecting the query threads. */
-extern ib_mutex_t que_thr_mutex;
-
/***********************************************************************//**
Creates a query graph fork node.
@return own: fork node */
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 72f2d8ffb74..be8ad78de82 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -52,7 +52,6 @@ extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
extern mysql_pfs_key_t fil_system_mutex_key;
extern mysql_pfs_key_t flush_list_mutex_key;
-extern mysql_pfs_key_t fts_bg_threads_mutex_key;
extern mysql_pfs_key_t fts_delete_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index a6d0bd8a86c..f0168bd1c27 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -197,14 +197,12 @@ enum latch_level_t {
SYNC_FTS_TOKENIZE,
SYNC_FTS_OPTIMIZE,
- SYNC_FTS_BG_THREADS,
SYNC_FTS_CACHE_INIT,
SYNC_RECV,
SYNC_LOG_FLUSH_ORDER,
SYNC_LOG,
SYNC_PURGE_QUEUE,
SYNC_TRX_SYS_HEADER,
- SYNC_REC_LOCK,
SYNC_TRX,
SYNC_RW_TRX_HASH_ELEMENT,
SYNC_READ_VIEW,
@@ -267,7 +265,6 @@ enum latch_id_t {
LATCH_ID_DICT_FOREIGN_ERR,
LATCH_ID_DICT_SYS,
LATCH_ID_FIL_SYSTEM,
- LATCH_ID_FTS_BG_THREADS,
LATCH_ID_FTS_DELETE,
LATCH_ID_FTS_DOC_ID,
LATCH_ID_FTS_PLL_TOKENIZE,
@@ -600,10 +597,10 @@ public:
}
/** Iterate over the counters */
- template <typename Callback>
- void iterate(Callback& callback) const
- UNIV_NOTHROW
+ template<typename C> void iterate(const C& callback) UNIV_NOTHROW
{
+ m_mutex.enter();
+
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
@@ -612,6 +609,8 @@ public:
callback(*it);
}
+
+ m_mutex.exit();
}
/** Disable the monitoring */
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
index 04ec10cc379..294304e672a 100644
--- a/storage/innobase/include/ut0mutex.h
+++ b/storage/innobase/include/ut0mutex.h
@@ -131,16 +131,10 @@ public:
/* Some of the slots will be null in non-debug mode */
- if (*it == NULL) {
- continue;
- }
-
- latch_meta_t* latch_meta = *it;
-
- bool ret = callback(*latch_meta);
-
- if (!ret) {
- return(ret);
+ if (latch_meta_t* l= *it) {
+ if (!callback(*l)) {
+ return false;
+ }
}
}
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index df206af34c7..71077e3f9fb 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2082,12 +2082,12 @@ static void lock_grant_and_move_on_page(ulint rec_fold, const page_id_t id)
lock = previous->hash;
}
- ut_ad(!lock->trx->is_wsrep());
ut_ad(previous->hash == lock || previous == lock);
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
while (lock) {
/* If the lock is a wait lock on this page, and it does not need to wait. */
+ ut_ad(!lock->trx->is_wsrep());
if (lock_get_wait(lock)
&& lock->un_member.rec_lock.page_id == id
&& !lock_rec_has_to_wait_in_queue(lock)) {
@@ -3964,11 +3964,10 @@ lock_grant_and_move_on_rec(
}
lock = previous->hash;
}
- ut_ad(!lock->trx->is_wsrep());
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
- for (;lock != NULL;) {
-
+ while (lock) {
+ ut_ad(!lock->trx->is_wsrep());
/* If the lock is a wait lock on this page, and it does not need to wait. */
if (lock->un_member.rec_lock.page_id == page_id
&& lock_rec_get_nth_bit(lock, heap_no)
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 7e24ff7ab5e..bfe18fd2519 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -1384,7 +1384,8 @@ os_file_create_func(
ut_a(type == OS_LOG_FILE
|| type == OS_DATA_FILE
- || type == OS_DATA_TEMP_FILE);
+ || type == OS_DATA_TEMP_FILE
+ || type == OS_DATA_FILE_NO_O_DIRECT);
ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
@@ -1430,7 +1431,8 @@ os_file_create_func(
/* We disable OS caching (O_DIRECT) only on data files */
if (!read_only
&& *success
- && (type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE)
+ && type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE
+ && type != OS_DATA_FILE_NO_O_DIRECT
&& (srv_file_flush_method == SRV_O_DIRECT
|| srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) {
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 649051da305..5e41d037b6c 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -460,7 +460,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- bool affects_fulltext = false;
+ bool affects_fulltext = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -583,17 +583,6 @@ row_ins_cascade_calc_update_vec(
padded_data, min_size);
}
- /* Check whether the current column has
- FTS index on it */
- if (table->fts
- && dict_table_is_fts_column(
- table->fts->indexes,
- dict_col_get_no(col),
- col->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -1223,8 +1212,6 @@ row_ins_foreign_check_on_constraint(
MEM_UNDEFINED(update->fields,
update->n_fields * sizeof *update->fields);
- bool affects_fulltext = false;
-
for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
ulint col_no = dict_index_get_nth_col_no(
@@ -1241,19 +1228,9 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (!affects_fulltext
- && table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col(index, i)->ind,
- dict_index_get_nth_col(index, i)
- ->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
}
- if (affects_fulltext) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
@@ -1267,24 +1244,10 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
}
- } else if (table->fts && cascade->is_delete == PLAIN_DELETE) {
+ } else if (table->fts && cascade->is_delete == PLAIN_DELETE
+ && foreign->affects_fulltext()) {
/* DICT_FOREIGN_ON_DELETE_CASCADE case */
- bool affects_fulltext = false;
-
- for (ulint i = 0; i < foreign->n_fields; i++) {
- if (dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col(index, i)->ind,
- dict_index_get_nth_col(index, i)->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- break;
- }
- }
-
- if (affects_fulltext) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 401a655517f..d7a0490db3d 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -3906,7 +3906,7 @@ exhausted:
/*********************************************************************//**
Check a pushed-down index condition.
-@return CHECK_NEG, CHECK_POS, or CHECK_OUT_OF_RANGE */
+@return CHECK_ABORTED_BY_USER, CHECK_NEG, CHECK_POS, or CHECK_OUT_OF_RANGE */
static
check_result_t
row_search_idx_cond_check(
@@ -3992,7 +3992,7 @@ row_search_idx_cond_check(
case CHECK_POS:
break;
default:
- ut_error;
+ return(result);
}
}
/* Convert the remaining fields to MySQL format.
@@ -4453,15 +4453,21 @@ early_not_found:
switch (row_search_idx_cond_check(
buf, prebuilt,
rec, offsets)) {
+ case CHECK_ABORTED_BY_USER:
+ goto aborted;
case CHECK_NEG:
case CHECK_OUT_OF_RANGE:
- case CHECK_ABORTED_BY_USER:
case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto shortcut_done;
case CHECK_POS:
goto shortcut_done;
}
+
+ ut_ad("incorrect code" == 0);
+aborted:
+ err = DB_INTERRUPTED;
+ goto shortcut_done;
}
if (!row_sel_store_mysql_rec(
@@ -4495,6 +4501,9 @@ early_not_found:
trx->op_info = "";
ut_ad(!sync_check_iterate(sync_check()));
ut_ad(!did_semi_consistent_read);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
DBUG_RETURN(err);
case SEL_RETRY:
@@ -5191,9 +5200,11 @@ no_gap_lock:
buf, prebuilt, rec, offsets)) {
case CHECK_NEG:
goto next_rec;
- case CHECK_OUT_OF_RANGE:
case CHECK_ABORTED_BY_USER:
- case CHECK_ERROR:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case CHECK_OUT_OF_RANGE:
+ case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
case CHECK_POS:
@@ -5251,8 +5262,10 @@ locks_ok_del_marked:
row_unlock_for_mysql(prebuilt, TRUE);
}
goto next_rec;
- case CHECK_OUT_OF_RANGE:
case CHECK_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case CHECK_OUT_OF_RANGE:
case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
@@ -5752,7 +5765,7 @@ normal_return:
func_exit:
trx->op_info = "";
- if (heap != NULL) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 68856d47b5e..987c5b60f21 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -88,7 +88,8 @@ row_undo_ins_remove_clust_rec(
online = dict_index_is_online_ddl(index);
if (online) {
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
- ut_ad(!node->trx->dict_operation_lock_mode);
+ ut_ad(node->trx->dict_operation_lock_mode
+ != RW_X_LATCH);
ut_ad(node->table->id != DICT_INDEXES_ID);
ut_ad(node->table->id != DICT_COLUMNS_ID);
mtr_s_lock_index(index, &mtr);
@@ -529,9 +530,6 @@ row_undo_ins(
return DB_SUCCESS;
}
- ut_ad(node->table->is_temporary()
- || lock_table_has_locks(node->table));
-
/* Iterate over all the indexes and undo the insert.*/
node->index = dict_table_get_first_index(node->table);
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index d32c6cd2510..af35dc1af7f 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -244,7 +244,10 @@ row_undo_mod_clust(
bool online;
ut_ad(thr_get_trx(thr) == node->trx);
+ ut_ad(node->trx->dict_operation_lock_mode);
ut_ad(node->trx->in_rollback);
+ ut_ad(rw_lock_own_flagged(&dict_sys.latch,
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
log_free_check();
pcur = &node->pcur;
@@ -261,7 +264,7 @@ row_undo_mod_clust(
online = dict_index_is_online_ddl(index);
if (online) {
- ut_ad(!node->trx->dict_operation_lock_mode);
+ ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH);
mtr_s_lock_index(index, &mtr);
}
@@ -300,7 +303,17 @@ row_undo_mod_clust(
ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
}
- if (err == DB_SUCCESS && online && dict_index_is_online_ddl(index)) {
+ /* Online rebuild cannot be initiated while we are holding
+ dict_sys.latch and index->lock. (It can be aborted.) */
+ ut_ad(online || !dict_index_is_online_ddl(index));
+
+ if (err == DB_SUCCESS && online) {
+
+ ut_ad(rw_lock_own_flagged(
+ &index->lock,
+ RW_LOCK_FLAG_S | RW_LOCK_FLAG_X
+ | RW_LOCK_FLAG_SX));
+
switch (node->rec_type) {
case TRX_UNDO_DEL_MARK_REC:
row_log_table_insert(
@@ -875,6 +888,37 @@ func_exit_no_pcur:
}
/***********************************************************//**
+Flags a secondary index corrupted. */
+static MY_ATTRIBUTE((nonnull))
+void
+row_undo_mod_sec_flag_corrupted(
+/*============================*/
+ trx_t* trx, /*!< in/out: transaction */
+ dict_index_t* index) /*!< in: secondary index */
+{
+ ut_ad(!dict_index_is_clust(index));
+
+ switch (trx->dict_operation_lock_mode) {
+ case RW_S_LATCH:
+ /* Because row_undo() is holding an S-latch
+ on the data dictionary during normal rollback,
+ we can only mark the index corrupted in the
+ data dictionary cache. TODO: fix this somehow.*/
+ mutex_enter(&dict_sys.mutex);
+ dict_set_corrupted_index_cache_only(index);
+ mutex_exit(&dict_sys.mutex);
+ break;
+ default:
+ ut_ad(0);
+ /* fall through */
+ case RW_X_LATCH:
+ /* This should be the rollback of a data dictionary
+ transaction. */
+ dict_set_corrupted(index, trx, "rollback");
+ }
+}
+
+/***********************************************************//**
Undoes a modify in secondary indexes when undo record type is UPD_DEL.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
@@ -987,7 +1031,8 @@ row_undo_mod_del_mark_sec(
}
if (err == DB_DUPLICATE_KEY) {
- index->type |= DICT_CORRUPT;
+ row_undo_mod_sec_flag_corrupted(
+ thr_get_trx(thr), index);
err = DB_SUCCESS;
/* Do not return any error to the caller. The
duplicate will be reported by ALTER TABLE or
@@ -1132,7 +1177,8 @@ row_undo_mod_upd_exist_sec(
}
if (err == DB_DUPLICATE_KEY) {
- index->type |= DICT_CORRUPT;
+ row_undo_mod_sec_flag_corrupted(
+ thr_get_trx(thr), index);
err = DB_SUCCESS;
} else if (err != DB_SUCCESS) {
break;
@@ -1295,8 +1341,6 @@ row_undo_mod(
return DB_SUCCESS;
}
- ut_ad(node->table->is_temporary()
- || lock_table_has_locks(node->table));
node->index = dict_table_get_first_index(node->table);
ut_ad(dict_index_is_clust(node->index));
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 82c999d8b53..375de331255 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -418,8 +418,7 @@ row_undo(
for online operation. (A table lock would only be acquired
when committing the ALTER TABLE operation.) */
trx_t* trx = node->trx;
- const bool locked_data_dict = UNIV_UNLIKELY(trx->is_recovered)
- && !trx->dict_operation_lock_mode;
+ const bool locked_data_dict = !trx->dict_operation_lock_mode;
if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_freeze_data_dictionary(trx);
@@ -441,7 +440,8 @@ row_undo(
err = DB_CORRUPTION;
}
- if (UNIV_UNLIKELY(locked_data_dict)) {
+ if (locked_data_dict) {
+
row_mysql_unfreeze_data_dictionary(trx);
}
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 11038c6020d..b809e5cb42a 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -459,14 +459,12 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_WORK_QUEUE);
LEVEL_MAP_INSERT(SYNC_FTS_TOKENIZE);
LEVEL_MAP_INSERT(SYNC_FTS_OPTIMIZE);
- LEVEL_MAP_INSERT(SYNC_FTS_BG_THREADS);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE_INIT);
LEVEL_MAP_INSERT(SYNC_RECV);
LEVEL_MAP_INSERT(SYNC_LOG_FLUSH_ORDER);
LEVEL_MAP_INSERT(SYNC_LOG);
LEVEL_MAP_INSERT(SYNC_PURGE_QUEUE);
LEVEL_MAP_INSERT(SYNC_TRX_SYS_HEADER);
- LEVEL_MAP_INSERT(SYNC_REC_LOCK);
LEVEL_MAP_INSERT(SYNC_TRX);
LEVEL_MAP_INSERT(SYNC_RW_TRX_HASH_ELEMENT);
LEVEL_MAP_INSERT(SYNC_READ_VIEW);
@@ -731,7 +729,6 @@ LatchDebug::check_order(
/* Fall through */
case SYNC_RECV:
- case SYNC_FTS_BG_THREADS:
case SYNC_WORK_QUEUE:
case SYNC_FTS_TOKENIZE:
case SYNC_FTS_OPTIMIZE:
@@ -796,15 +793,6 @@ LatchDebug::check_order(
}
break;
- case SYNC_REC_LOCK:
-
- if (find(latches, SYNC_LOCK_SYS) != 0) {
- basic_check(latches, level, SYNC_REC_LOCK - 1);
- } else {
- basic_check(latches, level, SYNC_REC_LOCK);
- }
- break;
-
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
@@ -1234,9 +1222,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(FIL_SYSTEM, SYNC_ANY_LATCH, fil_system_mutex_key);
- LATCH_ADD_MUTEX(FTS_BG_THREADS, SYNC_FTS_BG_THREADS,
- fts_bg_threads_mutex_key);
-
LATCH_ADD_MUTEX(FTS_DELETE, SYNC_FTS_OPTIMIZE, fts_delete_mutex_key);
LATCH_ADD_MUTEX(FTS_DOC_ID, SYNC_FTS_OPTIMIZE, fts_doc_id_mutex_key);
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index f88a3945773..dd78aa9ae14 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -41,7 +41,6 @@ mysql_pfs_key_t dict_foreign_err_mutex_key;
mysql_pfs_key_t dict_sys_mutex_key;
mysql_pfs_key_t fil_system_mutex_key;
mysql_pfs_key_t flush_list_mutex_key;
-mysql_pfs_key_t fts_bg_threads_mutex_key;
mysql_pfs_key_t fts_delete_mutex_key;
mysql_pfs_key_t fts_doc_id_mutex_key;
mysql_pfs_key_t fts_pll_tokenize_mutex_key;
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index ba006f37bb5..6b0395cef07 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -129,20 +129,35 @@ trx_undo_log_v_idx(
{
ut_ad(pos < table->n_v_def);
dict_v_col_t* vcol = dict_table_get_nth_v_col(table, pos);
- ulint n_idx = vcol->n_v_indexes;
byte* old_ptr;
- ut_ad(n_idx > 0);
+ ut_ad(!vcol->v_indexes.empty());
/* Size to reserve, max 5 bytes for each index id and position, plus
5 bytes for num of indexes, 2 bytes for write total length.
1 byte for undo log record format version marker */
- ulint size = n_idx * (5 + 5) + 5 + 2 + (first_v_col ? 1 : 0);
+ ulint size = 5 + 2 + (first_v_col ? 1 : 0);
+ const ulint avail = trx_undo_left(undo_block, ptr);
- if (trx_undo_left(undo_block, ptr) < size) {
+ if (avail < size) {
return(NULL);
}
+ size = 0;
+ ulint n_idx = 0;
+ for (const auto& v_index : vcol->v_indexes) {
+ n_idx++;
+ /* FIXME: index->id is 64 bits! */
+ size += mach_get_compressed_size(uint32_t(v_index.index->id));
+ size += mach_get_compressed_size(v_index.nth_field);
+ }
+ size += 2 + mach_get_compressed_size(n_idx);
+
+ if (avail < size) {
+ return(NULL);
+ }
+
+
if (first_v_col) {
/* write the version marker */
mach_write_to_1(ptr, VIRTUAL_COL_UNDO_FORMAT_1);
@@ -158,7 +173,8 @@ trx_undo_log_v_idx(
for (const auto& v_index : vcol->v_indexes) {
ptr += mach_write_compressed(
- ptr, static_cast<ulint>(v_index.index->id));
+ /* FIXME: index->id is 64 bits! */
+ ptr, uint32_t(v_index.index->id));
ptr += mach_write_compressed(ptr, v_index.nth_field);
}