summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
committerSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
commitef781162ff2eb97f405b19dc150ab674e91dbc05 (patch)
tree63b897dece50ab65652174af4cd0aabd8f3a8505 /storage
parente9af6b2a4d8750c32d4953f08f8bc5f2e33cb9e3 (diff)
parent16cebed54065ad9e18953aa86d48f6007d53c2d3 (diff)
downloadmariadb-git-ef781162ff2eb97f405b19dc150ab674e91dbc05.tar.gz
Merge branch '10.4' into 10.5
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/tabrest.cpp6
-rw-r--r--storage/innobase/btr/btr0btr.cc6
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/handler/handler0alter.cc16
-rw-r--r--storage/innobase/include/dict0types.h4
-rw-r--r--storage/innobase/include/lock0lock.h38
-rw-r--r--storage/innobase/lock/lock0lock.cc41
-rw-r--r--storage/innobase/row/row0ins.cc3
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.