summaryrefslogtreecommitdiff
path: root/storage/innobase/include/lock0priv.h
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-03-11 23:34:23 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-03-16 15:50:04 +0200
commitbd7ed1b923e8ddd896103d73461c4313a175cca6 (patch)
treef7309f0a96715fe8582949820360bfc0dbb21b56 /storage/innobase/include/lock0priv.h
parente15e879fae949a05de549a6676ae66d4f7f8c566 (diff)
downloadmariadb-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.h401
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);