mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 11:57:38 +02:00
MDEV-35174 Possible hang in trx_undo_prev_version()
In commit b7b9f3ce82 (MDEV-34515) we
accidentally made the InnoDB MVCC code acquire a shared
purge_sys.latch twice. Recursive shared latch acquisition may cause a
deadlock of InnoDB threads if another thread in between will start waiting
for an exclusive latch.
purge_sys_t::latch: In debug builds, use srw_lock_debug instead of
srw_spin_lock, so that bugs like this will result in debug assertion
failures.
trx_undo_report_row_operation(): Pass the view_guard to
trx_undo_prev_version() and the rest of the arguments in the same
order, so that the work to permute argument registers is minimized.
This commit is contained in:
parent
9849e3f948
commit
a4d2cc931d
2 changed files with 13 additions and 7 deletions
|
|
@ -125,7 +125,8 @@ class purge_sys_t
|
|||
|
||||
public:
|
||||
/** latch protecting view, m_enabled */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) mutable srw_spin_lock latch;
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE)
|
||||
mutable IF_DBUG(srw_lock_debug,srw_spin_lock) latch;
|
||||
private:
|
||||
/** Read view at the start of a purge batch. Any encountered index records
|
||||
that are older than view will be removed. */
|
||||
|
|
|
|||
|
|
@ -2040,8 +2040,10 @@ err_exit:
|
|||
|
||||
static dberr_t trx_undo_prev_version(const rec_t *rec, dict_index_t *index,
|
||||
rec_offs *offsets, mem_heap_t *heap,
|
||||
rec_t **old_vers, mem_heap_t *v_heap,
|
||||
dtuple_t **vrow, ulint v_status,
|
||||
rec_t **old_vers,
|
||||
const purge_sys_t::view_guard &check,
|
||||
ulint v_status,
|
||||
mem_heap_t *v_heap, dtuple_t **vrow,
|
||||
const trx_undo_rec_t *undo_rec);
|
||||
|
||||
inline const buf_block_t *
|
||||
|
|
@ -2142,7 +2144,8 @@ dberr_t trx_undo_prev_version_build(const rec_t *rec, dict_index_t *index,
|
|||
if (UNIV_UNLIKELY(end > offset &&
|
||||
end < srv_page_size - FIL_PAGE_DATA_END))
|
||||
err= trx_undo_prev_version(rec, index, offsets, heap,
|
||||
old_vers, v_heap, vrow, v_status, undo_rec);
|
||||
old_vers, check, v_status, v_heap, vrow,
|
||||
undo_rec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2152,8 +2155,10 @@ dberr_t trx_undo_prev_version_build(const rec_t *rec, dict_index_t *index,
|
|||
|
||||
static dberr_t trx_undo_prev_version(const rec_t *rec, dict_index_t *index,
|
||||
rec_offs *offsets, mem_heap_t *heap,
|
||||
rec_t **old_vers, mem_heap_t *v_heap,
|
||||
dtuple_t **vrow, ulint v_status,
|
||||
rec_t **old_vers,
|
||||
const purge_sys_t::view_guard &check,
|
||||
ulint v_status,
|
||||
mem_heap_t *v_heap, dtuple_t **vrow,
|
||||
const trx_undo_rec_t *undo_rec)
|
||||
{
|
||||
byte type, cmpl_info;
|
||||
|
|
@ -2223,7 +2228,7 @@ static dberr_t trx_undo_prev_version(const rec_t *rec, dict_index_t *index,
|
|||
the BLOB. */
|
||||
|
||||
if (update->info_bits & REC_INFO_DELETED_FLAG
|
||||
&& purge_sys.is_purgeable(trx_id)) {
|
||||
&& check.view().changes_visible(trx_id)) {
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue