diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-20 17:46:05 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-20 17:46:05 +0300 |
commit | 5ece2155cba93a9a57e37d0c4ec624145cf8d4cf (patch) | |
tree | cec927b268e9ac53767573ce21d53b811a9662ce /storage | |
parent | db6e5bd9aaec7239d7c62820849a61b1059e4ad9 (diff) | |
parent | b8e694a314b538b8bebec03a78b6df6570bd608b (diff) | |
download | mariadb-git-5ece2155cba93a9a57e37d0c4ec624145cf8d4cf.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 2 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 5 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 28 | ||||
-rw-r--r-- | storage/innobase/fts/fts0opt.cc | 41 | ||||
-rw-r--r-- | storage/innobase/fts/fts0que.cc | 24 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 21 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 296 | ||||
-rw-r--r-- | storage/innobase/include/fts0priv.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/fts0types.h | 21 | ||||
-rw-r--r-- | storage/innobase/include/fts0types.ic | 11 | ||||
-rw-r--r-- | storage/innobase/include/ut0ut.h | 8 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 2 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 43 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 20 | ||||
-rw-r--r-- | storage/innobase/ut/ut0ut.cc | 4 | ||||
-rw-r--r-- | storage/maria/ma_bitmap.c | 1 |
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 |