summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-11-20 09:18:41 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-11-24 15:43:10 +0200
commit06ef5509d0be2ed8197a981e2b9ceb8ac2bab0cc (patch)
tree7f7be0f04b704c20aa61460d39375ce76d5a7c6a
parent63dd2a97e4d12ee8000e7176b5b98543c079fee8 (diff)
downloadmariadb-git-06ef5509d0be2ed8197a981e2b9ceb8ac2bab0cc.tar.gz
MDEV-24167: Replace trx_purge_latch
-rw-r--r--mysql-test/suite/perfschema/r/sxlock_func.result2
-rw-r--r--storage/innobase/handler/ha_innodb.cc2
-rw-r--r--storage/innobase/include/sync0types.h2
-rw-r--r--storage/innobase/include/trx0purge.h14
-rw-r--r--storage/innobase/row/row0umod.cc48
-rw-r--r--storage/innobase/row/row0vers.cc2
-rw-r--r--storage/innobase/srv/srv0srv.cc10
-rw-r--r--storage/innobase/sync/sync0debug.cc4
-rw-r--r--storage/innobase/trx/trx0purge.cc9
-rw-r--r--storage/innobase/trx/trx0rec.cc13
10 files changed, 53 insertions, 53 deletions
diff --git a/mysql-test/suite/perfschema/r/sxlock_func.result b/mysql-test/suite/perfschema/r/sxlock_func.result
index 9d4575ef29e..c22842aea3d 100644
--- a/mysql-test/suite/perfschema/r/sxlock_func.result
+++ b/mysql-test/suite/perfschema/r/sxlock_func.result
@@ -12,7 +12,6 @@ wait/synch/sxlock/innodb/fil_space_latch
wait/synch/sxlock/innodb/fts_cache_init_rw_lock
wait/synch/sxlock/innodb/fts_cache_rw_lock
wait/synch/sxlock/innodb/index_tree_rw_lock
-wait/synch/sxlock/innodb/trx_purge_latch
select name from performance_schema.rwlock_instances
where name in
(
@@ -25,7 +24,6 @@ where name in
order by name;
name
wait/synch/sxlock/innodb/dict_operation_lock
-wait/synch/sxlock/innodb/trx_purge_latch
drop table if exists t1;
create table t1(a int) engine=innodb;
begin;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 88794334e75..9db051609d7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -569,7 +569,7 @@ static PSI_rwlock_info all_innodb_rwlocks[] = {
PSI_RWLOCK_KEY(fts_cache_rw_lock),
PSI_RWLOCK_KEY(fts_cache_init_rw_lock),
{ &trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0 },
- PSI_RWLOCK_KEY(trx_purge_latch),
+ { &trx_purge_latch_key, "trx_purge_latch", 0 },
PSI_RWLOCK_KEY(index_tree_rw_lock),
};
# endif /* UNIV_PFS_RWLOCK */
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index ee54b6fffc4..a12fb88ae55 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -224,7 +224,6 @@ enum latch_level_t {
SYNC_RSEG_HEADER_NEW,
SYNC_NOREDO_RSEG,
SYNC_REDO_RSEG,
- SYNC_PURGE_LATCH,
SYNC_TREE_NODE,
SYNC_TREE_NODE_FROM_HASH,
SYNC_TREE_NODE_NEW,
@@ -296,7 +295,6 @@ enum latch_id_t {
LATCH_ID_FIL_SPACE,
LATCH_ID_FTS_CACHE,
LATCH_ID_FTS_CACHE_INIT,
- LATCH_ID_TRX_PURGE,
LATCH_ID_IBUF_INDEX_TREE,
LATCH_ID_INDEX_TREE,
LATCH_ID_DICT_TABLE_STATS,
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index 38e9e7207a2..0aff65fd7b6 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -29,6 +29,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0rseg.h"
#include "que0types.h"
+#include "srw_lock.h"
#include <queue>
@@ -127,11 +128,9 @@ class purge_sys_t
{
public:
/** latch protecting view, m_enabled */
- MY_ALIGNED(CACHE_LINE_SIZE)
- mutable rw_lock_t latch;
+ MY_ALIGNED(CACHE_LINE_SIZE) mutable srw_lock latch;
private:
/** The purge will not remove undo logs which are >= this view */
- MY_ALIGNED(CACHE_LINE_SIZE)
ReadViewBase view;
/** whether purge is enabled; protected by latch and std::atomic */
std::atomic<bool> m_enabled;
@@ -249,23 +248,20 @@ public:
/** A wrapper around ReadView::changes_visible(). */
bool changes_visible(trx_id_t id, const table_name_t &name) const
{
- ut_ad(rw_lock_own(&latch, RW_LOCK_S));
return view.changes_visible(id, name);
}
/** A wrapper around ReadView::low_limit_no(). */
trx_id_t low_limit_no() const
{
-#if 0 /* Unfortunately we don't hold this assertion, see MDEV-22718. */
- ut_ad(rw_lock_own(&latch, RW_LOCK_S));
-#endif
+ /* MDEV-22718 FIXME: We are not holding latch here! */
return view.low_limit_no();
}
/** A wrapper around trx_sys_t::clone_oldest_view(). */
void clone_oldest_view()
{
- rw_lock_x_lock(&latch);
+ latch.wr_lock();
trx_sys.clone_oldest_view(&view);
- rw_lock_x_unlock(&latch);
+ latch.wr_unlock();
}
};
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index f710f54d0c1..585060229d7 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -214,8 +214,6 @@ static bool row_undo_mod_must_purge(undo_node_t* node, mtr_t* mtr)
ut_ad(btr_cur->index->is_primary());
DEBUG_SYNC_C("rollback_purge_clust");
- mtr->s_lock(&purge_sys.latch, __FILE__, __LINE__);
-
if (!purge_sys.changes_visible(node->new_trx_id, node->table->name)) {
return false;
}
@@ -239,6 +237,7 @@ row_undo_mod_clust(
{
btr_pcur_t* pcur;
mtr_t mtr;
+ bool have_latch = false;
dberr_t err;
dict_index_t* index;
bool online;
@@ -365,23 +364,32 @@ row_undo_mod_clust(
goto mtr_commit_exit;
}
+ ut_ad(rec_get_deleted_flag(btr_pcur_get_rec(pcur),
+ dict_table_is_comp(node->table)));
+
if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
+ if (btr_cur_optimistic_delete(&pcur->btr_cur, 0,
+ &mtr)) {
+ goto mtr_commit_exit;
+ }
+ btr_pcur_commit_specify_mtr(pcur, &mtr);
} else {
+ index->set_modified(mtr);
+ have_latch = true;
+ purge_sys.latch.rd_lock();
if (!row_undo_mod_must_purge(node, &mtr)) {
goto mtr_commit_exit;
}
- index->set_modified(mtr);
- }
-
- ut_ad(rec_get_deleted_flag(btr_pcur_get_rec(pcur),
- dict_table_is_comp(node->table)));
- if (btr_cur_optimistic_delete(&pcur->btr_cur, 0, &mtr)) {
- goto mtr_commit_exit;
+ if (btr_cur_optimistic_delete(&pcur->btr_cur, 0,
+ &mtr)) {
+ goto mtr_commit_exit;
+ }
+ purge_sys.latch.rd_unlock();
+ btr_pcur_commit_specify_mtr(pcur, &mtr);
+ have_latch = false;
}
- btr_pcur_commit_specify_mtr(pcur, &mtr);
-
mtr.start();
if (!btr_pcur_restore_position(
BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
@@ -389,18 +397,20 @@ row_undo_mod_clust(
goto mtr_commit_exit;
}
+ ut_ad(rec_get_deleted_flag(btr_pcur_get_rec(pcur),
+ dict_table_is_comp(node->table)));
+
if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
+ have_latch = true;
+ purge_sys.latch.rd_lock();
if (!row_undo_mod_must_purge(node, &mtr)) {
goto mtr_commit_exit;
}
index->set_modified(mtr);
}
- ut_ad(rec_get_deleted_flag(btr_pcur_get_rec(pcur),
- dict_table_is_comp(node->table)));
-
/* This operation is analogous to purge, we can free
also inherited externally stored fields. We can also
assume that the record was complete (including BLOBs),
@@ -409,8 +419,7 @@ row_undo_mod_clust(
rollback=false, just like purge does. */
btr_cur_pessimistic_delete(&err, FALSE, &pcur->btr_cur, 0,
false, &mtr);
- ut_ad(err == DB_SUCCESS
- || err == DB_OUT_OF_FILE_SPACE);
+ ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
} else if (!index->table->is_temporary() && node->new_trx_id) {
/* We rolled back a record so that it still exists.
We must reset the DB_TRX_ID if the history is no
@@ -421,7 +430,8 @@ row_undo_mod_clust(
goto mtr_commit_exit;
}
rec_t* rec = btr_pcur_get_rec(pcur);
- mtr.s_lock(&purge_sys.latch, __FILE__, __LINE__);
+ have_latch = true;
+ purge_sys.latch.rd_lock();
if (!purge_sys.changes_visible(node->new_trx_id,
node->table->name)) {
goto mtr_commit_exit;
@@ -493,6 +503,10 @@ row_undo_mod_clust(
}
mtr_commit_exit:
+ if (have_latch) {
+ purge_sys.latch.rd_unlock();
+ }
+
btr_pcur_commit_specify_mtr(pcur, &mtr);
func_exit:
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 7f410487b9a..88b55ded818 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -1124,7 +1124,6 @@ row_vers_build_for_consistent_read(
ut_ad(index->is_primary());
ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
- ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
ut_ad(rec_offs_validate(rec, index, *offsets));
@@ -1237,7 +1236,6 @@ row_vers_build_for_semi_consistent_read(
ut_ad(index->is_primary());
ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
- ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
ut_ad(rec_offs_validate(rec, index, *offsets));
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index c4785192665..5a420b9c5d3 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1492,13 +1492,13 @@ bool purge_sys_t::running() const
/** Stop purge during FLUSH TABLES FOR EXPORT */
void purge_sys_t::stop()
{
- rw_lock_x_lock(&latch);
+ latch.wr_lock();
if (!enabled())
{
/* Shutdown must have been initiated during FLUSH TABLES FOR EXPORT. */
ut_ad(!srv_undo_sources);
- rw_lock_x_unlock(&latch);
+ latch.wr_unlock();
return;
}
@@ -1506,7 +1506,7 @@ void purge_sys_t::stop()
const auto paused= m_paused++;
- rw_lock_x_unlock(&latch);
+ latch.wr_unlock();
if (!paused)
{
@@ -1529,7 +1529,7 @@ void purge_sys_t::resume()
ut_ad(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
ut_ad(!sync_check_iterate(sync_check()));
purge_coordinator_task.enable();
- rw_lock_x_lock(&latch);
+ latch.wr_lock();
int32_t paused= m_paused--;
ut_a(paused);
@@ -1540,7 +1540,7 @@ void purge_sys_t::resume()
srv_wake_purge_thread_if_not_active();
MONITOR_ATOMIC_INC(MONITOR_PURGE_RESUME_COUNT);
}
- rw_lock_x_unlock(&latch);
+ latch.wr_unlock();
}
/*******************************************************************//**
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index ec7a42ecb76..e16ec4efe81 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -483,7 +483,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_RSEG_HEADER_NEW);
LEVEL_MAP_INSERT(SYNC_NOREDO_RSEG);
LEVEL_MAP_INSERT(SYNC_REDO_RSEG);
- LEVEL_MAP_INSERT(SYNC_PURGE_LATCH);
LEVEL_MAP_INSERT(SYNC_TREE_NODE);
LEVEL_MAP_INSERT(SYNC_TREE_NODE_FROM_HASH);
LEVEL_MAP_INSERT(SYNC_TREE_NODE_NEW);
@@ -738,7 +737,6 @@ LatchDebug::check_order(
case SYNC_IBUF_BITMAP_MUTEX:
case SYNC_REDO_RSEG:
case SYNC_NOREDO_RSEG:
- case SYNC_PURGE_LATCH:
case SYNC_PURGE_QUEUE:
case SYNC_DICT_OPERATION:
case SYNC_DICT_HEADER:
@@ -1318,8 +1316,6 @@ sync_latch_meta_init()
LATCH_ADD_RWLOCK(FTS_CACHE_INIT, SYNC_FTS_CACHE_INIT,
fts_cache_init_rw_lock_key);
- LATCH_ADD_RWLOCK(TRX_PURGE, SYNC_PURGE_LATCH, trx_purge_latch_key);
-
LATCH_ADD_RWLOCK(IBUF_INDEX_TREE, SYNC_IBUF_INDEX_TREE,
index_tree_rw_lock_key);
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index c0375f25fa6..e909f72459b 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -36,7 +36,6 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0mon.h"
#include "srv0srv.h"
#include "srv0start.h"
-#include "sync0sync.h"
#include "trx0rec.h"
#include "trx0roll.h"
#include "trx0rseg.h"
@@ -45,6 +44,10 @@ Created 3/26/1996 Heikki Tuuri
#include <unordered_map>
+#ifdef UNIV_PFS_RWLOCK
+extern mysql_pfs_key_t trx_purge_latch_key;
+#endif /* UNIV_PFS_RWLOCK */
+
/** Maximum allowable purge history length. <=0 means 'infinite'. */
ulong srv_max_purge_lag = 0;
@@ -172,7 +175,7 @@ void purge_sys_t::create()
offset= 0;
hdr_page_no= 0;
hdr_offset= 0;
- rw_lock_create(trx_purge_latch_key, &latch, SYNC_PURGE_LATCH);
+ latch.init(trx_purge_latch_key);
mutex_create(LATCH_ID_PURGE_SYS_PQ, &pq_mutex);
truncate.current= NULL;
truncate.last= NULL;
@@ -193,7 +196,7 @@ void purge_sys_t::close()
ut_ad(trx->state == TRX_STATE_ACTIVE);
trx->state= TRX_STATE_NOT_STARTED;
trx->free();
- rw_lock_free(&latch);
+ latch.destroy();
mutex_free(&pq_mutex);
mem_heap_free(heap);
heap= nullptr;
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 49b0a21330d..d25399c8415 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2201,14 +2201,14 @@ trx_undo_get_undo_rec(
const table_name_t& name,
trx_undo_rec_t** undo_rec)
{
- rw_lock_s_lock(&purge_sys.latch);
+ purge_sys.latch.rd_lock();
bool missing_history = purge_sys.changes_visible(trx_id, name);
if (!missing_history) {
*undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap);
}
- rw_lock_s_unlock(&purge_sys.latch);
+ purge_sys.latch.rd_unlock();
return(missing_history);
}
@@ -2271,7 +2271,6 @@ trx_undo_prev_version_build(
byte* buf;
ut_ad(!index->table->is_temporary());
- ut_ad(!rw_lock_own(&purge_sys.latch, RW_LOCK_S));
ut_ad(index_mtr->memo_contains_page_flagged(index_rec,
MTR_MEMO_PAGE_S_FIX
| MTR_MEMO_PAGE_X_FIX));
@@ -2365,14 +2364,12 @@ trx_undo_prev_version_build(
if ((update->info_bits & REC_INFO_DELETED_FLAG)
&& row_upd_changes_disowned_external(update)) {
- bool missing_extern;
+ purge_sys.latch.rd_lock();
- rw_lock_s_lock(&purge_sys.latch);
-
- missing_extern = purge_sys.changes_visible(
+ bool missing_extern = purge_sys.changes_visible(
trx_id, index->table->name);
- rw_lock_s_unlock(&purge_sys.latch);
+ purge_sys.latch.rd_unlock();
if (missing_extern) {
/* treat as a fresh insert, not to