1 /***************************************************************************** 2 3 Copyright (c) 1997, 2021, Oracle and/or its affiliates. 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/log0recv.h 29 Recovery 30 31 Created 9/20/1997 Heikki Tuuri 32 *******************************************************/ 33 34 #ifndef log0recv_h 35 #define log0recv_h 36 37 #include "univ.i" 38 #include "ut0byte.h" 39 #include "buf0types.h" 40 #include "hash0hash.h" 41 #include "log0log.h" 42 #include "mtr0types.h" 43 #include "ut0new.h" 44 45 #include <list> 46 #include <vector> 47 48 #ifdef UNIV_HOTBACKUP 49 extern bool recv_replay_file_ops; 50 51 /*******************************************************************//** 52 Reads the checkpoint info needed in hot backup. 53 @return TRUE if success */ 54 ibool 55 recv_read_checkpoint_info_for_backup( 56 /*=================================*/ 57 const byte* hdr, /*!< in: buffer containing the log group 58 header */ 59 lsn_t* lsn, /*!< out: checkpoint lsn */ 60 lsn_t* offset, /*!< out: checkpoint offset in the log group */ 61 lsn_t* cp_no, /*!< out: checkpoint number */ 62 lsn_t* first_header_lsn) 63 /*!< out: lsn of of the start of the 64 first log file */ 65 MY_ATTRIBUTE((nonnull)); 66 /*******************************************************************//** 67 Scans the log segment and n_bytes_scanned is set to the length of valid 68 log scanned. */ 69 void 70 recv_scan_log_seg_for_backup( 71 /*=========================*/ 72 byte* buf, /*!< in: buffer containing log data */ 73 ulint buf_len, /*!< in: data length in that buffer */ 74 lsn_t* scanned_lsn, /*!< in/out: lsn of buffer start, 75 we return scanned lsn */ 76 ulint* scanned_checkpoint_no, 77 /*!< in/out: 4 lowest bytes of the 78 highest scanned checkpoint number so 79 far */ 80 ulint* n_bytes_scanned);/*!< out: how much we were able to 81 scan, smaller than buf_len if log 82 data ended here */ 83 #endif /* UNIV_HOTBACKUP */ 84 /*******************************************************************//** 85 Returns TRUE if recovery is currently running. 86 @return recv_recovery_on */ 87 UNIV_INLINE 88 bool 89 recv_recovery_is_on(void); 90 /*=====================*/ 91 /************************************************************************//** 92 Applies the hashed log records to the page, if the page lsn is less than the 93 lsn of a log record. This can be called when a buffer page has just been 94 read in, or also for a page already in the buffer pool. */ 95 void 96 recv_recover_page_func( 97 /*===================*/ 98 #ifndef UNIV_HOTBACKUP 99 ibool just_read_in, 100 /*!< in: TRUE if the i/o handler calls 101 this for a freshly read page */ 102 #endif /* !UNIV_HOTBACKUP */ 103 buf_block_t* block); /*!< in/out: buffer block */ 104 #ifndef UNIV_HOTBACKUP 105 /** Wrapper for recv_recover_page_func(). 106 Applies the hashed log records to the page, if the page lsn is less than the 107 lsn of a log record. This can be called when a buffer page has just been 108 read in, or also for a page already in the buffer pool. 109 @param jri in: TRUE if just read in (the i/o handler calls this for 110 a freshly read page) 111 @param block in/out: the buffer block 112 */ 113 # define recv_recover_page(jri, block) recv_recover_page_func(jri, block) 114 #else /* !UNIV_HOTBACKUP */ 115 /** Wrapper for recv_recover_page_func(). 116 Applies the hashed log records to the page, if the page lsn is less than the 117 lsn of a log record. This can be called when a buffer page has just been 118 read in, or also for a page already in the buffer pool. 119 @param jri in: TRUE if just read in (the i/o handler calls this for 120 a freshly read page) 121 @param block in/out: the buffer block 122 */ 123 # define recv_recover_page(jri, block) recv_recover_page_func(block) 124 #endif /* !UNIV_HOTBACKUP */ 125 /** Start recovering from a redo log checkpoint. 126 @see recv_recovery_from_checkpoint_finish 127 @param[in] flush_lsn FIL_PAGE_FILE_FLUSH_LSN 128 of first system tablespace page 129 @return error code or DB_SUCCESS */ 130 dberr_t 131 recv_recovery_from_checkpoint_start( 132 lsn_t flush_lsn); 133 /** Complete recovery from a checkpoint. */ 134 void 135 recv_recovery_from_checkpoint_finish(void); 136 /********************************************************//** 137 Initiates the rollback of active transactions. */ 138 void 139 recv_recovery_rollback_active(void); 140 /*===============================*/ 141 /******************************************************//** 142 Resets the logs. The contents of log files will be lost! */ 143 void 144 recv_reset_logs( 145 /*============*/ 146 lsn_t lsn); /*!< in: reset to this lsn 147 rounded up to be divisible by 148 OS_FILE_LOG_BLOCK_SIZE, after 149 which we add 150 LOG_BLOCK_HDR_SIZE */ 151 #ifdef UNIV_HOTBACKUP 152 /******************************************************//** 153 Creates new log files after a backup has been restored. */ 154 void 155 recv_reset_log_files_for_backup( 156 /*============================*/ 157 const char* log_dir, /*!< in: log file directory path */ 158 ulint n_log_files, /*!< in: number of log files */ 159 lsn_t log_file_size, /*!< in: log file size */ 160 lsn_t lsn); /*!< in: new start lsn, must be 161 divisible by OS_FILE_LOG_BLOCK_SIZE */ 162 #endif /* UNIV_HOTBACKUP */ 163 /********************************************************//** 164 Creates the recovery system. */ 165 void 166 recv_sys_create(void); 167 /*=================*/ 168 /**********************************************************//** 169 Release recovery system mutexes. */ 170 void 171 recv_sys_close(void); 172 /*================*/ 173 /********************************************************//** 174 Frees the recovery system memory. */ 175 void 176 recv_sys_mem_free(void); 177 /*===================*/ 178 /********************************************************//** 179 Inits the recovery system for a recovery operation. */ 180 void 181 recv_sys_init( 182 /*==========*/ 183 ulint available_memory); /*!< in: available memory in bytes */ 184 #ifndef UNIV_HOTBACKUP 185 /********************************************************//** 186 Frees the recovery system. */ 187 void 188 recv_sys_debug_free(void); 189 /*=====================*/ 190 /********************************************************//** 191 Reset the state of the recovery system variables. */ 192 void 193 recv_sys_var_init(void); 194 /*===================*/ 195 #endif /* !UNIV_HOTBACKUP */ 196 /*******************************************************************//** 197 Empties the hash table of stored log records, applying them to appropriate 198 pages. */ 199 void 200 recv_apply_hashed_log_recs( 201 /*=======================*/ 202 ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are 203 allowed during the application; if FALSE, 204 no ibuf operations are allowed, and after 205 the application all file pages are flushed to 206 disk and invalidated in buffer pool: this 207 alternative means that no new log records 208 can be generated during the application */ 209 #ifdef UNIV_HOTBACKUP 210 /*******************************************************************//** 211 Applies log records in the hash table to a backup. */ 212 void 213 recv_apply_log_recs_for_backup(void); 214 /*================================*/ 215 #endif /* UNIV_HOTBACKUP */ 216 217 /** Block of log record data */ 218 struct recv_data_t{ 219 recv_data_t* next; /*!< pointer to the next block or NULL */ 220 /*!< the log record data is stored physically 221 immediately after this struct, max amount 222 RECV_DATA_BLOCK_SIZE bytes of it */ 223 }; 224 225 /** Stored log record struct */ 226 struct recv_t{ 227 mlog_id_t type; /*!< log record type */ 228 ulint len; /*!< log record body length in bytes */ 229 recv_data_t* data; /*!< chain of blocks containing the log record 230 body */ 231 lsn_t start_lsn;/*!< start lsn of the log segment written by 232 the mtr which generated this log record: NOTE 233 that this is not necessarily the start lsn of 234 this log record */ 235 lsn_t end_lsn;/*!< end lsn of the log segment written by 236 the mtr which generated this log record: NOTE 237 that this is not necessarily the end lsn of 238 this log record */ 239 UT_LIST_NODE_T(recv_t) 240 rec_list;/*!< list of log records for this page */ 241 }; 242 243 /** States of recv_addr_t */ 244 enum recv_addr_state { 245 /** not yet processed */ 246 RECV_NOT_PROCESSED, 247 /** page is being read */ 248 RECV_BEING_READ, 249 /** log records are being applied on the page */ 250 RECV_BEING_PROCESSED, 251 /** log records have been applied on the page */ 252 RECV_PROCESSED, 253 /** log records have been discarded because the tablespace 254 does not exist */ 255 RECV_DISCARDED 256 }; 257 258 /** Hashed page file address struct */ 259 struct recv_addr_t{ 260 enum recv_addr_state state; 261 /*!< recovery state of the page */ 262 unsigned space:32;/*!< space id */ 263 unsigned page_no:32;/*!< page number */ 264 UT_LIST_BASE_NODE_T(recv_t) 265 rec_list;/*!< list of log records for this page */ 266 hash_node_t addr_hash;/*!< hash node in the hash bucket chain */ 267 }; 268 269 struct recv_dblwr_t { 270 /** Add a page frame to the doublewrite recovery buffer. */ addrecv_dblwr_t271 void add(const byte* page) { 272 pages.push_back(page); 273 } 274 275 /** Find a doublewrite copy of a page. 276 @param[in] space_id tablespace identifier 277 @param[in] page_no page number 278 @return page frame 279 @retval NULL if no page was found */ 280 const byte* find_page(ulint space_id, ulint page_no); 281 282 typedef std::list<const byte*, ut_allocator<const byte*> > list; 283 284 /** Recovered doublewrite buffer page frames */ 285 list pages; 286 }; 287 288 /* Recovery encryption information */ 289 typedef struct recv_encryption { 290 ulint space_id; /*!< the page number */ 291 byte* key; /*!< encryption key */ 292 byte* iv; /*!< encryption iv */ 293 } recv_encryption_t; 294 295 typedef std::vector<recv_encryption_t, ut_allocator<recv_encryption_t> > 296 encryption_list_t; 297 298 /** Recovery system data structure */ 299 struct recv_sys_t{ 300 #ifndef UNIV_HOTBACKUP 301 ib_mutex_t mutex; /*!< mutex protecting the fields apply_log_recs, 302 n_addrs, and the state field in each recv_addr 303 struct */ 304 ib_mutex_t writer_mutex;/*!< mutex coordinating 305 flushing between recv_writer_thread and 306 the recovery thread. */ 307 os_event_t flush_start;/*!< event to acticate 308 page cleaner threads */ 309 os_event_t flush_end;/*!< event to signal that the page 310 cleaner has finished the request */ 311 buf_flush_t flush_type;/*!< type of the flush request. 312 BUF_FLUSH_LRU: flush end of LRU, keeping free blocks. 313 BUF_FLUSH_LIST: flush all of blocks. */ 314 #endif /* !UNIV_HOTBACKUP */ 315 ibool apply_log_recs; 316 /*!< this is TRUE when log rec application to 317 pages is allowed; this flag tells the 318 i/o-handler if it should do log record 319 application */ 320 ibool apply_batch_on; 321 /*!< this is TRUE when a log rec application 322 batch is running */ 323 byte* last_block; 324 /*!< possible incomplete last recovered log 325 block */ 326 byte* last_block_buf_start; 327 /*!< the nonaligned start address of the 328 preceding buffer */ 329 byte* buf; /*!< buffer for parsing log records */ 330 ulint len; /*!< amount of data in buf */ 331 lsn_t parse_start_lsn; 332 /*!< this is the lsn from which we were able to 333 start parsing log records and adding them to 334 the hash table; zero if a suitable 335 start point not found yet */ 336 lsn_t scanned_lsn; 337 /*!< the log data has been scanned up to this 338 lsn */ 339 ulint scanned_checkpoint_no; 340 /*!< the log data has been scanned up to this 341 checkpoint number (lowest 4 bytes) */ 342 ulint recovered_offset; 343 /*!< start offset of non-parsed log records in 344 buf */ 345 lsn_t recovered_lsn; 346 /*!< the log records have been parsed up to 347 this lsn */ 348 bool found_corrupt_log; 349 /*!< set when finding a corrupt log 350 block or record, or there is a log 351 parsing buffer overflow */ 352 bool found_corrupt_fs; 353 /*!< set when an inconsistency with 354 the file system contents is detected 355 during log scan or apply */ 356 lsn_t mlog_checkpoint_lsn; 357 /*!< the LSN of a MLOG_CHECKPOINT 358 record, or 0 if none was parsed */ 359 mem_heap_t* heap; /*!< memory heap of log records and file 360 addresses*/ 361 hash_table_t* addr_hash;/*!< hash table of file addresses of pages */ 362 ulint n_addrs;/*!< number of not processed hashed file 363 addresses in the hash table */ 364 365 recv_dblwr_t dblwr; 366 367 encryption_list_t* /*!< Encryption information list */ 368 encryption_list; 369 }; 370 371 /** The recovery system */ 372 extern recv_sys_t* recv_sys; 373 374 /** TRUE when applying redo log records during crash recovery; FALSE 375 otherwise. Note that this is FALSE while a background thread is 376 rolling back incomplete transactions. */ 377 extern volatile bool recv_recovery_on; 378 /** If the following is TRUE, the buffer pool file pages must be invalidated 379 after recovery and no ibuf operations are allowed; this becomes TRUE if 380 the log record hash table becomes too full, and log records must be merged 381 to file pages already before the recovery is finished: in this case no 382 ibuf operations are allowed, as they could modify the pages read in the 383 buffer pool before the pages have been recovered to the up-to-date state. 384 385 TRUE means that recovery is running and no operations on the log files 386 are allowed yet: the variable name is misleading. */ 387 extern bool recv_no_ibuf_operations; 388 /** TRUE when recv_init_crash_recovery() has been called. */ 389 extern bool recv_needed_recovery; 390 #ifdef UNIV_DEBUG 391 /** TRUE if writing to the redo log (mtr_commit) is forbidden. 392 Protected by log_sys->mutex. */ 393 extern bool recv_no_log_write; 394 #endif /* UNIV_DEBUG */ 395 396 /** TRUE if buf_page_is_corrupted() should check if the log sequence 397 number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by 398 recv_recovery_from_checkpoint_start(). */ 399 extern bool recv_lsn_checks_on; 400 #ifdef UNIV_HOTBACKUP 401 /** TRUE when the redo log is being backed up */ 402 extern bool recv_is_making_a_backup; 403 #endif /* UNIV_HOTBACKUP */ 404 405 #ifndef UNIV_HOTBACKUP 406 /** Flag indicating if recv_writer thread is active. */ 407 extern volatile bool recv_writer_thread_active; 408 #endif /* !UNIV_HOTBACKUP */ 409 410 /** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many 411 times! */ 412 #define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) 413 414 /** Size of block reads when the log groups are scanned forward to do a 415 roll-forward */ 416 #define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE) 417 418 /** This many frames must be left free in the buffer pool when we scan 419 the log and store the scanned log records in the buffer pool: we will 420 use these free frames to read in pages when we start applying the 421 log records to the database. */ 422 extern ulint recv_n_pool_free_frames; 423 424 #ifndef UNIV_NONINL 425 #include "log0recv.ic" 426 #endif 427 428 #endif 429