| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. |
| 4 | Copyright (c) 2017, 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, Suite 500, Boston, MA 02110-1335 USA |
| 17 | |
| 18 | *****************************************************************************/ |
| 19 | |
| 20 | /**************************************************//** |
| 21 | @file include/trx0rec.h |
| 22 | Transaction undo log record |
| 23 | |
| 24 | Created 3/26/1996 Heikki Tuuri |
| 25 | *******************************************************/ |
| 26 | |
| 27 | #ifndef trx0rec_h |
| 28 | #define trx0rec_h |
| 29 | |
| 30 | #include "univ.i" |
| 31 | #include "trx0types.h" |
| 32 | #include "row0types.h" |
| 33 | #include "mtr0mtr.h" |
| 34 | #include "dict0types.h" |
| 35 | #include "data0data.h" |
| 36 | #include "rem0types.h" |
| 37 | #include "page0types.h" |
| 38 | #include "row0log.h" |
| 39 | #include "que0types.h" |
| 40 | |
| 41 | /***********************************************************************//** |
| 42 | Copies the undo record to the heap. |
| 43 | @return own: copy of undo log record */ |
| 44 | UNIV_INLINE |
| 45 | trx_undo_rec_t* |
| 46 | trx_undo_rec_copy( |
| 47 | /*==============*/ |
| 48 | const trx_undo_rec_t* undo_rec, /*!< in: undo log record */ |
| 49 | mem_heap_t* heap); /*!< in: heap where copied */ |
| 50 | /**********************************************************************//** |
| 51 | Reads the undo log record type. |
| 52 | @return record type */ |
| 53 | UNIV_INLINE |
| 54 | ulint |
| 55 | trx_undo_rec_get_type( |
| 56 | /*==================*/ |
| 57 | const trx_undo_rec_t* undo_rec); /*!< in: undo log record */ |
| 58 | /**********************************************************************//** |
| 59 | Reads the undo log record number. |
| 60 | @return undo no */ |
| 61 | UNIV_INLINE |
| 62 | undo_no_t |
| 63 | trx_undo_rec_get_undo_no( |
| 64 | /*=====================*/ |
| 65 | const trx_undo_rec_t* undo_rec); /*!< in: undo log record */ |
| 66 | |
| 67 | /**********************************************************************//** |
| 68 | Returns the start of the undo record data area. */ |
| 69 | #define trx_undo_rec_get_ptr(undo_rec, undo_no) \ |
| 70 | ((undo_rec) + trx_undo_rec_get_offset(undo_no)) |
| 71 | |
| 72 | /**********************************************************************//** |
| 73 | Reads from an undo log record the general parameters. |
| 74 | @return remaining part of undo log record after reading these values */ |
| 75 | byte* |
| 76 | trx_undo_rec_get_pars( |
| 77 | /*==================*/ |
| 78 | trx_undo_rec_t* undo_rec, /*!< in: undo log record */ |
| 79 | ulint* type, /*!< out: undo record type: |
| 80 | TRX_UNDO_INSERT_REC, ... */ |
| 81 | ulint* cmpl_info, /*!< out: compiler info, relevant only |
| 82 | for update type records */ |
| 83 | bool* updated_extern, /*!< out: true if we updated an |
| 84 | externally stored fild */ |
| 85 | undo_no_t* undo_no, /*!< out: undo log record number */ |
| 86 | table_id_t* table_id) /*!< out: table id */ |
| 87 | MY_ATTRIBUTE((nonnull)); |
| 88 | /*******************************************************************//** |
| 89 | Builds a row reference from an undo log record. |
| 90 | @return pointer to remaining part of undo record */ |
| 91 | byte* |
| 92 | trx_undo_rec_get_row_ref( |
| 93 | /*=====================*/ |
| 94 | byte* ptr, /*!< in: remaining part of a copy of an undo log |
| 95 | record, at the start of the row reference; |
| 96 | NOTE that this copy of the undo log record must |
| 97 | be preserved as long as the row reference is |
| 98 | used, as we do NOT copy the data in the |
| 99 | record! */ |
| 100 | dict_index_t* index, /*!< in: clustered index */ |
| 101 | const dtuple_t**ref, /*!< out, own: row reference */ |
| 102 | mem_heap_t* heap); /*!< in: memory heap from which the memory |
| 103 | needed is allocated */ |
| 104 | /**********************************************************************//** |
| 105 | Reads from an undo log update record the system field values of the old |
| 106 | version. |
| 107 | @return remaining part of undo log record after reading these values */ |
| 108 | byte* |
| 109 | trx_undo_update_rec_get_sys_cols( |
| 110 | /*=============================*/ |
| 111 | const byte* ptr, /*!< in: remaining part of undo |
| 112 | log record after reading |
| 113 | general parameters */ |
| 114 | trx_id_t* trx_id, /*!< out: trx id */ |
| 115 | roll_ptr_t* roll_ptr, /*!< out: roll ptr */ |
| 116 | ulint* info_bits); /*!< out: info bits state */ |
| 117 | /*******************************************************************//** |
| 118 | Builds an update vector based on a remaining part of an undo log record. |
| 119 | @return remaining part of the record, NULL if an error detected, which |
| 120 | means that the record is corrupted */ |
| 121 | byte* |
| 122 | trx_undo_update_rec_get_update( |
| 123 | /*===========================*/ |
| 124 | const byte* ptr, /*!< in: remaining part in update undo log |
| 125 | record, after reading the row reference |
| 126 | NOTE that this copy of the undo log record must |
| 127 | be preserved as long as the update vector is |
| 128 | used, as we do NOT copy the data in the |
| 129 | record! */ |
| 130 | dict_index_t* index, /*!< in: clustered index */ |
| 131 | ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC, |
| 132 | TRX_UNDO_UPD_DEL_REC, or |
| 133 | TRX_UNDO_DEL_MARK_REC; in the last case, |
| 134 | only trx id and roll ptr fields are added to |
| 135 | the update vector */ |
| 136 | trx_id_t trx_id, /*!< in: transaction id from this undorecord */ |
| 137 | roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */ |
| 138 | ulint info_bits,/*!< in: info bits from this undo record */ |
| 139 | mem_heap_t* heap, /*!< in: memory heap from which the memory |
| 140 | needed is allocated */ |
| 141 | upd_t** upd); /*!< out, own: update vector */ |
| 142 | /*******************************************************************//** |
| 143 | Builds a partial row from an update undo log record, for purge. |
| 144 | It contains the columns which occur as ordering in any index of the table. |
| 145 | Any missing columns are indicated by col->mtype == DATA_MISSING. |
| 146 | @return pointer to remaining part of undo record */ |
| 147 | byte* |
| 148 | trx_undo_rec_get_partial_row( |
| 149 | /*=========================*/ |
| 150 | const byte* ptr, /*!< in: remaining part in update undo log |
| 151 | record of a suitable type, at the start of |
| 152 | the stored index columns; |
| 153 | NOTE that this copy of the undo log record must |
| 154 | be preserved as long as the partial row is |
| 155 | used, as we do NOT copy the data in the |
| 156 | record! */ |
| 157 | dict_index_t* index, /*!< in: clustered index */ |
| 158 | const upd_t* update, /*!< in: updated columns */ |
| 159 | dtuple_t** row, /*!< out, own: partial row */ |
| 160 | ibool ignore_prefix, /*!< in: flag to indicate if we |
| 161 | expect blob prefixes in undo. Used |
| 162 | only in the assertion. */ |
| 163 | mem_heap_t* heap) /*!< in: memory heap from which the memory |
| 164 | needed is allocated */ |
| 165 | MY_ATTRIBUTE((nonnull, warn_unused_result)); |
| 166 | /** Report a RENAME TABLE operation. |
| 167 | @param[in,out] trx transaction |
| 168 | @param[in] table table that is being renamed |
| 169 | @return DB_SUCCESS or error code */ |
| 170 | dberr_t |
| 171 | trx_undo_report_rename(trx_t* trx, const dict_table_t* table) |
| 172 | MY_ATTRIBUTE((nonnull, warn_unused_result)); |
| 173 | /***********************************************************************//** |
| 174 | Writes information to an undo log about an insert, update, or a delete marking |
| 175 | of a clustered index record. This information is used in a rollback of the |
| 176 | transaction and in consistent reads that must look to the history of this |
| 177 | transaction. |
| 178 | @return DB_SUCCESS or error code */ |
| 179 | dberr_t |
| 180 | trx_undo_report_row_operation( |
| 181 | /*==========================*/ |
| 182 | que_thr_t* thr, /*!< in: query thread */ |
| 183 | dict_index_t* index, /*!< in: clustered index */ |
| 184 | const dtuple_t* clust_entry, /*!< in: in the case of an insert, |
| 185 | index entry to insert into the |
| 186 | clustered index; in updates, |
| 187 | may contain a clustered index |
| 188 | record tuple that also contains |
| 189 | virtual columns of the table; |
| 190 | otherwise, NULL */ |
| 191 | const upd_t* update, /*!< in: in the case of an update, |
| 192 | the update vector, otherwise NULL */ |
| 193 | ulint cmpl_info, /*!< in: compiler info on secondary |
| 194 | index updates */ |
| 195 | const rec_t* rec, /*!< in: case of an update or delete |
| 196 | marking, the record in the clustered |
| 197 | index; NULL if insert */ |
| 198 | const ulint* offsets, /*!< in: rec_get_offsets(rec) */ |
| 199 | roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the |
| 200 | undo log record */ |
| 201 | MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result)); |
| 202 | |
| 203 | /** status bit used for trx_undo_prev_version_build() */ |
| 204 | |
| 205 | /** TRX_UNDO_PREV_IN_PURGE tells trx_undo_prev_version_build() that it |
| 206 | is being called purge view and we would like to get the purge record |
| 207 | even it is in the purge view (in normal case, it will return without |
| 208 | fetching the purge record */ |
| 209 | #define TRX_UNDO_PREV_IN_PURGE 0x1 |
| 210 | |
| 211 | /** This tells trx_undo_prev_version_build() to fetch the old value in |
| 212 | the undo log (which is the after image for an update) */ |
| 213 | #define TRX_UNDO_GET_OLD_V_VALUE 0x2 |
| 214 | |
| 215 | /*******************************************************************//** |
| 216 | Build a previous version of a clustered index record. The caller must |
| 217 | hold a latch on the index page of the clustered index record. |
| 218 | @retval true if previous version was built, or if it was an insert |
| 219 | or the table has been rebuilt |
| 220 | @retval false if the previous version is earlier than purge_view, |
| 221 | which means that it may have been removed */ |
| 222 | bool |
| 223 | trx_undo_prev_version_build( |
| 224 | /*========================*/ |
| 225 | const rec_t* index_rec,/*!< in: clustered index record in the |
| 226 | index tree */ |
| 227 | mtr_t* index_mtr,/*!< in: mtr which contains the latch to |
| 228 | index_rec page and purge_view */ |
| 229 | const rec_t* rec, /*!< in: version of a clustered index record */ |
| 230 | dict_index_t* index, /*!< in: clustered index */ |
| 231 | ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */ |
| 232 | mem_heap_t* heap, /*!< in: memory heap from which the memory |
| 233 | needed is allocated */ |
| 234 | rec_t** old_vers,/*!< out, own: previous version, or NULL if |
| 235 | rec is the first inserted version, or if |
| 236 | history data has been deleted */ |
| 237 | mem_heap_t* v_heap, /* !< in: memory heap used to create vrow |
| 238 | dtuple if it is not yet created. This heap |
| 239 | diffs from "heap" above in that it could be |
| 240 | prebuilt->old_vers_heap for selection */ |
| 241 | const dtuple_t**vrow, /*!< out: virtual column info, if any */ |
| 242 | ulint v_status); |
| 243 | /*!< in: status determine if it is going |
| 244 | into this function by purge thread or not. |
| 245 | And if we read "after image" of undo log */ |
| 246 | |
| 247 | /** Parse MLOG_UNDO_INSERT. |
| 248 | @param[in] ptr log record |
| 249 | @param[in] end_ptr end of log record buffer |
| 250 | @param[in,out] page page or NULL |
| 251 | @return end of log record |
| 252 | @retval NULL if the log record is incomplete */ |
| 253 | byte* |
| 254 | trx_undo_parse_add_undo_rec( |
| 255 | const byte* ptr, |
| 256 | const byte* end_ptr, |
| 257 | page_t* page); |
| 258 | /** Erase the unused undo log page end. |
| 259 | @param[in,out] undo_page undo log page |
| 260 | @return whether the page contained something */ |
| 261 | bool |
| 262 | trx_undo_erase_page_end(page_t* undo_page); |
| 263 | |
| 264 | /** Read from an undo log record a non-virtual column value. |
| 265 | @param[in,out] ptr pointer to remaining part of the undo record |
| 266 | @param[in,out] field stored field |
| 267 | @param[in,out] len length of the field, or UNIV_SQL_NULL |
| 268 | @param[in,out] orig_len original length of the locally stored part |
| 269 | of an externally stored column, or 0 |
| 270 | @return remaining part of undo log record after reading these values */ |
| 271 | byte* |
| 272 | trx_undo_rec_get_col_val( |
| 273 | const byte* ptr, |
| 274 | const byte** field, |
| 275 | ulint* len, |
| 276 | ulint* orig_len); |
| 277 | |
| 278 | /** Read virtual column value from undo log |
| 279 | @param[in] table the table |
| 280 | @param[in] ptr undo log pointer |
| 281 | @param[in,out] row the dtuple to fill |
| 282 | @param[in] in_purge whether this is called by purge */ |
| 283 | void |
| 284 | trx_undo_read_v_cols( |
| 285 | const dict_table_t* table, |
| 286 | const byte* ptr, |
| 287 | const dtuple_t* row, |
| 288 | bool in_purge); |
| 289 | |
| 290 | /** Read virtual column index from undo log if the undo log contains such |
| 291 | info, and verify the column is still indexed, and output its position |
| 292 | @param[in] table the table |
| 293 | @param[in] ptr undo log pointer |
| 294 | @param[in] first_v_col if this is the first virtual column, which |
| 295 | has the version marker |
| 296 | @param[in,out] is_undo_log his function is used to parse both undo log, |
| 297 | and online log for virtual columns. So |
| 298 | check to see if this is undo log |
| 299 | @param[out] field_no the column number |
| 300 | @return remaining part of undo log record after reading these values */ |
| 301 | const byte* |
| 302 | trx_undo_read_v_idx( |
| 303 | const dict_table_t* table, |
| 304 | const byte* ptr, |
| 305 | bool first_v_col, |
| 306 | bool* is_undo_log, |
| 307 | ulint* field_no); |
| 308 | |
| 309 | /* Types of an undo log record: these have to be smaller than 16, as the |
| 310 | compilation info multiplied by 16 is ORed to this value in an undo log |
| 311 | record */ |
| 312 | |
| 313 | #define TRX_UNDO_RENAME_TABLE 9 /*!< RENAME TABLE */ |
| 314 | #define TRX_UNDO_INSERT_DEFAULT 10 /*!< insert a "default value" |
| 315 | pseudo-record for instant ALTER */ |
| 316 | #define TRX_UNDO_INSERT_REC 11 /* fresh insert into clustered index */ |
| 317 | #define TRX_UNDO_UPD_EXIST_REC 12 /* update of a non-delete-marked |
| 318 | record */ |
| 319 | #define TRX_UNDO_UPD_DEL_REC 13 /* update of a delete marked record to |
| 320 | a not delete marked record; also the |
| 321 | fields of the record can change */ |
| 322 | #define TRX_UNDO_DEL_MARK_REC 14 /* delete marking of a record; fields |
| 323 | do not change */ |
| 324 | #define TRX_UNDO_CMPL_INFO_MULT 16U /* compilation info is multiplied by |
| 325 | this and ORed to the type above */ |
| 326 | #define TRX_UNDO_UPD_EXTERN 128U /* This bit can be ORed to type_cmpl |
| 327 | to denote that we updated external |
| 328 | storage fields: used by purge to |
| 329 | free the external storage */ |
| 330 | |
| 331 | /** The search tuple corresponding to TRX_UNDO_INSERT_DEFAULT */ |
| 332 | extern const dtuple_t trx_undo_default_rec; |
| 333 | |
| 334 | #include "trx0rec.ic" |
| 335 | |
| 336 | #endif /* trx0rec_h */ |
| 337 | |