Commit 00cd53d3 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-23719: Make lock_sys use page_id_t

Since commit 8ccb3caa it should be
more efficient to use page_id_t rather than two separate variables
for tablespace identifier and page number.

lock_rec_fold(): Replaced with page_id_t::fold().

lock_rec_hash(): Replaced with lock_sys.hash(page_id).

lock_rec_expl_exist_on_page(), lock_rec_get_first_on_page_addr(),
lock_rec_get_first_on_page(): Replaced with lock_sys.get_first().
parent 852771ba
...@@ -5423,8 +5423,7 @@ btr_cur_compress_if_useful( ...@@ -5423,8 +5423,7 @@ btr_cur_compress_if_useful(
const buf_block_t* block = btr_cur_get_block(cursor); const buf_block_t* block = btr_cur_get_block(cursor);
/* Check whether page lock prevents the compression */ /* Check whether page lock prevents the compression */
if (!lock_test_prdt_page_lock(trx, block->page.id().space(), if (!lock_test_prdt_page_lock(trx, block->page.id())) {
block->page.id().page_no())) {
return(false); return(false);
} }
} }
......
...@@ -652,8 +652,7 @@ rtr_adjust_upper_level( ...@@ -652,8 +652,7 @@ rtr_adjust_upper_level(
new_prdt.op = 0; new_prdt.op = 0;
lock_prdt_update_parent(block, new_block, &prdt, &new_prdt, lock_prdt_update_parent(block, new_block, &prdt, &new_prdt,
index->table->space_id, page_cursor->block->page.id());
page_cursor->block->page.id().page_no());
mem_heap_free(heap); mem_heap_free(heap);
...@@ -881,8 +880,6 @@ rtr_page_split_and_insert( ...@@ -881,8 +880,6 @@ rtr_page_split_and_insert(
buf_block_t* block; buf_block_t* block;
page_t* page; page_t* page;
page_t* new_page; page_t* new_page;
ulint page_no;
ulint hint_page_no;
buf_block_t* new_block; buf_block_t* new_block;
page_zip_des_t* page_zip; page_zip_des_t* page_zip;
page_zip_des_t* new_page_zip; page_zip_des_t* new_page_zip;
...@@ -931,7 +928,7 @@ rtr_page_split_and_insert( ...@@ -931,7 +928,7 @@ rtr_page_split_and_insert(
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_get_n_recs(page) >= 1); ut_ad(page_get_n_recs(page) >= 1);
page_no = block->page.id().page_no(); const page_id_t page_id(block->page.id());
if (!page_has_prev(page) && !page_is_leaf(page)) { if (!page_has_prev(page) && !page_is_leaf(page)) {
first_rec = page_rec_get_next( first_rec = page_rec_get_next(
...@@ -969,10 +966,9 @@ rtr_page_split_and_insert( ...@@ -969,10 +966,9 @@ rtr_page_split_and_insert(
static_cast<uchar*>(first_rec)); static_cast<uchar*>(first_rec));
/* Allocate a new page to the index */ /* Allocate a new page to the index */
hint_page_no = page_no + 1;
const uint16_t page_level = btr_page_get_level(page); const uint16_t page_level = btr_page_get_level(page);
new_block = btr_page_alloc(cursor->index, hint_page_no, FSP_UP, new_block = btr_page_alloc(cursor->index, page_id.page_no() + 1,
page_level, mtr, mtr); FSP_UP, page_level, mtr, mtr);
if (!new_block) { if (!new_block) {
return NULL; return NULL;
} }
...@@ -1155,8 +1151,7 @@ rtr_page_split_and_insert( ...@@ -1155,8 +1151,7 @@ rtr_page_split_and_insert(
/* Check any predicate locks need to be moved/copied to the /* Check any predicate locks need to be moved/copied to the
new page */ new page */
lock_prdt_update_split(new_block, &prdt, &new_prdt, lock_prdt_update_split(new_block, &prdt, &new_prdt, page_id);
cursor->index->table->space_id, page_no);
/* Adjust the upper level. */ /* Adjust the upper level. */
rtr_adjust_upper_level(cursor, flags, block, new_block, rtr_adjust_upper_level(cursor, flags, block, new_block,
......
...@@ -298,8 +298,9 @@ rtr_pcur_getnext_from_path( ...@@ -298,8 +298,9 @@ rtr_pcur_getnext_from_path(
&& mode != PAGE_CUR_RTREE_LOCATE) { && mode != PAGE_CUR_RTREE_LOCATE) {
ut_ad(rtr_info->thr); ut_ad(rtr_info->thr);
lock_place_prdt_page_lock( lock_place_prdt_page_lock(
index->table->space_id, page_id_t(block->page.id().space(),
next_page_no, index, next_page_no),
index,
rtr_info->thr); rtr_info->thr);
} }
new_split = true; new_split = true;
...@@ -1689,7 +1690,6 @@ rtr_cur_search_with_match( ...@@ -1689,7 +1690,6 @@ rtr_cur_search_with_match(
const rec_t* best_rec; const rec_t* best_rec;
const rec_t* last_match_rec = NULL; const rec_t* last_match_rec = NULL;
bool match_init = false; bool match_init = false;
ulint space = block->page.id().space();
page_cur_mode_t orig_mode = mode; page_cur_mode_t orig_mode = mode;
const rec_t* first_rec = NULL; const rec_t* first_rec = NULL;
...@@ -1870,7 +1870,11 @@ rtr_cur_search_with_match( ...@@ -1870,7 +1870,11 @@ rtr_cur_search_with_match(
/* Lock the page, preventing it /* Lock the page, preventing it
from being shrunk */ from being shrunk */
lock_place_prdt_page_lock( lock_place_prdt_page_lock(
space, page_no, index, page_id_t(block->page
.id()
.space(),
page_no),
index,
rtr_info->thr); rtr_info->thr);
} }
} else { } else {
......
...@@ -699,10 +699,10 @@ fill_innodb_locks_from_cache( ...@@ -699,10 +699,10 @@ fill_innodb_locks_from_cache(
OK(field_store_string(fields[IDX_LOCK_INDEX], OK(field_store_string(fields[IDX_LOCK_INDEX],
row->lock_index)); row->lock_index));
OK(fields[IDX_LOCK_SPACE]->store( OK(fields[IDX_LOCK_SPACE]->store(
row->lock_space, true)); row->lock_page.space(), true));
fields[IDX_LOCK_SPACE]->set_notnull(); fields[IDX_LOCK_SPACE]->set_notnull();
OK(fields[IDX_LOCK_PAGE]->store( OK(fields[IDX_LOCK_PAGE]->store(
row->lock_page, true)); row->lock_page.page_no(), true));
fields[IDX_LOCK_PAGE]->set_notnull(); fields[IDX_LOCK_PAGE]->set_notnull();
OK(fields[IDX_LOCK_REC]->store( OK(fields[IDX_LOCK_REC]->store(
row->lock_rec, true)); row->lock_rec, true));
......
...@@ -3329,18 +3329,22 @@ ibuf_insert_low( ...@@ -3329,18 +3329,22 @@ ibuf_insert_low(
and done mtr_commit(&mtr) to release the latch. */ and done mtr_commit(&mtr) to release the latch. */
ibuf_mtr_start(&bitmap_mtr); ibuf_mtr_start(&bitmap_mtr);
index->set_modified(bitmap_mtr);
bitmap_page = ibuf_bitmap_get_map_page(page_id, zip_size, &bitmap_mtr); bitmap_page = ibuf_bitmap_get_map_page(page_id, zip_size, &bitmap_mtr);
/* We check if the index page is suitable for buffered entries */ /* We check if the index page is suitable for buffered entries */
if (buf_pool.page_hash_contains(page_id) if (buf_pool.page_hash_contains(page_id)) {
|| lock_rec_expl_exist_on_page(page_id.space(), commit_exit:
page_id.page_no())) {
ibuf_mtr_commit(&bitmap_mtr); ibuf_mtr_commit(&bitmap_mtr);
goto fail_exit; goto fail_exit;
} else {
lock_mutex_enter();
const auto lock_exists = lock_sys.get_first(page_id);
lock_mutex_exit();
if (lock_exists) {
goto commit_exit;
}
} }
if (op == IBUF_OP_INSERT) { if (op == IBUF_OP_INSERT) {
...@@ -3378,8 +3382,7 @@ ibuf_insert_low( ...@@ -3378,8 +3382,7 @@ ibuf_insert_low(
dfield_t* field; dfield_t* field;
if (counter == ULINT_UNDEFINED) { if (counter == ULINT_UNDEFINED) {
ibuf_mtr_commit(&bitmap_mtr); goto commit_exit;
goto fail_exit;
} }
field = dtuple_get_nth_field( field = dtuple_get_nth_field(
...@@ -3391,6 +3394,7 @@ ibuf_insert_low( ...@@ -3391,6 +3394,7 @@ ibuf_insert_low(
/* Set the bitmap bit denoting that the insert buffer contains /* Set the bitmap bit denoting that the insert buffer contains
buffered entries for this index page, if the bit is not set yet */ buffered entries for this index page, if the bit is not set yet */
index->set_modified(bitmap_mtr);
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>( ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
bitmap_page, page_id, physical_size, true, &bitmap_mtr); bitmap_page, page_id, physical_size, true, &bitmap_mtr);
ibuf_mtr_commit(&bitmap_mtr); ibuf_mtr_commit(&bitmap_mtr);
......
...@@ -252,15 +252,6 @@ lock_rec_restore_from_page_infimum( ...@@ -252,15 +252,6 @@ lock_rec_restore_from_page_infimum(
state; lock bits are reset on state; lock bits are reset on
the infimum */ the infimum */
/*********************************************************************//** /*********************************************************************//**
Determines if there are explicit record locks on a page.
@return an explicit record lock on the page, or NULL if there are none */
lock_t*
lock_rec_expl_exist_on_page(
/*========================*/
ulint space, /*!< in: space id */
ulint page_no)/*!< in: page number */
MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of Checks if locks of other transactions prevent an immediate insert of
a record. If they do, first tests if the query thread should anyway a record. If they do, first tests if the query thread should anyway
be suspended for some reason; if not, then puts the transaction and be suspended for some reason; if not, then puts the transaction and
...@@ -487,28 +478,6 @@ lock_rec_unlock( ...@@ -487,28 +478,6 @@ lock_rec_unlock(
and release possible other transactions waiting because of these locks. */ and release possible other transactions waiting because of these locks. */
void lock_release(trx_t* trx); void lock_release(trx_t* trx);
/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
searching for a lock in the hash table.
@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
ulint space, /*!< in: space */
ulint page_no)/*!< in: page number */
MY_ATTRIBUTE((const));
/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
searching for a lock in the hash table.
@return hashed value */
UNIV_INLINE
unsigned
lock_rec_hash(
/*==========*/
ulint space, /*!< in: space */
ulint page_no);/*!< in: page number */
/*************************************************************//** /*************************************************************//**
Get the lock hash table */ Get the lock hash table */
UNIV_INLINE UNIV_INLINE
...@@ -819,6 +788,46 @@ class lock_sys_t ...@@ -819,6 +788,46 @@ class lock_sys_t
/** Closes the lock system at database shutdown. */ /** Closes the lock system at database shutdown. */
void close(); void close();
/** @return the hash value for a page address */
ulint hash(const page_id_t id) const
{ ut_ad(mutex_own(&mutex)); return rec_hash.calc_hash(id.fold()); }
/** Get the first lock on a page.
@param lock_hash hash table to look at
@param id page number
@return first lock
@retval nullptr if none exists */
lock_t *get_first(const hash_table_t &lock_hash, const page_id_t id) const
{
ut_ad(&lock_hash == &rec_hash || &lock_hash == &prdt_hash ||
&lock_hash == &prdt_page_hash);
for (lock_t *lock= static_cast<lock_t*>
(HASH_GET_FIRST(&lock_hash, hash(id)));
lock; lock= static_cast<lock_t*>(HASH_GET_NEXT(hash, lock)))
if (lock->un_member.rec_lock.page_id == id)
return lock;
return nullptr;
}
/** Get the first record lock on a page.
@param id page number
@return first lock
@retval nullptr if none exists */
lock_t *get_first(const page_id_t id) const
{ return get_first(rec_hash, id); }
/** Get the first predicate lock on a SPATIAL INDEX page.
@param id page number
@return first lock
@retval nullptr if none exists */
lock_t *get_first_prdt(const page_id_t id) const
{ return get_first(prdt_hash, id); }
/** Get the first predicate lock on a SPATIAL INDEX page.
@param id page number
@return first lock
@retval nullptr if none exists */
lock_t *get_first_prdt_page(const page_id_t id) const
{ return get_first(prdt_page_hash, id); }
}; };
/*********************************************************************//** /*********************************************************************//**
...@@ -858,8 +867,7 @@ lock_rec_discard( ...@@ -858,8 +867,7 @@ lock_rec_discard(
without checking for deadlocks or conflicts. without checking for deadlocks or conflicts.
@param[in] type_mode lock mode and wait flag; type will be replaced @param[in] type_mode lock mode and wait flag; type will be replaced
with LOCK_REC with LOCK_REC
@param[in] space tablespace id @param[in] page_id index page number
@param[in] page_no index page number
@param[in] page R-tree index page, or NULL @param[in] page R-tree index page, or NULL
@param[in] heap_no record heap number in the index page @param[in] heap_no record heap number in the index page
@param[in] index the index tree @param[in] index the index tree
...@@ -873,8 +881,7 @@ lock_rec_create_low( ...@@ -873,8 +881,7 @@ lock_rec_create_low(
que_thr_t* thr, /*!< thread owning trx */ que_thr_t* thr, /*!< thread owning trx */
#endif #endif
unsigned type_mode, unsigned type_mode,
ulint space, const page_id_t page_id,
ulint page_no,
const page_t* page, const page_t* page,
ulint heap_no, ulint heap_no,
dict_index_t* index, dict_index_t* index,
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -28,34 +28,6 @@ Created 5/7/1996 Heikki Tuuri ...@@ -28,34 +28,6 @@ Created 5/7/1996 Heikki Tuuri
#include "buf0buf.h" #include "buf0buf.h"
#include "page0page.h" #include "page0page.h"
/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
searching for a lock in the hash table.
@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
ulint space, /*!< in: space */
ulint page_no)/*!< in: page number */
{
return page_id_t(space, page_no).fold();
}
/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
searching for a lock in the hash table.
@return hashed value */
UNIV_INLINE
unsigned
lock_rec_hash(
/*==========*/
ulint space, /*!< in: space */
ulint page_no)/*!< in: page number */
{
return unsigned(lock_sys.rec_hash.calc_hash(lock_rec_fold(space, page_no)));
}
/*********************************************************************//** /*********************************************************************//**
Gets the heap_no of the smallest user record on a page. Gets the heap_no of the smallest user record on a page.
@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */ @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
...@@ -122,12 +94,10 @@ lock_rec_create( ...@@ -122,12 +94,10 @@ lock_rec_create(
trx mutex */ trx mutex */
{ {
btr_assert_not_corrupted(block, index); btr_assert_not_corrupted(block, index);
const page_id_t id(block->page.id());
return lock_rec_create_low( return lock_rec_create_low(
#ifdef WITH_WSREP #ifdef WITH_WSREP
c_lock, thr, c_lock, thr,
#endif #endif
type_mode, id.space(), id.page_no(), type_mode, block->page.id(), block->frame, heap_no,
block->frame, heap_no,
index, trx, caller_owns_trx_mutex); index, trx, caller_owns_trx_mutex);
} }
...@@ -58,9 +58,7 @@ Acquire a "Page" lock on a block ...@@ -58,9 +58,7 @@ Acquire a "Page" lock on a block
@return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
dberr_t dberr_t
lock_place_prdt_page_lock( lock_place_prdt_page_lock(
/*======================*/ const page_id_t page_id, /*!< in: page identifier */
ulint space, /*!< in: space for the page to lock */
ulint pageno, /*!< in: page number */
dict_index_t* index, /*!< in: secondary index */ dict_index_t* index, /*!< in: secondary index */
que_thr_t* thr); /*!< in: query thread */ que_thr_t* thr); /*!< in: query thread */
...@@ -108,8 +106,7 @@ lock_prdt_update_split( ...@@ -108,8 +106,7 @@ lock_prdt_update_split(
buf_block_t* new_block, /*!< in/out: the new half page */ buf_block_t* new_block, /*!< in/out: the new half page */
lock_prdt_t* prdt, /*!< in: MBR on the old page */ lock_prdt_t* prdt, /*!< in: MBR on the old page */
lock_prdt_t* new_prdt, /*!< in: MBR on the new page */ lock_prdt_t* new_prdt, /*!< in: MBR on the new page */
ulint space, /*!< in: space id */ const page_id_t page_id); /*!< in: page number */
ulint page_no); /*!< in: page number */
/**************************************************************//** /**************************************************************//**
Ajust locks from an ancester page of Rtree on the appropriate level . */ Ajust locks from an ancester page of Rtree on the appropriate level . */
...@@ -120,8 +117,7 @@ lock_prdt_update_parent( ...@@ -120,8 +117,7 @@ lock_prdt_update_parent(
buf_block_t* right_block, /*!< in/out: the new half page */ buf_block_t* right_block, /*!< in/out: the new half page */
lock_prdt_t* left_prdt, /*!< in: MBR on the old page */ lock_prdt_t* left_prdt, /*!< in: MBR on the old page */
lock_prdt_t* right_prdt, /*!< in: MBR on the new page */ lock_prdt_t* right_prdt, /*!< in: MBR on the new page */
ulint space, /*!< in: space id */ const page_id_t page_id); /*!< in: parent page */
ulint page_no); /*!< in: page number */
/*********************************************************************//** /*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of Checks if locks of other transactions prevent an immediate insert of
...@@ -190,17 +186,11 @@ lock_prdt_rec_move( ...@@ -190,17 +186,11 @@ lock_prdt_rec_move(
const buf_block_t* donator); /*!< in: buffer block containing const buf_block_t* donator); /*!< in: buffer block containing
the donating record */ the donating record */
/** Check whether there are R-tree Page lock on a buffer page /** Check whether there are R-tree Page lock on a page
@param[in] trx trx to test the lock @param[in] trx trx to test the lock
@param[in] space space id for the page @param[in] page_id page identifier
@param[in] page_no page number @return true if there is none */
@return true if there is none */ bool lock_test_prdt_page_lock(const trx_t *trx, const page_id_t page_id);
bool
lock_test_prdt_page_lock(
/*=====================*/
const trx_t* trx,
ulint space,
ulint page_no);
/** Removes predicate lock objects set on an index page which is discarded. /** Removes predicate lock objects set on an index page which is discarded.
@param[in] block page to be discarded @param[in] block page to be discarded
......
...@@ -539,29 +539,6 @@ lock_t* ...@@ -539,29 +539,6 @@ lock_t*
lock_rec_get_next_on_page( lock_rec_get_next_on_page(
/*======================*/ /*======================*/
lock_t* lock); /*!< in: a record lock */ lock_t* lock); /*!< in: a record lock */
/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by its
file address.
@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page_addr(
/*============================*/
hash_table_t* lock_hash, /* Lock hash table */
ulint space, /*!< in: space */
ulint page_no); /*!< in: page number */
/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by a
pointer to it.
@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page(
/*=======================*/
hash_table_t* lock_hash, /*!< in: lock hash table */
const buf_block_t* block); /*!< in: buffer block */
/*********************************************************************//** /*********************************************************************//**
Gets the next explicit lock request on a record. Gets the next explicit lock request on a record.
...@@ -632,20 +609,6 @@ lock_get_wait( ...@@ -632,20 +609,6 @@ lock_get_wait(
/*==========*/ /*==========*/
const lock_t* lock); /*!< in: lock */ const lock_t* lock); /*!< in: lock */
/*********************************************************************//**
Looks for a suitable type record lock struct by the same trx on the same page.
This can be used to save space when a new record lock should be set on a page:
no new struct is needed, if a suitable old is found.
@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_find_similar_on_page(
/*==========================*/
ulint type_mode, /*!< in: lock type_mode field */
ulint heap_no, /*!< in: heap number of the record */
lock_t* lock, /*!< in: lock_rec_get_first_on_page() */
const trx_t* trx); /*!< in: transaction */
/*********************************************************************//** /*********************************************************************//**
Checks if a transaction has the specified table lock, or stronger. This Checks if a transaction has the specified table lock, or stronger. This
function should only be called by the thread that owns the transaction. function should only be called by the thread that owns the transaction.
......
...@@ -121,70 +121,6 @@ lock_rec_get_next_on_page( ...@@ -121,70 +121,6 @@ lock_rec_get_next_on_page(
return((lock_t*) lock_rec_get_next_on_page_const(lock)); return((lock_t*) lock_rec_get_next_on_page_const(lock));
} }
/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by its
file address.
@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page_addr(
/*============================*/
hash_table_t* lock_hash, /* Lock hash table */
ulint space, /*!< in: space */
ulint page_no) /*!< in: page number */
{
ut_ad(lock_mutex_own());
for (lock_t* lock = static_cast<lock_t*>(
HASH_GET_FIRST(lock_hash,
lock_rec_hash(space, page_no)));
lock != NULL;
lock = static_cast<lock_t*>(HASH_GET_NEXT(hash, lock))) {
if (lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no) {
return(lock);
}
}
return(NULL);
}
/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by a
pointer to it.
@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page(
/*=======================*/
hash_table_t* lock_hash, /*!< in: lock hash table */
const buf_block_t* block) /*!< in: buffer block */
{
ut_ad(lock_mutex_own());
const page_id_t page_id(block->page.id());
ulint space = page_id.space();
ulint page_no = page_id.page_no();
for (lock_t* lock = static_cast<lock_t*>(
HASH_GET_FIRST(lock_hash,
lock_rec_hash(space, page_no)));
lock != NULL;
lock = static_cast<lock_t*>(HASH_GET_NEXT(hash, lock))) {
if (lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no) {
return(lock);
}
}
return(NULL);
}
/*********************************************************************//** /*********************************************************************//**
Gets the next explicit lock request on a record. Gets the next explicit lock request on a record.
@return next lock, NULL if none exists or if heap_no == ULINT_UNDEFINED */ @return next lock, NULL if none exists or if heap_no == ULINT_UNDEFINED */
...@@ -229,16 +165,11 @@ lock_rec_get_first( ...@@ -229,16 +165,11 @@ lock_rec_get_first(
const buf_block_t* block, /*!< in: block containing the record */ const buf_block_t* block, /*!< in: block containing the record */
ulint heap_no)/*!< in: heap number of the record */ ulint heap_no)/*!< in: heap number of the record */
{ {
ut_ad(lock_mutex_own()); for (lock_t *lock= lock_sys.get_first(*hash, block->page.id());
lock; lock= lock_rec_get_next_on_page(lock))
for (lock_t* lock = lock_rec_get_first_on_page(hash, block); lock; if (lock_rec_get_nth_bit(lock, heap_no))
lock = lock_rec_get_next_on_page(lock)) { return lock;
if (lock_rec_get_nth_bit(lock, heap_no)) { return nullptr;
return(lock);
}
}
return(NULL);
} }
/*********************************************************************//** /*********************************************************************//**
...@@ -275,23 +206,15 @@ lock_rec_get_next_on_page_const( ...@@ -275,23 +206,15 @@ lock_rec_get_next_on_page_const(
/*============================*/ /*============================*/
const lock_t* lock) /*!< in: a record lock */ const lock_t* lock) /*!< in: a record lock */
{ {
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
ut_ad(lock_get_type_low(lock) == LOCK_REC); ut_ad(lock_get_type_low(lock) == LOCK_REC);
ulint space = lock->un_member.rec_lock.space;
ulint page_no = lock->un_member.rec_lock.page_no;
while ((lock = static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock)))
!= NULL) {
if (lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no) {
return(lock); const page_id_t page_id(lock->un_member.rec_lock.page_id);
}
}
return(NULL); while (!!(lock= static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock))))
if (lock->un_member.rec_lock.page_id == page_id)
break;
return lock;
} }
/*********************************************************************//** /*********************************************************************//**
...@@ -354,37 +277,6 @@ lock_get_wait( ...@@ -354,37 +277,6 @@ lock_get_wait(
return(lock->type_mode & LOCK_WAIT); return(lock->type_mode & LOCK_WAIT);
} }
/*********************************************************************//**
Looks for a suitable type record lock struct by the same trx on the same page.
This can be used to save space when a new record lock should be set on a page:
no new struct is needed, if a suitable old is found.
@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_find_similar_on_page(
/*==========================*/
ulint type_mode, /*!< in: lock type_mode field */
ulint heap_no, /*!< in: heap number of the record */
lock_t* lock, /*!< in: lock_rec_get_first_on_page() */
const trx_t* trx) /*!< in: transaction */
{
ut_ad(lock_mutex_own());
for (/* No op */;
lock != NULL;
lock = lock_rec_get_next_on_page(lock)) {
if (lock->trx == trx
&& lock->type_mode == type_mode
&& lock_rec_get_n_bits(lock) > heap_no) {
return(lock);
}
}
return(NULL);
}
/*********************************************************************//** /*********************************************************************//**
Checks if a transaction has the specified table lock, or stronger. This Checks if a transaction has the specified table lock, or stronger. This
function should only be called by the thread that owns the transaction. function should only be called by the thread that owns the transaction.
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2019, MariaDB Corporation. Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -25,6 +25,7 @@ Created 5/7/1996 Heikki Tuuri ...@@ -25,6 +25,7 @@ Created 5/7/1996 Heikki Tuuri
*******************************************************/ *******************************************************/
#include "dict0types.h" #include "dict0types.h"
#include "buf0types.h"
#include "ut0lst.h" #include "ut0lst.h"
#ifndef lock0types_h #ifndef lock0types_h
...@@ -89,8 +90,8 @@ struct lock_table_t { ...@@ -89,8 +90,8 @@ struct lock_table_t {
/** Record lock for a page */ /** Record lock for a page */
struct lock_rec_t { struct lock_rec_t {
ib_uint32_t space; /*!< space id */ /** page identifier */
ib_uint32_t page_no; /*!< page number */ page_id_t page_id;
ib_uint32_t n_bits; /*!< number of bits in the lock ib_uint32_t n_bits; /*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is bitmap; NOTE: the lock bitmap is
placed immediately after the placed immediately after the
...@@ -105,12 +106,12 @@ struct lock_rec_t { ...@@ -105,12 +106,12 @@ struct lock_rec_t {
/** Print the record lock into the given output stream /** Print the record lock into the given output stream
@param[in,out] out the output stream @param[in,out] out the output stream
@return the given output stream. */ @return the given output stream. */
inline inline std::ostream &lock_rec_t::print(std::ostream &out) const
std::ostream& lock_rec_t::print(std::ostream& out) const
{ {
out << "[lock_rec_t: space=" << space << ", page_no=" << page_no out << "[lock_rec_t: space=" << page_id.space()
<< ", n_bits=" << n_bits << "]"; << ", page_no=" << page_id.page_no()
return(out); << ", n_bits=" << n_bits << "]";
return out;
} }
inline inline
......
...@@ -31,6 +31,7 @@ Created July 17, 2007 Vasil Dimov ...@@ -31,6 +31,7 @@ Created July 17, 2007 Vasil Dimov
#include "trx0types.h" #include "trx0types.h"
#include "dict0types.h" #include "dict0types.h"
#include "buf0types.h"
/** The maximum amount of memory that can be consumed by innodb_trx, /** The maximum amount of memory that can be consumed by innodb_trx,
innodb_locks and innodb_lock_waits information schema tables. */ innodb_locks and innodb_lock_waits information schema tables. */
...@@ -90,10 +91,8 @@ struct i_s_locks_row_t { ...@@ -90,10 +91,8 @@ struct i_s_locks_row_t {
lock_get_table_name() */ lock_get_table_name() */
/** index name of a record lock; NULL for table locks */ /** index name of a record lock; NULL for table locks */
const char* lock_index; const char* lock_index;
/** tablespace identifier of the record; 0 if !lock_index */ /** page identifier of the record; (0,0) if !lock_index */
uint32_t lock_space; page_id_t lock_page;
/** page number of the record; 0 if !lock_index */
uint32_t lock_page;
/** heap number of the record; 0 if !lock_index */ /** heap number of the record; 0 if !lock_index */
uint16_t lock_rec; uint16_t lock_rec;
/** lock mode corresponding to lock_mode_values_typelib */ /** lock mode corresponding to lock_mode_values_typelib */
......
This diff is collapsed.
...@@ -394,7 +394,8 @@ lock_prdt_find_on_page( ...@@ -394,7 +394,8 @@ lock_prdt_find_on_page(
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
for (lock = lock_rec_get_first_on_page(lock_hash_get(type_mode), block); for (lock = lock_sys.get_first(*lock_hash_get(type_mode),
block->page.id());
lock != NULL; lock != NULL;
lock = lock_rec_get_next_on_page(lock)) { lock = lock_rec_get_next_on_page(lock)) {
...@@ -457,7 +458,8 @@ lock_prdt_add_to_queue( ...@@ -457,7 +458,8 @@ lock_prdt_add_to_queue(
lock_t* lock; lock_t* lock;
for (lock = lock_rec_get_first_on_page(lock_hash_get(type_mode), block); for (lock = lock_sys.get_first(*lock_hash_get(type_mode),
block->page.id());
lock != NULL; lock != NULL;
lock = lock_rec_get_next_on_page(lock)) { lock = lock_rec_get_next_on_page(lock)) {
...@@ -619,16 +621,12 @@ lock_prdt_update_parent( ...@@ -619,16 +621,12 @@ lock_prdt_update_parent(
buf_block_t* right_block, /*!< in/out: the new half page */ buf_block_t* right_block, /*!< in/out: the new half page */
lock_prdt_t* left_prdt, /*!< in: MBR on the old page */ lock_prdt_t* left_prdt, /*!< in: MBR on the old page */
lock_prdt_t* right_prdt, /*!< in: MBR on the new page */ lock_prdt_t* right_prdt, /*!< in: MBR on the new page */
ulint space, /*!< in: parent space id */ const page_id_t page_id) /*!< in: parent page */
ulint page_no) /*!< in: parent page number */
{ {
lock_t* lock;
lock_mutex_enter(); lock_mutex_enter();
/* Get all locks in parent */ /* Get all locks in parent */
for (lock = lock_rec_get_first_on_page_addr( for (lock_t *lock = lock_sys.get_first_prdt(page_id);
&lock_sys.prdt_hash, space, page_no);
lock; lock;
lock = lock_rec_get_next_on_page(lock)) { lock = lock_rec_get_next_on_page(lock)) {
lock_prdt_t* lock_prdt; lock_prdt_t* lock_prdt;
...@@ -675,21 +673,15 @@ lock_prdt_update_split_low( ...@@ -675,21 +673,15 @@ lock_prdt_update_split_low(
buf_block_t* new_block, /*!< in/out: the new half page */ buf_block_t* new_block, /*!< in/out: the new half page */
lock_prdt_t* prdt, /*!< in: MBR on the old page */ lock_prdt_t* prdt, /*!< in: MBR on the old page */
lock_prdt_t* new_prdt, /*!< in: MBR on the new page */ lock_prdt_t* new_prdt, /*!< in: MBR on the new page */
ulint space, /*!< in: space id */ const page_id_t page_id, /*!< in: page number */
ulint page_no, /*!< in: page number */
unsigned type_mode) /*!< in: LOCK_PREDICATE or unsigned type_mode) /*!< in: LOCK_PREDICATE or
LOCK_PRDT_PAGE */ LOCK_PRDT_PAGE */
{ {
lock_t* lock; lock_t* lock;
lock_mutex_enter(); for (lock = lock_sys.get_first(*lock_hash_get(type_mode), page_id);
for (lock = lock_rec_get_first_on_page_addr(
lock_hash_get(type_mode), space, page_no);
lock; lock;
lock = lock_rec_get_next_on_page(lock)) { lock = lock_rec_get_next_on_page(lock)) {
ut_ad(lock);
/* First dealing with Page Lock */ /* First dealing with Page Lock */
if (lock->type_mode & LOCK_PRDT_PAGE) { if (lock->type_mode & LOCK_PRDT_PAGE) {
/* Duplicate the lock to new page */ /* Duplicate the lock to new page */
...@@ -739,8 +731,6 @@ lock_prdt_update_split_low( ...@@ -739,8 +731,6 @@ lock_prdt_update_split_low(
trx_mutex_exit(lock->trx); trx_mutex_exit(lock->trx);
} }
} }
lock_mutex_exit();
} }
/**************************************************************//** /**************************************************************//**
...@@ -751,14 +741,17 @@ lock_prdt_update_split( ...@@ -751,14 +741,17 @@ lock_prdt_update_split(
buf_block_t* new_block, /*!< in/out: the new half page */ buf_block_t* new_block, /*!< in/out: the new half page */
lock_prdt_t* prdt, /*!< in: MBR on the old page */ lock_prdt_t* prdt, /*!< in: MBR on the old page */
lock_prdt_t* new_prdt, /*!< in: MBR on the new page */ lock_prdt_t* new_prdt, /*!< in: MBR on the new page */
ulint space, /*!< in: space id */ const page_id_t page_id) /*!< in: page number */
ulint page_no) /*!< in: page number */
{ {
lock_mutex_enter();
lock_prdt_update_split_low(new_block, prdt, new_prdt, lock_prdt_update_split_low(new_block, prdt, new_prdt,
space, page_no, LOCK_PREDICATE); page_id, LOCK_PREDICATE);
lock_prdt_update_split_low(new_block, NULL, NULL, lock_prdt_update_split_low(new_block, NULL, NULL,
space, page_no, LOCK_PRDT_PAGE); page_id, LOCK_PRDT_PAGE);
lock_mutex_exit();
} }
/*********************************************************************//** /*********************************************************************//**
...@@ -814,9 +807,9 @@ lock_prdt_lock( ...@@ -814,9 +807,9 @@ lock_prdt_lock(
ut_ad(!dict_index_is_online_ddl(index)); ut_ad(!dict_index_is_online_ddl(index));
ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE)); ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
hash_table_t* hash = type_mode == LOCK_PREDICATE const hash_table_t& hash = type_mode == LOCK_PREDICATE
? &lock_sys.prdt_hash ? lock_sys.prdt_hash
: &lock_sys.prdt_page_hash; : lock_sys.prdt_page_hash;
/* Another transaction cannot have an implicit lock on the record, /* Another transaction cannot have an implicit lock on the record,
because when we come here, we already have modified the clustered because when we come here, we already have modified the clustered
...@@ -826,7 +819,7 @@ lock_prdt_lock( ...@@ -826,7 +819,7 @@ lock_prdt_lock(
lock_mutex_enter(); lock_mutex_enter();
const unsigned prdt_mode = type_mode | mode; const unsigned prdt_mode = type_mode | mode;
lock_t* lock = lock_rec_get_first_on_page(hash, block); lock_t* lock = lock_sys.get_first(hash, block->page.id());
if (lock == NULL) { if (lock == NULL) {
lock = lock_rec_create( lock = lock_rec_create(
...@@ -905,9 +898,7 @@ Acquire a "Page" lock on a block ...@@ -905,9 +898,7 @@ Acquire a "Page" lock on a block
@return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
dberr_t dberr_t
lock_place_prdt_page_lock( lock_place_prdt_page_lock(
/*======================*/ const page_id_t page_id, /*!< in: page identifier */
ulint space, /*!< in: space for the page to lock */
ulint page_no, /*!< in: page number */
dict_index_t* index, /*!< in: secondary index */ dict_index_t* index, /*!< in: secondary index */
que_thr_t* thr) /*!< in: query thread */ que_thr_t* thr) /*!< in: query thread */
{ {
...@@ -924,9 +915,7 @@ lock_place_prdt_page_lock( ...@@ -924,9 +915,7 @@ lock_place_prdt_page_lock(
lock_mutex_enter(); lock_mutex_enter();
const lock_t* lock = lock_rec_get_first_on_page_addr( const lock_t* lock = lock_sys.get_first_prdt_page(page_id);
&lock_sys.prdt_page_hash, space, page_no);
const ulint mode = LOCK_S | LOCK_PRDT_PAGE; const ulint mode = LOCK_S | LOCK_PRDT_PAGE;
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
...@@ -952,7 +941,7 @@ lock_place_prdt_page_lock( ...@@ -952,7 +941,7 @@ lock_place_prdt_page_lock(
#ifdef WITH_WSREP #ifdef WITH_WSREP
NULL, NULL, /* FIXME: replicate SPATIAL INDEX locks */ NULL, NULL, /* FIXME: replicate SPATIAL INDEX locks */
#endif #endif
mode, space, page_no, NULL, PRDT_HEAPNO, mode, page_id, NULL, PRDT_HEAPNO,
index, trx, FALSE); index, trx, FALSE);
#ifdef PRDT_DIAG #ifdef PRDT_DIAG
...@@ -967,25 +956,19 @@ lock_place_prdt_page_lock( ...@@ -967,25 +956,19 @@ lock_place_prdt_page_lock(
/** Check whether there are R-tree Page lock on a page /** Check whether there are R-tree Page lock on a page
@param[in] trx trx to test the lock @param[in] trx trx to test the lock
@param[in] space space id for the page @param[in] page_id page identifier
@param[in] page_no page number
@return true if there is none */ @return true if there is none */
bool bool lock_test_prdt_page_lock(const trx_t *trx, const page_id_t page_id)
lock_test_prdt_page_lock(
const trx_t* trx,
ulint space,
ulint page_no)
{ {
lock_t* lock; lock_t* lock;
lock_mutex_enter(); lock_mutex_enter();
lock = lock_rec_get_first_on_page_addr( lock = lock_sys.get_first_prdt_page(page_id);
&lock_sys.prdt_page_hash, space, page_no);
lock_mutex_exit(); lock_mutex_exit();
return(lock == NULL || trx == lock->trx); return(!lock || trx == lock->trx);
} }
/*************************************************************//** /*************************************************************//**
...@@ -1030,15 +1013,10 @@ lock_prdt_page_free_from_discard( ...@@ -1030,15 +1013,10 @@ lock_prdt_page_free_from_discard(
{ {
lock_t* lock; lock_t* lock;
lock_t* next_lock; lock_t* next_lock;
ulint space;
ulint page_no;
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
space = block->page.id().space(); lock = lock_sys.get_first(*lock_hash, block->page.id());
page_no = block->page.id().page_no();
lock = lock_rec_get_first_on_page_addr(lock_hash, space, page_no);
while (lock != NULL) { while (lock != NULL) {
next_lock = lock_rec_get_next_on_page(lock); next_lock = lock_rec_get_next_on_page(lock);
......
...@@ -499,9 +499,8 @@ row_purge_remove_sec_if_poss_leaf( ...@@ -499,9 +499,8 @@ row_purge_remove_sec_if_poss_leaf(
&& btr_cur->rtr_info->thr && btr_cur->rtr_info->thr
? thr_get_trx( ? thr_get_trx(
btr_cur->rtr_info->thr) btr_cur->rtr_info->thr)
: NULL, : nullptr,
block->page.id().space(), block->page.id())) {
block->page.id().page_no())) {
/* this is the last record on page, /* this is the last record on page,
and it has a "page" lock on it, and it has a "page" lock on it,
which mean search is still depending which mean search is still depending
......
...@@ -394,13 +394,11 @@ i_s_locks_row_validate( ...@@ -394,13 +394,11 @@ i_s_locks_row_validate(
if (!row->lock_index) { if (!row->lock_index) {
/* table lock */ /* table lock */
ut_ad(!row->lock_data); ut_ad(!row->lock_data);
ut_ad(!row->lock_space); ut_ad(row->lock_page == page_id_t(0, 0));
ut_ad(!row->lock_page);
ut_ad(!row->lock_rec); ut_ad(!row->lock_rec);
} else { } else {
/* record lock */ /* record lock */
/* row->lock_data == NULL if buf_page_try_get() == NULL */ /* row->lock_data == NULL if buf_page_try_get() == NULL */
ut_ad(row->lock_page);
} }
return(TRUE); return(TRUE);
...@@ -631,9 +629,7 @@ fill_lock_data( ...@@ -631,9 +629,7 @@ fill_lock_data(
mtr_start(&mtr); mtr_start(&mtr);
block = buf_page_try_get(page_id_t(lock->un_member.rec_lock.space, block = buf_page_try_get(lock->un_member.rec_lock.page_id, &mtr);
lock->un_member.rec_lock.page_no),
&mtr);
if (block == NULL) { if (block == NULL) {
...@@ -754,8 +750,7 @@ static bool fill_locks_row( ...@@ -754,8 +750,7 @@ static bool fill_locks_row(
return false; return false;
} }
row->lock_space = lock->un_member.rec_lock.space; row->lock_page = lock->un_member.rec_lock.page_id;
row->lock_page = lock->un_member.rec_lock.page_no;
row->lock_rec = heap_no; row->lock_rec = heap_no;
if (!fill_lock_data(&row->lock_data, lock, heap_no, cache)) { if (!fill_lock_data(&row->lock_data, lock, heap_no, cache)) {
...@@ -766,8 +761,7 @@ static bool fill_locks_row( ...@@ -766,8 +761,7 @@ static bool fill_locks_row(
} else { } else {
row->lock_index = NULL; row->lock_index = NULL;
row->lock_space = 0; row->lock_page = page_id_t(0, 0);
row->lock_page = 0;
row->lock_rec = 0; row->lock_rec = 0;
row->lock_data = NULL; row->lock_data = NULL;
...@@ -831,13 +825,9 @@ fold_lock( ...@@ -831,13 +825,9 @@ fold_lock(
switch (lock_get_type(lock)) { switch (lock_get_type(lock)) {
case LOCK_REC: case LOCK_REC:
ut_a(heap_no != 0xFFFF); ut_a(heap_no != 0xFFFF);
ret = ut_fold_ulint_pair((ulint) lock->trx->id, ret = ut_fold_ulint_pair((ulint) lock->trx->id,
lock->un_member.rec_lock.space); lock->un_member.rec_lock.page_id.
fold());
ret = ut_fold_ulint_pair(ret,
lock->un_member.rec_lock.page_no);
ret = ut_fold_ulint_pair(ret, heap_no); ret = ut_fold_ulint_pair(ret, heap_no);
break; break;
...@@ -880,8 +870,7 @@ locks_row_eq_lock( ...@@ -880,8 +870,7 @@ locks_row_eq_lock(
ut_a(heap_no != 0xFFFF); ut_a(heap_no != 0xFFFF);
return(row->lock_trx_id == lock->trx->id return(row->lock_trx_id == lock->trx->id
&& row->lock_space == lock->un_member.rec_lock.space && row->lock_page == lock->un_member.rec_lock.page_id
&& row->lock_page == lock->un_member.rec_lock.page_no
&& row->lock_rec == heap_no); && row->lock_rec == heap_no);
case LOCK_TABLE: case LOCK_TABLE:
...@@ -1477,8 +1466,8 @@ trx_i_s_create_lock_id( ...@@ -1477,8 +1466,8 @@ trx_i_s_create_lock_id(
res_len = snprintf(lock_id, lock_id_size, res_len = snprintf(lock_id, lock_id_size,
TRX_ID_FMT TRX_ID_FMT
":%u:%u:%u", ":%u:%u:%u",
row->lock_trx_id, row->lock_space, row->lock_trx_id, row->lock_page.space(),
row->lock_page, row->lock_rec); row->lock_page.page_no(), row->lock_rec);
} else { } else {
/* table lock */ /* table lock */
res_len = snprintf(lock_id, lock_id_size, res_len = snprintf(lock_id, lock_id_size,
......
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