1 /***************************************************************************** 2 3 Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2018, MariaDB Corporation. 5 6 This program is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free Software 8 Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along with 15 this program; if not, write to the Free Software Foundation, Inc., 16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA 17 18 *****************************************************************************/ 19 20 /**************************************************//** 21 @file include/lock0prdt.h 22 The predicate lock system 23 24 Created 9/7/2013 Jimmy Yang 25 *******************************************************/ 26 #ifndef lock0prdt_h 27 #define lock0prdt_h 28 29 #include "lock0lock.h" 30 31 /* Predicate lock data */ 32 typedef struct lock_prdt { 33 void* data; /* Predicate data */ 34 uint16 op; /* Predicate operator */ 35 } lock_prdt_t; 36 37 /*********************************************************************//** 38 Acquire a predicate lock on a block 39 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 40 dberr_t 41 lock_prdt_lock( 42 /*===========*/ 43 buf_block_t* block, /*!< in/out: buffer block of rec */ 44 lock_prdt_t* prdt, /*!< in: Predicate for the lock */ 45 dict_index_t* index, /*!< in: secondary index */ 46 enum lock_mode mode, /*!< in: mode of the lock which 47 the read cursor should set on 48 records: LOCK_S or LOCK_X; the 49 latter is possible in 50 SELECT FOR UPDATE */ 51 ulint type_mode, 52 /*!< in: LOCK_PREDICATE or LOCK_PRDT_PAGE */ 53 que_thr_t* thr); /*!< in: query thread 54 (can be NULL if BTR_NO_LOCKING_FLAG) */ 55 56 /*********************************************************************//** 57 Acquire a "Page" lock on a block 58 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 59 dberr_t 60 lock_place_prdt_page_lock( 61 /*======================*/ 62 ulint space, /*!< in: space for the page to lock */ 63 ulint pageno, /*!< in: page number */ 64 dict_index_t* index, /*!< in: secondary index */ 65 que_thr_t* thr); /*!< in: query thread */ 66 67 /*********************************************************************//** 68 Initiate a Predicate lock from a MBR */ 69 void 70 lock_init_prdt_from_mbr( 71 /*====================*/ 72 lock_prdt_t* prdt, /*!< in/out: predicate to initialized */ 73 rtr_mbr_t* mbr, /*!< in: Minimum Bounding Rectangle */ 74 ulint mode, /*!< in: Search mode */ 75 mem_heap_t* heap); /*!< in: heap for allocating memory */ 76 77 /*********************************************************************//** 78 Get predicate lock's minimum bounding box 79 @return the minimum bounding box*/ 80 lock_prdt_t* 81 lock_get_prdt_from_lock( 82 /*====================*/ 83 const lock_t* lock); /*!< in: the lock */ 84 85 /*********************************************************************//** 86 Checks if a predicate lock request for a new lock has to wait for 87 request lock2. 88 @return true if new lock has to wait for lock2 to be removed */ 89 bool 90 lock_prdt_has_to_wait( 91 /*==================*/ 92 const trx_t* trx, /*!< in: trx of new lock */ 93 ulint type_mode,/*!< in: precise mode of the new lock 94 to set: LOCK_S or LOCK_X, possibly 95 ORed to LOCK_PREDICATE or LOCK_PRDT_PAGE, 96 LOCK_INSERT_INTENTION */ 97 lock_prdt_t* prdt, /*!< in: lock predicate to check */ 98 const lock_t* lock2); /*!< in: another record lock; NOTE that 99 it is assumed that this has a lock bit 100 set on the same record as in the new 101 lock we are setting */ 102 103 /**************************************************************//** 104 Update predicate lock when page splits */ 105 void 106 lock_prdt_update_split( 107 /*===================*/ 108 buf_block_t* new_block, /*!< in/out: the new half page */ 109 lock_prdt_t* prdt, /*!< in: MBR on the old page */ 110 lock_prdt_t* new_prdt, /*!< in: MBR on the new page */ 111 ulint space, /*!< in: space id */ 112 ulint page_no); /*!< in: page number */ 113 114 /**************************************************************//** 115 Ajust locks from an ancester page of Rtree on the appropriate level . */ 116 void 117 lock_prdt_update_parent( 118 /*====================*/ 119 buf_block_t* left_block, /*!< in/out: page to be split */ 120 buf_block_t* right_block, /*!< in/out: the new half page */ 121 lock_prdt_t* left_prdt, /*!< in: MBR on the old page */ 122 lock_prdt_t* right_prdt, /*!< in: MBR on the new page */ 123 ulint space, /*!< in: space id */ 124 ulint page_no); /*!< in: page number */ 125 126 /*********************************************************************//** 127 Checks if locks of other transactions prevent an immediate insert of 128 a predicate record. 129 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 130 dberr_t 131 lock_prdt_insert_check_and_lock( 132 /*============================*/ 133 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is 134 set, does nothing */ 135 const rec_t* rec, /*!< in: record after which to insert */ 136 buf_block_t* block, /*!< in/out: buffer block of rec */ 137 dict_index_t* index, /*!< in: index */ 138 que_thr_t* thr, /*!< in: query thread */ 139 mtr_t* mtr, /*!< in/out: mini-transaction */ 140 lock_prdt_t* prdt); /*!< in: Minimum Bound Rectangle */ 141 142 /*********************************************************************//** 143 Append a predicate to the lock */ 144 void 145 lock_prdt_set_prdt( 146 /*===============*/ 147 lock_t* lock, /*!< in: lock */ 148 const lock_prdt_t* prdt); /*!< in: Predicate */ 149 150 #if 0 151 152 /*********************************************************************//** 153 Checks if a predicate lock request for a new lock has to wait for 154 request lock2. 155 @return true if new lock has to wait for lock2 to be removed */ 156 UNIV_INLINE 157 bool 158 lock_prdt_has_to_wait( 159 /*==================*/ 160 const trx_t* trx, /*!< in: trx of new lock */ 161 ulint type_mode,/*!< in: precise mode of the new lock 162 to set: LOCK_S or LOCK_X, possibly 163 ORed to LOCK_PREDICATE or LOCK_PRDT_PAGE, 164 LOCK_INSERT_INTENTION */ 165 lock_prdt_t* prdt, /*!< in: lock predicate to check */ 166 const lock_t* lock2); /*!< in: another record lock; NOTE that 167 it is assumed that this has a lock bit 168 set on the same record as in the new 169 lock we are setting */ 170 171 /*********************************************************************//** 172 Get predicate lock's minimum bounding box 173 @return the minimum bounding box*/ 174 UNIV_INLINE 175 rtr_mbr_t* 176 prdt_get_mbr_from_prdt( 177 /*===================*/ 178 const lock_prdt_t* prdt); /*!< in: the lock predicate */ 179 180 181 #endif 182 /*************************************************************//** 183 Moves the locks of a record to another record and resets the lock bits of 184 the donating record. */ 185 void 186 lock_prdt_rec_move( 187 /*===============*/ 188 const buf_block_t* receiver, /*!< in: buffer block containing 189 the receiving record */ 190 const buf_block_t* donator); /*!< in: buffer block containing 191 the donating record */ 192 193 /** Check whether there are R-tree Page lock on a buffer page 194 @param[in] trx trx to test the lock 195 @param[in] space space id for the page 196 @param[in] page_no page number 197 @return true if there is none */ 198 bool 199 lock_test_prdt_page_lock( 200 /*=====================*/ 201 const trx_t* trx, 202 ulint space, 203 ulint page_no); 204 205 /** Removes predicate lock objects set on an index page which is discarded. 206 @param[in] block page to be discarded 207 @param[in] lock_hash lock hash */ 208 void 209 lock_prdt_page_free_from_discard( 210 /*=============================*/ 211 const buf_block_t* block, 212 hash_table_t* lock_hash); 213 214 #endif 215