lock0lock.h
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:19k
- /******************************************************
- The transaction lock system
- (c) 1996 Innobase Oy
- Created 5/7/1996 Heikki Tuuri
- *******************************************************/
- #ifndef lock0lock_h
- #define lock0lock_h
- #include "univ.i"
- #include "trx0types.h"
- #include "rem0types.h"
- #include "dict0types.h"
- #include "que0types.h"
- #include "page0types.h"
- #include "lock0types.h"
- #include "read0types.h"
- #include "hash0hash.h"
- extern ibool lock_print_waits;
- /*****************************************************************
- Cancels a waiting record lock request and releases the waiting transaction
- that requested it. NOTE: does NOT check if waiting lock requests behind this
- one can now be granted! */
- void
- lock_rec_cancel(
- /*============*/
- lock_t* lock); /* in: waiting record lock request */
- /*************************************************************************
- Creates the lock system at database start. */
- void
- lock_sys_create(
- /*============*/
- ulint n_cells); /* in: number of slots in lock hash table */
- /*************************************************************************
- Checks if some transaction has an implicit x-lock on a record in a secondary
- index. */
- trx_t*
- lock_sec_rec_some_has_impl_off_kernel(
- /*==================================*/
- /* out: transaction which has the x-lock, or
- NULL */
- rec_t* rec, /* in: user record */
- dict_index_t* index); /* in: secondary index */
- /*************************************************************************
- Checks if some transaction has an implicit x-lock on a record in a clustered
- index. */
- UNIV_INLINE
- trx_t*
- lock_clust_rec_some_has_impl(
- /*=========================*/
- /* out: transaction which has the x-lock, or
- NULL */
- rec_t* rec, /* in: user record */
- dict_index_t* index); /* in: clustered index */
- /*****************************************************************
- Resets the lock bits for a single record. Releases transactions
- waiting for lock requests here. */
- void
- lock_rec_reset_and_release_wait(
- /*============================*/
- rec_t* rec); /* in: record whose locks bits should be reset */
- /*****************************************************************
- Makes a record to inherit the locks of another record as gap type
- locks, but does not reset the lock bits of the other record. Also
- waiting lock requests on rec are inherited as GRANTED gap locks. */
- void
- lock_rec_inherit_to_gap(
- /*====================*/
- rec_t* heir, /* in: record which inherits */
- rec_t* rec); /* in: record from which inherited; does NOT reset
- the locks on this record */
- /*****************************************************************
- Updates the lock table when we have reorganized a page. NOTE: we copy
- also the locks set on the infimum of the page; the infimum may carry
- locks if an update of a record is occurring on the page, and its locks
- were temporarily stored on the infimum. */
- void
- lock_move_reorganize_page(
- /*======================*/
- page_t* page, /* in: old index page */
- page_t* new_page); /* in: reorganized page */
- /*****************************************************************
- Moves the explicit locks on user records to another page if a record
- list end is moved to another page. */
- void
- lock_move_rec_list_end(
- /*===================*/
- page_t* new_page, /* in: index page to move to */
- page_t* page, /* in: index page */
- rec_t* rec); /* in: record on page: this is the
- first record moved */
- /*****************************************************************
- Moves the explicit locks on user records to another page if a record
- list start is moved to another page. */
- void
- lock_move_rec_list_start(
- /*=====================*/
- page_t* new_page, /* in: index page to move to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page: this is the
- first record NOT copied */
- rec_t* old_end); /* in: old previous-to-last record on
- new_page before the records were copied */
- /*****************************************************************
- Updates the lock table when a page is split to the right. */
- void
- lock_update_split_right(
- /*====================*/
- page_t* right_page, /* in: right page */
- page_t* left_page); /* in: left page */
- /*****************************************************************
- Updates the lock table when a page is merged to the right. */
- void
- lock_update_merge_right(
- /*====================*/
- rec_t* orig_succ, /* in: original successor of infimum
- on the right page before merge */
- page_t* left_page); /* in: merged index page which will be
- discarded */
- /*****************************************************************
- Updates the lock table when the root page is copied to another in
- btr_root_raise_and_insert. Note that we leave lock structs on the
- root page, even though they do not make sense on other than leaf
- pages: the reason is that in a pessimistic update the infimum record
- of the root page will act as a dummy carrier of the locks of the record
- to be updated. */
- void
- lock_update_root_raise(
- /*===================*/
- page_t* new_page, /* in: index page to which copied */
- page_t* root); /* in: root page */
- /*****************************************************************
- Updates the lock table when a page is copied to another and the original page
- is removed from the chain of leaf pages, except if page is the root! */
- void
- lock_update_copy_and_discard(
- /*=========================*/
- page_t* new_page, /* in: index page to which copied */
- page_t* page); /* in: index page; NOT the root! */
- /*****************************************************************
- Updates the lock table when a page is split to the left. */
- void
- lock_update_split_left(
- /*===================*/
- page_t* right_page, /* in: right page */
- page_t* left_page); /* in: left page */
- /*****************************************************************
- Updates the lock table when a page is merged to the left. */
- void
- lock_update_merge_left(
- /*===================*/
- page_t* left_page, /* in: left page to which merged */
- rec_t* orig_pred, /* in: original predecessor of supremum
- on the left page before merge */
- page_t* right_page); /* in: merged index page which will be
- discarded */
- /*****************************************************************
- Resets the original locks on heir and replaces them with gap type locks
- inherited from rec. */
- void
- lock_rec_reset_and_inherit_gap_locks(
- /*=================================*/
- rec_t* heir, /* in: heir record */
- rec_t* rec); /* in: record */
- /*****************************************************************
- Updates the lock table when a page is discarded. */
- void
- lock_update_discard(
- /*================*/
- rec_t* heir, /* in: record which will inherit the locks */
- page_t* page); /* in: index page which will be discarded */
- /*****************************************************************
- Updates the lock table when a new user record is inserted. */
- void
- lock_update_insert(
- /*===============*/
- rec_t* rec); /* in: the inserted record */
- /*****************************************************************
- Updates the lock table when a record is removed. */
- void
- lock_update_delete(
- /*===============*/
- rec_t* rec); /* in: the record to be removed */
- /*************************************************************************
- Stores on the page infimum record the explicit locks of another record.
- This function is used to store the lock state of a record when it is
- updated and the size of the record changes in the update. The record
- is in such an update moved, perhaps to another page. The infimum record
- acts as a dummy carrier record, taking care of lock releases while the
- actual record is being moved. */
- void
- lock_rec_store_on_page_infimum(
- /*===========================*/
- rec_t* rec); /* in: record whose lock state is stored
- on the infimum record of the same page; lock
- bits are reset on the record */
- /*************************************************************************
- Restores the state of explicit lock requests on a single record, where the
- state was stored on the infimum of the page. */
- void
- lock_rec_restore_from_page_infimum(
- /*===============================*/
- rec_t* rec, /* in: record whose lock state is restored */
- page_t* page); /* in: page (rec is not necessarily on this page)
- whose infimum stored the lock state; lock bits are
- reset on the infimum */
- /*************************************************************************
- Returns TRUE if there are explicit record locks on a page. */
- ibool
- lock_rec_expl_exist_on_page(
- /*========================*/
- /* out: TRUE if there are explicit record locks on
- the page */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
- /*************************************************************************
- Checks if locks of other transactions prevent an immediate insert of
- 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
- the query thread to the lock wait state and inserts a waiting request
- for a gap x-lock to the lock queue. */
- ulint
- lock_rec_insert_check_and_lock(
- /*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- rec_t* rec, /* in: record after which to insert */
- dict_index_t* index, /* in: index */
- que_thr_t* thr, /* in: query thread */
- ibool* inherit);/* out: set to TRUE if the new inserted
- record maybe should inherit LOCK_GAP type
- locks from the successor record */
- /*************************************************************************
- Checks if locks of other transactions prevent an immediate modify (update,
- delete mark, or delete unmark) of a clustered index record. If they do,
- first tests if the query thread should anyway be suspended for some
- reason; if not, then puts the transaction and the query thread to the
- lock wait state and inserts a waiting request for a record x-lock to the
- lock queue. */
- ulint
- lock_clust_rec_modify_check_and_lock(
- /*=================================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- rec_t* rec, /* in: record which should be modified */
- dict_index_t* index, /* in: clustered index */
- que_thr_t* thr); /* in: query thread */
- /*************************************************************************
- Checks if locks of other transactions prevent an immediate modify
- (delete mark or delete unmark) of a secondary index record. */
- ulint
- lock_sec_rec_modify_check_and_lock(
- /*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- rec_t* rec, /* in: record which should be modified;
- NOTE: as this is a secondary index, we
- always have to modify the clustered index
- record first: see the comment below */
- dict_index_t* index, /* in: secondary index */
- que_thr_t* thr); /* in: query thread */
- /*************************************************************************
- Checks if locks of other transactions prevent an immediate read, or passing
- over by a read cursor, of a clustered index record. If they do, first tests
- if the query thread should anyway be suspended for some reason; if not, then
- puts the transaction and the query thread to the lock wait state and inserts a
- waiting request for a record lock to the lock queue. Sets the requested mode
- lock on the record. */
- ulint
- lock_clust_rec_read_check_and_lock(
- /*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- rec_t* rec, /* in: user record or page supremum record
- which should be read or passed over by a read
- cursor */
- dict_index_t* index, /* in: clustered index */
- ulint mode, /* in: mode of the lock which the read cursor
- should set on records: LOCK_S or LOCK_X; the
- latter is possible in SELECT FOR UPDATE */
- que_thr_t* thr); /* in: query thread */
- /*************************************************************************
- Like the counterpart for a clustered index above, but now we read a
- secondary index record. */
- ulint
- lock_sec_rec_read_check_and_lock(
- /*=============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- rec_t* rec, /* in: user record or page supremum record
- which should be read or passed over by a read
- cursor */
- dict_index_t* index, /* in: secondary index */
- ulint mode, /* in: mode of the lock which the read cursor
- should set on records: LOCK_S or LOCK_X; the
- latter is possible in SELECT FOR UPDATE */
- que_thr_t* thr); /* in: query thread */
- /*************************************************************************
- Checks that a record is seen in a consistent read. */
- ibool
- lock_clust_rec_cons_read_sees(
- /*==========================*/
- /* out: TRUE if sees, or FALSE if an earlier
- version of the record should be retrieved */
- rec_t* rec, /* in: user record which should be read or
- passed over by a read cursor */
- dict_index_t* index, /* in: clustered index */
- read_view_t* view); /* in: consistent read view */
- /*************************************************************************
- Checks that a non-clustered index record is seen in a consistent read. */
- ulint
- lock_sec_rec_cons_read_sees(
- /*========================*/
- /* out: TRUE if certainly sees, or FALSE if an
- earlier version of the clustered index record
- might be needed: NOTE that a non-clustered
- index page contains so little information on
- its modifications that also in the case FALSE,
- the present version of rec may be the right,
- but we must check this from the clustered
- index record */
- rec_t* rec, /* in: user record which should be read or
- passed over by a read cursor */
- dict_index_t* index, /* in: non-clustered index */
- read_view_t* view); /* in: consistent read view */
- /*************************************************************************
- Locks the specified database table in the mode given. If the lock cannot
- be granted immediately, the query thread is put to wait. */
- ulint
- lock_table(
- /*=======*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
- does nothing */
- dict_table_t* table, /* in: database table in dictionary cache */
- ulint mode, /* in: lock mode */
- que_thr_t* thr); /* in: query thread */
- /*************************************************************************
- Checks if there are any locks set on the table. */
- ibool
- lock_is_on_table(
- /*=============*/
- /* out: TRUE if there are lock(s) */
- dict_table_t* table); /* in: database table in dictionary cache */
- /*************************************************************************
- Releases transaction locks, and releases possible other transactions waiting
- because of these locks. */
- void
- lock_release_off_kernel(
- /*====================*/
- trx_t* trx); /* in: transaction */
- /*************************************************************************
- Calculates the fold value of a page file address: used in inserting or
- searching for a lock in the hash table. */
- UNIV_INLINE
- ulint
- lock_rec_fold(
- /*===========*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
- /*************************************************************************
- Calculates the hash value of a page file address: used in inserting or
- searching for a lock in the hash table. */
- UNIV_INLINE
- ulint
- lock_rec_hash(
- /*==========*/
- /* out: hashed value */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
- /*************************************************************************
- Gets the mutex protecting record locks on a given page address. */
- mutex_t*
- lock_rec_get_mutex_for_addr(
- /*========================*/
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
- /*************************************************************************
- Validates the lock queue on a single record. */
- ibool
- lock_rec_queue_validate(
- /*====================*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: record to look at */
- dict_index_t* index); /* in: index, or NULL if not known */
- /*************************************************************************
- Prints info of a table lock. */
- void
- lock_table_print(
- /*=============*/
- lock_t* lock); /* in: table type lock */
- /*************************************************************************
- Prints info of a record lock. */
- void
- lock_rec_print(
- /*===========*/
- lock_t* lock); /* in: record type lock */
- /*************************************************************************
- Prints info of locks for all transactions. */
- void
- lock_print_info(void);
- /*=================*/
- /*************************************************************************
- Validates the lock queue on a table. */
- ibool
- lock_table_queue_validate(
- /*======================*/
- /* out: TRUE if ok */
- dict_table_t* table); /* in: table */
- /*************************************************************************
- Validates the record lock queues on a page. */
- ibool
- lock_rec_validate_page(
- /*===================*/
- /* out: TRUE if ok */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
- /*************************************************************************
- Validates the lock system. */
- ibool
- lock_validate(void);
- /*===============*/
- /* out: TRUE if ok */
- /* The lock system */
- extern lock_sys_t* lock_sys;
- /* Lock modes and types */
- #define LOCK_NONE 0 /* this flag is used elsewhere to note
- consistent read */
- #define LOCK_IS 2 /* intention shared */
- #define LOCK_IX 3 /* intention exclusive */
- #define LOCK_S 4 /* shared */
- #define LOCK_X 5 /* exclusive */
- #define LOCK_MODE_MASK 0xF /* mask used to extract mode from the
- type_mode field in a lock */
- #define LOCK_TABLE 16 /* these type values should be so high that */
- #define LOCK_REC 32 /* they can be ORed to the lock mode */
- #define LOCK_TYPE_MASK 0xF0 /* mask used to extract lock type from the
- type_mode field in a lock */
- #define LOCK_WAIT 256 /* this wait bit should be so high that
- it can be ORed to the lock mode and type;
- when this bit is set, it means that the
- lock has not yet been granted, it is just
- waiting for its turn in the wait queue */
- #define LOCK_GAP 512 /* this gap bit should be so high that
- it can be ORed to the other flags;
- when this bit is set, it means that the
- lock holds only on the gap before the record;
- for instance, an x-lock on the gap does not
- give permission to modify the record on which
- the bit is set; locks of this type are created
- when records are removed from the index chain
- of records */
- /* When lock bits are reset, the following flags are available: */
- #define LOCK_RELEASE_WAIT 1
- #define LOCK_NOT_RELEASE_WAIT 2
- /* Lock operation struct */
- typedef struct lock_op_struct lock_op_t;
- struct lock_op_struct{
- dict_table_t* table; /* table to be locked */
- ulint mode; /* lock mode */
- };
- #define LOCK_OP_START 1
- #define LOCK_OP_COMPLETE 2
- /* The lock system struct */
- struct lock_sys_struct{
- hash_table_t* rec_hash; /* hash table of the record locks */
- };
- /* The lock system */
- extern lock_sys_t* lock_sys;
- #ifndef UNIV_NONINL
- #include "lock0lock.ic"
- #endif
- #endif