MDEV-25594: Assertion failure in DeadlockChecker::check_and_resolve()

ha_innobase::index_read(): If an autocommit non-locking transaction was
already started, refuse to access a SPATIAL INDEX.
Once a non-locking autocommit transaction has started, it must remain
in that mode (not acquire any locks).

This should fix one cause of the assertion failure that would occur in
DeadlockChecker::check_and_resolve() under heavy load, presumably
due to concurrent execution of trx_commit_in_memory().
This commit is contained in:
Marko Mäkelä 2021-05-18 08:37:24 +03:00
parent 23cad4d8c5
commit b9a2e4609f
2 changed files with 22 additions and 6 deletions

View File

@ -9399,8 +9399,12 @@ ha_innobase::index_read(
/* For R-Tree index, we will always place the page lock to /* For R-Tree index, we will always place the page lock to
pages being searched */ pages being searched */
if (dict_index_is_spatial(index)) { if (index->is_spatial() && !m_prebuilt->trx->will_lock) {
++m_prebuilt->trx->will_lock; if (trx_is_started(m_prebuilt->trx)) {
DBUG_RETURN(HA_ERR_READ_ONLY_TRANSACTION);
} else {
m_prebuilt->trx->will_lock = true;
}
} }
/* Note that if the index for which the search template is built is not /* Note that if the index for which the search template is built is not

View File

@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2020, MariaDB Corporation. Copyright (c) 2013, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -1036,6 +1036,21 @@ struct dict_index_t{
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF)); return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
} }
/** @return whether this is a generated clustered index */
bool is_gen_clust() const { return type == DICT_CLUSTERED; }
/** @return whether this is a clustered index */
bool is_clust() const { return type & DICT_CLUSTERED; }
/** @return whether this is a unique index */
bool is_unique() const { return type & DICT_UNIQUE; }
/** @return whether this is a spatial index */
bool is_spatial() const { return UNIV_UNLIKELY(type & DICT_SPATIAL); }
/** @return whether this is the change buffer */
bool is_ibuf() const { return UNIV_UNLIKELY(type & DICT_IBUF); }
/** @return whether the index includes virtual columns */ /** @return whether the index includes virtual columns */
bool has_virtual() const { return type & DICT_VIRTUAL; } bool has_virtual() const { return type & DICT_VIRTUAL; }
@ -1075,9 +1090,6 @@ struct dict_index_t{
} }
} }
/** @return whether this is the change buffer */
bool is_ibuf() const { return UNIV_UNLIKELY(type & DICT_IBUF); }
/** Assign the number of new column to be added as a part /** Assign the number of new column to be added as a part
of the index of the index
@param n_vcol number of virtual columns to be added */ @param n_vcol number of virtual columns to be added */