1
0
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:
Marko Mäkelä
2020-11-20 09:18:41 +02:00
parent 63dd2a97e4
commit 06ef5509d0
10 changed files with 53 additions and 53 deletions

View File

@@ -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_init_rw_lock
wait/synch/sxlock/innodb/fts_cache_rw_lock wait/synch/sxlock/innodb/fts_cache_rw_lock
wait/synch/sxlock/innodb/index_tree_rw_lock wait/synch/sxlock/innodb/index_tree_rw_lock
wait/synch/sxlock/innodb/trx_purge_latch
select name from performance_schema.rwlock_instances select name from performance_schema.rwlock_instances
where name in where name in
( (
@@ -25,7 +24,6 @@ where name in
order by name; order by name;
name name
wait/synch/sxlock/innodb/dict_operation_lock wait/synch/sxlock/innodb/dict_operation_lock
wait/synch/sxlock/innodb/trx_purge_latch
drop table if exists t1; drop table if exists t1;
create table t1(a int) engine=innodb; create table t1(a int) engine=innodb;
begin; begin;

View File

@@ -569,7 +569,7 @@ static PSI_rwlock_info all_innodb_rwlocks[] = {
PSI_RWLOCK_KEY(fts_cache_rw_lock), PSI_RWLOCK_KEY(fts_cache_rw_lock),
PSI_RWLOCK_KEY(fts_cache_init_rw_lock), PSI_RWLOCK_KEY(fts_cache_init_rw_lock),
{ &trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0 }, { &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), PSI_RWLOCK_KEY(index_tree_rw_lock),
}; };
# endif /* UNIV_PFS_RWLOCK */ # endif /* UNIV_PFS_RWLOCK */

View File

@@ -224,7 +224,6 @@ enum latch_level_t {
SYNC_RSEG_HEADER_NEW, SYNC_RSEG_HEADER_NEW,
SYNC_NOREDO_RSEG, SYNC_NOREDO_RSEG,
SYNC_REDO_RSEG, SYNC_REDO_RSEG,
SYNC_PURGE_LATCH,
SYNC_TREE_NODE, SYNC_TREE_NODE,
SYNC_TREE_NODE_FROM_HASH, SYNC_TREE_NODE_FROM_HASH,
SYNC_TREE_NODE_NEW, SYNC_TREE_NODE_NEW,
@@ -296,7 +295,6 @@ enum latch_id_t {
LATCH_ID_FIL_SPACE, LATCH_ID_FIL_SPACE,
LATCH_ID_FTS_CACHE, LATCH_ID_FTS_CACHE,
LATCH_ID_FTS_CACHE_INIT, LATCH_ID_FTS_CACHE_INIT,
LATCH_ID_TRX_PURGE,
LATCH_ID_IBUF_INDEX_TREE, LATCH_ID_IBUF_INDEX_TREE,
LATCH_ID_INDEX_TREE, LATCH_ID_INDEX_TREE,
LATCH_ID_DICT_TABLE_STATS, LATCH_ID_DICT_TABLE_STATS,

View File

@@ -29,6 +29,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0rseg.h" #include "trx0rseg.h"
#include "que0types.h" #include "que0types.h"
#include "srw_lock.h"
#include <queue> #include <queue>
@@ -127,11 +128,9 @@ class purge_sys_t
{ {
public: public:
/** latch protecting view, m_enabled */ /** latch protecting view, m_enabled */
MY_ALIGNED(CACHE_LINE_SIZE) MY_ALIGNED(CACHE_LINE_SIZE) mutable srw_lock latch;
mutable rw_lock_t latch;
private: private:
/** The purge will not remove undo logs which are >= this view */ /** The purge will not remove undo logs which are >= this view */
MY_ALIGNED(CACHE_LINE_SIZE)
ReadViewBase view; ReadViewBase view;
/** whether purge is enabled; protected by latch and std::atomic */ /** whether purge is enabled; protected by latch and std::atomic */
std::atomic<bool> m_enabled; std::atomic<bool> m_enabled;
@@ -249,23 +248,20 @@ public:
/** A wrapper around ReadView::changes_visible(). */ /** A wrapper around ReadView::changes_visible(). */
bool changes_visible(trx_id_t id, const table_name_t &name) const 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); return view.changes_visible(id, name);
} }
/** A wrapper around ReadView::low_limit_no(). */ /** A wrapper around ReadView::low_limit_no(). */
trx_id_t low_limit_no() const trx_id_t low_limit_no() const
{ {
#if 0 /* Unfortunately we don't hold this assertion, see MDEV-22718. */ /* MDEV-22718 FIXME: We are not holding latch here! */
ut_ad(rw_lock_own(&latch, RW_LOCK_S));
#endif
return view.low_limit_no(); return view.low_limit_no();
} }
/** A wrapper around trx_sys_t::clone_oldest_view(). */ /** A wrapper around trx_sys_t::clone_oldest_view(). */
void clone_oldest_view() void clone_oldest_view()
{ {
rw_lock_x_lock(&latch); latch.wr_lock();
trx_sys.clone_oldest_view(&view); trx_sys.clone_oldest_view(&view);
rw_lock_x_unlock(&latch); latch.wr_unlock();
} }
}; };

