#include "univ.i"#include "ut0byte.h"#include "page0types.h"#include "hash0hash.h"#include "log0log.h"Include dependency graph for log0recv.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Classes | |
| struct | recv_data_struct |
| struct | recv_struct |
| struct | recv_addr_struct |
| struct | recv_sys_struct |
Defines | |
| #define | RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) |
| #define | RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE) |
| #define | RECV_NOT_PROCESSED 71 |
| #define | RECV_BEING_READ 72 |
| #define | RECV_BEING_PROCESSED 73 |
| #define | RECV_PROCESSED 74 |
| #define | RECV_REPLICA_SPACE_ADD 1 |
Typedefs | |
| typedef recv_data_struct | recv_data_t |
| typedef recv_struct | recv_t |
| typedef recv_addr_struct | recv_addr_t |
| typedef recv_sys_struct | recv_sys_t |
Functions | |
| ibool | recv_read_cp_info_for_backup (byte *hdr, dulint *lsn, ulint *offset, ulint *fsp_limit, dulint *cp_no, dulint *first_header_lsn) |
| void | recv_scan_log_seg_for_backup (byte *buf, ulint buf_len, dulint *scanned_lsn, ulint *scanned_checkpoint_no, ulint *n_bytes_scanned) |
| UNIV_INLINE ibool | recv_recovery_is_on (void) |
| UNIV_INLINE ibool | recv_recovery_from_backup_is_on (void) |
| void | recv_recover_page (ibool recover_backup, ibool just_read_in, page_t *page, ulint space, ulint page_no) |
| ulint | recv_recovery_from_checkpoint_start (ulint type, dulint limit_lsn, dulint min_flushed_lsn, dulint max_flushed_lsn) |
| void | recv_recovery_from_checkpoint_finish (void) |
| ibool | recv_scan_log_recs (ibool apply_automatically, ulint available_memory, ibool store_to_hash, byte *buf, ulint len, dulint start_lsn, dulint *contiguous_lsn, dulint *group_scanned_lsn) |
| void | recv_reset_logs (dulint lsn, ibool new_logs_created) |
| void | recv_sys_create (void) |
| void | recv_sys_init (ibool recover_from_backup, ulint available_memory) |
| void | recv_apply_hashed_log_recs (ibool allow_ibuf) |
| void | recv_compare_spaces (ulint space1, ulint space2, ulint n_pages) |
| void | recv_compare_spaces_low (ulint space1, ulint space2, ulint n_pages) |
Variables | |
| recv_sys_t * | recv_sys |
| ibool | recv_recovery_on |
| ibool | recv_no_ibuf_operations |
| ibool | recv_needed_recovery |
| ibool | recv_lsn_checks_on |
| ulint | recv_max_parsed_page_no |
| ulint | recv_n_pool_free_frames |
| #define RECV_BEING_PROCESSED 73 |
| #define RECV_BEING_READ 72 |
| #define RECV_NOT_PROCESSED 71 |
Definition at line 359 of file log0recv.h.
Referenced by recv_add_to_hash_table(), recv_apply_hashed_log_recs(), and recv_read_in_area().
| #define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) |
Definition at line 352 of file log0recv.h.
Referenced by recv_scan_log_recs(), recv_sys_add_to_parsing_buf(), and recv_sys_init().
| #define RECV_PROCESSED 74 |
Definition at line 362 of file log0recv.h.
Referenced by recv_apply_log_recs_for_backup(), and recv_recover_page().
| #define RECV_REPLICA_SPACE_ADD 1 |
Definition at line 367 of file log0recv.h.
| #define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE) |
Definition at line 356 of file log0recv.h.
Referenced by recv_copy_group(), recv_group_scan_log_recs(), and recv_truncate_group().
| typedef struct recv_addr_struct recv_addr_t |
Definition at line 268 of file log0recv.h.
| typedef struct recv_data_struct recv_data_t |
Definition at line 240 of file log0recv.h.
| typedef struct recv_sys_struct recv_sys_t |
Definition at line 280 of file log0recv.h.
| typedef struct recv_struct recv_t |
Definition at line 249 of file log0recv.h.
| void recv_apply_hashed_log_recs | ( | ibool | allow_ibuf | ) |
Definition at line 1324 of file log0recv.c.
References recv_sys_struct::addr_hash, recv_sys_struct::apply_batch_on, recv_sys_struct::apply_log_recs, buf_flush_batch(), BUF_FLUSH_LIST, buf_flush_wait_batch_end(), buf_page_get, buf_page_peek(), buf_pool_invalidate(), FALSE, HASH_GET_FIRST, hash_get_n_cells(), HASH_GET_NEXT, log_sys, mtr_commit(), mtr_start(), recv_sys_struct::mutex, log_struct::mutex, mutex_enter, mutex_exit(), recv_sys_struct::n_addrs, os_thread_sleep(), page, recv_addr_struct::page_no, page_t, recv_no_ibuf_operations, RECV_NOT_PROCESSED, recv_read_in_area(), recv_recover_page(), recv_sys, recv_sys_empty_hash(), RW_X_LATCH, recv_addr_struct::space, recv_addr_struct::state, SYNC_NO_ORDER_CHECK, TRUE, ut_a, ut_ad, ut_dulint_max, and ut_print_timestamp().
Referenced by log_checkpoint(), log_preflush_pool_modified_pages(), recv_recovery_from_checkpoint_finish(), and recv_scan_log_recs().
01326 : if TRUE, also ibuf operations are 01327 allowed during the application; if FALSE, 01328 no ibuf operations are allowed, and after 01329 the application all file pages are flushed to 01330 disk and invalidated in buffer pool: this 01331 alternative means that no new log records 01332 can be generated during the application; 01333 the caller must in this case own the log 01334 mutex */ 01335 { 01336 recv_addr_t* recv_addr; 01337 page_t* page; 01338 ulint i; 01339 ulint space; 01340 ulint page_no; 01341 ulint n_pages; 01342 ibool has_printed = FALSE; 01343 mtr_t mtr; 01344 loop: 01345 mutex_enter(&(recv_sys->mutex)); 01346 01347 if (recv_sys->apply_batch_on) { 01348 01349 mutex_exit(&(recv_sys->mutex)); 01350 01351 os_thread_sleep(500000); 01352 01353 goto loop; 01354 } 01355 01356 #ifdef UNIV_SYNC_DEBUG 01357 ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); 01358 #endif /* UNIV_SYNC_DEBUG */ 01359 if (!allow_ibuf) { 01360 recv_no_ibuf_operations = TRUE; 01361 } 01362 01363 recv_sys->apply_log_recs = TRUE; 01364 recv_sys->apply_batch_on = TRUE; 01365 01366 for (i = 0; i < hash_get_n_cells(recv_sys->addr_hash); i++) { 01367 01368 recv_addr = HASH_GET_FIRST(recv_sys->addr_hash, i); 01369 01370 while (recv_addr) { 01371 space = recv_addr->space; 01372 page_no = recv_addr->page_no; 01373 01374 if (recv_addr->state == RECV_NOT_PROCESSED) { 01375 if (!has_printed) { 01376 ut_print_timestamp(stderr); 01377 fputs( 01378 " InnoDB: Starting an apply batch of log records to the database...\n" 01379 "InnoDB: Progress in percents: ",stderr); 01380 has_printed = TRUE; 01381 } 01382 01383 mutex_exit(&(recv_sys->mutex)); 01384 01385 if (buf_page_peek(space, page_no)) { 01386 01387 mtr_start(&mtr); 01388 01389 page = buf_page_get(space, page_no, 01390 RW_X_LATCH, &mtr); 01391 01392 #ifdef UNIV_SYNC_DEBUG 01393 buf_page_dbg_add_level(page, 01394 SYNC_NO_ORDER_CHECK); 01395 #endif /* UNIV_SYNC_DEBUG */ 01396 recv_recover_page(FALSE, FALSE, page, 01397 space, page_no); 01398 mtr_commit(&mtr); 01399 } else { 01400 recv_read_in_area(space, page_no); 01401 } 01402 01403 mutex_enter(&(recv_sys->mutex)); 01404 } 01405 01406 recv_addr = HASH_GET_NEXT(addr_hash, recv_addr); 01407 } 01408 01409 if (has_printed 01410 && (i * 100) / hash_get_n_cells(recv_sys->addr_hash) 01411 != ((i + 1) * 100) 01412 / hash_get_n_cells(recv_sys->addr_hash)) { 01413 01414 fprintf(stderr, "%lu ", 01415 (ulong) ((i * 100) / hash_get_n_cells(recv_sys->addr_hash))); 01416 } 01417 } 01418 01419 /* Wait until all the pages have been processed */ 01420 01421 while (recv_sys->n_addrs != 0) { 01422 01423 mutex_exit(&(recv_sys->mutex)); 01424 01425 os_thread_sleep(500000); 01426 01427 mutex_enter(&(recv_sys->mutex)); 01428 } 01429 01430 if (has_printed) { 01431 01432 fprintf(stderr, "\n"); 01433 } 01434 01435 if (!allow_ibuf) { 01436 /* Flush all the file pages to disk and invalidate them in 01437 the buffer pool */ 01438 01439 mutex_exit(&(recv_sys->mutex)); 01440 mutex_exit(&(log_sys->mutex)); 01441 01442 n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, 01443 ut_dulint_max); 01444 ut_a(n_pages != ULINT_UNDEFINED); 01445 01446 buf_flush_wait_batch_end(BUF_FLUSH_LIST); 01447 01448 buf_pool_invalidate(); 01449 01450 mutex_enter(&(log_sys->mutex)); 01451 mutex_enter(&(recv_sys->mutex)); 01452 01453 recv_no_ibuf_operations = FALSE; 01454 } 01455 01456 recv_sys->apply_log_recs = FALSE; 01457 recv_sys->apply_batch_on = FALSE; 01458 01459 recv_sys_empty_hash(); 01460 01461 if (has_printed) { 01462 fprintf(stderr, "InnoDB: Apply batch completed\n"); 01463 } 01464 01465 mutex_exit(&(recv_sys->mutex)); 01466 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool recv_read_cp_info_for_backup | ( | byte * | hdr, | |
| dulint * | lsn, | |||
| ulint * | offset, | |||
| ulint * | fsp_limit, | |||
| dulint * | cp_no, | |||
| dulint * | first_header_lsn | |||
| ) |
Definition at line 556 of file log0recv.c.
References FALSE, LOG_CHECKPOINT_1, LOG_CHECKPOINT_2, LOG_CHECKPOINT_FSP_FREE_LIMIT, LOG_CHECKPOINT_FSP_MAGIC_N, LOG_CHECKPOINT_FSP_MAGIC_N_VAL, LOG_CHECKPOINT_LSN, LOG_CHECKPOINT_NO, LOG_CHECKPOINT_OFFSET, LOG_FILE_START_LSN, mach_read_from_4(), mach_read_from_8(), recv_check_cp_is_consistent(), TRUE, ut_dulint_cmp(), and ut_dulint_zero.
00558 : TRUE if success */ 00559 byte* hdr, /* in: buffer containing the log group header */ 00560 dulint* lsn, /* out: checkpoint lsn */ 00561 ulint* offset, /* out: checkpoint offset in the log group */ 00562 ulint* fsp_limit,/* out: fsp limit of space 0, 1000000000 if the 00563 database is running with < version 3.23.50 of InnoDB */ 00564 dulint* cp_no, /* out: checkpoint number */ 00565 dulint* first_header_lsn) 00566 /* out: lsn of of the start of the first log file */ 00567 { 00568 ulint max_cp = 0; 00569 dulint max_cp_no = ut_dulint_zero; 00570 byte* cp_buf; 00571 00572 cp_buf = hdr + LOG_CHECKPOINT_1; 00573 00574 if (recv_check_cp_is_consistent(cp_buf)) { 00575 max_cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO); 00576 max_cp = LOG_CHECKPOINT_1; 00577 } 00578 00579 cp_buf = hdr + LOG_CHECKPOINT_2; 00580 00581 if (recv_check_cp_is_consistent(cp_buf)) { 00582 if (ut_dulint_cmp(mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO), 00583 max_cp_no) > 0) { 00584 max_cp = LOG_CHECKPOINT_2; 00585 } 00586 } 00587 00588 if (max_cp == 0) { 00589 return(FALSE); 00590 } 00591 00592 cp_buf = hdr + max_cp; 00593 00594 *lsn = mach_read_from_8(cp_buf + LOG_CHECKPOINT_LSN); 00595 *offset = mach_read_from_4(cp_buf + LOG_CHECKPOINT_OFFSET); 00596 00597 /* If the user is running a pre-3.23.50 version of InnoDB, its 00598 checkpoint data does not contain the fsp limit info */ 00599 if (mach_read_from_4(cp_buf + LOG_CHECKPOINT_FSP_MAGIC_N) 00600 == LOG_CHECKPOINT_FSP_MAGIC_N_VAL) { 00601 00602 *fsp_limit = mach_read_from_4( 00603 cp_buf + LOG_CHECKPOINT_FSP_FREE_LIMIT); 00604 00605 if (*fsp_limit == 0) { 00606 *fsp_limit = 1000000000; 00607 } 00608 } else { 00609 *fsp_limit = 1000000000; 00610 } 00611 00612 /* fprintf(stderr, "fsp limit %lu MB\n", *fsp_limit); */ 00613 00614 *cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO); 00615 00616 *first_header_lsn = mach_read_from_8(hdr + LOG_FILE_START_LSN); 00617 00618 return(TRUE); 00619 }
Here is the call graph for this function:

| void recv_recover_page | ( | ibool | recover_backup, | |
| ibool | just_read_in, | |||
| page_t * | page, | |||
| ulint | space, | |||
| ulint | page_no | |||
| ) |
Definition at line 1084 of file log0recv.c.
References recv_sys_struct::apply_log_recs, yaSSL::block, buf, buf_block_align(), buf_flush_recv_note_modification(), buf_frame_get_newest_modification(), BUF_KEEP_OLD, buf_page_get_known_nowait(), recv_struct::data, recv_struct::end_lsn, FALSE, FIL_PAGE_END_LSN_OLD_CHKSUM, FIL_PAGE_LSN, recv_struct::len, mach_read_from_8(), mach_write_to_8(), mem_alloc, mem_free, MLOG_INIT_FILE_PAGE, mtr_struct::modifications, mtr_commit(), MTR_LOG_NONE, mtr_set_log_mode(), mtr_start(), recv_sys_struct::mutex, mutex_enter, mutex_exit(), recv_sys_struct::n_addrs, NULL, recv_addr_struct::page_no, recv_addr_struct::rec_list, RECV_BEING_PROCESSED, RECV_DATA_BLOCK_SIZE, recv_data_copy_to_buf(), recv_get_fil_addr_struct(), recv_max_page_lsn, recv_parse_or_apply_log_rec_body(), RECV_PROCESSED, recv_sys, rw_lock_x_lock_move_ownership(), RW_X_LATCH, recv_addr_struct::space, recv_struct::start_lsn, recv_addr_struct::state, SYNC_NO_ORDER_CHECK, TRUE, recv_struct::type, UNIV_PAGE_SIZE, ut_a, ut_dulint_add(), ut_dulint_cmp(), ut_dulint_is_zero(), ut_dulint_zero, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by buf_page_io_complete(), recv_apply_hashed_log_recs(), and recv_apply_log_recs_for_backup().
01086 : TRUE if we are recovering a backup 01087 page: then we do not acquire any latches 01088 since the page was read in outside the 01089 buffer pool */ 01090 ibool just_read_in, /* in: TRUE if the i/o-handler calls this for 01091 a freshly read page */ 01092 page_t* page, /* in: buffer page */ 01093 ulint space, /* in: space id */ 01094 ulint page_no) /* in: page number */ 01095 { 01096 buf_block_t* block = NULL; 01097 recv_addr_t* recv_addr; 01098 recv_t* recv; 01099 byte* buf; 01100 dulint start_lsn; 01101 dulint end_lsn; 01102 dulint page_lsn; 01103 dulint page_newest_lsn; 01104 ibool modification_to_page; 01105 ibool success; 01106 mtr_t mtr; 01107 01108 mutex_enter(&(recv_sys->mutex)); 01109 01110 if (recv_sys->apply_log_recs == FALSE) { 01111 01112 /* Log records should not be applied now */ 01113 01114 mutex_exit(&(recv_sys->mutex)); 01115 01116 return; 01117 } 01118 01119 recv_addr = recv_get_fil_addr_struct(space, page_no); 01120 01121 if ((recv_addr == NULL) 01122 || (recv_addr->state == RECV_BEING_PROCESSED) 01123 || (recv_addr->state == RECV_PROCESSED)) { 01124 01125 mutex_exit(&(recv_sys->mutex)); 01126 01127 return; 01128 } 01129 01130 /* fprintf(stderr, "Recovering space %lu, page %lu\n", space, page_no); */ 01131 01132 recv_addr->state = RECV_BEING_PROCESSED; 01133 01134 mutex_exit(&(recv_sys->mutex)); 01135 01136 mtr_start(&mtr); 01137 mtr_set_log_mode(&mtr, MTR_LOG_NONE); 01138 01139 if (!recover_backup) { 01140 block = buf_block_align(page); 01141 01142 if (just_read_in) { 01143 /* Move the ownership of the x-latch on the page to this OS 01144 thread, so that we can acquire a second x-latch on it. This 01145 is needed for the operations to the page to pass the debug 01146 checks. */ 01147 01148 rw_lock_x_lock_move_ownership(&(block->lock)); 01149 } 01150 01151 success = buf_page_get_known_nowait(RW_X_LATCH, page, 01152 BUF_KEEP_OLD, 01153 __FILE__, __LINE__, 01154 &mtr); 01155 ut_a(success); 01156 01157 #ifdef UNIV_SYNC_DEBUG 01158 buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK); 01159 #endif /* UNIV_SYNC_DEBUG */ 01160 } 01161 01162 /* Read the newest modification lsn from the page */ 01163 page_lsn = mach_read_from_8(page + FIL_PAGE_LSN); 01164 01165 if (!recover_backup) { 01166 /* It may be that the page has been modified in the buffer 01167 pool: read the newest modification lsn there */ 01168 01169 page_newest_lsn = buf_frame_get_newest_modification(page); 01170 01171 if (!ut_dulint_is_zero(page_newest_lsn)) { 01172 01173 page_lsn = page_newest_lsn; 01174 } 01175 } else { 01176 /* In recovery from a backup we do not really use the buffer 01177 pool */ 01178 01179 page_newest_lsn = ut_dulint_zero; 01180 } 01181 01182 modification_to_page = FALSE; 01183 start_lsn = end_lsn = ut_dulint_zero; 01184 01185 recv = UT_LIST_GET_FIRST(recv_addr->rec_list); 01186 01187 while (recv) { 01188 end_lsn = recv->end_lsn; 01189 01190 if (recv->len > RECV_DATA_BLOCK_SIZE) { 01191 /* We have to copy the record body to a separate 01192 buffer */ 01193 01194 buf = mem_alloc(recv->len); 01195 01196 recv_data_copy_to_buf(buf, recv); 01197 } else { 01198 buf = ((byte*)(recv->data)) + sizeof(recv_data_t); 01199 } 01200 01201 if (recv->type == MLOG_INIT_FILE_PAGE) { 01202 page_lsn = page_newest_lsn; 01203 01204 mach_write_to_8(page + UNIV_PAGE_SIZE 01205 - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_zero); 01206 mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero); 01207 } 01208 01209 if (ut_dulint_cmp(recv->start_lsn, page_lsn) >= 0) { 01210 01211 if (!modification_to_page) { 01212 01213 modification_to_page = TRUE; 01214 start_lsn = recv->start_lsn; 01215 } 01216 01217 #ifdef UNIV_DEBUG 01218 if (log_debug_writes) { 01219 fprintf(stderr, 01220 "InnoDB: Applying log rec type %lu len %lu to space %lu page no %lu\n", 01221 (ulong) recv->type, (ulong) recv->len, 01222 (ulong) recv_addr->space, 01223 (ulong) recv_addr->page_no); 01224 } 01225 #endif /* UNIV_DEBUG */ 01226 01227 recv_parse_or_apply_log_rec_body(recv->type, buf, 01228 buf + recv->len, page, &mtr); 01229 mach_write_to_8(page + UNIV_PAGE_SIZE 01230 - FIL_PAGE_END_LSN_OLD_CHKSUM, 01231 ut_dulint_add(recv->start_lsn, 01232 recv->len)); 01233 mach_write_to_8(page + FIL_PAGE_LSN, 01234 ut_dulint_add(recv->start_lsn, 01235 recv->len)); 01236 } 01237 01238 if (recv->len > RECV_DATA_BLOCK_SIZE) { 01239 mem_free(buf); 01240 } 01241 01242 recv = UT_LIST_GET_NEXT(rec_list, recv); 01243 } 01244 01245 mutex_enter(&(recv_sys->mutex)); 01246 01247 if (ut_dulint_cmp(recv_max_page_lsn, page_lsn) < 0) { 01248 recv_max_page_lsn = page_lsn; 01249 } 01250 01251 recv_addr->state = RECV_PROCESSED; 01252 01253 ut_a(recv_sys->n_addrs); 01254 recv_sys->n_addrs--; 01255 01256 mutex_exit(&(recv_sys->mutex)); 01257 01258 if (!recover_backup && modification_to_page) { 01259 ut_a(block); 01260 01261 buf_flush_recv_note_modification(block, start_lsn, end_lsn); 01262 } 01263 01264 /* Make sure that committing mtr does not change the modification 01265 lsn values of page */ 01266 01267 mtr.modifications = FALSE; 01268 01269 mtr_commit(&mtr); 01270 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE ibool recv_recovery_from_backup_is_on | ( | void | ) |
| void recv_recovery_from_checkpoint_finish | ( | void | ) |
Definition at line 2937 of file log0recv.c.
References FALSE, recv_sys_struct::found_corrupt_log, NULL, os_thread_create(), recv_apply_hashed_log_recs(), recv_needed_recovery, recv_recovery_on, recv_sys, recv_sys_free(), SRV_FORCE_NO_LOG_REDO, SRV_FORCE_NO_TRX_UNDO, srv_force_recovery, TRUE, trx_rollback_or_clean_all_without_sess(), trx_sys_print_mysql_binlog_offset(), and trx_sys_print_mysql_master_log_pos().
Referenced by innobase_start_or_create_for_mysql().
02939 { 02940 int i; 02941 02942 /* Apply the hashed log records to the respective file pages */ 02943 02944 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { 02945 02946 recv_apply_hashed_log_recs(TRUE); 02947 } 02948 02949 #ifdef UNIV_DEBUG 02950 if (log_debug_writes) { 02951 fprintf(stderr, 02952 "InnoDB: Log records applied to the database\n"); 02953 } 02954 #endif /* UNIV_DEBUG */ 02955 02956 if (recv_needed_recovery) { 02957 trx_sys_print_mysql_master_log_pos(); 02958 trx_sys_print_mysql_binlog_offset(); 02959 } 02960 02961 if (recv_sys->found_corrupt_log) { 02962 02963 fprintf(stderr, 02964 "InnoDB: WARNING: the log file may have been corrupt and it\n" 02965 "InnoDB: is possible that the log scan or parsing did not proceed\n" 02966 "InnoDB: far enough in recovery. Please run CHECK TABLE\n" 02967 "InnoDB: on your InnoDB tables to check that they are ok!\n" 02968 "InnoDB: It may be safest to recover your InnoDB database from\n" 02969 "InnoDB: a backup!\n"); 02970 } 02971 02972 /* Free the resources of the recovery system */ 02973 02974 recv_recovery_on = FALSE; 02975 02976 #ifndef UNIV_LOG_DEBUG 02977 recv_sys_free(); 02978 #endif 02979 if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { 02980 /* Rollback the uncommitted transactions which have no user 02981 session */ 02982 02983 os_thread_create(trx_rollback_or_clean_all_without_sess, 02984 (void *)&i, NULL); 02985 } 02986 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint recv_recovery_from_checkpoint_start | ( | ulint | type, | |
| dulint | limit_lsn, | |||
| dulint | min_flushed_lsn, | |||
| dulint | max_flushed_lsn | |||
| ) |
Definition at line 2574 of file log0recv.c.
References recv_sys_struct::apply_log_recs, recv_sys_struct::archive_group, log_group_struct::archived_file_no, log_struct::archived_lsn, log_group_struct::archived_offset, log_struct::archiving_state, buf, log_struct::buf, log_struct::buf_free, log_struct::buf_next_to_write, buf_pool_get_curr_size(), log_struct::checkpoint_buf, DB_ERROR, DB_SUCCESS, err, FALSE, fil_io(), fil_load_single_table_tablespaces(), log_group_struct::id, recv_sys_struct::last_block, log_struct::last_checkpoint_lsn, recv_sys_struct::limit_lsn, LOG_ARCH_OFF, LOG_ARCHIVE, LOG_CHECKPOINT, LOG_CHECKPOINT_ARCHIVED_LSN, log_checkpoint_get_nth_group_info(), LOG_CHECKPOINT_LSN, LOG_CHECKPOINT_NO, LOG_FILE_HDR_SIZE, LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, log_group_get_capacity(), log_group_read_checkpoint_info(), log_struct::log_groups, log_sys, log_struct::lsn, mach_read_from_8(), memset, log_struct::mutex, recv_sys_struct::mutex, mutex_enter, mutex_exit(), log_struct::next_checkpoint_lsn, log_struct::next_checkpoint_no, OS_FILE_LOG, OS_FILE_LOG_BLOCK_SIZE, OS_FILE_READ, OS_FILE_WRITE, recv_sys_struct::parse_start_lsn, recv_sys_struct::recovered_lsn, recv_find_max_checkpoint(), recv_group_scan_log_recs(), recv_lsn_checks_on, recv_max_page_lsn, recv_needed_recovery, recv_recovery_on, recv_synchronize_groups(), recv_sys, recv_sys_create(), recv_sys_init(), recv_sys_struct::scanned_checkpoint_no, recv_sys_struct::scanned_lsn, log_group_struct::scanned_lsn, log_group_struct::space_id, SRV_FORCE_NO_LOG_REDO, srv_force_recovery, srv_start_lsn, TRUE, trx_sys_doublewrite_init_or_restore_pages(), ut_ad, ut_dulint_add(), ut_dulint_align_down(), ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), ut_dulint_max, ut_error, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, ut_memcmp(), ut_memcpy(), ut_print_timestamp(), log_struct::written_to_all_lsn, and log_struct::written_to_some_lsn.
Referenced by innobase_start_or_create_for_mysql().
02576 : error code or DB_SUCCESS */ 02577 ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */ 02578 dulint limit_lsn, /* in: recover up to this lsn if possible */ 02579 dulint min_flushed_lsn,/* in: min flushed lsn from data files */ 02580 dulint max_flushed_lsn)/* in: max flushed lsn from data files */ 02581 { 02582 log_group_t* group; 02583 log_group_t* max_cp_group; 02584 log_group_t* up_to_date_group; 02585 ulint max_cp_field; 02586 dulint checkpoint_lsn; 02587 dulint checkpoint_no; 02588 dulint old_scanned_lsn; 02589 dulint group_scanned_lsn; 02590 dulint contiguous_lsn; 02591 dulint archived_lsn; 02592 ulint capacity; 02593 byte* buf; 02594 byte log_hdr_buf[LOG_FILE_HDR_SIZE]; 02595 ulint err; 02596 02597 ut_ad((type != LOG_CHECKPOINT) 02598 || (ut_dulint_cmp(limit_lsn, ut_dulint_max) == 0)); 02599 02600 if (type == LOG_CHECKPOINT) { 02601 recv_sys_create(); 02602 recv_sys_init(FALSE, buf_pool_get_curr_size()); 02603 } 02604 02605 if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) { 02606 fprintf(stderr, 02607 "InnoDB: The user has set SRV_FORCE_NO_LOG_REDO on\n"); 02608 fprintf(stderr, 02609 "InnoDB: Skipping log redo\n"); 02610 02611 return(DB_SUCCESS); 02612 } 02613 02614 recv_recovery_on = TRUE; 02615 02616 recv_sys->limit_lsn = limit_lsn; 02617 02618 mutex_enter(&(log_sys->mutex)); 02619 02620 /* Look for the latest checkpoint from any of the log groups */ 02621 02622 err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field); 02623 02624 if (err != DB_SUCCESS) { 02625 02626 mutex_exit(&(log_sys->mutex)); 02627 02628 return(err); 02629 } 02630 02631 log_group_read_checkpoint_info(max_cp_group, max_cp_field); 02632 02633 buf = log_sys->checkpoint_buf; 02634 02635 checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); 02636 checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); 02637 archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); 02638 02639 /* Read the first log file header to print a note if this is 02640 a recovery from a restored InnoDB Hot Backup */ 02641 02642 fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id, 02643 0, 0, LOG_FILE_HDR_SIZE, 02644 log_hdr_buf, max_cp_group); 02645 02646 if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, 02647 (byte*)"ibbackup", (sizeof "ibbackup") - 1)) { 02648 /* This log file was created by ibbackup --restore: print 02649 a note to the user about it */ 02650 02651 fprintf(stderr, 02652 "InnoDB: The log file was created by ibbackup --apply-log at\n" 02653 "InnoDB: %s\n", log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP); 02654 fprintf(stderr, 02655 "InnoDB: NOTE: the following crash recovery is part of a normal restore.\n"); 02656 02657 /* Wipe over the label now */ 02658 02659 memset(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, 02660 ' ', 4); 02661 /* Write to the log file to wipe over the label */ 02662 fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, 02663 max_cp_group->space_id, 02664 0, 0, OS_FILE_LOG_BLOCK_SIZE, 02665 log_hdr_buf, max_cp_group); 02666 } 02667 02668 #ifdef UNIV_LOG_ARCHIVE 02669 group = UT_LIST_GET_FIRST(log_sys->log_groups); 02670 02671 while (group) { 02672 log_checkpoint_get_nth_group_info(buf, group->id, 02673 &(group->archived_file_no), 02674 &(group->archived_offset)); 02675 02676 group = UT_LIST_GET_NEXT(log_groups, group); 02677 } 02678 #endif /* UNIV_LOG_ARCHIVE */ 02679 02680 if (type == LOG_CHECKPOINT) { 02681 /* Start reading the log groups from the checkpoint lsn up. The 02682 variable contiguous_lsn contains an lsn up to which the log is 02683 known to be contiguously written to all log groups. */ 02684 02685 recv_sys->parse_start_lsn = checkpoint_lsn; 02686 recv_sys->scanned_lsn = checkpoint_lsn; 02687 recv_sys->scanned_checkpoint_no = 0; 02688 recv_sys->recovered_lsn = checkpoint_lsn; 02689 02690 srv_start_lsn = checkpoint_lsn; 02691 02692 /* NOTE: we always do a 'recovery' at startup, but only if 02693 there is something wrong we will print a message to the 02694 user about recovery: */ 02695 02696 if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0 02697 || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) { 02698 02699 if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) 02700 < 0) { 02701 fprintf(stderr, 02702 "InnoDB: ##########################################################\n" 02703 "InnoDB: WARNING!\n" 02704 "InnoDB: The log sequence number in ibdata files is higher\n" 02705 "InnoDB: than the log sequence number in the ib_logfiles! Are you sure\n" 02706 "InnoDB: you are using the right ib_logfiles to start up the database?\n" 02707 "InnoDB: Log sequence number in ib_logfiles is %lu %lu, log\n" 02708 "InnoDB: sequence numbers stamped to ibdata file headers are between\n" 02709 "InnoDB: %lu %lu and %lu %lu.\n" 02710 "InnoDB: ##########################################################\n", 02711 (ulong) ut_dulint_get_high(checkpoint_lsn), 02712 (ulong) ut_dulint_get_low(checkpoint_lsn), 02713 (ulong) ut_dulint_get_high(min_flushed_lsn), 02714 (ulong) ut_dulint_get_low(min_flushed_lsn), 02715 (ulong) ut_dulint_get_high(max_flushed_lsn), 02716 (ulong) ut_dulint_get_low(max_flushed_lsn)); 02717 } 02718 02719 recv_needed_recovery = TRUE; 02720 02721 ut_print_timestamp(stderr); 02722 02723 fprintf(stderr, 02724 " InnoDB: Database was not shut down normally!\n" 02725 "InnoDB: Starting crash recovery.\n"); 02726 02727 fprintf(stderr, 02728 "InnoDB: Reading tablespace information from the .ibd files...\n"); 02729 02730 fil_load_single_table_tablespaces(); 02731 02732 /* If we are using the doublewrite method, we will 02733 check if there are half-written pages in data files, 02734 and restore them from the doublewrite buffer if 02735 possible */ 02736 02737 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { 02738 02739 fprintf(stderr, 02740 "InnoDB: Restoring possible half-written data pages from the doublewrite\n" 02741 "InnoDB: buffer...\n"); 02742 trx_sys_doublewrite_init_or_restore_pages( 02743 TRUE); 02744 } 02745 02746 ut_print_timestamp(stderr); 02747 02748 fprintf(stderr, 02749 " InnoDB: Starting log scan based on checkpoint at\n" 02750 "InnoDB: log sequence number %lu %lu.\n", 02751 (ulong) ut_dulint_get_high(checkpoint_lsn), 02752 (ulong) ut_dulint_get_low(checkpoint_lsn)); 02753 } else { 02754 /* Init the doublewrite buffer memory structure */ 02755 trx_sys_doublewrite_init_or_restore_pages(FALSE); 02756 } 02757 } 02758 02759 contiguous_lsn = ut_dulint_align_down(recv_sys->scanned_lsn, 02760 OS_FILE_LOG_BLOCK_SIZE); 02761 if (type == LOG_ARCHIVE) { 02762 /* Try to recover the remaining part from logs: first from 02763 the logs of the archived group */ 02764 02765 group = recv_sys->archive_group; 02766 capacity = log_group_get_capacity(group); 02767 02768 if ((ut_dulint_cmp(recv_sys->scanned_lsn, 02769 ut_dulint_add(checkpoint_lsn, capacity)) > 0) 02770 || (ut_dulint_cmp(checkpoint_lsn, 02771 ut_dulint_add(recv_sys->scanned_lsn, capacity)) > 0)) { 02772 02773 mutex_exit(&(log_sys->mutex)); 02774 02775 /* The group does not contain enough log: probably 02776 an archived log file was missing or corrupt */ 02777 02778 return(DB_ERROR); 02779 } 02780 02781 recv_group_scan_log_recs(group, &contiguous_lsn, 02782 &group_scanned_lsn); 02783 if (ut_dulint_cmp(recv_sys->scanned_lsn, checkpoint_lsn) < 0) { 02784 02785 mutex_exit(&(log_sys->mutex)); 02786 02787 /* The group did not contain enough log: an archived 02788 log file was missing or invalid, or the log group 02789 was corrupt */ 02790 02791 return(DB_ERROR); 02792 } 02793 02794 group->scanned_lsn = group_scanned_lsn; 02795 up_to_date_group = group; 02796 } else { 02797 up_to_date_group = max_cp_group; 02798 } 02799 02800 ut_ad(RECV_SCAN_SIZE <= log_sys->buf_size); 02801 02802 group = UT_LIST_GET_FIRST(log_sys->log_groups); 02803 02804 if ((type == LOG_ARCHIVE) && (group == recv_sys->archive_group)) { 02805 group = UT_LIST_GET_NEXT(log_groups, group); 02806 } 02807 02808 while (group) { 02809 old_scanned_lsn = recv_sys->scanned_lsn; 02810 02811 recv_group_scan_log_recs(group, &contiguous_lsn, 02812 &group_scanned_lsn); 02813 group->scanned_lsn = group_scanned_lsn; 02814 02815 if (ut_dulint_cmp(old_scanned_lsn, group_scanned_lsn) < 0) { 02816 /* We found a more up-to-date group */ 02817 02818 up_to_date_group = group; 02819 } 02820 02821 if ((type == LOG_ARCHIVE) 02822 && (group == recv_sys->archive_group)) { 02823 group = UT_LIST_GET_NEXT(log_groups, group); 02824 } 02825 02826 group = UT_LIST_GET_NEXT(log_groups, group); 02827 } 02828 02829 /* We currently have only one log group */ 02830 if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) { 02831 ut_print_timestamp(stderr); 02832 fprintf(stderr, 02833 " InnoDB: ERROR: We were only able to scan the log up to\n" 02834 "InnoDB: %lu %lu, but a checkpoint was at %lu %lu.\n" 02835 "InnoDB: It is possible that the database is now corrupt!\n", 02836 (ulong) ut_dulint_get_high(group_scanned_lsn), 02837 (ulong) ut_dulint_get_low(group_scanned_lsn), 02838 (ulong) ut_dulint_get_high(checkpoint_lsn), 02839 (ulong) ut_dulint_get_low(checkpoint_lsn)); 02840 } 02841 02842 if (ut_dulint_cmp(group_scanned_lsn, recv_max_page_lsn) < 0) { 02843 ut_print_timestamp(stderr); 02844 fprintf(stderr, 02845 " InnoDB: ERROR: We were only able to scan the log up to %lu %lu\n" 02846 "InnoDB: but a database page a had an lsn %lu %lu. It is possible that the\n" 02847 "InnoDB: database is now corrupt!\n", 02848 (ulong) ut_dulint_get_high(group_scanned_lsn), 02849 (ulong) ut_dulint_get_low(group_scanned_lsn), 02850 (ulong) ut_dulint_get_high(recv_max_page_lsn), 02851 (ulong) ut_dulint_get_low(recv_max_page_lsn)); 02852 } 02853 02854 if (ut_dulint_cmp(recv_sys->recovered_lsn, checkpoint_lsn) < 0) { 02855 02856 mutex_exit(&(log_sys->mutex)); 02857 02858 if (ut_dulint_cmp(recv_sys->recovered_lsn, limit_lsn) >= 0) { 02859 02860 return(DB_SUCCESS); 02861 } 02862 02863 ut_error; 02864 02865 return(DB_ERROR); 02866 } 02867 02868 /* Synchronize the uncorrupted log groups to the most up-to-date log 02869 group; we also copy checkpoint info to groups */ 02870 02871 log_sys->next_checkpoint_lsn = checkpoint_lsn; 02872 log_sys->next_checkpoint_no = ut_dulint_add(checkpoint_no, 1); 02873 02874 #ifdef UNIV_LOG_ARCHIVE 02875 log_sys->archived_lsn = archived_lsn; 02876 #endif /* UNIV_LOG_ARCHIVE */ 02877 02878 recv_synchronize_groups(up_to_date_group); 02879 02880 if (!recv_needed_recovery) { 02881 if (ut_dulint_cmp(checkpoint_lsn, recv_sys->recovered_lsn) 02882 != 0) { 02883 fprintf(stderr, 02884 "InnoDB: Warning: we did not need to do crash recovery, but log scan\n" 02885 "InnoDB: progressed past the checkpoint lsn %lu %lu up to lsn %lu %lu\n", 02886 (ulong) ut_dulint_get_high(checkpoint_lsn), 02887 (ulong) ut_dulint_get_low(checkpoint_lsn), 02888 (ulong) ut_dulint_get_high(recv_sys->recovered_lsn), 02889 (ulong) ut_dulint_get_low(recv_sys->recovered_lsn)); 02890 } 02891 } else { 02892 srv_start_lsn = recv_sys->recovered_lsn; 02893 } 02894 02895 log_sys->lsn = recv_sys->recovered_lsn; 02896 02897 ut_memcpy(log_sys->buf, recv_sys->last_block, OS_FILE_LOG_BLOCK_SIZE); 02898 02899 log_sys->buf_free = ut_dulint_get_low(log_sys->lsn) 02900 % OS_FILE_LOG_BLOCK_SIZE; 02901 log_sys->buf_next_to_write = log_sys->buf_free; 02902 log_sys->written_to_some_lsn = log_sys->lsn; 02903 log_sys->written_to_all_lsn = log_sys->lsn; 02904 02905 log_sys->last_checkpoint_lsn = checkpoint_lsn; 02906 02907 log_sys->next_checkpoint_no = ut_dulint_add(checkpoint_no, 1); 02908 02909 #ifdef UNIV_LOG_ARCHIVE 02910 if (ut_dulint_cmp(archived_lsn, ut_dulint_max) == 0) { 02911 02912 log_sys->archiving_state = LOG_ARCH_OFF; 02913 } 02914 #endif /* UNIV_LOG_ARCHIVE */ 02915 02916 mutex_enter(&(recv_sys->mutex)); 02917 02918 recv_sys->apply_log_recs = TRUE; 02919 02920 mutex_exit(&(recv_sys->mutex)); 02921 02922 mutex_exit(&(log_sys->mutex)); 02923 02924 recv_lsn_checks_on = TRUE; 02925 02926 /* The database is now ready to start almost normal processing of user 02927 transactions: transaction rollbacks and the application of the log 02928 records in the hash table can be run in background. */ 02929 02930 return(DB_SUCCESS); 02931 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE ibool recv_recovery_is_on | ( | void | ) |
Referenced by buf_page_io_complete(), lock_sec_rec_cons_read_sees(), lock_sec_rec_read_check_and_lock(), lock_sec_rec_some_has_impl_off_kernel(), and log_checkpoint().
Here is the caller graph for this function:

