1 /***************************************************************************** 2 3 Copyright (c) 1997, 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/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 /** Whether to store redo log records to the hash table */ 372 enum store_t { 373 /** Do not store redo log records. */ 374 STORE_NO, 375 /** Store redo log records. */ 376 STORE_YES, 377 /** Store redo log records if the tablespace exists. */ 378 STORE_IF_EXISTS 379 }; 380 381 /** Parse log records from a buffer and optionally store them to a 382 hash table to wait merging to file pages. 383 @param[in] checkpoint_lsn the LSN of the latest checkpoint 384 @param[in] store whether to store page operations 385 @param[in] apply whether to apply the records 386 @return whether MLOG_CHECKPOINT record was seen the first time, 387 or corruption was noticed */ 388 __attribute__((warn_unused_result)) 389 bool 390 recv_parse_log_recs( 391 lsn_t checkpoint_lsn, 392 store_t store); 393 394 /*******************************************************//** 395 Moves the parsing buffer data left to the buffer start. */ 396 void 397 recv_sys_justify_left_parsing_buf(void); 398 399 400 /*******************************************************//** 401 Adds data from a new log block to the parsing buffer of recv_sys if 402 recv_sys->parse_start_lsn is non-zero. 403 @return true if more data added */ 404 bool 405 recv_sys_add_to_parsing_buf( 406 /*========================*/ 407 const byte* log_block, /*!< in: log block */ 408 lsn_t scanned_lsn); /*!< in: lsn of how far we were able 409 to find data in this log block */ 410 411 /** The recovery system */ 412 extern recv_sys_t* recv_sys; 413 414 /** TRUE when applying redo log records during crash recovery; FALSE 415 otherwise. Note that this is FALSE while a background thread is 416 rolling back incomplete transactions. */ 417 extern volatile bool recv_recovery_on; 418 /** If the following is TRUE, the buffer pool file pages must be invalidated 419 after recovery and no ibuf operations are allowed; this becomes TRUE if 420 the log record hash table becomes too full, and log records must be merged 421 to file pages already before the recovery is finished: in this case no 422 ibuf operations are allowed, as they could modify the pages read in the 423 buffer pool before the pages have been recovered to the up-to-date state. 424 425 TRUE means that recovery is running and no operations on the log files 426 are allowed yet: the variable name is misleading. */ 427 extern bool recv_no_ibuf_operations; 428 /** TRUE when recv_init_crash_recovery() has been called. */ 429 extern bool recv_needed_recovery; 430 #ifdef UNIV_DEBUG 431 /** TRUE if writing to the redo log (mtr_commit) is forbidden. 432 Protected by log_sys->mutex. */ 433 extern bool recv_no_log_write; 434 #endif /* UNIV_DEBUG */ 435 436 /** TRUE if buf_page_is_corrupted() should check if the log sequence 437 number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by 438 recv_recovery_from_checkpoint_start(). */ 439 extern bool recv_lsn_checks_on; 440 #if 1 441 /** TRUE when the redo log is being backed up */ 442 extern bool recv_is_making_a_backup; 443 /** last flushed lsn read at the start of backup */ 444 extern volatile lsn_t backup_redo_log_flushed_lsn; 445 #endif /* UNIV_HOTBACKUP */ 446 447 #ifndef UNIV_HOTBACKUP 448 /** Flag indicating if recv_writer thread is active. */ 449 extern volatile bool recv_writer_thread_active; 450 #endif /* !UNIV_HOTBACKUP */ 451 452 /** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many 453 times! */ 454 #define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) 455 456 /** Size of block reads when the log groups are scanned forward to do a 457 roll-forward */ 458 #define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE) 459 460 /** This many frames must be left free in the buffer pool when we scan 461 the log and store the scanned log records in the buffer pool: we will 462 use these free frames to read in pages when we start applying the 463 log records to the database. */ 464 extern ulint recv_n_pool_free_frames; 465 466 /** Check the 4-byte checksum to the trailer checksum field of a log 467 block. 468 @param[in] log block 469 @return whether the checksum matches */ 470 bool 471 log_block_checksum_is_ok( 472 const byte* block); /*!< in: pointer to a log block */ 473 474 /********************************************************//** 475 Looks for the maximum consistent checkpoint from the log groups. 476 @return error code or DB_SUCCESS */ 477 UNIV_INTERN __attribute__((nonnull, warn_unused_result)) 478 dberr_t 479 recv_find_max_checkpoint( 480 /*=====================*/ 481 log_group_t** max_group, /*!< out: max group */ 482 ulint* max_field); /*!< out: LOG_CHECKPOINT_1 or 483 LOG_CHECKPOINT_2 */ 484 #ifndef UNIV_NONINL 485 #include "log0recv.ic" 486 #endif 487 488 #endif 489