summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-08-10 21:08:46 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-08-10 21:08:46 +0300
commiteae968f62d285de97ed607c87bc131cd863d5d03 (patch)
treeb86dacfaf9e1340161d3675204544a4db937eb05 /storage/innobase
parent101ddc5e2708e4e32f1aaa7a02fe85f0da95b73a (diff)
parentbafc5c1321a7dff5f2da292111bf98fed9d1658d (diff)
downloadmariadb-git-eae968f62d285de97ed607c87bc131cd863d5d03.tar.gz
Merge 10.3 into 10.4
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/fil/fil0crypt.cc122
-rw-r--r--storage/innobase/fil/fil0fil.cc114
-rw-r--r--storage/innobase/include/fil0fil.h54
-rw-r--r--storage/innobase/include/sync0types.h1
-rw-r--r--storage/innobase/lock/lock0lock.cc22
-rw-r--r--storage/innobase/sync/sync0debug.cc2
6 files changed, 121 insertions, 194 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 7c342ca0637..7c4046871cc 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "fil0pagecompress.h"
#include <my_crypt.h>
-/** Mutex for keys */
-static ib_mutex_t fil_crypt_key_mutex;
-
static bool fil_crypt_threads_inited = false;
/** Is encryption enabled/disabled */
@@ -113,8 +110,6 @@ UNIV_INTERN
void
fil_space_crypt_init()
{
- mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex);
-
fil_crypt_throttle_sleep_event = os_event_create(0);
mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex);
@@ -128,7 +123,6 @@ void
fil_space_crypt_cleanup()
{
os_event_destroy(fil_crypt_throttle_sleep_event);
- mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
}
@@ -1582,6 +1576,94 @@ fil_crypt_return_iops(
fil_crypt_update_total_stat(state);
}
+/** Return the next tablespace from rotation_list.
+@param space previous tablespace (NULL to start from the start)
+@param recheck whether the removal condition needs to be rechecked after
+the encryption parameters were changed
+@param encrypt expected state of innodb_encrypt_tables
+@return the next tablespace to process (n_pending_ops incremented)
+@retval NULL if this was the last */
+inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
+ bool recheck, bool encrypt)
+{
+ ut_ad(mutex_own(&mutex));
+
+ sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
+ space ? space : rotation_list.begin();
+ const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
+ rotation_list.end();
+
+ if (space)
+ {
+ while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
+
+ /* If one of the encryption threads already started the encryption
+ of the table then don't remove the unencrypted spaces from rotation list
+
+ If there is a change in innodb_encrypt_tables variables value then
+ don't remove the last processed tablespace from the rotation list. */
+ space->release();
+
+ if (!space->referenced() &&
+ (!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables &&
+ space->is_in_rotation_list)
+ {
+ ut_a(!rotation_list.empty());
+ rotation_list.remove(*space);
+ space->is_in_rotation_list= false;
+ }
+ }
+
+ if (it == end)
+ return NULL;
+
+ space= &*it;
+ space->acquire();
+ return space;
+}
+
+/** Return the next tablespace.
+@param space previous tablespace (NULL to start from the beginning)
+@param recheck whether the removal condition needs to be rechecked after
+the encryption parameters were changed
+@param encrypt expected state of innodb_encrypt_tables
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_next(fil_space_t *space, bool recheck,
+ bool encrypt)
+{
+ mutex_enter(&fil_system.mutex);
+
+ if (!srv_fil_crypt_rotate_key_age)
+ space= fil_system.keyrotate_next(space, recheck, encrypt);
+ else if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system.space_list);
+ /* We can trust that space is not NULL because at least the
+ system tablespace is always present and loaded first. */
+ space->acquire();
+ }
+ else
+ {
+ /* Move on to the next fil_space_t */
+ space->release();
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ /* Skip abnormal tablespaces or those that are being created by
+ fil_ibd_create(), or being dropped. */
+ while (space &&
+ (UT_LIST_GET_LEN(space->chain) == 0 ||
+ space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE))
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ if (space)
+ space->acquire();
+ }
+
+ mutex_exit(&fil_system.mutex);
+ return space;
+}
+
/** Search for a space needing rotation
@param[in,out] key_state Key state
@param[in,out] state Rotation state
@@ -1614,13 +1696,8 @@ static bool fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- /* If key rotation is enabled (default) we iterate all tablespaces.
- If key rotation is not enabled we iterate only the tablespaces
- added to keyrotation list. */
- state->space = srv_fil_crypt_rotate_key_age
- ? fil_space_next(state->space)
- : fil_system.keyrotate_next(state->space, *recheck,
- key_state->key_version);
+ state->space = fil_space_next(state->space, *recheck,
+ key_state->key_version != 0);
while (!state->should_shutdown() && state->space) {
/* If there is no crypt data and we have not yet read
@@ -1638,13 +1715,16 @@ static bool fil_crypt_find_space_to_rotate(
return true;
}
- state->space = srv_fil_crypt_rotate_key_age
- ? fil_space_next(state->space)
- : fil_system.keyrotate_next(state->space, *recheck,
- key_state->key_version);
+ state->space = fil_space_next(state->space, *recheck,
+ key_state->key_version != 0);
+ }
+
+ if (state->space) {
+ state->space->release();
+ state->space = NULL;
}
- /* if we didn't find any space return iops */
+ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state);
return false;
@@ -2455,13 +2535,11 @@ static void fil_crypt_rotation_list_fill()
if (!space->size) {
/* Protect the tablespace while we may
release fil_system.mutex. */
- space->n_pending_ops++;
-#ifndef DBUG_OFF
+ ut_d(space->acquire());
ut_d(const fil_space_t* s=)
fil_system.read_page0(space->id);
ut_ad(!s || s == space);
-#endif
- space->n_pending_ops--;
+ ut_d(space->release());
if (!space->size) {
/* Page 0 was not loaded.
Skip this tablespace. */
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 57303a25300..d47e9f3f5bf 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -4914,120 +4914,6 @@ test_make_filepath()
#endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */
/* @} */
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_t::acquire() and fil_space_t::release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system.space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-fil_space_t*
-fil_space_next(fil_space_t* prev_space)
-{
- fil_space_t* space=prev_space;
-
- mutex_enter(&fil_system.mutex);
-
- if (!space) {
- space = UT_LIST_GET_FIRST(fil_system.space_list);
- } else {
- ut_a(space->referenced());
-
- /* Move on to the next fil_space_t */
- space->release();
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- /* Skip spaces that are being created by
- fil_ibd_create(), or dropped, or !tablespace. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping()
- || space->purpose != FIL_TYPE_TABLESPACE)) {
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- if (space != NULL) {
- space->acquire();
- }
-
- mutex_exit(&fil_system.mutex);
-
- return(space);
-}
-
-/**
-Remove space from key rotation list if there are no more
-pending operations.
-@param[in,out] space Tablespace */
-static
-void
-fil_space_remove_from_keyrotation(fil_space_t* space)
-{
- ut_ad(mutex_own(&fil_system.mutex));
- ut_ad(space);
-
- if (!space->referenced() && space->is_in_rotation_list) {
- space->is_in_rotation_list = false;
- ut_a(!fil_system.rotation_list.empty());
- fil_system.rotation_list.remove(*space);
- }
-}
-
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_t::acquire() and fil_space_t::release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system.space_list.
-@param[in] recheck recheck of the tablespace is needed or
- still encryption thread does write page0 for it
-@param[in] key_version key version of the key state thread
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-fil_space_t *fil_system_t::keyrotate_next(fil_space_t *prev_space,
- bool recheck, uint key_version)
-{
- mutex_enter(&fil_system.mutex);
-
- /* If one of the encryption threads already started the encryption
- of the table then don't remove the unencrypted spaces from rotation list
-
- If there is a change in innodb_encrypt_tables variables value then
- don't remove the last processed tablespace from the rotation list. */
- const bool remove= (!recheck || prev_space->crypt_data) &&
- !key_version == !srv_encrypt_tables;
- sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
- prev_space ? prev_space : fil_system.rotation_list.end();
-
- if (it == fil_system.rotation_list.end())
- it= fil_system.rotation_list.begin();
- else
- {
- /* Move on to the next fil_space_t */
- prev_space->release();
-
- ++it;
-
- while (it != fil_system.rotation_list.end() &&
- (UT_LIST_GET_LEN(it->chain) == 0 || it->is_stopping()))
- ++it;
-
- if (remove)
- fil_space_remove_from_keyrotation(prev_space);
- }
-
- fil_space_t *space= it == fil_system.rotation_list.end() ? NULL : &*it;
-
- if (space)
- space->acquire();
-
- mutex_exit(&fil_system.mutex);
- return space;
-}
-
/** Determine the block size of the data file.
@param[in] space tablespace
@param[in] offset page number
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 64a6676e396..2cbf233a4cb 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -980,24 +980,15 @@ public:
@retval NULL if the tablespace does not exist or cannot be read */
fil_space_t* read_page0(ulint id);
- /** Return the next fil_space_t from key rotation list.
- Once started, the caller must keep calling this until it returns NULL.
- fil_space_acquire() and fil_space_t::release() are invoked here, which
- blocks a concurrent operation from dropping the tablespace.
- @param[in] prev_space Previous tablespace or NULL to start
- from beginning of fil_system->rotation
- list
- @param[in] recheck recheck of the tablespace is needed or
- still encryption thread does write page0
- for it
- @param[in] key_version key version of the key state thread
- If NULL, use the first fil_space_t on fil_system->space_list.
- @return pointer to the next fil_space_t.
- @retval NULL if this was the last */
- fil_space_t* keyrotate_next(
- fil_space_t* prev_space,
- bool remove,
- uint key_version);
+ /** Return the next tablespace from rotation_list.
+ @param space previous tablespace (NULL to start from the start)
+ @param recheck whether the removal condition needs to be rechecked after
+ the encryption parameters were changed
+ @param encrypt expected state of innodb_encrypt_tables
+ @return the next tablespace to process (n_pending_ops incremented)
+ @retval NULL if this was the last */
+ inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck,
+ bool encrypt);
};
/** The tablespace memory cache. */
@@ -1152,33 +1143,6 @@ when it could be dropped concurrently.
fil_space_t*
fil_space_acquire_for_io(ulint id);
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_t::release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system.space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-fil_space_t*
-fil_space_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_t::release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system.space_list.
-@param[in] remove Whether to remove the previous tablespace from
- the rotation list
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-fil_space_t*
-fil_space_keyrotate_next(fil_space_t* prev_space, bool remove)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Replay a file rename operation if possible.
@param[in] space_id tablespace identifier
@param[in] first_page_no first page number in the file
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 32fdc89d6e4..339154a9615 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -360,7 +360,6 @@ enum latch_id_t {
LATCH_ID_SCRUB_STAT_MUTEX,
LATCH_ID_DEFRAGMENT_MUTEX,
LATCH_ID_BTR_DEFRAGMENT_MUTEX,
- LATCH_ID_FIL_CRYPT_MUTEX,
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
LATCH_ID_FIL_CRYPT_DATA_MUTEX,
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 86708818b36..c6de0e606b9 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -746,7 +746,7 @@ lock_rec_has_to_wait(
/* if BF thread is locking and has conflict with another BF
thread, we need to look at trx ordering and lock types */
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)
- && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
+ && wsrep_thd_is_BF(lock2->trx->mysql_thd, FALSE)) {
mtr_t mtr;
if (UNIV_UNLIKELY(wsrep_debug)) {
@@ -1094,7 +1094,7 @@ wsrep_kill_victim(
return;
}
- my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
+ my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE);
mtr_t mtr;
if ((!bf_other) ||
@@ -1418,7 +1418,7 @@ lock_rec_create_low(
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
- while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE)
+ while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, FALSE)
&& wsrep_thd_order_before(hash->trx->mysql_thd,
trx->mysql_thd)) {
prev = hash;
@@ -1817,11 +1817,9 @@ lock_rec_add_to_queue(
= lock_rec_other_has_expl_req(
mode, block, false, heap_no, trx);
#ifdef WITH_WSREP
- //ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- // wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)));
if (other_lock && trx->is_wsrep() &&
!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) {
+ !wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE)) {
ib::info() << "WSREP BF lock conflict for my lock:\n BF:" <<
((wsrep_thd_is_BF(trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
@@ -2030,6 +2028,7 @@ lock_rec_has_to_wait_in_queue(
ulint bit_offset;
hash_table_t* hash;
+ ut_ad(wait_lock);
ut_ad(lock_mutex_own());
ut_ad(lock_get_wait(wait_lock));
ut_ad(lock_get_type_low(wait_lock) == LOCK_REC);
@@ -2044,9 +2043,11 @@ lock_rec_has_to_wait_in_queue(
hash = lock_hash_get(wait_lock->type_mode);
for (lock = lock_rec_get_first_on_page_addr(hash, space, page_no);
+#ifdef WITH_WSREP
+ lock &&
+#endif
lock != wait_lock;
lock = lock_rec_get_next_on_page_const(lock)) {
-
const byte* p = (const byte*) &lock[1];
if (heap_no < lock_rec_get_n_bits(lock)
@@ -2054,7 +2055,8 @@ lock_rec_has_to_wait_in_queue(
&& lock_has_to_wait(wait_lock, lock)) {
#ifdef WITH_WSREP
if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) &&
- wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) {
+ wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE)) {
+
if (UNIV_UNLIKELY(wsrep_debug)) {
mtr_t mtr;
ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id)
@@ -6705,7 +6707,7 @@ DeadlockChecker::select_victim() const
/* The joining transaction is 'smaller',
choose it as the victim and roll it back. */
#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(m_start->mysql_thd, TRUE)) {
+ if (wsrep_thd_is_BF(m_start->mysql_thd, FALSE)) {
return(m_wait_lock->trx);
}
#endif /* WITH_WSREP */
@@ -6713,7 +6715,7 @@ DeadlockChecker::select_victim() const
}
#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, TRUE)) {
+ if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, FALSE)) {
return(m_start);
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 485e867dfe6..5efb447e548 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -1485,8 +1485,6 @@ sync_latch_meta_init()
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(BTR_DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
- LATCH_ADD_MUTEX(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK,