summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2019-07-25 22:17:04 +1000
committerNikita Malyavin <nikitamalyavin@gmail.com>2021-04-27 11:51:17 +0300
commit300253acf12bf66fdea8e64abae5d717c289e559 (patch)
tree1166e1aca1f0378d147c76d73bb9ca02cc2001d5 /storage
parenta35cde8cd8364edc0a23752fc5fde442c8b78a0a (diff)
downloadmariadb-git-300253acf12bf66fdea8e64abae5d717c289e559.tar.gz
revive innodb_debug_sync
innodb_debug_sync was introduced in commit b393e2cb0c079b30563dcc87a62002c9c778643c and reverted in commit fc58c1721631fcc6c9414482b3b7e90cd8e7325d due to memory leak reported by valgrind, see MDEV-21336. The leak is now fixed by adding `rw_lock_free(&slot->debug_sync_lock)` after background thread working loop is finished, and the patch is reapplied, with respect to c++98 fixes by Marko. The missing DEBUG_SYNC for MDEV-18546 in row0vers.cc is also reapplied.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/ha_innodb.cc38
-rw-r--r--storage/innobase/include/srv0srv.h10
-rw-r--r--storage/innobase/row/row0purge.cc20
-rw-r--r--storage/innobase/row/row0vers.cc1
-rw-r--r--storage/innobase/srv/srv0srv.cc17
5 files changed, 86 insertions, 0 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 91d12f64fa5..22fe3b5d9ed 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -19559,6 +19559,33 @@ innodb_log_checksums_update(
thd, *static_cast<const my_bool*>(save));
}
+#ifdef UNIV_DEBUG
+static
+void
+innobase_debug_sync_callback(srv_slot_t *slot, const void *value)
+{
+ const char *value_str = *static_cast<const char* const*>(value);
+ size_t len = strlen(value_str) + 1;
+
+
+ // One allocation for list node object and value.
+ void *buf = ut_malloc_nokey(sizeof(srv_slot_t::debug_sync_t) + len-1);
+ srv_slot_t::debug_sync_t *sync = new(buf) srv_slot_t::debug_sync_t();
+ strcpy(sync->str, value_str);
+
+ rw_lock_x_lock(&slot->debug_sync_lock);
+ UT_LIST_ADD_LAST(slot->debug_sync, sync);
+ rw_lock_x_unlock(&slot->debug_sync_lock);
+}
+static
+void
+innobase_debug_sync_set(THD *thd, st_mysql_sys_var*, void *, const void *value)
+{
+ srv_for_each_thread(SRV_WORKER, innobase_debug_sync_callback, value);
+ srv_for_each_thread(SRV_PURGE, innobase_debug_sync_callback, value);
+}
+#endif
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
@@ -21205,6 +21232,16 @@ static MYSQL_SYSVAR_BOOL(debug_force_scrubbing,
0,
"Perform extra scrubbing to increase test exposure",
NULL, NULL, FALSE);
+
+char *innobase_debug_sync;
+static MYSQL_SYSVAR_STR(debug_sync, innobase_debug_sync,
+ PLUGIN_VAR_NOCMDARG,
+ "debug_sync for innodb purge threads. "
+ "Use it to set up sync points for all purge threads "
+ "at once. The commands will be applied sequentially at"
+ " the beginning of purging the next undo record.",
+ NULL,
+ innobase_debug_sync_set, NULL);
#endif /* UNIV_DEBUG */
static MYSQL_SYSVAR_BOOL(instrument_semaphores, innodb_instrument_semaphores,
@@ -21428,6 +21465,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(background_scrub_data_check_interval),
#ifdef UNIV_DEBUG
MYSQL_SYSVAR(debug_force_scrubbing),
+ MYSQL_SYSVAR(debug_sync),
#endif
MYSQL_SYSVAR(instrument_semaphores),
MYSQL_SYSVAR(buf_dump_status_frequency),
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index d196a4d6db6..62d7c139ee2 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -1142,6 +1142,16 @@ struct srv_slot_t{
to do */
que_thr_t* thr; /*!< suspended query thread
(only used for user threads) */
+#ifdef UNIV_DEBUG
+ struct debug_sync_t {
+ UT_LIST_NODE_T(debug_sync_t)
+ debug_sync_list;
+ char str[1];
+ };
+ UT_LIST_BASE_NODE_T(debug_sync_t)
+ debug_sync;
+ rw_lock_t debug_sync_lock;
+#endif
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 024625e9e0a..10a0b91f8f8 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -46,6 +46,7 @@ Created 3/14/1997 Heikki Tuuri
#include "handler.h"
#include "ha_innodb.h"
#include "fil0fil.h"
+#include "debug_sync.h"
/*************************************************************************
IMPORTANT NOTE: Any operation that generates redo MUST check that there
@@ -1208,6 +1209,25 @@ row_purge_step(
node->start();
+#ifdef UNIV_DEBUG
+ srv_slot_t *slot = thr->thread_slot;
+ ut_ad(slot);
+
+ rw_lock_x_lock(&slot->debug_sync_lock);
+ while (UT_LIST_GET_LEN(slot->debug_sync)) {
+ srv_slot_t::debug_sync_t *sync =
+ UT_LIST_GET_FIRST(slot->debug_sync);
+ bool result = debug_sync_set_action(current_thd,
+ sync->str,
+ strlen(sync->str));
+ ut_a(!result);
+
+ UT_LIST_REMOVE(slot->debug_sync, sync);
+ ut_free(sync);
+ }
+ rw_lock_x_unlock(&slot->debug_sync_lock);
+#endif
+
if (!(node->undo_recs == NULL || ib_vector_is_empty(node->undo_recs))) {
trx_purge_rec_t*purge_rec;
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 2d8704764d1..b9bc8418366 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -467,6 +467,7 @@ row_vers_build_clust_v_col(
vcol_info->set_used();
maria_table = vcol_info->table();
}
+ DEBUG_SYNC(current_thd, "ib_clust_v_col_before_row_allocated");
ib_vcol_row vc(NULL);
byte *record = vc.record(thd, index, &maria_table);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 44e0946f067..56c717e142b 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2601,6 +2601,13 @@ DECLARE_THREAD(srv_worker_thread)(
slot = srv_reserve_slot(SRV_WORKER);
+#ifdef UNIV_DEBUG
+ UT_LIST_INIT(slot->debug_sync,
+ &srv_slot_t::debug_sync_t::debug_sync_list);
+ rw_lock_create(PFS_NOT_INSTRUMENTED, &slot->debug_sync_lock,
+ SYNC_NO_ORDER_CHECK);
+#endif
+
ut_a(srv_n_purge_threads > 1);
ut_a(ulong(my_atomic_loadlint(&srv_sys.n_threads_active[SRV_WORKER]))
< srv_n_purge_threads);
@@ -2625,6 +2632,8 @@ DECLARE_THREAD(srv_worker_thread)(
purge_sys->latch here. */
} while (purge_sys->state != PURGE_STATE_EXIT);
+ ut_d(rw_lock_free(&slot->debug_sync_lock));
+
srv_free_slot(slot);
rw_lock_x_lock(&purge_sys->latch);
@@ -2848,6 +2857,12 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
slot = srv_reserve_slot(SRV_PURGE);
+#ifdef UNIV_DEBUG
+ UT_LIST_INIT(slot->debug_sync,
+ &srv_slot_t::debug_sync_t::debug_sync_list);
+ rw_lock_create(PFS_NOT_INSTRUMENTED, &slot->debug_sync_lock,
+ SYNC_NO_ORDER_CHECK);
+#endif
ulint rseg_history_len = trx_sys->rseg_history_len;
do {
@@ -2881,6 +2896,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
shutdown state. */
ut_a(srv_get_task_queue_length() == 0);
+ ut_d(rw_lock_free(&slot->debug_sync_lock));
+
srv_free_slot(slot);
/* Note that we are shutting down. */