diff options
author | Sergei Golubchik <serg@mariadb.org> | 2022-05-09 22:04:06 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2022-05-09 22:04:06 +0200 |
commit | ef781162ff2eb97f405b19dc150ab674e91dbc05 (patch) | |
tree | 63b897dece50ab65652174af4cd0aabd8f3a8505 /storage | |
parent | e9af6b2a4d8750c32d4953f08f8bc5f2e33cb9e3 (diff) | |
parent | 16cebed54065ad9e18953aa86d48f6007d53c2d3 (diff) | |
download | mariadb-git-ef781162ff2eb97f405b19dc150ab674e91dbc05.tar.gz |
Merge branch '10.4' into 10.5
Diffstat (limited to 'storage')
-rw-r--r-- | storage/connect/tabrest.cpp | 6 | ||||
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 6 | ||||
-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/dict0types.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 38 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 41 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 3 |
8 files changed, 86 insertions, 32 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 1f1233ff682..8c4caf3510a 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2,7 +2,7 @@ Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2014, 2021, MariaDB Corporation. +Copyright (c) 2014, 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 @@ -2660,8 +2660,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 (!dict_table_is_locking_disabled(cursor->index->table)) { - lock_update_split_left(next_block, block); + if (is_leaf && !dict_table_is_locking_disabled(cursor->index->table)) { + 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 9daaf0fbef3..6b4b2c7c629 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -16623,8 +16623,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 296a55522e2..4c44abae0d7 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -10659,6 +10659,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); } @@ -10982,7 +10986,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); } @@ -11386,6 +11398,8 @@ foreign_fail: row_mysql_unlock_data_dictionary(trx); trx->free(); 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/dict0types.h b/storage/innobase/include/dict0types.h index d0da45ab218..76ffef236a1 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, 2019, 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 @@ -71,7 +71,7 @@ enum dict_err_ignore_t { DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root page is FIL_NULL or incorrect value */ DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */ - DICT_ERR_IGNORE_RECOVER_LOCK = 8, + DICT_ERR_IGNORE_RECOVER_LOCK = 8 | 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 a107359ccf1..40bb557a5b2 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +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 the terms of the GNU General Public License as published by the Free Software @@ -151,6 +151,40 @@ lock_update_copy_and_discard( which copied */ const buf_block_t* block); /*!< in: index page; NOT the root! */ +/** 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 07fff9b21ad..381c59f4847 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2021, MariaDB Corporation. +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 the terms of the GNU General Public License as published by the Free Software @@ -2949,6 +2949,17 @@ lock_update_split_right( lock_mutex_exit(); } +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); + + lock_mutex_enter(); + lock_rec_inherit_to_gap(right_block, left_block, + h, PAGE_HEAP_NO_SUPREMUM); + lock_mutex_exit(); +} + /*************************************************************//** Updates the lock table when a page is merged to the right. */ void @@ -4961,25 +4972,25 @@ loop: holding a space->latch. */ if (!sync_check_find(SYNC_FSP)) 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->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, block, 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, block, rec, + lock->index, offsets); + } nth_bit = i + 1; @@ -5063,12 +5074,6 @@ static void lock_rec_block_validate(const page_id_t page_id) BUF_GET_POSSIBLY_FREED, __FILE__, __LINE__, &mtr, &err); - if (err != DB_SUCCESS) { - ib::error() << "Lock rec block validate failed for tablespace " - << space->name - << page_id << " err " << err; - } - if (block && block->page.status != buf_page_t::FREED) { buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 586d1eaf496..8f2f26be5cf 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3201,9 +3201,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. |