summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-05-20 17:46:05 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-05-20 17:46:05 +0300
commit5ece2155cba93a9a57e37d0c4ec624145cf8d4cf (patch)
treecec927b268e9ac53767573ce21d53b811a9662ce /storage
parentdb6e5bd9aaec7239d7c62820849a61b1059e4ad9 (diff)
parentb8e694a314b538b8bebec03a78b6df6570bd608b (diff)
downloadmariadb-git-5ece2155cba93a9a57e37d0c4ec624145cf8d4cf.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.cc2
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc5
-rw-r--r--storage/innobase/fts/fts0fts.cc28
-rw-r--r--storage/innobase/fts/fts0opt.cc41
-rw-r--r--storage/innobase/fts/fts0que.cc24
-rw-r--r--storage/innobase/handler/ha_innodb.cc2
-rw-r--r--storage/innobase/handler/handler0alter.cc21
-rw-r--r--storage/innobase/include/dict0mem.h296
-rw-r--r--storage/innobase/include/fts0priv.h2
-rw-r--r--storage/innobase/include/fts0types.h21
-rw-r--r--storage/innobase/include/fts0types.ic11
-rw-r--r--storage/innobase/include/ut0ut.h8
-rw-r--r--storage/innobase/lock/lock0lock.cc2
-rw-r--r--storage/innobase/os/os0file.cc4
-rw-r--r--storage/innobase/row/row0ins.cc43
-rw-r--r--storage/innobase/row/row0sel.cc20
-rw-r--r--storage/innobase/ut/ut0ut.cc4
-rw-r--r--storage/maria/ma_bitmap.c1
18 files changed, 255 insertions, 280 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 28876716375..e7cb05307d0 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2161,7 +2161,9 @@ dict_index_remove_from_cache_low(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(table->id);
+#ifdef BTR_CUR_HASH_ADAPT
ut_ad(!index->freed());
+#endif /* BTR_CUR_HASH_ADAPT */
/* No need to acquire the dict_index_t::lock here because
there can't be any active operations on this index (or table). */
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 90d62835856..ecb7912850f 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -2681,10 +2681,7 @@ fseg_free_extent(
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_d(space->modify_check(*mtr));
-
-#if defined BTR_CUR_HASH_ADAPT || defined UNIV_DEBUG
- const ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
-#endif /* BTR_CUR_HASH_ADAPT || UNIV_DEBUG */
+ ut_d(ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE));
const uint16_t xoffset= uint16_t(descr - xdes->frame + XDES_FLST_NODE);
const uint16_t ioffset= uint16_t(seg_inode - iblock->frame);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 18a9db369c4..7691e19a33a 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -583,7 +583,7 @@ fts_cache_init(
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = ib_vector_create(
- cache->sync_heap, sizeof(fts_update_t), 4);
+ cache->sync_heap, sizeof(doc_id_t), 4);
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
/* Reset the cache data for all the FTS indexes. */
@@ -2592,11 +2592,11 @@ dberr_t
fts_cmp_set_sync_doc_id(
/*====================*/
const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id_cmp, /*!< in: Doc ID to compare */
+ doc_id_t cmp_doc_id, /*!< in: Doc ID to compare */
ibool read_only, /*!< in: TRUE if read the
synced_doc_id only */
doc_id_t* doc_id) /*!< out: larger document id
- after comparing "doc_id_cmp"
+ after comparing "cmp_doc_id"
to the one stored in CONFIG
table */
{
@@ -2667,10 +2667,10 @@ retry:
goto func_exit;
}
- if (doc_id_cmp == 0 && *doc_id) {
+ if (cmp_doc_id == 0 && *doc_id) {
cache->synced_doc_id = *doc_id - 1;
} else {
- cache->synced_doc_id = ut_max(doc_id_cmp, *doc_id);
+ cache->synced_doc_id = ut_max(cmp_doc_id, *doc_id);
}
mutex_enter(&cache->doc_id_lock);
@@ -2681,7 +2681,7 @@ retry:
}
mutex_exit(&cache->doc_id_lock);
- if (doc_id_cmp > *doc_id) {
+ if (cmp_doc_id > *doc_id) {
error = fts_update_sync_doc_id(
table, cache->synced_doc_id, trx);
}
@@ -2803,7 +2803,7 @@ fts_doc_ids_create(void)
fts_doc_ids->self_heap = ib_heap_allocator_create(heap);
fts_doc_ids->doc_ids = static_cast<ib_vector_t*>(ib_vector_create(
- fts_doc_ids->self_heap, sizeof(fts_update_t), 32));
+ fts_doc_ids->self_heap, sizeof(doc_id_t), 32));
return(fts_doc_ids);
}
@@ -3878,7 +3878,7 @@ fts_sync_add_deleted_cache(
ut_a(ib_vector_size(doc_ids) > 0);
- ib_vector_sort(doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(doc_ids, fts_doc_id_cmp);
info = pars_info_create();
@@ -3896,13 +3896,13 @@ fts_sync_add_deleted_cache(
"BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
- fts_update_t* update;
+ doc_id_t* update;
doc_id_t write_doc_id;
- update = static_cast<fts_update_t*>(ib_vector_get(doc_ids, i));
+ update = static_cast<doc_id_t*>(ib_vector_get(doc_ids, i));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id", &write_doc_id);
error = fts_eval_sql(sync->trx, graph);
@@ -5193,12 +5193,12 @@ fts_cache_append_deleted_doc_ids(
for (ulint i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
- fts_update_t* update;
+ doc_id_t* update;
- update = static_cast<fts_update_t*>(
+ update = static_cast<doc_id_t*>(
ib_vector_get(cache->deleted_doc_ids, i));
- ib_vector_push(vector, &update->doc_id);
+ ib_vector_push(vector, &update);
}
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index fd2156c006e..849cbb7e15b 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, 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
@@ -925,7 +925,7 @@ fts_fetch_doc_ids(
int i = 0;
sel_node_t* sel_node = static_cast<sel_node_t*>(row);
fts_doc_ids_t* fts_doc_ids = static_cast<fts_doc_ids_t*>(user_arg);
- fts_update_t* update = static_cast<fts_update_t*>(
+ doc_id_t* update = static_cast<doc_id_t*>(
ib_vector_push(fts_doc_ids->doc_ids, NULL));
for (exp = sel_node->select_list;
@@ -941,8 +941,7 @@ fts_fetch_doc_ids(
/* Note: The column numbers below must match the SELECT. */
switch (i) {
case 0: /* DOC_ID */
- update->fts_indexes = NULL;
- update->doc_id = fts_read_doc_id(
+ *update = fts_read_doc_id(
static_cast<byte*>(data));
break;
@@ -1010,7 +1009,7 @@ fts_table_fetch_doc_ids(
mutex_exit(&dict_sys.mutex);
if (error == DB_SUCCESS) {
- ib_vector_sort(doc_ids->doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp);
}
if (alloc_bk_trx) {
@@ -1027,7 +1026,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
- fts_update_t* array, /*!< in: array to sort */
+ doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: the array lower bound */
int upper, /*!< in: the array upper bound */
doc_id_t doc_id) /*!< in: the doc id to search for */
@@ -1041,9 +1040,9 @@ fts_bsearch(
while (lower < upper) {
int i = (lower + upper) >> 1;
- if (doc_id > array[i].doc_id) {
+ if (doc_id > array[i]) {
lower = i + 1;
- } else if (doc_id < array[i].doc_id) {
+ } else if (doc_id < array[i]) {
upper = i - 1;
} else {
return(i); /* Found. */
@@ -1052,7 +1051,7 @@ fts_bsearch(
}
if (lower == upper && lower < orig_size) {
- if (doc_id == array[lower].doc_id) {
+ if (doc_id == array[lower]) {
return(lower);
} else if (lower == 0) {
return(-1);
@@ -1079,7 +1078,7 @@ fts_optimize_lookup(
{
int pos;
int upper = static_cast<int>(ib_vector_size(doc_ids));
- fts_update_t* array = (fts_update_t*) doc_ids->data;
+ doc_id_t* array = (doc_id_t*) doc_ids->data;
pos = fts_bsearch(array, static_cast<int>(lower), upper, first_doc_id);
@@ -1092,10 +1091,10 @@ fts_optimize_lookup(
/* If i is 1, it could be first_doc_id is less than
either the first or second array item, do a
double check */
- if (i == 1 && array[0].doc_id <= last_doc_id
- && first_doc_id < array[0].doc_id) {
+ if (i == 1 && array[0] <= last_doc_id
+ && first_doc_id < array[0]) {
pos = 0;
- } else if (i < upper && array[i].doc_id <= last_doc_id) {
+ } else if (i < upper && array[i] <= last_doc_id) {
/* Check if the "next" doc id is within the
first & last doc id of the node. */
@@ -1234,12 +1233,12 @@ test_again:
delta for decoding the entries following this document's
entries. */
if (*del_pos >= 0 && *del_pos < (int) ib_vector_size(del_vec)) {
- fts_update_t* update;
+ doc_id_t* update;
- update = (fts_update_t*) ib_vector_get(
+ update = (doc_id_t*) ib_vector_get(
del_vec, ulint(*del_pos));
- del_doc_id = update->doc_id;
+ del_doc_id = *update;
}
if (enc->src_ilist_ptr == src_node->ilist && doc_id == 0) {
@@ -2025,7 +2024,7 @@ fts_optimize_purge_deleted_doc_ids(
ulint i;
pars_info_t* info;
que_t* graph;
- fts_update_t* update;
+ doc_id_t* update;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
char deleted[MAX_FULL_NAME_LEN];
@@ -2035,11 +2034,11 @@ fts_optimize_purge_deleted_doc_ids(
ut_a(ib_vector_size(optim->to_delete->doc_ids) > 0);
- update = static_cast<fts_update_t*>(
+ update = static_cast<doc_id_t*>(
ib_vector_get(optim->to_delete->doc_ids, 0));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
/* This is required for the SQL parser to work. It must be able
to find the following variables. So we do it twice. */
@@ -2061,11 +2060,11 @@ fts_optimize_purge_deleted_doc_ids(
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
- update = static_cast<fts_update_t*>(ib_vector_get(
+ update = static_cast<doc_id_t*>(ib_vector_get(
optim->to_delete->doc_ids, i));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id1", &write_doc_id);
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index c912f5e0764..c789502512c 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -731,10 +731,10 @@ fts_query_union_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's not already in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
fts_ranking_t ranking;
@@ -762,10 +762,10 @@ fts_query_remove_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
ut_free(rbt_remove_node(query->doc_ids, parent.last));
@@ -792,10 +792,10 @@ fts_query_change_ranking(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
fts_ranking_t* ranking;
@@ -829,7 +829,7 @@ fts_query_intersect_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
fts_ranking_t* ranking= NULL;
/* There are three types of intersect:
@@ -841,7 +841,7 @@ fts_query_intersect_doc_id(
if it matches 'b' and it's in doc_ids.(multi_exist = true). */
/* Check if the doc id is deleted and it's in our set */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0) {
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0) {
fts_ranking_t new_ranking;
if (rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
@@ -3651,8 +3651,8 @@ fts_query_prepare_result(
if (query->flags == FTS_OPT_RANKING) {
fts_word_freq_t* word_freq;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array =
- (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates =
+ (doc_id_t*) query->deleted->doc_ids->data;
node = rbt_first(query->word_freqs);
ut_ad(node);
@@ -3667,7 +3667,7 @@ fts_query_prepare_result(
doc_freq = rbt_value(fts_doc_freq_t, node);
/* Don't put deleted docs into result */
- if (fts_bsearch(array, 0, static_cast<int>(size),
+ if (fts_bsearch(updates, 0, static_cast<int>(size),
doc_freq->doc_id) >= 0) {
/* one less matching doc count */
--word_freq->doc_count;
@@ -4018,7 +4018,7 @@ fts_query(
DEBUG_SYNC_C("fts_deleted_doc_ids_append");
/* Sort the vector so that we can do a binary search over the ids. */
- ib_vector_sort(query.deleted->doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(query.deleted->doc_ids, fts_doc_id_cmp);
/* Convert the query string to lower case before parsing. We own
the ut_malloc'ed result and so remember to free it before return. */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 98ea873a9d6..c98dc54ddb0 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -20141,7 +20141,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"Number of threads performing background key rotation ",
NULL,
innodb_encryption_threads_update,
- srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
+ 0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 7720c7f0897..2d8c7c3f942 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1018,16 +1018,12 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
@return whether the table will be rebuilt */
bool need_rebuild () const { return(old_table != new_table); }
- /** Clear uncommmitted added indexes after a failed operation. */
- void clear_added_indexes()
- {
- for (ulint i = 0; i < num_to_add_index; i++) {
- if (!add_index[i]->is_committed()) {
- add_index[i]->detach_columns();
- add_index[i]->n_fields = 0;
- }
- }
- }
+ /** Clear uncommmitted added indexes after a failed operation. */
+ void clear_added_indexes()
+ {
+ for (ulint i= 0; i < num_to_add_index; i++)
+ add_index[i]->detach_columns(true);
+ }
/** Convert table-rebuilding ALTER to instant ALTER. */
void prepare_instant()
@@ -6190,6 +6186,7 @@ prepare_inplace_alter_table_dict(
create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table,
ha_alter_info->create_info, NULL, NULL,
srv_file_per_table);
+ ut_d(bool stats_wait = false);
/* The primary index would be rebuilt if a FTS Doc ID
column is to be added, and the primary index definition
@@ -6241,6 +6238,7 @@ prepare_inplace_alter_table_dict(
XXX what may happen if bg stats opens the table after we
have unlocked data dictionary below? */
dict_stats_wait_bg_to_stop_using_table(user_table, ctx->trx);
+ ut_d(stats_wait = true);
online_retry_drop_indexes_low(ctx->new_table, ctx->trx);
@@ -7123,7 +7121,8 @@ error_handled:
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
holding dict_sys.latch X-latch. */
- DBUG_ASSERT(user_table->get_ref_count() == 1 || ctx->online);
+ ut_ad(!stats_wait || ctx->online
+ || user_table->get_ref_count() == 1);
online_retry_drop_indexes_with_trx(user_table, ctx->trx);
} else {
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 1691cb22512..0984b464049 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -579,101 +579,103 @@ private:
static const unsigned DROPPED = 1023;
public:
- /** Detach the column from an index.
- @param[in] index index to be detached from */
- inline void detach(const dict_index_t& index);
-
- /** Data for instantly added columns */
- struct def_t {
- /** original default value of instantly added column */
- const void* data;
- /** len of data, or UNIV_SQL_DEFAULT if unavailable */
- ulint len;
- } def_val;
-
- /** Retrieve the column name.
- @param[in] table the table of this column */
- const char* name(const dict_table_t& table) const;
-
- /** @return whether this is a virtual column */
- bool is_virtual() const { return prtype & DATA_VIRTUAL; }
- /** @return whether NULL is an allowed value for this column */
- bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
-
- /** @return whether table of this system field is TRX_ID-based */
- bool vers_native() const
- {
- ut_ad(vers_sys_start() || vers_sys_end());
- ut_ad(mtype == DATA_INT || mtype == DATA_FIXBINARY);
- return mtype == DATA_INT;
- }
- /** @return whether this user column (not row_start, row_end)
- has System Versioning property */
- bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
- /** @return whether this is the system version start */
- bool vers_sys_start() const
- {
- return (prtype & DATA_VERSIONED) == DATA_VERS_START;
- }
- /** @return whether this is the system version end */
- bool vers_sys_end() const
- {
- return (prtype & DATA_VERSIONED) == DATA_VERS_END;
- }
+ /** Detach a virtual column from an index.
+ @param index being-freed index */
+ inline void detach(const dict_index_t &index);
- /** @return whether this is an instantly-added column */
- bool is_added() const
- {
- DBUG_ASSERT(def_val.len != UNIV_SQL_DEFAULT || !def_val.data);
- return def_val.len != UNIV_SQL_DEFAULT;
- }
- /** Flag the column instantly dropped */
- void set_dropped() { ind = DROPPED; }
- /** Flag the column instantly dropped.
- @param[in] not_null whether the column was NOT NULL
- @param[in] len2 whether the length exceeds 255 bytes
- @param[in] fixed_len the fixed length in bytes, or 0 */
- void set_dropped(bool not_null, bool len2, unsigned fixed)
- {
- DBUG_ASSERT(!len2 || !fixed);
- prtype = not_null
- ? DATA_NOT_NULL | DATA_BINARY_TYPE
- : DATA_BINARY_TYPE;
- if (fixed) {
- mtype = DATA_FIXBINARY;
- len = static_cast<uint16_t>(fixed);
- } else {
- mtype = DATA_BINARY;
- len = len2 ? 65535 : 255;
- }
- mbminlen = mbmaxlen = 0;
- ind = DROPPED;
- ord_part = 0;
- max_prefix = 0;
- }
- /** @return whether the column was instantly dropped */
- bool is_dropped() const { return ind == DROPPED; }
- /** @return whether the column was instantly dropped
- @param[in] index the clustered index */
- inline bool is_dropped(const dict_index_t& index) const;
+ /** Data for instantly added columns */
+ struct def_t
+ {
+ /** original default value of instantly added column */
+ const void *data;
+ /** len of data, or UNIV_SQL_DEFAULT if unavailable */
+ ulint len;
+ } def_val;
+
+ /** Retrieve the column name.
+ @param table the table of this column */
+ const char *name(const dict_table_t &table) const;
+
+ /** @return whether this is a virtual column */
+ bool is_virtual() const { return prtype & DATA_VIRTUAL; }
+ /** @return whether NULL is an allowed value for this column */
+ bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
+
+ /** @return whether table of this system field is TRX_ID-based */
+ bool vers_native() const
+ {
+ ut_ad(vers_sys_start() || vers_sys_end());
+ ut_ad(mtype == DATA_INT || mtype == DATA_FIXBINARY);
+ return mtype == DATA_INT;
+ }
+ /** @return whether this user column (not row_start, row_end)
+ has System Versioning property */
+ bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
+ /** @return whether this is the system version start */
+ bool vers_sys_start() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_START;
+ }
+ /** @return whether this is the system version end */
+ bool vers_sys_end() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_END;
+ }
- /** Get the default value of an instantly-added column.
- @param[out] len value length (in bytes), or UNIV_SQL_NULL
- @return default value
- @retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
- const byte* instant_value(ulint* len) const
- {
- DBUG_ASSERT(is_added());
- *len = def_val.len;
- return static_cast<const byte*>(def_val.data);
- }
+ /** @return whether this is an instantly-added column */
+ bool is_added() const
+ {
+ DBUG_ASSERT(def_val.len != UNIV_SQL_DEFAULT || !def_val.data);
+ return def_val.len != UNIV_SQL_DEFAULT;
+ }
+ /** Flag the column instantly dropped */
+ void set_dropped() { ind = DROPPED; }
+ /** Flag the column instantly dropped.
+ @param not_null whether the column was NOT NULL
+ @param len2 whether the length exceeds 255 bytes
+ @param fixed_len the fixed length in bytes, or 0 */
+ void set_dropped(bool not_null, bool len2, unsigned fixed)
+ {
+ DBUG_ASSERT(!len2 || !fixed);
+ prtype= not_null ? DATA_NOT_NULL | DATA_BINARY_TYPE : DATA_BINARY_TYPE;
+ if (fixed)
+ {
+ mtype= DATA_FIXBINARY;
+ len= static_cast<uint16_t>(fixed);
+ }
+ else
+ {
+ mtype= DATA_BINARY;
+ len= len2 ? 65535 : 255;
+ }
+ mbminlen= mbmaxlen= 0;
+ ind= DROPPED;
+ ord_part= 0;
+ max_prefix= 0;
+ }
+ /** @return whether the column was instantly dropped */
+ bool is_dropped() const { return ind == DROPPED; }
+ /** @return whether the column was instantly dropped
+ @param index the clustered index */
+ inline bool is_dropped(const dict_index_t &index) const;
+
+ /** Get the default value of an instantly-added column.
+ @param[out] len value length (in bytes), or UNIV_SQL_NULL
+ @return default value
+ @retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
+ const byte *instant_value(ulint *len) const
+ {
+ DBUG_ASSERT(is_added());
+ *len= def_val.len;
+ return static_cast<const byte*>(def_val.data);
+ }
- /** Remove the 'instant ADD' status of the column */
- void clear_instant()
- {
- def_val.len = UNIV_SQL_DEFAULT;
- def_val.data = NULL;
- }
+ /** Remove the 'instant ADD' status of the column */
+ void clear_instant()
+ {
+ def_val.len= UNIV_SQL_DEFAULT;
+ def_val.data= NULL;
+ }
/** @return whether two columns have compatible data type encoding */
bool same_type(const dict_col_t &other) const
@@ -719,24 +721,21 @@ public:
/** @return whether two collations codes have the same character encoding */
static bool same_encoding(uint16_t a, uint16_t b);
- /** Determine if the columns have the same format
- except for is_nullable() and is_versioned().
- @param[in] other column to compare to
- @return whether the columns have the same format */
- bool same_format(const dict_col_t& other) const
- {
- return same_type(other)
- && len >= other.len
- && mbminlen == other.mbminlen
- && mbmaxlen == other.mbmaxlen
- && !((prtype ^ other.prtype)
- & ~(DATA_NOT_NULL | DATA_VERSIONED
- | CHAR_COLL_MASK << 16
- | DATA_LONG_TRUE_VARCHAR));
- }
+ /** Determine if the columns have the same format
+ except for is_nullable() and is_versioned().
+ @param other column to compare to
+ @return whether the columns have the same format */
+ bool same_format(const dict_col_t &other) const
+ {
+ return same_type(other) && len >= other.len &&
+ mbminlen == other.mbminlen && mbmaxlen == other.mbmaxlen &&
+ !((prtype ^ other.prtype) & ~(DATA_NOT_NULL | DATA_VERSIONED |
+ CHAR_COLL_MASK << 16 |
+ DATA_LONG_TRUE_VARCHAR));
+ }
/** @return whether the column values are comparable by memcmp() */
- inline bool is_binary() const { return prtype & DATA_BINARY_TYPE; }
+ bool is_binary() const { return prtype & DATA_BINARY_TYPE; }
};
/** Index information put in a list of virtual column structure. Index
@@ -774,27 +773,30 @@ struct dict_v_col_t{
std::forward_list<dict_v_idx_t, ut_allocator<dict_v_idx_t> >
v_indexes;
- /** Detach the column from an index.
- @param[in] index index to be detached from */
- void detach(const dict_index_t& index)
- {
- if (!n_v_indexes) 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;
- }
- } while (i != v_indexes.end());
- }
+ /** Detach the column from an index.
+ @param index index to be detached from */
+ void detach(const dict_index_t &index)
+ {
+ if (!n_v_indexes) 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;
+ }
+ }
+ while (i != v_indexes.end());
+ }
};
/** Data structure for newly added virtual column in a table */
@@ -1204,15 +1206,22 @@ public:
/** @return whether the index is corrupted */
inline bool is_corrupted() const;
- /** Detach the columns from the index that is to be freed. */
- void detach_columns()
- {
- if (has_virtual()) {
- for (unsigned i = 0; i < n_fields; i++) {
- fields[i].col->detach(*this);
- }
- }
- }
+ /** Detach the virtual columns from the index that is to be removed.
+ @param whether to reset fields[].col */
+ void detach_columns(bool clear= false)
+ {
+ if (!has_virtual())
+ return;
+ for (unsigned i= 0; i < n_fields; i++)
+ {
+ dict_col_t* col= fields[i].col;
+ if (!col || !col->is_virtual())
+ continue;
+ col->detach(*this);
+ if (clear)
+ fields[i].col= nullptr;
+ }
+ }
/** Determine how many fields of a given prefix can be set NULL.
@param[in] n_prefix number of fields in the prefix
@@ -1358,13 +1367,12 @@ public:
inline record_size_info_t record_size_info() const;
};
-/** Detach a column from an index.
-@param[in] index index to be detached from */
-inline void dict_col_t::detach(const dict_index_t& index)
+/** Detach a virtual column from an index.
+@param index being-freed index */
+inline void dict_col_t::detach(const dict_index_t &index)
{
- if (is_virtual()) {
- reinterpret_cast<dict_v_col_t*>(this)->detach(index);
- }
+ if (is_virtual())
+ reinterpret_cast<dict_v_col_t*>(this)->detach(index);
}
/** The status of online index creation */
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index 6d8617da0c9..09d3a77ba79 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -239,7 +239,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
- fts_update_t* array, /*!< in: array to sort */
+ doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: lower bound of array*/
int upper, /*!< in: upper bound of array*/
doc_id_t doc_id) /*!< in: doc id to lookup */
diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h
index a08a60b9e95..44c3ab77695 100644
--- a/storage/innobase/include/fts0types.h
+++ b/storage/innobase/include/fts0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -80,20 +80,6 @@ struct fts_index_cache_t {
CHARSET_INFO* charset; /*!< charset */
};
-/** For supporting the tracking of updates on multiple FTS indexes we need
-to track which FTS indexes need to be updated. For INSERT and DELETE we
-update all fts indexes. */
-struct fts_update_t {
- doc_id_t doc_id; /*!< The doc id affected */
-
- ib_vector_t* fts_indexes; /*!< The FTS indexes that need to be
- updated. A NULL value means all
- indexes need to be updated. This
- vector is not allocated on the heap
- and so must be freed explicitly,
- when we are done with it */
-};
-
/** Stop word control infotmation. */
struct fts_stopword_t {
ulint status; /*!< Status of the stopword tree */
@@ -319,10 +305,9 @@ fts_ranking_doc_id_cmp(
const void* p2); /*!< in: id2 */
/******************************************************************//**
-Compare two fts_update_t instances doc_ids. */
+Compare two doc_ids. */
UNIV_INLINE
-int
-fts_update_doc_id_cmp(
+int fts_doc_id_cmp(
/*==================*/
/*!< out:
< 0 if n1 < n2,
diff --git a/storage/innobase/include/fts0types.ic b/storage/innobase/include/fts0types.ic
index 4974a7a6802..facc1e5c40b 100644
--- a/storage/innobase/include/fts0types.ic
+++ b/storage/innobase/include/fts0types.ic
@@ -79,19 +79,18 @@ fts_ranking_doc_id_cmp(
}
/******************************************************************//**
-Compare two fts_update_t doc_ids.
+Compare two doc_ids.
@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */
UNIV_INLINE
-int
-fts_update_doc_id_cmp(
+int fts_doc_id_cmp(
/*==================*/
const void* p1, /*!< in: id1 */
const void* p2) /*!< in: id2 */
{
- const fts_update_t* up1 = (const fts_update_t*) p1;
- const fts_update_t* up2 = (const fts_update_t*) p2;
+ const doc_id_t* up1 = static_cast<const doc_id_t*>(p1);
+ const doc_id_t* up2 = static_cast<const doc_id_t*>(p2);
- return((int)(up1->doc_id - up2->doc_id));
+ return static_cast<int>(*up1 - *up2);
}
/******************************************************************//**
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 0814b90979d..14e31b1d9a8 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -411,6 +411,14 @@ class error : public logger {
public:
ATTRIBUTE_COLD
~error();
+ /** Indicates that error::~error() was invoked. Can be used to
+ determine if error messages were logged during innodb code execution.
+ @return true if there were error messages, false otherwise. */
+ static bool was_logged() { return logged; }
+
+private:
+ /** true if error::~error() was invoked, false otherwise */
+ static bool logged;
};
/** The class fatal is used to emit an error message and stop the server
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 61052b15431..622e5ba7515 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -6207,7 +6207,7 @@ static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
ut_ad(lock->trx == element->trx);
if (lock_get_type_low(lock) == LOCK_REC)
{
- ut_ad(!dict_index_is_online_ddl(lock->index) ||
+ ut_ad(lock->index->online_status != ONLINE_INDEX_CREATION ||
lock->index->is_primary());
ut_ad(lock->index->table != table);
}
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index fdbac4a69bf..cfc2e1f57a8 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -4005,7 +4005,7 @@ static bool is_linux_native_aio_supported()
case -EINVAL:
case -ENOSYS:
- ib::error()
+ ib::warn()
<< "Linux Native AIO not supported. You can either"
" move "
<< (srv_read_only_mode ? log_file_path : "tmpdir")
@@ -4015,7 +4015,7 @@ static bool is_linux_native_aio_supported()
/* fall through. */
default:
- ib::error()
+ ib::warn()
<< "Linux Native AIO check on "
<< (srv_read_only_mode ? log_file_path : "tmpdir")
<< "returned error[" << -err << "]";
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index e5b697dbe31..4cf19e3ee8e 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -58,35 +58,22 @@ check.
If you make a change in this module make sure that no codepath is
introduced where a call to log_free_check() is bypassed. */
-/***********************************************************//**
-Creates an entry template for each index of a table. */
-static
-void
-ins_node_create_entry_list(
-/*=======================*/
- ins_node_t* node) /*!< in: row insert node */
+/** Create an row template for each index of a table. */
+static void ins_node_create_entry_list(ins_node_t *node)
{
- dict_index_t* index;
- dtuple_t* entry;
-
- ut_ad(node->entry_sys_heap);
-
- /* We will include all indexes (include those corrupted
- secondary indexes) in the entry list. Filtration of
- these corrupted index will be done in row_ins() */
-
- node->entry_list.reserve(UT_LIST_GET_LEN(node->table->indexes));
-
- for (index = dict_table_get_first_index(node->table);
- index != 0;
- index = dict_table_get_next_index(index)) {
-
- entry = row_build_index_entry_low(
- node->row, NULL, index, node->entry_sys_heap,
- ROW_BUILD_FOR_INSERT);
-
- node->entry_list.push_back(entry);
- }
+ node->entry_list.reserve(UT_LIST_GET_LEN(node->table->indexes));
+
+ for (dict_index_t *index= dict_table_get_first_index(node->table); index;
+ index= dict_table_get_next_index(index))
+ {
+ /* Corrupted or incomplete secondary indexes will be filtered out in
+ row_ins(). */
+ dtuple_t *entry= index->online_status >= ONLINE_INDEX_ABORTED
+ ? dtuple_create(node->entry_sys_heap, 0)
+ : row_build_index_entry_low(node->row, NULL, index, node->entry_sys_heap,
+ ROW_BUILD_FOR_INSERT);
+ node->entry_list.push_back(entry);
+ }
}
/*****************************************************************//**
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 7bcbbe8dcea..34d83ef5e80 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -1280,10 +1280,6 @@ void
row_sel_open_pcur(
/*==============*/
plan_t* plan, /*!< in: table plan */
-#ifdef BTR_CUR_HASH_ADAPT
- rw_lock_t* ahi_latch,
- /*!< in: the adaptive hash index latch */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
@@ -1327,7 +1323,7 @@ row_sel_open_pcur(
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
BTR_SEARCH_LEAF, &plan->pcur,
- ahi_latch, mtr);
+ NULL, mtr);
} else {
/* Open the cursor to the start or the end of the index
(FALSE: no init) */
@@ -1472,16 +1468,12 @@ row_sel_try_search_shortcut(
ut_ad(plan->unique_search);
ut_ad(!plan->must_get_clust);
- rw_lock_t* ahi_latch = btr_get_search_latch(index);
- rw_lock_s_lock(ahi_latch);
-
- row_sel_open_pcur(plan, ahi_latch, mtr);
+ row_sel_open_pcur(plan, mtr);
const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, *index)) {
retry:
- rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY);
}
@@ -1493,7 +1485,6 @@ retry:
if (btr_pcur_get_up_match(&(plan->pcur)) < plan->n_exact_match) {
exhausted:
- rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED);
}
@@ -1539,7 +1530,6 @@ exhausted:
ut_ad(plan->pcur.latch_mode == BTR_SEARCH_LEAF);
plan->n_rows_fetched++;
- rw_lock_s_unlock(ahi_latch);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -1661,11 +1651,7 @@ table_loop:
if (!plan->pcur_is_open) {
/* Evaluate the expressions to build the search tuple and
open the cursor */
- row_sel_open_pcur(plan,
-#ifdef BTR_CUR_HASH_ADAPT
- NULL,
-#endif /* BTR_CUR_HASH_ADAPT */
- &mtr);
+ row_sel_open_pcur(plan, &mtr);
cursor_just_opened = TRUE;
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index 5c19fcb6825..c7762fb2273 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -576,9 +576,13 @@ warn::~warn()
sql_print_warning("InnoDB: %s", m_oss.str().c_str());
}
+/** true if error::~error() was invoked, false otherwise */
+bool error::logged;
+
error::~error()
{
sql_print_error("InnoDB: %s", m_oss.str().c_str());
+ logged = true;
}
#ifdef _MSC_VER
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 391ffb4b2e6..e3b1e887747 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -1288,6 +1288,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16;
data= bitmap->map+byte;
+ first_found= 0; /* Don't update full_head_size */
DBUG_ASSERT(data <= end);
}
else