| void recv_reset_logs | ( | dulint | lsn, | |
| ibool | new_logs_created | |||
| ) |
Definition at line 2992 of file log0recv.c.
References log_group_struct::archived_file_no, log_struct::archived_lsn, log_group_struct::archived_offset, log_struct::buf, log_struct::buf_free, log_struct::buf_next_to_write, log_struct::last_checkpoint_lsn, LOG_BLOCK_HDR_SIZE, log_block_init(), log_block_set_first_rec_group(), LOG_FILE_HDR_SIZE, log_struct::log_groups, log_make_checkpoint_at(), log_sys, log_struct::lsn, log_group_struct::lsn, log_group_struct::lsn_offset, log_struct::mutex, mutex_enter, mutex_exit(), log_struct::next_checkpoint_no, OS_FILE_LOG_BLOCK_SIZE, recv_truncate_group(), TRUE, ut_ad, ut_dulint_add(), ut_dulint_align_up(), ut_dulint_max, ut_dulint_zero, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, log_struct::written_to_all_lsn, and log_struct::written_to_some_lsn.
Referenced by innobase_start_or_create_for_mysql().
02994 : reset to this lsn rounded up to 02995 be divisible by OS_FILE_LOG_BLOCK_SIZE, 02996 after which we add LOG_BLOCK_HDR_SIZE */ 02997 #ifdef UNIV_LOG_ARCHIVE 02998 ulint arch_log_no, /* in: next archived log file number */ 02999 #endif /* UNIV_LOG_ARCHIVE */ 03000 ibool new_logs_created)/* in: TRUE if resetting logs is done 03001 at the log creation; FALSE if it is done 03002 after archive recovery */ 03003 { 03004 log_group_t* group; 03005 03006 #ifdef UNIV_SYNC_DEBUG 03007 ut_ad(mutex_own(&(log_sys->mutex))); 03008 #endif /* UNIV_SYNC_DEBUG */ 03009 log_sys->lsn = ut_dulint_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE); 03010 03011 group = UT_LIST_GET_FIRST(log_sys->log_groups); 03012 03013 while (group) { 03014 group->lsn = log_sys->lsn; 03015 group->lsn_offset = LOG_FILE_HDR_SIZE; 03016 #ifdef UNIV_LOG_ARCHIVE 03017 group->archived_file_no = arch_log_no; 03018 group->archived_offset = 0; 03019 #endif /* UNIV_LOG_ARCHIVE */ 03020 03021 if (!new_logs_created) { 03022 recv_truncate_group(group, group->lsn, group->lsn, 03023 group->lsn, group->lsn); 03024 } 03025 03026 group = UT_LIST_GET_NEXT(log_groups, group); 03027 } 03028 03029 log_sys->buf_next_to_write = 0; 03030 log_sys->written_to_some_lsn = log_sys->lsn; 03031 log_sys->written_to_all_lsn = log_sys->lsn; 03032 03033 log_sys->next_checkpoint_no = ut_dulint_zero; 03034 log_sys->last_checkpoint_lsn = ut_dulint_zero; 03035 03036 #ifdef UNIV_LOG_ARCHIVE 03037 log_sys->archived_lsn = log_sys->lsn; 03038 #endif /* UNIV_LOG_ARCHIVE */ 03039 03040 log_block_init(log_sys->buf, log_sys->lsn); 03041 log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE); 03042 03043 log_sys->buf_free = LOG_BLOCK_HDR_SIZE; 03044 log_sys->lsn = ut_dulint_add(log_sys->lsn, LOG_BLOCK_HDR_SIZE); 03045 03046 mutex_exit(&(log_sys->mutex)); 03047 03048 /* Reset the checkpoint fields in logs */ 03049 03050 log_make_checkpoint_at(ut_dulint_max, TRUE); 03051 log_make_checkpoint_at(ut_dulint_max, TRUE); 03052 03053 mutex_enter(&(log_sys->mutex)); 03054 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool recv_scan_log_recs | ( | ibool | apply_automatically, | |
| ulint | available_memory, | |||
| ibool | store_to_hash, | |||
| byte * | buf, | |||
| ulint | len, | |||
| dulint | start_lsn, | |||
| dulint * | contiguous_lsn, | |||
| dulint * | group_scanned_lsn | |||
| ) |
Definition at line 2320 of file log0recv.c.
References FALSE, yaSSL::finished, recv_sys_struct::found_corrupt_log, recv_sys_struct::heap, recv_sys_struct::len, log_block_calc_checksum(), log_block_checksum_is_ok_or_old_format(), log_block_convert_lsn_to_no(), log_block_get_checkpoint_no(), log_block_get_checksum(), log_block_get_data_len(), log_block_get_first_rec_group(), log_block_get_flush_bit(), log_block_get_hdr_no(), mem_heap_get_size(), OS_FILE_LOG_BLOCK_SIZE, recv_sys_struct::parse_start_lsn, recv_sys_struct::recovered_lsn, recv_sys_struct::recovered_offset, recv_apply_hashed_log_recs(), recv_is_from_backup, recv_is_making_a_backup, recv_needed_recovery, recv_parse_log_recs(), RECV_PARSING_BUF_SIZE, recv_scan_print_counter, recv_sys, recv_sys_add_to_parsing_buf(), recv_sys_justify_left_parsing_buf(), recv_sys_struct::scanned_checkpoint_no, recv_sys_struct::scanned_lsn, TRUE, ut_a, ut_ad, ut_dulint_add(), ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), ut_dulint_is_zero(), and ut_error.
Referenced by log_check_log_recs(), and recv_group_scan_log_recs().
02322 : TRUE if limit_lsn has been reached, or 02323 not able to scan any more in this log group */ 02324 ibool apply_automatically,/* in: TRUE if we want this function to 02325 apply log records automatically when the 02326 hash table becomes full; in the hot backup tool 02327 the tool does the applying, not this 02328 function */ 02329 ulint available_memory,/* in: we let the hash table of recs to grow 02330 to this size, at the maximum */ 02331 ibool store_to_hash, /* in: TRUE if the records should be stored 02332 to the hash table; this is set to FALSE if just 02333 debug checking is needed */ 02334 byte* buf, /* in: buffer containing a log segment or 02335 garbage */ 02336 ulint len, /* in: buffer length */ 02337 dulint start_lsn, /* in: buffer start lsn */ 02338 dulint* contiguous_lsn, /* in/out: it is known that all log groups 02339 contain contiguous log data up to this lsn */ 02340 dulint* group_scanned_lsn)/* out: scanning succeeded up to this lsn */ 02341 { 02342 byte* log_block; 02343 ulint no; 02344 dulint scanned_lsn; 02345 ibool finished; 02346 ulint data_len; 02347 ibool more_data; 02348 02349 ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); 02350 ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0); 02351 ut_ad(len > 0); 02352 ut_a(apply_automatically <= TRUE); 02353 ut_a(store_to_hash <= TRUE); 02354 02355 finished = FALSE; 02356 02357 log_block = buf; 02358 scanned_lsn = start_lsn; 02359 more_data = FALSE; 02360 02361 while (log_block < buf + len && !finished) { 02362 02363 no = log_block_get_hdr_no(log_block); 02364 /* 02365 fprintf(stderr, "Log block header no %lu\n", no); 02366 02367 fprintf(stderr, "Scanned lsn no %lu\n", 02368 log_block_convert_lsn_to_no(scanned_lsn)); 02369 */ 02370 if (no != log_block_convert_lsn_to_no(scanned_lsn) 02371 || !log_block_checksum_is_ok_or_old_format(log_block)) { 02372 02373 if (no == log_block_convert_lsn_to_no(scanned_lsn) 02374 && !log_block_checksum_is_ok_or_old_format( 02375 log_block)) { 02376 fprintf(stderr, 02377 "InnoDB: Log block no %lu at lsn %lu %lu has\n" 02378 "InnoDB: ok header, but checksum field contains %lu, should be %lu\n", 02379 (ulong) no, 02380 (ulong) ut_dulint_get_high(scanned_lsn), 02381 (ulong) ut_dulint_get_low(scanned_lsn), 02382 (ulong) log_block_get_checksum(log_block), 02383 (ulong) log_block_calc_checksum(log_block)); 02384 } 02385 02386 /* Garbage or an incompletely written log block */ 02387 02388 finished = TRUE; 02389 02390 break; 02391 } 02392 02393 if (log_block_get_flush_bit(log_block)) { 02394 /* This block was a start of a log flush operation: 02395 we know that the previous flush operation must have 02396 been completed for all log groups before this block 02397 can have been flushed to any of the groups. Therefore, 02398 we know that log data is contiguous up to scanned_lsn 02399 in all non-corrupt log groups. */ 02400 02401 if (ut_dulint_cmp(scanned_lsn, *contiguous_lsn) > 0) { 02402 *contiguous_lsn = scanned_lsn; 02403 } 02404 } 02405 02406 data_len = log_block_get_data_len(log_block); 02407 02408 if ((store_to_hash || (data_len == OS_FILE_LOG_BLOCK_SIZE)) 02409 && (ut_dulint_cmp(ut_dulint_add(scanned_lsn, data_len), 02410 recv_sys->scanned_lsn) > 0) 02411 && (recv_sys->scanned_checkpoint_no > 0) 02412 && (log_block_get_checkpoint_no(log_block) 02413 < recv_sys->scanned_checkpoint_no) 02414 && (recv_sys->scanned_checkpoint_no 02415 - log_block_get_checkpoint_no(log_block) 02416 > 0x80000000UL)) { 02417 02418 /* Garbage from a log buffer flush which was made 02419 before the most recent database recovery */ 02420 02421 finished = TRUE; 02422 #ifdef UNIV_LOG_DEBUG 02423 /* This is not really an error, but currently 02424 we stop here in the debug version: */ 02425 02426 ut_error; 02427 #endif 02428 break; 02429 } 02430 02431 if (ut_dulint_is_zero(recv_sys->parse_start_lsn) 02432 && (log_block_get_first_rec_group(log_block) > 0)) { 02433 02434 /* We found a point from which to start the parsing 02435 of log records */ 02436 02437 recv_sys->parse_start_lsn = 02438 ut_dulint_add(scanned_lsn, 02439 log_block_get_first_rec_group(log_block)); 02440 recv_sys->scanned_lsn = recv_sys->parse_start_lsn; 02441 recv_sys->recovered_lsn = recv_sys->parse_start_lsn; 02442 } 02443 02444 scanned_lsn = ut_dulint_add(scanned_lsn, data_len); 02445 02446 if (ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) > 0) { 02447 02448 /* We were able to find more log data: add it to the 02449 parsing buffer if parse_start_lsn is already 02450 non-zero */ 02451 02452 if (recv_sys->len + 4 * OS_FILE_LOG_BLOCK_SIZE 02453 >= RECV_PARSING_BUF_SIZE) { 02454 fprintf(stderr, 02455 "InnoDB: Error: log parsing buffer overflow. Recovery may have failed!\n"); 02456 02457 recv_sys->found_corrupt_log = TRUE; 02458 02459 } else if (!recv_sys->found_corrupt_log) { 02460 more_data = recv_sys_add_to_parsing_buf( 02461 log_block, scanned_lsn); 02462 } 02463 02464 recv_sys->scanned_lsn = scanned_lsn; 02465 recv_sys->scanned_checkpoint_no = 02466 log_block_get_checkpoint_no(log_block); 02467 } 02468 02469 if (data_len < OS_FILE_LOG_BLOCK_SIZE) { 02470 /* Log data for this group ends here */ 02471 02472 finished = TRUE; 02473 } else { 02474 log_block += OS_FILE_LOG_BLOCK_SIZE; 02475 } 02476 } 02477 02478 *group_scanned_lsn = scanned_lsn; 02479 02480 if (recv_needed_recovery 02481 || (recv_is_from_backup && !recv_is_making_a_backup)) { 02482 recv_scan_print_counter++; 02483 02484 if (finished || (recv_scan_print_counter % 80 == 0)) { 02485 02486 fprintf(stderr, 02487 "InnoDB: Doing recovery: scanned up to log sequence number %lu %lu\n", 02488 (ulong) ut_dulint_get_high(*group_scanned_lsn), 02489 (ulong) ut_dulint_get_low(*group_scanned_lsn)); 02490 } 02491 } 02492 02493 if (more_data && !recv_sys->found_corrupt_log) { 02494 /* Try to parse more log records */ 02495 02496 recv_parse_log_recs(store_to_hash); 02497 02498 if (store_to_hash && mem_heap_get_size(recv_sys->heap) 02499 > available_memory 02500 && apply_automatically) { 02501 02502 /* Hash table of log records has grown too big: 02503 empty it; FALSE means no ibuf operations 02504 allowed, as we cannot add new records to the 02505 log yet: they would be produced by ibuf 02506 operations */ 02507 02508 recv_apply_hashed_log_recs(FALSE); 02509 } 02510 02511 if (recv_sys->recovered_offset > RECV_PARSING_BUF_SIZE / 4) { 02512 /* Move parsing buffer data to the buffer start */ 02513 02514 recv_sys_justify_left_parsing_buf(); 02515 } 02516 } 02517 02518 return(finished); 02519 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void recv_scan_log_seg_for_backup | ( | byte * | buf, | |
| ulint | buf_len, | |||
| dulint * | scanned_lsn, | |||
| ulint * | scanned_checkpoint_no, | |||
| ulint * | n_bytes_scanned | |||
| ) |
Definition at line 661 of file log0recv.c.
References log_block_checksum_is_ok_or_old_format(), log_block_convert_lsn_to_no(), log_block_get_checkpoint_no(), log_block_get_data_len(), log_block_get_hdr_no(), OS_FILE_LOG_BLOCK_SIZE, and ut_dulint_add().
00663 : buffer containing log data */ 00664 ulint buf_len, /* in: data length in that buffer */ 00665 dulint* scanned_lsn, /* in/out: lsn of buffer start, 00666 we return scanned lsn */ 00667 ulint* scanned_checkpoint_no, 00668 /* in/out: 4 lowest bytes of the 00669 highest scanned checkpoint number so 00670 far */ 00671 ulint* n_bytes_scanned)/* out: how much we were able to 00672 scan, smaller than buf_len if log 00673 data ended here */ 00674 { 00675 ulint data_len; 00676 byte* log_block; 00677 ulint no; 00678 00679 *n_bytes_scanned = 0; 00680 00681 for (log_block = buf; log_block < buf + buf_len; 00682 log_block += OS_FILE_LOG_BLOCK_SIZE) { 00683 00684 no = log_block_get_hdr_no(log_block); 00685 00686 /* fprintf(stderr, "Log block header no %lu\n", no); */ 00687 00688 if (no != log_block_convert_lsn_to_no(*scanned_lsn) 00689 || !log_block_checksum_is_ok_or_old_format(log_block)) { 00690 /* 00691 fprintf(stderr, 00692 "Log block n:o %lu, scanned lsn n:o %lu\n", 00693 no, log_block_convert_lsn_to_no(*scanned_lsn)); 00694 */ 00695 /* Garbage or an incompletely written log block */ 00696 00697 log_block += OS_FILE_LOG_BLOCK_SIZE; 00698 /* 00699 fprintf(stderr, 00700 "Next log block n:o %lu\n", 00701 log_block_get_hdr_no(log_block)); 00702 */ 00703 break; 00704 } 00705 00706 if (*scanned_checkpoint_no > 0 00707 && log_block_get_checkpoint_no(log_block) 00708 < *scanned_checkpoint_no 00709 && *scanned_checkpoint_no 00710 - log_block_get_checkpoint_no(log_block) 00711 > 0x80000000UL) { 00712 00713 /* Garbage from a log buffer flush which was made 00714 before the most recent database recovery */ 00715 /* 00716 fprintf(stderr, 00717 "Scanned cp n:o %lu, block cp n:o %lu\n", 00718 *scanned_checkpoint_no, 00719 log_block_get_checkpoint_no(log_block)); 00720 */ 00721 break; 00722 } 00723 00724 data_len = log_block_get_data_len(log_block); 00725 00726 *scanned_checkpoint_no 00727 = log_block_get_checkpoint_no(log_block); 00728 *scanned_lsn = ut_dulint_add(*scanned_lsn, data_len); 00729 00730 *n_bytes_scanned += data_len; 00731 00732 if (data_len < OS_FILE_LOG_BLOCK_SIZE) { 00733 /* Log data ends here */ 00734 00735 /* fprintf(stderr, "Log block data len %lu\n", 00736 data_len); */ 00737 00738 break; 00739 } 00740 } 00741 }
Here is the call graph for this function:

