1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/lock0lock.h
29 The transaction lock system
30 
31 Created 5/7/1996 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef lock0lock_h
35 #define lock0lock_h
36 
37 #include "univ.i"
38 #include "buf0types.h"
39 #include "trx0types.h"
40 #include "mtr0types.h"
41 #include "rem0types.h"
42 #include "dict0types.h"
43 #include "que0types.h"
44 #include "lock0types.h"
45 #include "read0types.h"
46 #include "hash0hash.h"
47 #include "srv0srv.h"
48 #include "ut0vec.h"
49 
50 #ifdef UNIV_DEBUG
51 extern ibool	lock_print_waits;
52 #endif /* UNIV_DEBUG */
53 
54 /*********************************************************************//**
55 Gets the size of a lock struct.
56 @return	size in bytes */
57 UNIV_INTERN
58 ulint
59 lock_get_size(void);
60 /*===============*/
61 /*********************************************************************//**
62 Creates the lock system at database start. */
63 UNIV_INTERN
64 void
65 lock_sys_create(
66 /*============*/
67 	ulint	n_cells);	/*!< in: number of slots in lock hash table */
68 /*********************************************************************//**
69 Closes the lock system at database shutdown. */
70 UNIV_INTERN
71 void
72 lock_sys_close(void);
73 /*================*/
74 /*********************************************************************//**
75 Gets the heap_no of the smallest user record on a page.
76 @return	heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
77 UNIV_INLINE
78 ulint
79 lock_get_min_heap_no(
80 /*=================*/
81 	const buf_block_t*	block);	/*!< in: buffer block */
82 /*************************************************************//**
83 Updates the lock table when we have reorganized a page. NOTE: we copy
84 also the locks set on the infimum of the page; the infimum may carry
85 locks if an update of a record is occurring on the page, and its locks
86 were temporarily stored on the infimum. */
87 UNIV_INTERN
88 void
89 lock_move_reorganize_page(
90 /*======================*/
91 	const buf_block_t*	block,	/*!< in: old index page, now
92 					reorganized */
93 	const buf_block_t*	oblock);/*!< in: copy of the old, not
94 					reorganized page */
95 /*************************************************************//**
96 Moves the explicit locks on user records to another page if a record
97 list end is moved to another page. */
98 UNIV_INTERN
99 void
100 lock_move_rec_list_end(
101 /*===================*/
102 	const buf_block_t*	new_block,	/*!< in: index page to move to */
103 	const buf_block_t*	block,		/*!< in: index page */
104 	const rec_t*		rec);		/*!< in: record on page: this
105 						is the first record moved */
106 /*************************************************************//**
107 Moves the explicit locks on user records to another page if a record
108 list start is moved to another page. */
109 UNIV_INTERN
110 void
111 lock_move_rec_list_start(
112 /*=====================*/
113 	const buf_block_t*	new_block,	/*!< in: index page to move to */
114 	const buf_block_t*	block,		/*!< in: index page */
115 	const rec_t*		rec,		/*!< in: record on page:
116 						this is the first
117 						record NOT copied */
118 	const rec_t*		old_end);	/*!< in: old
119 						previous-to-last
120 						record on new_page
121 						before the records
122 						were copied */
123 /*************************************************************//**
124 Updates the lock table when a page is split to the right. */
125 UNIV_INTERN
126 void
127 lock_update_split_right(
128 /*====================*/
129 	const buf_block_t*	right_block,	/*!< in: right page */
130 	const buf_block_t*	left_block);	/*!< in: left page */
131 /*************************************************************//**
132 Updates the lock table when a page is merged to the right. */
133 UNIV_INTERN
134 void
135 lock_update_merge_right(
136 /*====================*/
137 	const buf_block_t*	right_block,	/*!< in: right page to
138 						which merged */
139 	const rec_t*		orig_succ,	/*!< in: original
140 						successor of infimum
141 						on the right page
142 						before merge */
143 	const buf_block_t*	left_block);	/*!< in: merged index
144 						page which will be
145 						discarded */
146 /*************************************************************//**
147 Updates the lock table when the root page is copied to another in
148 btr_root_raise_and_insert. Note that we leave lock structs on the
149 root page, even though they do not make sense on other than leaf
150 pages: the reason is that in a pessimistic update the infimum record
151 of the root page will act as a dummy carrier of the locks of the record
152 to be updated. */
153 UNIV_INTERN
154 void
155 lock_update_root_raise(
156 /*===================*/
157 	const buf_block_t*	block,	/*!< in: index page to which copied */
158 	const buf_block_t*	root);	/*!< in: root page */
159 /*************************************************************//**
160 Updates the lock table when a page is copied to another and the original page
161 is removed from the chain of leaf pages, except if page is the root! */
162 UNIV_INTERN
163 void
164 lock_update_copy_and_discard(
165 /*=========================*/
166 	const buf_block_t*	new_block,	/*!< in: index page to
167 						which copied */
168 	const buf_block_t*	block);		/*!< in: index page;
169 						NOT the root! */
170 /*************************************************************//**
171 Updates the lock table when a page is split to the left. */
172 UNIV_INTERN
173 void
174 lock_update_split_left(
175 /*===================*/
176 	const buf_block_t*	right_block,	/*!< in: right page */
177 	const buf_block_t*	left_block);	/*!< in: left page */
178 /*************************************************************//**
179 Updates the lock table when a page is merged to the left. */
180 UNIV_INTERN
181 void
182 lock_update_merge_left(
183 /*===================*/
184 	const buf_block_t*	left_block,	/*!< in: left page to
185 						which merged */
186 	const rec_t*		orig_pred,	/*!< in: original predecessor
187 						of supremum on the left page
188 						before merge */
189 	const buf_block_t*	right_block);	/*!< in: merged index page
190 						which will be discarded */
191 /*************************************************************//**
192 Resets the original locks on heir and replaces them with gap type locks
193 inherited from rec. */
194 UNIV_INTERN
195 void
196 lock_rec_reset_and_inherit_gap_locks(
197 /*=================================*/
198 	const buf_block_t*	heir_block,	/*!< in: block containing the
199 						record which inherits */
200 	const buf_block_t*	block,		/*!< in: block containing the
201 						record from which inherited;
202 						does NOT reset the locks on
203 						this record */
204 	ulint			heir_heap_no,	/*!< in: heap_no of the
205 						inheriting record */
206 	ulint			heap_no);	/*!< in: heap_no of the
207 						donating record */
208 /*************************************************************//**
209 Updates the lock table when a page is discarded. */
210 UNIV_INTERN
211 void
212 lock_update_discard(
213 /*================*/
214 	const buf_block_t*	heir_block,	/*!< in: index page
215 						which will inherit the locks */
216 	ulint			heir_heap_no,	/*!< in: heap_no of the record
217 						which will inherit the locks */
218 	const buf_block_t*	block);		/*!< in: index page
219 						which will be discarded */
220 /*************************************************************//**
221 Updates the lock table when a new user record is inserted. */
222 UNIV_INTERN
223 void
224 lock_update_insert(
225 /*===============*/
226 	const buf_block_t*	block,	/*!< in: buffer block containing rec */
227 	const rec_t*		rec);	/*!< in: the inserted record */
228 /*************************************************************//**
229 Updates the lock table when a record is removed. */
230 UNIV_INTERN
231 void
232 lock_update_delete(
233 /*===============*/
234 	const buf_block_t*	block,	/*!< in: buffer block containing rec */
235 	const rec_t*		rec);	/*!< in: the record to be removed */
236 /*********************************************************************//**
237 Stores on the page infimum record the explicit locks of another record.
238 This function is used to store the lock state of a record when it is
239 updated and the size of the record changes in the update. The record
240 is in such an update moved, perhaps to another page. The infimum record
241 acts as a dummy carrier record, taking care of lock releases while the
242 actual record is being moved. */
243 UNIV_INTERN
244 void
245 lock_rec_store_on_page_infimum(
246 /*===========================*/
247 	const buf_block_t*	block,	/*!< in: buffer block containing rec */
248 	const rec_t*		rec);	/*!< in: record whose lock state
249 					is stored on the infimum
250 					record of the same page; lock
251 					bits are reset on the
252 					record */
253 /*********************************************************************//**
254 Restores the state of explicit lock requests on a single record, where the
255 state was stored on the infimum of the page. */
256 UNIV_INTERN
257 void
258 lock_rec_restore_from_page_infimum(
259 /*===============================*/
260 	const buf_block_t*	block,	/*!< in: buffer block containing rec */
261 	const rec_t*		rec,	/*!< in: record whose lock state
262 					is restored */
263 	const buf_block_t*	donator);/*!< in: page (rec is not
264 					necessarily on this page)
265 					whose infimum stored the lock
266 					state; lock bits are reset on
267 					the infimum */
268 /*********************************************************************//**
269 Determines if there are explicit record locks on a page.
270 @return	an explicit record lock on the page, or NULL if there are none */
271 UNIV_INTERN
272 lock_t*
273 lock_rec_expl_exist_on_page(
274 /*========================*/
275 	ulint	space,	/*!< in: space id */
276 	ulint	page_no)/*!< in: page number */
277 	MY_ATTRIBUTE((warn_unused_result));
278 /*********************************************************************//**
279 Checks if locks of other transactions prevent an immediate insert of
280 a record. If they do, first tests if the query thread should anyway
281 be suspended for some reason; if not, then puts the transaction and
282 the query thread to the lock wait state and inserts a waiting request
283 for a gap x-lock to the lock queue.
284 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
285 UNIV_INTERN
286 dberr_t
287 lock_rec_insert_check_and_lock(
288 /*===========================*/
289 	ulint		flags,	/*!< in: if BTR_NO_LOCKING_FLAG bit is
290 				set, does nothing */
291 	const rec_t*	rec,	/*!< in: record after which to insert */
292 	buf_block_t*	block,	/*!< in/out: buffer block of rec */
293 	dict_index_t*	index,	/*!< in: index */
294 	que_thr_t*	thr,	/*!< in: query thread */
295 	mtr_t*		mtr,	/*!< in/out: mini-transaction */
296 	ibool*		inherit)/*!< out: set to TRUE if the new
297 				inserted record maybe should inherit
298 				LOCK_GAP type locks from the successor
299 				record */
300 	MY_ATTRIBUTE((nonnull, warn_unused_result));
301 /*********************************************************************//**
302 Checks if locks of other transactions prevent an immediate modify (update,
303 delete mark, or delete unmark) of a clustered index record. If they do,
304 first tests if the query thread should anyway be suspended for some
305 reason; if not, then puts the transaction and the query thread to the
306 lock wait state and inserts a waiting request for a record x-lock to the
307 lock queue.
308 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
309 UNIV_INTERN
310 dberr_t
311 lock_clust_rec_modify_check_and_lock(
312 /*=================================*/
313 	ulint			flags,	/*!< in: if BTR_NO_LOCKING_FLAG
314 					bit is set, does nothing */
315 	const buf_block_t*	block,	/*!< in: buffer block of rec */
316 	const rec_t*		rec,	/*!< in: record which should be
317 					modified */
318 	dict_index_t*		index,	/*!< in: clustered index */
319 	const ulint*		offsets,/*!< in: rec_get_offsets(rec, index) */
320 	que_thr_t*		thr)	/*!< in: query thread */
321 	MY_ATTRIBUTE((warn_unused_result, nonnull));
322 /*********************************************************************//**
323 Checks if locks of other transactions prevent an immediate modify
324 (delete mark or delete unmark) of a secondary index record.
325 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
326 UNIV_INTERN
327 dberr_t
328 lock_sec_rec_modify_check_and_lock(
329 /*===============================*/
330 	ulint		flags,	/*!< in: if BTR_NO_LOCKING_FLAG
331 				bit is set, does nothing */
332 	buf_block_t*	block,	/*!< in/out: buffer block of rec */
333 	const rec_t*	rec,	/*!< in: record which should be
334 				modified; NOTE: as this is a secondary
335 				index, we always have to modify the
336 				clustered index record first: see the
337 				comment below */
338 	dict_index_t*	index,	/*!< in: secondary index */
339 	que_thr_t*	thr,	/*!< in: query thread
340 				(can be NULL if BTR_NO_LOCKING_FLAG) */
341 	mtr_t*		mtr)	/*!< in/out: mini-transaction */
342 	MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,4,6)));
343 /*********************************************************************//**
344 Like lock_clust_rec_read_check_and_lock(), but reads a
345 secondary index record.
346 @return	DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
347 or DB_QUE_THR_SUSPENDED */
348 UNIV_INTERN
349 dberr_t
350 lock_sec_rec_read_check_and_lock(
351 /*=============================*/
352 	ulint			flags,	/*!< in: if BTR_NO_LOCKING_FLAG
353 					bit is set, does nothing */
354 	const buf_block_t*	block,	/*!< in: buffer block of rec */
355 	const rec_t*		rec,	/*!< in: user record or page
356 					supremum record which should
357 					be read or passed over by a
358 					read cursor */
359 	dict_index_t*		index,	/*!< in: secondary index */
360 	const ulint*		offsets,/*!< in: rec_get_offsets(rec, index) */
361 	enum lock_mode		mode,	/*!< in: mode of the lock which
362 					the read cursor should set on
363 					records: LOCK_S or LOCK_X; the
364 					latter is possible in
365 					SELECT FOR UPDATE */
366 	ulint			gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
367 					LOCK_REC_NOT_GAP */
368 	que_thr_t*		thr);	/*!< in: query thread */
369 /*********************************************************************//**
370 Checks if locks of other transactions prevent an immediate read, or passing
371 over by a read cursor, of a clustered index record. If they do, first tests
372 if the query thread should anyway be suspended for some reason; if not, then
373 puts the transaction and the query thread to the lock wait state and inserts a
374 waiting request for a record lock to the lock queue. Sets the requested mode
375 lock on the record.
376 @return	DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
377 or DB_QUE_THR_SUSPENDED */
378 UNIV_INTERN
379 dberr_t
380 lock_clust_rec_read_check_and_lock(
381 /*===============================*/
382 	ulint			flags,	/*!< in: if BTR_NO_LOCKING_FLAG
383 					bit is set, does nothing */
384 	const buf_block_t*	block,	/*!< in: buffer block of rec */
385 	const rec_t*		rec,	/*!< in: user record or page
386 					supremum record which should
387 					be read or passed over by a
388 					read cursor */
389 	dict_index_t*		index,	/*!< in: clustered index */
390 	const ulint*		offsets,/*!< in: rec_get_offsets(rec, index) */
391 	enum lock_mode		mode,	/*!< in: mode of the lock which
392 					the read cursor should set on
393 					records: LOCK_S or LOCK_X; the
394 					latter is possible in
395 					SELECT FOR UPDATE */
396 	ulint			gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
397 					LOCK_REC_NOT_GAP */
398 	que_thr_t*		thr);	/*!< in: query thread */
399 /*********************************************************************//**
400 Checks if locks of other transactions prevent an immediate read, or passing
401 over by a read cursor, of a clustered index record. If they do, first tests
402 if the query thread should anyway be suspended for some reason; if not, then
403 puts the transaction and the query thread to the lock wait state and inserts a
404 waiting request for a record lock to the lock queue. Sets the requested mode
405 lock on the record. This is an alternative version of
406 lock_clust_rec_read_check_and_lock() that does not require the parameter
407 "offsets".
408 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
409 UNIV_INTERN
410 dberr_t
411 lock_clust_rec_read_check_and_lock_alt(
412 /*===================================*/
413 	ulint			flags,	/*!< in: if BTR_NO_LOCKING_FLAG
414 					bit is set, does nothing */
415 	const buf_block_t*	block,	/*!< in: buffer block of rec */
416 	const rec_t*		rec,	/*!< in: user record or page
417 					supremum record which should
418 					be read or passed over by a
419 					read cursor */
420 	dict_index_t*		index,	/*!< in: clustered index */
421 	enum lock_mode		mode,	/*!< in: mode of the lock which
422 					the read cursor should set on
423 					records: LOCK_S or LOCK_X; the
424 					latter is possible in
425 					SELECT FOR UPDATE */
426 	ulint			gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
427 					LOCK_REC_NOT_GAP */
428 	que_thr_t*		thr)	/*!< in: query thread */
429 	MY_ATTRIBUTE((nonnull, warn_unused_result));
430 /*********************************************************************//**
431 Checks that a record is seen in a consistent read.
432 @return true if sees, or false if an earlier version of the record
433 should be retrieved */
434 UNIV_INTERN
435 bool
436 lock_clust_rec_cons_read_sees(
437 /*==========================*/
438 	const rec_t*	rec,	/*!< in: user record which should be read or
439 				passed over by a read cursor */
440 	dict_index_t*	index,	/*!< in: clustered index */
441 	const ulint*	offsets,/*!< in: rec_get_offsets(rec, index) */
442 	read_view_t*	view);	/*!< in: consistent read view */
443 /*********************************************************************//**
444 Checks that a non-clustered index record is seen in a consistent read.
445 
446 NOTE that a non-clustered index page contains so little information on
447 its modifications that also in the case false, the present version of
448 rec may be the right, but we must check this from the clustered index
449 record.
450 
451 @return true if certainly sees, or false if an earlier version of the
452 clustered index record might be needed */
453 UNIV_INTERN
454 bool
455 lock_sec_rec_cons_read_sees(
456 /*========================*/
457 	const rec_t*		rec,	/*!< in: user record which
458 					should be read or passed over
459 					by a read cursor */
460 	const read_view_t*	view)	/*!< in: consistent read view */
461 	MY_ATTRIBUTE((nonnull, warn_unused_result));
462 /*********************************************************************//**
463 Locks the specified database table in the mode given. If the lock cannot
464 be granted immediately, the query thread is put to wait.
465 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
466 UNIV_INTERN
467 dberr_t
468 lock_table(
469 /*=======*/
470 	ulint		flags,	/*!< in: if BTR_NO_LOCKING_FLAG bit is set,
471 				does nothing */
472 	dict_table_t*	table,	/*!< in/out: database table
473 				in dictionary cache */
474 	enum lock_mode	mode,	/*!< in: lock mode */
475 	que_thr_t*	thr)	/*!< in: query thread */
476 	MY_ATTRIBUTE((nonnull, warn_unused_result));
477 /*********************************************************************//**
478 Creates a table IX lock object for a resurrected transaction. */
479 UNIV_INTERN
480 void
481 lock_table_ix_resurrect(
482 /*====================*/
483 	dict_table_t*	table,	/*!< in/out: table */
484 	trx_t*		trx);	/*!< in/out: transaction */
485 /*************************************************************//**
486 Removes a granted record lock of a transaction from the queue and grants
487 locks to other transactions waiting in the queue if they now are entitled
488 to a lock. */
489 UNIV_INTERN
490 void
491 lock_rec_unlock(
492 /*============*/
493 	trx_t*			trx,	/*!< in/out: transaction that has
494 					set a record lock */
495 	const buf_block_t*	block,	/*!< in: buffer block containing rec */
496 	const rec_t*		rec,	/*!< in: record */
497 	enum lock_mode		lock_mode);/*!< in: LOCK_S or LOCK_X */
498 /*********************************************************************//**
499 Releases a transaction's locks, and releases possible other transactions
500 waiting because of these locks. Change the state of the transaction to
501 TRX_STATE_COMMITTED_IN_MEMORY. */
502 UNIV_INTERN
503 void
504 lock_trx_release_locks(
505 /*===================*/
506 	trx_t*	trx);	/*!< in/out: transaction */
507 /*********************************************************************//**
508 Removes locks on a table to be dropped or truncated.
509 If remove_also_table_sx_locks is TRUE then table-level S and X locks are
510 also removed in addition to other table-level and record-level locks.
511 No lock, that is going to be removed, is allowed to be a wait lock. */
512 UNIV_INTERN
513 void
514 lock_remove_all_on_table(
515 /*=====================*/
516 	dict_table_t*	table,			/*!< in: table to be dropped
517 						or truncated */
518 	ibool		remove_also_table_sx_locks);/*!< in: also removes
519 						table S and X locks */
520 
521 /*********************************************************************//**
522 Calculates the fold value of a page file address: used in inserting or
523 searching for a lock in the hash table.
524 @return	folded value */
525 UNIV_INLINE
526 ulint
527 lock_rec_fold(
528 /*==========*/
529 	ulint	space,	/*!< in: space */
530 	ulint	page_no)/*!< in: page number */
531 	MY_ATTRIBUTE((const));
532 /*********************************************************************//**
533 Calculates the hash value of a page file address: used in inserting or
534 searching for a lock in the hash table.
535 @return	hashed value */
536 UNIV_INLINE
537 ulint
538 lock_rec_hash(
539 /*==========*/
540 	ulint	space,	/*!< in: space */
541 	ulint	page_no);/*!< in: page number */
542 
543 /**********************************************************************//**
544 Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
545 if none found.
546 @return bit index == heap number of the record, or ULINT_UNDEFINED if
547 none found */
548 UNIV_INTERN
549 ulint
550 lock_rec_find_set_bit(
551 /*==================*/
552 	const lock_t*	lock);	/*!< in: record lock with at least one
553 				bit set */
554 
555 /*********************************************************************//**
556 Gets the source table of an ALTER TABLE transaction.  The table must be
557 covered by an IX or IS table lock.
558 @return the source table of transaction, if it is covered by an IX or
559 IS table lock; dest if there is no source table, and NULL if the
560 transaction is locking more than two tables or an inconsistency is
561 found */
562 UNIV_INTERN
563 dict_table_t*
564 lock_get_src_table(
565 /*===============*/
566 	trx_t*		trx,	/*!< in: transaction */
567 	dict_table_t*	dest,	/*!< in: destination of ALTER TABLE */
568 	enum lock_mode*	mode);	/*!< out: lock mode of the source table */
569 /*********************************************************************//**
570 Determine if the given table is exclusively "owned" by the given
571 transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
572 on the table.
573 @return TRUE if table is only locked by trx, with LOCK_IX, and
574 possibly LOCK_AUTO_INC */
575 UNIV_INTERN
576 ibool
577 lock_is_table_exclusive(
578 /*====================*/
579 	const dict_table_t*	table,	/*!< in: table */
580 	const trx_t*		trx)	/*!< in: transaction */
581 	MY_ATTRIBUTE((nonnull));
582 /*********************************************************************//**
583 Checks if a lock request lock1 has to wait for request lock2.
584 @return	TRUE if lock1 has to wait for lock2 to be removed */
585 UNIV_INTERN
586 ibool
587 lock_has_to_wait(
588 /*=============*/
589 	const lock_t*	lock1,	/*!< in: waiting lock */
590 	const lock_t*	lock2);	/*!< in: another lock; NOTE that it is
591 				assumed that this has a lock bit set
592 				on the same record as in lock1 if the
593 				locks are record locks */
594 /*********************************************************************//**
595 Reports that a transaction id is insensible, i.e., in the future. */
596 UNIV_INTERN
597 void
598 lock_report_trx_id_insanity(
599 /*========================*/
600 	trx_id_t	trx_id,		/*!< in: trx id */
601 	const rec_t*	rec,		/*!< in: user record */
602 	dict_index_t*	index,		/*!< in: index */
603 	const ulint*	offsets,	/*!< in: rec_get_offsets(rec, index) */
604 	trx_id_t	max_trx_id)	/*!< in: trx_sys_get_max_trx_id() */
605 	MY_ATTRIBUTE((nonnull));
606 /*********************************************************************//**
607 Prints info of a table lock. */
608 UNIV_INTERN
609 void
610 lock_table_print(
611 /*=============*/
612 	FILE*		file,	/*!< in: file where to print */
613 	const lock_t*	lock);	/*!< in: table type lock */
614 /*********************************************************************//**
615 Prints info of a record lock. */
616 UNIV_INTERN
617 void
618 lock_rec_print(
619 /*===========*/
620 	FILE*		file,	/*!< in: file where to print */
621 	const lock_t*	lock);	/*!< in: record type lock */
622 /*********************************************************************//**
623 Prints info of locks for all transactions.
624 @return FALSE if not able to obtain lock mutex and exits without
625 printing info */
626 UNIV_INTERN
627 ibool
628 lock_print_info_summary(
629 /*====================*/
630 	FILE*	file,	/*!< in: file where to print */
631 	ibool   nowait)	/*!< in: whether to wait for the lock mutex */
632 	MY_ATTRIBUTE((nonnull, warn_unused_result));
633 /*********************************************************************//**
634 Prints info of locks for each transaction. This function assumes that the
635 caller holds the lock mutex and more importantly it will release the lock
636 mutex on behalf of the caller. (This should be fixed in the future). */
637 UNIV_INTERN
638 void
639 lock_print_info_all_transactions(
640 /*=============================*/
641 	FILE*	file);	/*!< in: file where to print */
642 /*********************************************************************//**
643 Return approximate number or record locks (bits set in the bitmap) for
644 this transaction. Since delete-marked records may be removed, the
645 record count will not be precise.
646 The caller must be holding lock_sys->mutex. */
647 UNIV_INTERN
648 ulint
649 lock_number_of_rows_locked(
650 /*=======================*/
651 	const trx_lock_t*	trx_lock)	/*!< in: transaction locks */
652 	MY_ATTRIBUTE((nonnull, warn_unused_result));
653 
654 /*******************************************************************//**
655 Gets the type of a lock. Non-inline version for using outside of the
656 lock module.
657 @return	LOCK_TABLE or LOCK_REC */
658 UNIV_INTERN
659 ulint
660 lock_get_type(
661 /*==========*/
662 	const lock_t*	lock);	/*!< in: lock */
663 
664 /*******************************************************************//**
665 Gets the id of the transaction owning a lock.
666 @return	transaction id */
667 UNIV_INTERN
668 trx_id_t
669 lock_get_trx_id(
670 /*============*/
671 	const lock_t*	lock);	/*!< in: lock */
672 
673 /*******************************************************************//**
674 Gets the mode of a lock in a human readable string.
675 The string should not be free()'d or modified.
676 @return	lock mode */
677 UNIV_INTERN
678 const char*
679 lock_get_mode_str(
680 /*==============*/
681 	const lock_t*	lock);	/*!< in: lock */
682 
683 /*******************************************************************//**
684 Gets the type of a lock in a human readable string.
685 The string should not be free()'d or modified.
686 @return	lock type */
687 UNIV_INTERN
688 const char*
689 lock_get_type_str(
690 /*==============*/
691 	const lock_t*	lock);	/*!< in: lock */
692 
693 /*******************************************************************//**
694 Gets the id of the table on which the lock is.
695 @return	id of the table */
696 UNIV_INTERN
697 table_id_t
698 lock_get_table_id(
699 /*==============*/
700 	const lock_t*	lock);	/*!< in: lock */
701 
702 /*******************************************************************//**
703 Gets the name of the table on which the lock is.
704 The string should not be free()'d or modified.
705 @return	name of the table */
706 UNIV_INTERN
707 const char*
708 lock_get_table_name(
709 /*================*/
710 	const lock_t*	lock);	/*!< in: lock */
711 
712 /*******************************************************************//**
713 For a record lock, gets the index on which the lock is.
714 @return	index */
715 UNIV_INTERN
716 const dict_index_t*
717 lock_rec_get_index(
718 /*===============*/
719 	const lock_t*	lock);	/*!< in: lock */
720 
721 /*******************************************************************//**
722 For a record lock, gets the name of the index on which the lock is.
723 The string should not be free()'d or modified.
724 @return	name of the index */
725 UNIV_INTERN
726 const char*
727 lock_rec_get_index_name(
728 /*====================*/
729 	const lock_t*	lock);	/*!< in: lock */
730 
731 /*******************************************************************//**
732 For a record lock, gets the tablespace number on which the lock is.
733 @return	tablespace number */
734 UNIV_INTERN
735 ulint
736 lock_rec_get_space_id(
737 /*==================*/
738 	const lock_t*	lock);	/*!< in: lock */
739 
740 /*******************************************************************//**
741 For a record lock, gets the page number on which the lock is.
742 @return	page number */
743 UNIV_INTERN
744 ulint
745 lock_rec_get_page_no(
746 /*=================*/
747 	const lock_t*	lock);	/*!< in: lock */
748 /*******************************************************************//**
749 Check if there are any locks (table or rec) against table.
750 @return	TRUE if locks exist */
751 UNIV_INTERN
752 ibool
753 lock_table_has_locks(
754 /*=================*/
755 	const dict_table_t*	table);	/*!< in: check if there are any locks
756 					held on records in this table or on the
757 					table itself */
758 
759 /*********************************************************************//**
760 A thread which wakes up threads whose lock wait may have lasted too long.
761 @return	a dummy parameter */
762 extern "C" UNIV_INTERN
763 os_thread_ret_t
764 DECLARE_THREAD(lock_wait_timeout_thread)(
765 /*=====================================*/
766 	void*	arg);	/*!< in: a dummy parameter required by
767 			os_thread_create */
768 
769 /********************************************************************//**
770 Releases a user OS thread waiting for a lock to be released, if the
771 thread is already suspended. */
772 UNIV_INTERN
773 void
774 lock_wait_release_thread_if_suspended(
775 /*==================================*/
776 	que_thr_t*	thr);	/*!< in: query thread associated with the
777 				user OS thread	 */
778 
779 /***************************************************************//**
780 Puts a user OS thread to wait for a lock to be released. If an error
781 occurs during the wait trx->error_state associated with thr is
782 != DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
783 are possible errors. DB_DEADLOCK is returned if selective deadlock
784 resolution chose this transaction as a victim. */
785 UNIV_INTERN
786 void
787 lock_wait_suspend_thread(
788 /*=====================*/
789 	que_thr_t*	thr);	/*!< in: query thread associated with the
790 				user OS thread */
791 /*********************************************************************//**
792 Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
793 function should be called at the the end of an SQL statement, by the
794 connection thread that owns the transaction (trx->mysql_thd). */
795 UNIV_INTERN
796 void
797 lock_unlock_table_autoinc(
798 /*======================*/
799 	trx_t*	trx);			/*!< in/out: transaction */
800 /*********************************************************************//**
801 Check whether the transaction has already been rolled back because it
802 was selected as a deadlock victim, or if it has to wait then cancel
803 the wait lock.
804 @return DB_DEADLOCK, DB_LOCK_WAIT or DB_SUCCESS */
805 UNIV_INTERN
806 dberr_t
807 lock_trx_handle_wait(
808 /*=================*/
809 	trx_t*	trx)	/*!< in/out: trx lock state */
810 	MY_ATTRIBUTE((nonnull));
811 /*********************************************************************//**
812 Get the number of locks on a table.
813 @return number of locks */
814 UNIV_INTERN
815 ulint
816 lock_table_get_n_locks(
817 /*===================*/
818 	const dict_table_t*	table)	/*!< in: table */
819 	MY_ATTRIBUTE((nonnull));
820 #ifdef UNIV_DEBUG
821 /*********************************************************************//**
822 Checks that a transaction id is sensible, i.e., not in the future.
823 @return	true if ok */
824 UNIV_INTERN
825 bool
826 lock_check_trx_id_sanity(
827 /*=====================*/
828 	trx_id_t	trx_id,		/*!< in: trx id */
829 	const rec_t*	rec,		/*!< in: user record */
830 	dict_index_t*	index,		/*!< in: index */
831 	const ulint*	offsets)	/*!< in: rec_get_offsets(rec, index) */
832 	MY_ATTRIBUTE((nonnull, warn_unused_result));
833 /*******************************************************************//**
834 Check if the transaction holds any locks on the sys tables
835 or its records.
836 @return	the strongest lock found on any sys table or 0 for none */
837 UNIV_INTERN
838 const lock_t*
839 lock_trx_has_sys_table_locks(
840 /*=========================*/
841 	const trx_t*	trx)	/*!< in: transaction to check */
842 	MY_ATTRIBUTE((warn_unused_result));
843 
844 /*******************************************************************//**
845 Check if the transaction holds an exclusive lock on a record.
846 @return	whether the locks are held */
847 UNIV_INTERN
848 bool
849 lock_trx_has_rec_x_lock(
850 /*====================*/
851 	const trx_t*		trx,	/*!< in: transaction to check */
852 	const dict_table_t*	table,	/*!< in: table to check */
853 	const buf_block_t*	block,	/*!< in: buffer block of the record */
854 	ulint			heap_no)/*!< in: record heap number */
855 	MY_ATTRIBUTE((nonnull, warn_unused_result));
856 #endif /* UNIV_DEBUG */
857 
858 /** Lock modes and types */
859 /* @{ */
860 #define LOCK_MODE_MASK	0xFUL	/*!< mask used to extract mode from the
861 				type_mode field in a lock */
862 /** Lock types */
863 /* @{ */
864 #define LOCK_TABLE	16	/*!< table lock */
865 #define	LOCK_REC	32	/*!< record lock */
866 #define LOCK_TYPE_MASK	0xF0UL	/*!< mask used to extract lock type from the
867 				type_mode field in a lock */
868 #if LOCK_MODE_MASK & LOCK_TYPE_MASK
869 # error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
870 #endif
871 
872 #define LOCK_WAIT	256	/*!< Waiting lock flag; when set, it
873 				means that the lock has not yet been
874 				granted, it is just waiting for its
875 				turn in the wait queue */
876 /* Precise modes */
877 #define LOCK_ORDINARY	0	/*!< this flag denotes an ordinary
878 				next-key lock in contrast to LOCK_GAP
879 				or LOCK_REC_NOT_GAP */
880 #define LOCK_GAP	512	/*!< when this bit is set, it means that the
881 				lock holds only on the gap before the record;
882 				for instance, an x-lock on the gap does not
883 				give permission to modify the record on which
884 				the bit is set; locks of this type are created
885 				when records are removed from the index chain
886 				of records */
887 #define LOCK_REC_NOT_GAP 1024	/*!< this bit means that the lock is only on
888 				the index record and does NOT block inserts
889 				to the gap before the index record; this is
890 				used in the case when we retrieve a record
891 				with a unique key, and is also used in
892 				locking plain SELECTs (not part of UPDATE
893 				or DELETE) when the user has set the READ
894 				COMMITTED isolation level */
895 #define LOCK_INSERT_INTENTION 2048 /*!< this bit is set when we place a waiting
896 				gap type record lock request in order to let
897 				an insert of an index record to wait until
898 				there are no conflicting locks by other
899 				transactions on the gap; note that this flag
900 				remains set when the waiting lock is granted,
901 				or if the lock is inherited to a neighboring
902 				record */
903 
904 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
905 # error
906 #endif
907 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
908 # error
909 #endif
910 /* @} */
911 
912 /** Lock operation struct */
913 struct lock_op_t{
914 	dict_table_t*	table;	/*!< table to be locked */
915 	enum lock_mode	mode;	/*!< lock mode */
916 };
917 
918 /** The lock system struct */
919 struct lock_sys_t{
920 	ib_mutex_t	mutex;			/*!< Mutex protecting the
921 						locks */
922 	hash_table_t*	rec_hash;		/*!< hash table of the record
923 						locks */
924 	ib_mutex_t	wait_mutex;		/*!< Mutex protecting the
925 						next two fields */
926 	srv_slot_t*	waiting_threads;	/*!< Array  of user threads
927 						suspended while waiting for
928 						locks within InnoDB, protected
929 						by the lock_sys->wait_mutex */
930 	srv_slot_t*	last_slot;		/*!< highest slot ever used
931 						in the waiting_threads array,
932 						protected by
933 						lock_sys->wait_mutex */
934 	ibool		rollback_complete;
935 						/*!< TRUE if rollback of all
936 						recovered transactions is
937 						complete. Protected by
938 						lock_sys->mutex */
939 
940 	ulint		n_lock_max_wait_time;	/*!< Max wait time */
941 
942 	os_event_t	timeout_event;		/*!< Set to the event that is
943 						created in the lock wait monitor
944 						thread. A value of 0 means the
945 						thread is not active */
946 
947 	bool		timeout_thread_active;	/*!< True if the timeout thread
948 						is running */
949 };
950 
951 /** The lock system */
952 extern lock_sys_t*	lock_sys;
953 
954 /** Test if lock_sys->mutex can be acquired without waiting. */
955 #define lock_mutex_enter_nowait() mutex_enter_nowait(&lock_sys->mutex)
956 
957 /** Test if lock_sys->mutex is owned. */
958 #define lock_mutex_own() mutex_own(&lock_sys->mutex)
959 
960 /** Acquire the lock_sys->mutex. */
961 #define lock_mutex_enter() do {			\
962 	mutex_enter(&lock_sys->mutex);		\
963 } while (0)
964 
965 /** Release the lock_sys->mutex. */
966 #define lock_mutex_exit() do {			\
967 	mutex_exit(&lock_sys->mutex);		\
968 } while (0)
969 
970 /** Test if lock_sys->wait_mutex is owned. */
971 #define lock_wait_mutex_own() mutex_own(&lock_sys->wait_mutex)
972 
973 /** Acquire the lock_sys->wait_mutex. */
974 #define lock_wait_mutex_enter() do {		\
975 	mutex_enter(&lock_sys->wait_mutex);	\
976 } while (0)
977 
978 /** Release the lock_sys->wait_mutex. */
979 #define lock_wait_mutex_exit() do {		\
980 	mutex_exit(&lock_sys->wait_mutex);	\
981 } while (0)
982 
983 #ifdef WITH_WSREP
984 /*********************************************************************//**
985 Cancels a waiting lock request and releases possible other transactions
986 waiting behind it. */
987 UNIV_INTERN
988 void
989 lock_cancel_waiting_and_release(
990 /*============================*/
991 	lock_t*	lock);	/*!< in/out: waiting lock request */
992 #endif /* WITH_WSREP */
993 #ifndef UNIV_NONINL
994 #include "lock0lock.ic"
995 #endif
996 
997 #endif
998