1 /***************************************************************************** 2 3 Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License, version 2.0, as published by the 7 Free Software Foundation. 8 9 This program is also distributed with certain software (including but not 10 limited to OpenSSL) that is licensed under separate terms, as designated in a 11 particular file or component or in included license documentation. The authors 12 of MySQL hereby grant you an additional permission to link the program and 13 your derivative works with the separately licensed software that they have 14 included with MySQL. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19 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 St, Fifth Floor, Boston, MA 02110-1301 USA 24 25 *****************************************************************************/ 26 27 /** @file include/trx0rec.h 28 Transaction undo log record 29 30 Created 3/26/1996 Heikki Tuuri 31 *******************************************************/ 32 33 #ifndef trx0rec_h 34 #define trx0rec_h 35 36 #include "univ.i" 37 38 #include "data0data.h" 39 #include "dict0types.h" 40 #include "lob0undo.h" 41 #include "mtr0mtr.h" 42 #include "page0types.h" 43 #include "rem0types.h" 44 #include "row0log.h" 45 #include "row0types.h" 46 #include "trx0types.h" 47 48 #ifndef UNIV_HOTBACKUP 49 #include "que0types.h" 50 51 /** Copies the undo record to the heap. 52 @param[in] undo_page Undo Page 53 @param[in] undo_offset offset of the undo record in the page 54 @param[in] heap heap where copied 55 @return copy of undo log record */ 56 UNIV_INLINE 57 trx_undo_rec_t *trx_undo_rec_copy(const page_t *undo_page, uint32_t undo_offset, 58 mem_heap_t *heap); 59 60 /** Reads the undo log record type. 61 @return record type */ 62 UNIV_INLINE 63 ulint trx_undo_rec_get_type( 64 const trx_undo_rec_t *undo_rec); /*!< in: undo log record */ 65 /** Reads from an undo log record the record compiler info. 66 @return compiler info */ 67 UNIV_INLINE 68 ulint trx_undo_rec_get_cmpl_info( 69 const trx_undo_rec_t *undo_rec); /*!< in: undo log record */ 70 /** Returns TRUE if an undo log record contains an extern storage field. 71 @return true if extern */ 72 UNIV_INLINE 73 ibool trx_undo_rec_get_extern_storage( 74 const trx_undo_rec_t *undo_rec); /*!< in: undo log record */ 75 /** Reads the undo log record number. 76 @return undo no */ 77 UNIV_INLINE 78 undo_no_t trx_undo_rec_get_undo_no( 79 const trx_undo_rec_t *undo_rec); /*!< in: undo log record */ 80 81 /** Returns the start of the undo record data area. */ 82 #define trx_undo_rec_get_ptr(undo_rec, undo_no) \ 83 ((undo_rec) + trx_undo_rec_get_offset(undo_no)) 84 85 /** Reads from an undo log record the table ID 86 @param[in] undo_rec Undo log record 87 @return the table ID */ 88 table_id_t trx_undo_rec_get_table_id(const trx_undo_rec_t *undo_rec) 89 MY_ATTRIBUTE((warn_unused_result)); 90 91 /** Builds a row reference from an undo log record. 92 @return pointer to remaining part of undo record */ 93 byte *trx_undo_rec_get_row_ref( 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 dtuple_t **ref, /*!< out, own: row reference */ 102 mem_heap_t *heap); /*!< in: memory heap from which the memory 103 needed is allocated */ 104 /** Reads from an undo log update record the system field values of the old 105 version. 106 @return remaining part of undo log record after reading these values */ 107 byte *trx_undo_update_rec_get_sys_cols( 108 const byte *ptr, /*!< in: remaining part of undo 109 log record after reading 110 general parameters */ 111 trx_id_t *trx_id, /*!< out: trx id */ 112 roll_ptr_t *roll_ptr, /*!< out: roll ptr */ 113 ulint *info_bits); /*!< out: info bits state */ 114 115 struct type_cmpl_t; 116 117 /** Builds an update vector based on a remaining part of an undo log record. 118 @return remaining part of the record, NULL if an error detected, which 119 means that the record is corrupted. */ 120 byte *trx_undo_update_rec_get_update( 121 const byte *ptr, /*!< in: remaining part in update undo log 122 record, after reading the row reference 123 NOTE that this copy of the undo log record must 124 be preserved as long as the update vector is 125 used, as we do NOT copy the data in the 126 record! */ 127 const dict_index_t *index, /*!< in: clustered index */ 128 ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC, 129 TRX_UNDO_UPD_DEL_REC, or 130 TRX_UNDO_DEL_MARK_REC; in the last case, 131 only trx id and roll ptr fields are added to 132 the update vector */ 133 trx_id_t trx_id, /*!< in: transaction id from this undo record */ 134 roll_ptr_t roll_ptr, /*!< in: roll pointer from this undo record */ 135 ulint info_bits, /*!< in: info bits from this undo record */ 136 trx_t *trx, /*!< in: transaction */ 137 mem_heap_t *heap, /*!< in: memory heap from which the memory 138 needed is allocated */ 139 upd_t **upd, /*!< out, own: update vector */ 140 lob::undo_vers_t *lob_undo, /*!< out: LOB undo information. */ 141 type_cmpl_t &type_cmpl); /*!< out: type compilation info */ 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 *trx_undo_rec_get_partial_row( 148 const byte *ptr, /*!< in: remaining part in update undo log 149 record of a suitable type, at the start of 150 the stored index columns; 151 NOTE that this copy of the undo log record must 152 be preserved as long as the partial row is 153 used, as we do NOT copy the data in the 154 record! */ 155 dict_index_t *index, /*!< in: clustered index */ 156 dtuple_t **row, /*!< out, own: partial row */ 157 ibool ignore_prefix, /*!< in: flag to indicate if we 158 expect blob prefixes in undo. Used 159 only in the assertion. */ 160 mem_heap_t *heap) /*!< in: memory heap from which the memory 161 needed is allocated */ 162 MY_ATTRIBUTE((warn_unused_result)); 163 /** Writes information to an undo log about an insert, update, or a delete 164 marking of a clustered index record. This information is used in a rollback of 165 the transaction and in consistent reads that must look to the history of this 166 transaction. 167 @return DB_SUCCESS or error code */ 168 dberr_t trx_undo_report_row_operation( 169 ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is 170 set, does nothing */ 171 ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or 172 TRX_UNDO_MODIFY_OP */ 173 que_thr_t *thr, /*!< in: query thread */ 174 dict_index_t *index, /*!< in: clustered index */ 175 const dtuple_t *clust_entry, /*!< in: in the case of an insert, 176 index entry to insert into the 177 clustered index, otherwise NULL */ 178 const upd_t *update, /*!< in: in the case of an update, 179 the update vector, otherwise NULL */ 180 ulint cmpl_info, /*!< in: compiler info on secondary 181 index updates */ 182 const rec_t *rec, /*!< in: case of an update or delete 183 marking, the record in the clustered 184 index, otherwise NULL */ 185 const ulint *offsets, /*!< in: rec_get_offsets(rec) */ 186 roll_ptr_t *roll_ptr) /*!< out: rollback pointer to the 187 inserted undo log record, 188 0 if BTR_NO_UNDO_LOG 189 flag was specified */ 190 MY_ATTRIBUTE((warn_unused_result)); 191 192 /** status bit used for trx_undo_prev_version_build() */ 193 194 /** TRX_UNDO_PREV_IN_PURGE tells trx_undo_prev_version_build() that it 195 is being called purge view and we would like to get the purge record 196 even it is in the purge view (in normal case, it will return without 197 fetching the purge record */ 198 #define TRX_UNDO_PREV_IN_PURGE 0x1 199 200 /** This tells trx_undo_prev_version_build() to fetch the old value in 201 the undo log (which is the after image for an update) */ 202 #define TRX_UNDO_GET_OLD_V_VALUE 0x2 203 204 /** Build a previous version of a clustered index record. The caller must hold 205 a latch on the index page of the clustered index record. 206 If the vrow passed to this function is not null, then this function will store 207 information about virtual columns from the requested version in vrow, unless the 208 change did not affect any secondary index nor ordering field of clustered index 209 (the change has UPD_NODE_NO_ORD_CHANGE flag) in which case the requested 210 information can not be reconstructed from undo log, and the caller may assume 211 that the (virtual) columns of secondary index have the same values they have in 212 the more recent version (the one `rec` comes from). 213 Equivalently, if the vrow is not returned, it is either because it was not 214 requested, or not available due to UPD_NODE_NO_ORD_CHANGE. 215 Obviously vrow is also not set in case rec is the oldest version in history, 216 in which case we also set old_vers to NULL. 217 @param[in] index_rec clustered index record in the index tree 218 @param[in] index_mtr mtr which contains the latch to index_rec page 219 and purge_view 220 @param[in] rec version of a clustered index record 221 @param[in] index clustered index 222 @param[in,out] offsets rec_get_offsets(rec, index) 223 @param[in] heap memory heap from which the memory needed is 224 allocated 225 @param[out] old_vers previous version, or NULL if rec is the first 226 inserted version, or if history data has been 227 deleted 228 @param[in] v_heap memory heap used to create vrow dtuple if it is 229 not yet created. This heap diffs from "heap" 230 above in that it could be 231 prebuilt->old_vers_heap for selection 232 @param[out] vrow virtual column info, if any 233 @param[in] v_status status determine if it is going into this 234 function by purge thread or not. And if we read 235 "after image" of undo log has been rebuilt 236 @param[in] lob_undo LOB undo information. 237 @retval true if previous version was built, or if it was an insert or the table 238 has been rebuilt 239 @retval false if the previous version is earlier than purge_view, or being 240 purged, which means that it may have been removed */ 241 bool trx_undo_prev_version_build(const rec_t *index_rec, mtr_t *index_mtr, 242 const rec_t *rec, const dict_index_t *index, 243 ulint *offsets, mem_heap_t *heap, 244 rec_t **old_vers, mem_heap_t *v_heap, 245 const dtuple_t **vrow, ulint v_status, 246 lob::undo_vers_t *lob_undo); 247 248 #endif /* !UNIV_HOTBACKUP */ 249 /** Parses a redo log record of adding an undo log record. 250 @return end of log record or NULL */ 251 byte *trx_undo_parse_add_undo_rec(byte *ptr, /*!< in: buffer */ 252 byte *end_ptr, /*!< in: buffer end */ 253 page_t *page); /*!< in: page or NULL */ 254 /** Parses a redo log record of erasing of an undo page end. 255 @return end of log record or NULL */ 256 byte *trx_undo_parse_erase_page_end(byte *ptr, /*!< in: buffer */ 257 byte *end_ptr, /*!< in: buffer end */ 258 page_t *page, /*!< in: page or NULL */ 259 mtr_t *mtr); /*!< in: mtr or NULL */ 260 261 /** Read from an undo log record a non-virtual column value. 262 @param[in,out] ptr pointer to remaining part of the undo record 263 @param[in,out] field stored field 264 @param[in,out] len length of the field, or UNIV_SQL_NULL 265 @param[in,out] orig_len original length of the locally stored part 266 of an externally stored column, or 0 267 @return remaining part of undo log record after reading these values */ 268 byte *trx_undo_rec_get_col_val(const byte *ptr, const byte **field, ulint *len, 269 ulint *orig_len); 270 271 /** Read virtual column value from undo log 272 @param[in] table the table 273 @param[in] ptr undo log pointer 274 @param[in,out] row the dtuple to fill 275 @param[in] in_purge called by purge thread 276 @param[in] online true if this is from online DDL log 277 @param[in] col_map online rebuild column map 278 @param[in,out] heap memory heap to keep value when necessary */ 279 void trx_undo_read_v_cols(const dict_table_t *table, const byte *ptr, 280 const dtuple_t *row, bool in_purge, bool online, 281 const ulint *col_map, mem_heap_t *heap); 282 283 /** Read virtual column index from undo log if the undo log contains such 284 info, and verify the column is still indexed, and output its position 285 @param[in] table the table 286 @param[in] ptr undo log pointer 287 @param[in] first_v_col if this is the first virtual column, which 288 has the version marker 289 @param[in,out] is_undo_log his function is used to parse both undo log, 290 and online log for virtual columns. So 291 check to see if this is undo log 292 @param[out] field_no the column number 293 @return remaining part of undo log record after reading these values */ 294 const byte *trx_undo_read_v_idx(const dict_table_t *table, const byte *ptr, 295 bool first_v_col, bool *is_undo_log, 296 ulint *field_no); 297 298 #ifndef UNIV_HOTBACKUP 299 300 /* Types of an undo log record: these have to be smaller than 16, as the 301 compilation info multiplied by 16 is ORed to this value in an undo log 302 record */ 303 304 #define TRX_UNDO_INSERT_REC 11 /* fresh insert into clustered index */ 305 #define TRX_UNDO_UPD_EXIST_REC \ 306 12 /* update of a non-delete-marked \ 307 record */ 308 #define TRX_UNDO_UPD_DEL_REC \ 309 13 /* update of a delete marked record to \ 310 a not delete marked record; also the \ 311 fields of the record can change */ 312 #define TRX_UNDO_DEL_MARK_REC \ 313 14 /* delete marking of a record; fields \ 314 do not change */ 315 #define TRX_UNDO_CMPL_INFO_MULT \ 316 16 /* compilation info is multiplied by \ 317 this and ORed to the type above */ 318 319 #define TRX_UNDO_MODIFY_BLOB \ 320 64 /* If this bit is set in type_cmpl, \ 321 then the undo log record has support \ 322 for partial update of BLOBs. Also to \ 323 make the undo log format extensible, \ 324 introducing a new flag next to the \ 325 type_cmpl flag. */ 326 327 #define TRX_UNDO_UPD_EXTERN \ 328 128 /* This bit can be ORed to type_cmpl \ 329 to denote that we updated external \ 330 storage fields: used by purge to \ 331 free the external storage */ 332 333 /* Operation type flags used in trx_undo_report_row_operation */ 334 #define TRX_UNDO_INSERT_OP 1 335 #define TRX_UNDO_MODIFY_OP 2 336 337 /** The type and compilation info flag in the undo record for update. 338 For easier understanding let the 8 bits be numbered as 339 7, 6, 5, 4, 3, 2, 1, 0. */ 340 struct type_cmpl_t { type_cmpl_ttype_cmpl_t341 type_cmpl_t() : m_flag(0) {} 342 readtype_cmpl_t343 const byte *read(const byte *ptr) { 344 m_flag = mach_read_from_1(ptr); 345 return (ptr + 1); 346 } 347 type_infotype_cmpl_t348 ulint type_info() { 349 /* Get 0-3 */ 350 return (m_flag & 0x0F); 351 } 352 cmpl_infotype_cmpl_t353 ulint cmpl_info() { 354 /* Get bits 5 and 4 */ 355 return ((m_flag >> 4) & 0x03); 356 } 357 358 /** Is an LOB updated by this update operation. 359 @return true if LOB is updated, false otherwise. */ is_lob_updatedtype_cmpl_t360 bool is_lob_updated() { 361 /* Check if bit 7 is set. */ 362 return (m_flag & TRX_UNDO_UPD_EXTERN); 363 } 364 365 /** Does the undo log record contains information about LOB partial 366 update vector. 367 @return true if undo contains LOB update info. */ is_lob_undotype_cmpl_t368 bool is_lob_undo() const { 369 /* Check if bit 6 is set. */ 370 return (m_flag & TRX_UNDO_MODIFY_BLOB); 371 } 372 373 private: 374 uint8_t m_flag; 375 }; 376 377 /** Reads from an undo log record the general parameters. 378 @return remaining part of undo log record after reading these values */ 379 byte *trx_undo_rec_get_pars( 380 trx_undo_rec_t *undo_rec, /*!< in: undo log record */ 381 ulint *type, /*!< out: undo record type: 382 TRX_UNDO_INSERT_REC, ... */ 383 ulint *cmpl_info, /*!< out: compiler info, relevant only 384 for update type records */ 385 bool *updated_extern, /*!< out: true if we updated an 386 externally stored fild */ 387 undo_no_t *undo_no, /*!< out: undo log record number */ 388 table_id_t *table_id, /*!< out: table id */ 389 type_cmpl_t &type_cmpl); /*!< out: type compilation info. */ 390 391 /** Get the max free space of undo log by assuming it's a fresh new page 392 and the free space doesn't count for the undo log header too. */ 393 size_t trx_undo_max_free_space(); 394 395 /** Decide if the following undo log record is a multi-value virtual column 396 @param[in] undo_rec undo log record 397 @return true if this is a multi-value virtual column log, otherwise false */ 398 bool trx_undo_rec_is_multi_value(const byte *undo_rec); 399 400 /** Read from an undo log record a non-virtual column value. 401 @param[in,out] ptr pointer to remaining part of the undo record 402 @param[in,out] field stored field 403 @param[in,out] heap memory heap 404 @return remaining part of undo log record after reading these values */ 405 const byte *trx_undo_rec_get_multi_value(const byte *ptr, dfield_t *field, 406 mem_heap_t *heap); 407 #include "trx0rec.ic" 408 409 #endif /* !UNIV_HOTBACKUP */ 410 411 #endif /* trx0rec_h */ 412