diff options
author | Sergei Golubchik <serg@mariadb.org> | 2022-05-10 11:53:59 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2022-05-10 14:01:23 +0200 |
commit | 3bc98a4ec4e7e7493ee93048dddfad87ceb3d8ff (patch) | |
tree | ad189995a78fdc6068059e65b8455d3d4e61e719 /storage | |
parent | f4d671bff2c4dcfe1bb2af6d40122576e4fcfa91 (diff) | |
parent | fe3d07cab82b2215dc64f52ac93122072c33d021 (diff) | |
download | mariadb-git-3bc98a4ec4e7e7493ee93048dddfad87ceb3d8ff.tar.gz |
Merge branch '10.5' into 10.6
Diffstat (limited to 'storage')
-rw-r--r-- | storage/connect/tabrest.cpp | 6 | ||||
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 4 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 4 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 16 | ||||
-rw-r--r-- | storage/innobase/include/buf0types.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/dict0types.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 37 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 40 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 3 | ||||
-rw-r--r-- | storage/perfschema/pfs_engine_table.cc | 3 |
10 files changed, 88 insertions, 31 deletions
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp index c66d8d76f3d..7e8b51714fb 100644 --- a/storage/connect/tabrest.cpp +++ b/storage/connect/tabrest.cpp @@ -112,7 +112,11 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename) } // endif f - pID = vfork(); +#ifdef HAVE_VFORK + pID = vfork(); +#else + pID = fork(); +#endif sprintf(fn, "-o%s", filename); if (pID == 0) { diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index cb52f4d3545..4436cf0159d 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2595,8 +2595,8 @@ btr_insert_into_right_sibling( max_size = page_get_max_insert_size_after_reorganize(next_page, 1); /* Extends gap lock for the next page */ - if (cursor->index->has_locking()) { - lock_update_split_left(next_block, block); + if (is_leaf && cursor->index->has_locking()) { + lock_update_node_pointer(block, next_block); } rec = page_cur_tuple_insert( diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8c865035751..f36ef0e107f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -16696,8 +16696,8 @@ ha_innobase::get_auto_increment( (3) It is restricted only for insert operations. */ - if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE - && autoinc < col_max_value) { + if (increment > 1 && increment <= ~autoinc && autoinc < col_max_value + && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE) { ulonglong prev_auto_inc = autoinc; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 75ab4bec2e9..ad5d9d5b0e4 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -10669,6 +10669,10 @@ commit_cache_norebuild( : NULL; DBUG_ASSERT((ctx->new_table->fts == NULL) == (ctx->new_table->fts_doc_id_index == NULL)); + if (table->found_next_number_field + && !altered_table->found_next_number_field) { + ctx->prebuilt->table->persistent_autoinc = 0; + } DBUG_RETURN(found); } @@ -10850,7 +10854,15 @@ ha_innobase::commit_inplace_alter_table( if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { DBUG_ASSERT(!ctx0); MONITOR_ATOMIC_DEC(MONITOR_PENDING_ALTER_TABLE); - ha_alter_info->group_commit_ctx = NULL; + if (table->found_next_number_field + && !altered_table->found_next_number_field) { + m_prebuilt->table->persistent_autoinc = 0; + /* Don't reset ha_alter_info->group_commit_ctx to make + partitions engine to call this function for all + partitions. */ + } + else + ha_alter_info->group_commit_ctx = NULL; DBUG_RETURN(false); } @@ -11352,6 +11364,8 @@ foreign_fail: purge_sys.resume_FTS(); } MONITOR_ATOMIC_DEC(MONITOR_PENDING_ALTER_TABLE); + /* There is no need to reset dict_table_t::persistent_autoinc + as the table is reloaded */ DBUG_RETURN(false); } diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index 5bd15889194..3cc71a3f503 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -146,7 +146,7 @@ public: m_id= (m_id & ~uint64_t{0} << 32) | page_no; } - constexpr ulonglong raw() { return m_id; } + constexpr ulonglong raw() const { return m_id; } private: /** The page identifier */ diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index 104e99fc0cd..271e4e1fb76 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, 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 @@ -72,7 +72,7 @@ enum dict_err_ignore_t { DICT_ERR_IGNORE_FK_NOKEY = 1, /*!< ignore error if any foreign key is missing */ DICT_ERR_IGNORE_INDEX = 2, /*!< ignore corrupted indexes */ - DICT_ERR_IGNORE_RECOVER_LOCK = 4, + DICT_ERR_IGNORE_RECOVER_LOCK = 4 | DICT_ERR_IGNORE_FK_NOKEY, /*!< Used when recovering table locks for resurrected transactions. Silently load a missing diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index a11bc60e7a0..b67a1011f6b 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2022, Oracle and/or its affiliates. Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -136,6 +136,41 @@ void lock_update_root_raise(const buf_block_t &block, const page_id_t root); @param new_block the target page @param old old page (not index root page) */ void lock_update_copy_and_discard(const buf_block_t &new_block, page_id_t old); + +/** Update gap locks between the last record of the left_block and the +first record of the right_block when a record is about to be inserted +at the start of the right_block, even though it should "naturally" be +inserted as the last record of the left_block according to the +current node pointer in the parent page. + +That is, we assume that the lowest common ancestor of the left_block +and right_block routes the key of the new record to the left_block, +but a heuristic which tries to avoid overflowing left_block has chosen +to insert the record into right_block instead. Said ancestor performs +this routing by comparing the key of the record to a "split point" - +all records greater or equal to than the split point (node pointer) +are in right_block, and smaller ones in left_block. +The split point may be smaller than the smallest key in right_block. + +The gap between the last record on the left_block and the first record +on the right_block is represented as a gap lock attached to the supremum +pseudo-record of left_block, and a gap lock attached to the new first +record of right_block. + +Thus, inserting the new record, and subsequently adjusting the node +pointers in parent pages to values smaller or equal to the new +records' key, will mean that gap will be sliced at a different place +("moved to the left"): fragment of the 1st gap will now become treated +as 2nd. Therefore, we must copy any GRANTED locks from 1st gap to the +2nd gap. Any WAITING locks must be of INSERT_INTENTION type (as no +other GAP locks ever wait for anything) and can stay at 1st gap, as +their only purpose is to notify the requester they can retry +insertion, and there's no correctness requirement to avoid waking them +up too soon. +@param left_block left page +@param right_block right page */ +void lock_update_node_pointer(const buf_block_t *left_block, + const buf_block_t *right_block); /*************************************************************//** Updates the lock table when a page is split to the left. */ void diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index a9aa1f9281e..4d8d3345c47 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2022, Oracle and/or its affiliates. Copyright (c) 2014, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -2752,6 +2752,18 @@ lock_update_split_right( PAGE_HEAP_NO_SUPREMUM, h); } +void lock_update_node_pointer(const buf_block_t *left_block, + const buf_block_t *right_block) +{ + const ulint h= lock_get_min_heap_no(right_block); + const page_id_t l{left_block->page.id()}; + const page_id_t r{right_block->page.id()}; + LockMultiGuard g{lock_sys.rec_hash, l, r}; + + lock_rec_inherit_to_gap(g.cell2(), r, g.cell1(), l, right_block->page.frame, + h, PAGE_HEAP_NO_SUPREMUM); +} + #ifdef UNIV_DEBUG static void lock_assert_no_spatial(const page_id_t id) { @@ -4759,25 +4771,25 @@ loop: holding a tablespace latch. */ if (!latched) for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) { - - if (i == PAGE_HEAP_NO_SUPREMUM - || lock_rec_get_nth_bit(lock, i)) { + bool locked = lock_rec_get_nth_bit(lock, i); + if (locked || i == PAGE_HEAP_NO_SUPREMUM) { rec = page_find_rec_with_heap_no(block->page.frame, i); ut_a(rec); - ut_ad(!lock_rec_get_nth_bit(lock, i) - || page_rec_is_leaf(rec)); - offsets = rec_get_offsets(rec, lock->index, offsets, - lock->index->n_core_fields, - ULINT_UNDEFINED, &heap); + ut_ad(!locked || page_rec_is_leaf(rec)); /* If this thread is holding the file space latch (fil_space_t::latch), the following check WILL break the latching order and may cause a deadlock of threads. */ - lock_rec_queue_validate( - true, id, rec, lock->index, offsets); + if (locked) { + offsets = rec_get_offsets(rec, lock->index, + offsets, lock->index->n_core_fields, + ULINT_UNDEFINED, &heap); + lock_rec_queue_validate(true, id, rec, + lock->index, offsets); + } nth_bit = i + 1; @@ -4859,12 +4871,6 @@ static void lock_rec_block_validate(const page_id_t page_id) BUF_GET_POSSIBLY_FREED, &mtr, &err); - if (err != DB_SUCCESS) { - ib::error() << "Lock rec block validate failed for tablespace " - << space->chain.start->name - << page_id << " err " << err; - } - ut_ad(!block || block->page.is_freed() || lock_rec_validate_page(block, space->is_latched())); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 2b2a0769710..a002f104516 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3121,9 +3121,6 @@ row_ins_clust_index_entry( #endif /* WITH_WSREP */ const ulint orig_n_fields = entry->n_fields; - /* Try first optimistic descent to the B-tree */ - log_free_check(); - /* For intermediate table during copy alter table, skip the undo log and record lock checking for insertion operation. diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 6b9c6a7e066..71a058273f7 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -731,7 +731,8 @@ static bool allow_drop_table_privilege() { assert(thd->lex != NULL); if ((thd->lex->sql_command != SQLCOM_TRUNCATE) && - (thd->lex->sql_command != SQLCOM_GRANT)) { + (thd->lex->sql_command != SQLCOM_GRANT) && + (thd->lex->sql_command != SQLCOM_REVOKE)) { return false; } |