summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-05-10 11:53:59 +0200
committerSergei Golubchik <serg@mariadb.org>2022-05-10 14:01:23 +0200
commit3bc98a4ec4e7e7493ee93048dddfad87ceb3d8ff (patch)
treead189995a78fdc6068059e65b8455d3d4e61e719 /storage
parentf4d671bff2c4dcfe1bb2af6d40122576e4fcfa91 (diff)
parentfe3d07cab82b2215dc64f52ac93122072c33d021 (diff)
downloadmariadb-git-3bc98a4ec4e7e7493ee93048dddfad87ceb3d8ff.tar.gz
Merge branch '10.5' into 10.6
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/tabrest.cpp6
-rw-r--r--storage/innobase/btr/btr0btr.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/handler/handler0alter.cc16
-rw-r--r--storage/innobase/include/buf0types.h2
-rw-r--r--storage/innobase/include/dict0types.h4
-rw-r--r--storage/innobase/include/lock0lock.h37
-rw-r--r--storage/innobase/lock/lock0lock.cc40
-rw-r--r--storage/innobase/row/row0ins.cc3
-rw-r--r--storage/perfschema/pfs_engine_table.cc3
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;
}