Commit 06ef5509 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24167: Replace trx_purge_latch

parent 63dd2a97
......@@ -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;
......
......@@ -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 */
......
......@@ -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,
......
......@@ -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 @@ class purge_sys_t
/** 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();
}
};
......
......@@ -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:
......
......@@ -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));
......
......@@ -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();
}
/*******************************************************************//**
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment