diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-11 23:34:23 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-16 15:50:04 +0200 |
commit | bd7ed1b923e8ddd896103d73461c4313a175cca6 (patch) | |
tree | f7309f0a96715fe8582949820360bfc0dbb21b56 /storage/innobase/include/lock0priv.h | |
parent | e15e879fae949a05de549a6676ae66d4f7f8c566 (diff) | |
download | mariadb-git-bd7ed1b923e8ddd896103d73461c4313a175cca6.tar.gz |
MDEV-13935 INSERT stuck at state Unlocking tables
Revert the dead code for MySQL 5.7 multi-master replication (GCS),
also known as
WL#6835: InnoDB: GCS Replication: Deterministic Deadlock Handling
(High Prio Transactions in InnoDB).
Also, make innodb_lock_schedule_algorithm=vats skip SPATIAL INDEX,
because the code does not seem to be compatible with them.
Add FIXME comments to some SPATIAL INDEX locking code. It looks
like Galera write-set replication might not work with SPATIAL INDEX.
Diffstat (limited to 'storage/innobase/include/lock0priv.h')
-rw-r--r-- | storage/innobase/include/lock0priv.h | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h index 43f59151991..0f35e0ca6d0 100644 --- a/storage/innobase/include/lock0priv.h +++ b/storage/innobase/include/lock0priv.h @@ -562,407 +562,6 @@ enum lock_rec_req_status { LOCK_REC_SUCCESS_CREATED }; -/** -Record lock ID */ -struct RecID { - - RecID(ulint space_id, ulint page_no, ulint heap_no) - : - m_space_id(static_cast<uint32_t>(space_id)), - m_page_no(static_cast<uint32_t>(page_no)), - m_heap_no(static_cast<uint32_t>(heap_no)), - m_fold(lock_rec_fold(m_space_id, m_page_no)) - { - ut_ad(space_id < UINT32_MAX); - ut_ad(page_no < UINT32_MAX); - ut_ad(heap_no < UINT32_MAX); - } - - RecID(const buf_block_t* block, ulint heap_no) - : - m_space_id(block->page.id.space()), - m_page_no(block->page.id.page_no()), - m_heap_no(static_cast<uint32_t>(heap_no)), - m_fold(lock_rec_fold(m_space_id, m_page_no)) - { - ut_ad(heap_no < UINT32_MAX); - } - - /** - @return the "folded" value of {space, page_no} */ - ulint fold() const - { - return(m_fold); - } - - /** - Tablespace ID */ - uint32_t m_space_id; - - /** - Page number within the space ID */ - uint32_t m_page_no; - - /** - Heap number within the page */ - uint32_t m_heap_no; - - /** - Hashed key value */ - ulint m_fold; -}; - -/** -Create record locks */ -class RecLock { -public: - - /** - @param[in,out] thr Transaction query thread requesting the record - lock - @param[in] index Index on which record lock requested - @param[in] rec_id Record lock tuple {space, page_no, heap_no} - @param[in] mode The lock mode */ - RecLock(que_thr_t* thr, - dict_index_t* index, - const RecID& rec_id, - ulint mode) - : - m_thr(thr), - m_trx(thr_get_trx(thr)), - m_mode(mode), - m_index(index), - m_rec_id(rec_id) - { - ut_ad(is_predicate_lock(m_mode)); - - init(NULL); - } - - /** - @param[in,out] thr Transaction query thread requesting the record - lock - @param[in] index Index on which record lock requested - @param[in] block Buffer page containing record - @param[in] heap_no Heap number within the block - @param[in] mode The lock mode - @param[in] prdt The predicate for the rtree lock */ - RecLock(que_thr_t* thr, - dict_index_t* index, - const buf_block_t* - block, - ulint heap_no, - ulint mode, - lock_prdt_t* prdt = NULL) - : - m_thr(thr), - m_trx(thr_get_trx(thr)), - m_mode(mode), - m_index(index), - m_rec_id(block, heap_no) - { - btr_assert_not_corrupted(block, index); - - init(block->frame); - } - - /** - @param[in] index Index on which record lock requested - @param[in] rec_id Record lock tuple {space, page_no, heap_no} - @param[in] mode The lock mode */ - RecLock(dict_index_t* index, - const RecID& rec_id, - ulint mode) - : - m_thr(), - m_trx(), - m_mode(mode), - m_index(index), - m_rec_id(rec_id) - { - ut_ad(is_predicate_lock(m_mode)); - - init(NULL); - } - - /** - @param[in] index Index on which record lock requested - @param[in] block Buffer page containing record - @param[in] heap_no Heap number withing block - @param[in] mode The lock mode */ - RecLock(dict_index_t* index, - const buf_block_t* - block, - ulint heap_no, - ulint mode) - : - m_thr(), - m_trx(), - m_mode(mode), - m_index(index), - m_rec_id(block, heap_no) - { - btr_assert_not_corrupted(block, index); - - init(block->frame); - } - - /** - Enqueue a lock wait for a transaction. If it is a high priority - transaction (cannot rollback) then jump ahead in the record lock wait - queue and if the transaction at the head of the queue is itself waiting - roll it back. - @param[in, out] wait_for The lock that the the joining - transaction is waiting for - @param[in] prdt Predicate [optional] - @return DB_LOCK_WAIT, DB_DEADLOCK, or - DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that - there was a deadlock, but another transaction was chosen - as a victim, and we got the lock immediately: no need to - wait then */ - dberr_t add_to_waitq( - lock_t* wait_for, - const lock_prdt_t* - prdt = NULL); - - /** - Create a lock for a transaction and initialise it. - @param[in, out] trx Transaction requesting the new lock - @param[in] owns_trx_mutex true if caller owns the trx_t::mutex - @param[in] add_to_hash add the lock to hash table - @param[in] prdt Predicate lock (optional) - @param[in,out] c_lock Conflicting lock request or NULL - in Galera conflicting lock is selected - as deadlock victim if requester - is BF transaction. - @return new lock instance */ - lock_t* create( - trx_t* trx, - bool owns_trx_mutex, - bool add_to_hash, - const lock_prdt_t* - prdt = NULL -#ifdef WITH_WSREP - ,lock_t* c_lock = NULL -#endif /* WITH_WSREP */ - ); - - /** - Check of the lock is on m_rec_id. - @param[in] lock Lock to compare with - @return true if the record lock is on m_rec_id*/ - bool is_on_row(const lock_t* lock) const; - - /** - Create the lock instance - @param[in, out] trx The transaction requesting the lock - @param[in, out] index Index on which record lock is required - @param[in] mode The lock mode desired - @param[in] rec_id The record id - @param[in] size Size of the lock + bitmap requested - @return a record lock instance */ - static lock_t* lock_alloc( - trx_t* trx, - dict_index_t* index, - ulint mode, - const RecID& rec_id, - ulint size); - -private: - /* - @return the record lock size in bytes */ - size_t lock_size() const - { - return(m_size); - } - - /** - Do some checks and prepare for creating a new record lock */ - void prepare() const; - - /** - Collect the transactions that will need to be rolled back asynchronously - @param[in, out] trx Transaction to be rolled back */ - void mark_trx_for_rollback(trx_t* trx); - - /** - Jump the queue for the record over all low priority transactions and - add the lock. If all current granted locks are compatible, grant the - lock. Otherwise, mark all granted transaction for asynchronous - rollback and add to hit list. - @param[in, out] lock Lock being requested - @param[in] conflict_lock First conflicting lock from the head - @return true if the lock is granted */ - bool jump_queue(lock_t* lock, const lock_t* conflict_lock); - - /** Find position in lock queue and add the high priority transaction - lock. Intention and GAP only locks can be granted even if there are - waiting locks in front of the queue. To add the High priority - transaction in a safe position we keep the following rule. - - 1. If the lock can be granted, add it before the first waiting lock - in the queue so that all currently waiting locks need to do conflict - check before getting granted. - - 2. If the lock has to wait, add it after the last granted lock or the - last waiting high priority transaction in the queue whichever is later. - This ensures that the transaction is granted only after doing conflict - check with all granted transactions. - @param[in] lock Lock being requested - @param[in] conflict_lock First conflicting lock from the head - @param[out] high_priority high priority transaction ahead in queue - @return true if the lock can be granted */ - bool - lock_add_priority( - lock_t* lock, - const lock_t* conflict_lock, - bool* high_priority); - - /** Iterate over the granted locks and prepare the hit list for ASYNC Rollback. - If the transaction is waiting for some other lock then wake up with deadlock error. - Currently we don't mark following transactions for ASYNC Rollback. - 1. Read only transactions - 2. Background transactions - 3. Other High priority transactions - @param[in] lock Lock being requested - @param[in] conflict_lock First conflicting lock from the head */ - void make_trx_hit_list(lock_t* lock, const lock_t* conflict_lock); - - /** - Setup the requesting transaction state for lock grant - @param[in,out] lock Lock for which to change state */ - void set_wait_state(lock_t* lock); - - /** - Add the lock to the record lock hash and the transaction's lock list - @param[in,out] lock Newly created record lock to add to the - rec hash and the transaction lock list - @param[in] add_to_hash If the lock should be added to the hash table */ - void lock_add(lock_t* lock, bool add_to_hash); - - /** - Check and resolve any deadlocks - @param[in, out] lock The lock being acquired - @return DB_LOCK_WAIT, DB_DEADLOCK, or - DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that - there was a deadlock, but another transaction was chosen - as a victim, and we got the lock immediately: no need to - wait then */ - dberr_t deadlock_check(lock_t* lock); - - /** - Check the outcome of the deadlock check - @param[in,out] victim_trx Transaction selected for rollback - @param[in,out] lock Lock being requested - @return DB_LOCK_WAIT, DB_DEADLOCK or DB_SUCCESS_LOCKED_REC */ - dberr_t check_deadlock_result(const trx_t* victim_trx, lock_t* lock); - - /** - Setup the context from the requirements */ - void init(const page_t* page) - { - ut_ad(lock_mutex_own()); - ut_ad(!srv_read_only_mode); - ut_ad(dict_index_is_clust(m_index) - || !dict_index_is_online_ddl(m_index)); - ut_ad(m_thr == NULL || m_trx == thr_get_trx(m_thr)); - - m_size = is_predicate_lock(m_mode) - ? lock_size(m_mode) : lock_size(page); - - /** If rec is the supremum record, then we reset the - gap and LOCK_REC_NOT_GAP bits, as all locks on the - supremum are automatically of the gap type */ - - if (m_rec_id.m_heap_no == PAGE_HEAP_NO_SUPREMUM) { - ut_ad(!(m_mode & LOCK_REC_NOT_GAP)); - - m_mode &= ~(LOCK_GAP | LOCK_REC_NOT_GAP); - } - } - - /** - Calculate the record lock physical size required for a predicate lock. - @param[in] mode For predicate locks the lock mode - @return the size of the lock data structure required in bytes */ - static size_t lock_size(ulint mode) - { - ut_ad(is_predicate_lock(mode)); - - /* The lock is always on PAGE_HEAP_NO_INFIMUM(0), - so we only need 1 bit (which is rounded up to 1 - byte) for lock bit setting */ - - size_t n_bytes; - - if (mode & LOCK_PREDICATE) { - const ulint align = UNIV_WORD_SIZE - 1; - - /* We will attach the predicate structure - after lock. Make sure the memory is - aligned on 8 bytes, the mem_heap_alloc - will align it with MEM_SPACE_NEEDED - anyway. */ - - n_bytes = (1 + sizeof(lock_prdt_t) + align) & ~align; - - /* This should hold now */ - - ut_ad(n_bytes == sizeof(lock_prdt_t) + UNIV_WORD_SIZE); - - } else { - n_bytes = 1; - } - - return(n_bytes); - } - - /** - Calculate the record lock physical size required, non-predicate lock. - @param[in] page For non-predicate locks the buffer page - @return the size of the lock data structure required in bytes */ - static size_t lock_size(const page_t* page) - { - ulint n_recs = page_dir_get_n_heap(page); - - /* Make lock bitmap bigger by a safety margin */ - - return(1 + ((n_recs + LOCK_PAGE_BITMAP_MARGIN) / 8)); - } - - /** - @return true if the requested lock mode is for a predicate - or page lock */ - static bool is_predicate_lock(ulint mode) - { - return(mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE)); - } - -private: - /** The query thread of the transaction */ - que_thr_t* m_thr; - - /** - Transaction requesting the record lock */ - trx_t* m_trx; - - /** - Lock mode requested */ - ulint m_mode; - - /** - Size of the record lock in bytes */ - size_t m_size; - - /** - Index on which the record lock is required */ - dict_index_t* m_index; - - /** - The record lock tuple {space, page_no, heap_no} */ - RecID m_rec_id; -}; - #ifdef UNIV_DEBUG /** The count of the types of locks. */ static const ulint lock_types = UT_ARR_SIZE(lock_compatibility_matrix); |