View File

@@ -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()); ut_ad(btr_cur->index->is_primary());
DEBUG_SYNC_C("rollback_purge_clust"); 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)) { if (!purge_sys.changes_visible(node->new_trx_id, node->table->name)) {
return false; return false;
} }
@@ -239,6 +237,7 @@ row_undo_mod_clust(
{ {
btr_pcur_t* pcur; btr_pcur_t* pcur;
mtr_t mtr; mtr_t mtr;
bool have_latch = false;
dberr_t err; dberr_t err;
dict_index_t* index; dict_index_t* index;
bool online; bool online;
@@ -365,23 +364,32 @@ row_undo_mod_clust(
goto mtr_commit_exit; 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()) { if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO); 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 { } else {
index->set_modified(mtr);
have_latch = true;
purge_sys.latch.rd_lock();
if (!row_undo_mod_must_purge(node, &mtr)) { if (!row_undo_mod_must_purge(node, &mtr)) {
goto mtr_commit_exit; goto mtr_commit_exit;
} }
index->set_modified(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;
} }
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;
}
btr_pcur_commit_specify_mtr(pcur, &mtr);
mtr.start(); mtr.start();
if (!btr_pcur_restore_position( if (!btr_pcur_restore_position(
BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
@@ -389,18 +397,20 @@ row_undo_mod_clust(
goto mtr_commit_exit; 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()) { if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO); mtr.set_log_mode(MTR_LOG_NO_REDO);
} else { } else {
have_latch = true;
purge_sys.latch.rd_lock();
if (!row_undo_mod_must_purge(node, &mtr)) { if (!row_undo_mod_must_purge(node, &mtr)) {
goto mtr_commit_exit; goto mtr_commit_exit;
} }
index->set_modified(mtr); 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 /* This operation is analogous to purge, we can free
also inherited externally stored fields. We can also also inherited externally stored fields. We can also
assume that the record was complete (including BLOBs), assume that the record was complete (including BLOBs),
@@ -409,8 +419,7 @@ row_undo_mod_clust(
rollback=false, just like purge does. */ rollback=false, just like purge does. */
btr_cur_pessimistic_delete(&err, FALSE, &pcur->btr_cur, 0, btr_cur_pessimistic_delete(&err, FALSE, &pcur->btr_cur, 0,
false, &mtr); false, &mtr);
ut_ad(err == DB_SUCCESS ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
|| err == DB_OUT_OF_FILE_SPACE);
} else if (!index->table->is_temporary() && node->new_trx_id) { } else if (!index->table->is_temporary() && node->new_trx_id) {
/* We rolled back a record so that it still exists. /* We rolled back a record so that it still exists.
We must reset the DB_TRX_ID if the history is no We must reset the DB_TRX_ID if the history is no
@@ -421,7 +430,8 @@ row_undo_mod_clust(
goto mtr_commit_exit; goto mtr_commit_exit;
} }
rec_t* rec = btr_pcur_get_rec(pcur); 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, if (!purge_sys.changes_visible(node->new_trx_id,
node->table->name)) { node->table->name)) {
goto mtr_commit_exit; goto mtr_commit_exit;
@@ -493,6 +503,10 @@ row_undo_mod_clust(
} }
mtr_commit_exit: mtr_commit_exit:
if (have_latch) {
purge_sys.latch.rd_unlock();
}
btr_pcur_commit_specify_mtr(pcur, &mtr); btr_pcur_commit_specify_mtr(pcur, &mtr);
func_exit: func_exit:

View File

@@ -1124,7 +1124,6 @@ row_vers_build_for_consistent_read(
ut_ad(index->is_primary()); ut_ad(index->is_primary());
ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_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)); 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(index->is_primary());
ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_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)); ut_ad(rec_offs_validate(rec, index, *offsets));

View File

@@ -1492,13 +1492,13 @@ bool purge_sys_t::running() const
/** Stop purge during FLUSH TABLES FOR EXPORT */ /** Stop purge during FLUSH TABLES FOR EXPORT */
void purge_sys_t::stop() void purge_sys_t::stop()
{ {
rw_lock_x_lock(&latch); latch.wr_lock();
if (!enabled()) if (!enabled())
{ {
/* Shutdown must have been initiated during FLUSH TABLES FOR EXPORT. */ /* Shutdown must have been initiated during FLUSH TABLES FOR EXPORT. */
ut_ad(!srv_undo_sources); ut_ad(!srv_undo_sources);
rw_lock_x_unlock(&latch); latch.wr_unlock();
return; return;
} }
@@ -1506,7 +1506,7 @@ void purge_sys_t::stop()
const auto paused= m_paused++; const auto paused= m_paused++;
rw_lock_x_unlock(&latch); latch.wr_unlock();
if (!paused) if (!paused)
{ {
@@ -1529,7 +1529,7 @@ void purge_sys_t::resume()
ut_ad(srv_force_recovery < SRV_FORCE_NO_BACKGROUND); ut_ad(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
ut_ad(!sync_check_iterate(sync_check())); ut_ad(!sync_check_iterate(sync_check()));
purge_coordinator_task.enable(); purge_coordinator_task.enable();
rw_lock_x_lock(&latch); latch.wr_lock();
int32_t paused= m_paused--; int32_t paused= m_paused--;
ut_a(paused); ut_a(paused);
@@ -1540,7 +1540,7 @@ void purge_sys_t::resume()
srv_wake_purge_thread_if_not_active(); srv_wake_purge_thread_if_not_active();
MONITOR_ATOMIC_INC(MONITOR_PURGE_RESUME_COUNT); MONITOR_ATOMIC_INC(MONITOR_PURGE_RESUME_COUNT);
} }
rw_lock_x_unlock(&latch); latch.wr_unlock();
} }
/*******************************************************************//** /*******************************************************************//**

View File

@@ -483,7 +483,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_RSEG_HEADER_NEW); LEVEL_MAP_INSERT(SYNC_RSEG_HEADER_NEW);
LEVEL_MAP_INSERT(SYNC_NOREDO_RSEG); LEVEL_MAP_INSERT(SYNC_NOREDO_RSEG);
LEVEL_MAP_INSERT(SYNC_REDO_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);
LEVEL_MAP_INSERT(SYNC_TREE_NODE_FROM_HASH); LEVEL_MAP_INSERT(SYNC_TREE_NODE_FROM_HASH);
LEVEL_MAP_INSERT(SYNC_TREE_NODE_NEW); LEVEL_MAP_INSERT(SYNC_TREE_NODE_NEW);
@@ -738,7 +737,6 @@ LatchDebug::check_order(
case SYNC_IBUF_BITMAP_MUTEX: case SYNC_IBUF_BITMAP_MUTEX:
case SYNC_REDO_RSEG: case SYNC_REDO_RSEG:
case SYNC_NOREDO_RSEG: case SYNC_NOREDO_RSEG:
case SYNC_PURGE_LATCH:
case SYNC_PURGE_QUEUE: case SYNC_PURGE_QUEUE:
case SYNC_DICT_OPERATION: case SYNC_DICT_OPERATION:
case SYNC_DICT_HEADER: case SYNC_DICT_HEADER:
@@ -1318,8 +1316,6 @@ sync_latch_meta_init()
LATCH_ADD_RWLOCK(FTS_CACHE_INIT, SYNC_FTS_CACHE_INIT, LATCH_ADD_RWLOCK(FTS_CACHE_INIT, SYNC_FTS_CACHE_INIT,
fts_cache_init_rw_lock_key); 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, LATCH_ADD_RWLOCK(IBUF_INDEX_TREE, SYNC_IBUF_INDEX_TREE,
index_tree_rw_lock_key); index_tree_rw_lock_key);

View File

@@ -36,7 +36,6 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0mon.h" #include "srv0mon.h"
#include "srv0srv.h" #include "srv0srv.h"
#include "srv0start.h" #include "srv0start.h"
#include "sync0sync.h"
#include "trx0rec.h" #include "trx0rec.h"
#include "trx0roll.h" #include "trx0roll.h"
#include "trx0rseg.h" #include "trx0rseg.h"
@@ -45,6 +44,10 @@ Created 3/26/1996 Heikki Tuuri
#include <unordered_map> #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'. */ /** Maximum allowable purge history length. <=0 means 'infinite'. */
ulong srv_max_purge_lag = 0; ulong srv_max_purge_lag = 0;
@@ -172,7 +175,7 @@ void purge_sys_t::create()
offset= 0; offset= 0;
hdr_page_no= 0; hdr_page_no= 0;
hdr_offset= 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); mutex_create(LATCH_ID_PURGE_SYS_PQ, &pq_mutex);
truncate.current= NULL; truncate.current= NULL;
truncate.last= NULL; truncate.last= NULL;
@@ -193,7 +196,7 @@ void purge_sys_t::close()
ut_ad(trx->state == TRX_STATE_ACTIVE); ut_ad(trx->state == TRX_STATE_ACTIVE);
trx->state= TRX_STATE_NOT_STARTED; trx->state= TRX_STATE_NOT_STARTED;
trx->free(); trx->free();
rw_lock_free(&latch); latch.destroy();
mutex_free(&pq_mutex); mutex_free(&pq_mutex);
mem_heap_free(heap); mem_heap_free(heap);
heap= nullptr; heap= nullptr;

View File

@@ -2201,14 +2201,14 @@ trx_undo_get_undo_rec(
const table_name_t& name, const table_name_t& name,
trx_undo_rec_t** undo_rec) 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); bool missing_history = purge_sys.changes_visible(trx_id, name);
if (!missing_history) { if (!missing_history) {
*undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap); *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); return(missing_history);
} }
@@ -2271,7 +2271,6 @@ trx_undo_prev_version_build(
byte* buf; byte* buf;
ut_ad(!index->table->is_temporary()); 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, ut_ad(index_mtr->memo_contains_page_flagged(index_rec,
MTR_MEMO_PAGE_S_FIX MTR_MEMO_PAGE_S_FIX
| MTR_MEMO_PAGE_X_FIX)); | MTR_MEMO_PAGE_X_FIX));
@@ -2365,14 +2364,12 @@ trx_undo_prev_version_build(
if ((update->info_bits & REC_INFO_DELETED_FLAG) if ((update->info_bits & REC_INFO_DELETED_FLAG)
&& row_upd_changes_disowned_external(update)) { && row_upd_changes_disowned_external(update)) {
bool missing_extern; purge_sys.latch.rd_lock();
rw_lock_s_lock(&purge_sys.latch); bool missing_extern = purge_sys.changes_visible(
missing_extern = purge_sys.changes_visible(
trx_id, index->table->name); trx_id, index->table->name);
rw_lock_s_unlock(&purge_sys.latch); purge_sys.latch.rd_unlock();
if (missing_extern) { if (missing_extern) {
/* treat as a fresh insert, not to /* treat as a fresh insert, not to