| void recv_sys_create | ( | void | ) |
Definition at line 105 of file log0recv.c.
References recv_sys_struct::addr_hash, recv_sys_struct::heap, mem_alloc, recv_sys_struct::mutex, mutex_create, NULL, recv_sys, and SYNC_RECV.
Referenced by log_init(), and recv_recovery_from_checkpoint_start().
00107 { 00108 if (recv_sys != NULL) { 00109 00110 return; 00111 } 00112 00113 recv_sys = mem_alloc(sizeof(recv_sys_t)); 00114 00115 mutex_create(&recv_sys->mutex, SYNC_RECV); 00116 00117 recv_sys->heap = NULL; 00118 recv_sys->addr_hash = NULL; 00119 }
Here is the caller graph for this function:

| void recv_sys_init | ( | ibool | recover_from_backup, | |
| ulint | available_memory | |||
| ) |
Definition at line 125 of file log0recv.c.
References recv_sys_struct::addr_hash, recv_sys_struct::apply_batch_on, recv_sys_struct::apply_log_recs, recv_sys_struct::buf, FALSE, recv_sys_struct::found_corrupt_log, hash_create(), recv_sys_struct::heap, recv_sys_struct::last_block, recv_sys_struct::last_block_buf_start, recv_sys_struct::len, mem_alloc, mem_heap_create, mem_heap_create_in_buffer, recv_sys_struct::mutex, mutex_enter, mutex_exit(), recv_sys_struct::n_addrs, NULL, OS_FILE_LOG_BLOCK_SIZE, recv_sys_struct::recovered_offset, recv_is_from_backup, recv_max_page_lsn, RECV_PARSING_BUF_SIZE, recv_sys, TRUE, ut_align(), ut_dulint_zero, and ut_malloc().
Referenced by log_init(), and recv_recovery_from_checkpoint_start().
00127 : TRUE if this is called 00128 to recover from a hot backup */ 00129 ulint available_memory) /* in: available memory in bytes */ 00130 { 00131 if (recv_sys->heap != NULL) { 00132 00133 return; 00134 } 00135 00136 mutex_enter(&(recv_sys->mutex)); 00137 00138 if (!recover_from_backup) { 00139 recv_sys->heap = mem_heap_create_in_buffer(256); 00140 } else { 00141 recv_sys->heap = mem_heap_create(256); 00142 recv_is_from_backup = TRUE; 00143 } 00144 00145 recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE); 00146 recv_sys->len = 0; 00147 recv_sys->recovered_offset = 0; 00148 00149 recv_sys->addr_hash = hash_create(available_memory / 64); 00150 recv_sys->n_addrs = 0; 00151 00152 recv_sys->apply_log_recs = FALSE; 00153 recv_sys->apply_batch_on = FALSE; 00154 00155 recv_sys->last_block_buf_start = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE); 00156 00157 recv_sys->last_block = ut_align(recv_sys->last_block_buf_start, 00158 OS_FILE_LOG_BLOCK_SIZE); 00159 recv_sys->found_corrupt_log = FALSE; 00160 00161 recv_max_page_lsn = ut_dulint_zero; 00162 00163 mutex_exit(&(recv_sys->mutex)); 00164 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool recv_lsn_checks_on |
Definition at line 57 of file log0recv.c.
Referenced by buf_page_is_corrupted(), and recv_recovery_from_checkpoint_start().
Definition at line 86 of file log0recv.c.
Referenced by recv_parse_log_rec(), and recv_sys_empty_hash().
Definition at line 93 of file log0recv.c.
Referenced by buf_read_recv_pages(), log_check_log_recs(), and recv_group_scan_log_recs().
| ibool recv_needed_recovery |
Definition at line 55 of file log0recv.c.
Referenced by innobase_start_or_create_for_mysql(), recv_recovery_from_checkpoint_finish(), recv_recovery_from_checkpoint_start(), and recv_scan_log_recs().
| ibool recv_no_ibuf_operations |
Definition at line 69 of file log0recv.c.
Referenced by buf_page_io_complete(), fil_io(), ibuf_page(), log_write_up_to(), and recv_apply_hashed_log_recs().
| ibool recv_recovery_on |
Definition at line 52 of file log0recv.c.
Referenced by buf_LRU_buf_pool_running_out(), buf_LRU_get_free_block(), log_preflush_pool_modified_pages(), recv_recovery_from_checkpoint_finish(), and recv_recovery_from_checkpoint_start().
Definition at line 51 of file log0recv.c.
Referenced by log_check_log_recs(), log_init(), mlog_parse_nbytes(), mlog_parse_string(), page_cur_parse_insert_rec(), recv_add_to_hash_table(), recv_apply_hashed_log_recs(), recv_apply_log_recs_for_backup(), recv_get_fil_addr_struct(), recv_hash(), recv_parse_log_rec(), recv_parse_log_recs(), recv_parse_or_apply_log_rec_body(), recv_read_in_area(), recv_recover_page(), recv_recovery_from_checkpoint_finish(), recv_recovery_from_checkpoint_start(), recv_report_corrupt_log(), recv_scan_log_recs(), recv_synchronize_groups(), recv_sys_add_to_parsing_buf(), recv_sys_create(), recv_sys_empty_hash(), recv_sys_free(), recv_sys_init(), recv_sys_justify_left_parsing_buf(), and recv_truncate_group().
1.4.7

