mirror of
https://github.com/MariaDB/server.git
synced 2025-08-09 22:24:09 +03:00
MDEV-24167: Replace trx_purge_latch
This commit is contained in:
@@ -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 @@ 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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -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,22 +364,31 @@ 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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
mtr.start();
|
||||
if (!btr_pcur_restore_position(
|
||||
@@ -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
|
||||
|
Reference in New Issue
Block a user