30 #include "log0recv.ic"
46 #ifndef UNIV_HOTBACKUP
58 UNIV_INTERN ibool recv_replay_file_ops = TRUE;
63 #define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t))
66 #define RECV_READ_AHEAD_AREA 32
74 #ifdef UNIV_LOG_ARCHIVE
76 UNIV_INTERN ibool recv_recovery_from_backup_on;
79 #ifndef UNIV_HOTBACKUP
85 UNIV_INTERN ibool recv_no_log_write = FALSE;
101 static ibool recv_log_scan_is_startup_type;
114 # define recv_is_making_a_backup FALSE
116 # define recv_is_from_backup FALSE
118 # define recv_needed_recovery FALSE
123 # define buf_pool_get_curr_size() (5 * 1024 * 1024)
127 static ulint recv_scan_print_counter;
130 static ulint recv_previous_parsed_rec_type;
132 static ulint recv_previous_parsed_rec_offset;
134 static ulint recv_previous_parsed_rec_is_multi;
152 #ifdef UNIV_PFS_THREAD
153 UNIV_INTERN mysql_pfs_key_t trx_rollback_clean_thread_key;
156 #ifdef UNIV_PFS_MUTEX
157 UNIV_INTERN mysql_pfs_key_t recv_sys_mutex_key;
160 #ifndef UNIV_HOTBACKUP
161 # ifdef UNIV_PFS_THREAD
162 UNIV_INTERN mysql_pfs_key_t recv_writer_thread_key;
165 # ifdef UNIV_PFS_MUTEX
166 UNIV_INTERN mysql_pfs_key_t recv_writer_mutex_key;
171 UNIV_INTERN os_thread_t recv_writer_thread_handle = 0;
176 #ifndef UNIV_HOTBACKUP
182 recv_init_crash_recovery(
void);
200 mutex_create(recv_sys_mutex_key, &
recv_sys->
mutex, SYNC_RECV);
202 #ifndef UNIV_HOTBACKUP
235 #ifndef UNIV_HOTBACKUP
276 #ifndef UNIV_HOTBACKUP
290 #ifdef UNIV_LOG_ARCHIVE
291 recv_recovery_from_backup_on = FALSE;
298 recv_log_scan_is_startup_type = FALSE;
302 recv_scan_print_counter = 0;
304 recv_previous_parsed_rec_type = 999999;
306 recv_previous_parsed_rec_offset = 0;
308 recv_previous_parsed_rec_is_multi = 0;
321 extern "C" UNIV_INTERN
325 void* arg __attribute__((unused)))
331 #ifdef UNIV_PFS_THREAD
332 pfs_register_thread(recv_writer_thread_key);
335 #ifdef UNIV_DEBUG_THREAD_CREATION
336 fprintf(stderr,
"InnoDB: recv_writer thread running, id %lu\n",
366 OS_THREAD_DUMMY_RETURN;
376 ulint available_memory)
383 #ifndef UNIV_HOTBACKUP
393 MEM_HEAP_FOR_RECV_SYS);
432 recv_sys_empty_hash(
void)
439 "InnoDB: Error: %lu pages with log records"
440 " were left unprocessed!\n"
441 "InnoDB: Maximum page number with"
442 " log records on it %lu\n",
454 #ifndef UNIV_HOTBACKUP
455 # ifndef UNIV_LOG_DEBUG
460 recv_sys_debug_free(
void)
482 # ifdef UNIV_LOG_ARCHIVE
494 lsn_t checkpoint_lsn,
505 if (archived_lsn == LSN_MAX) {
507 archived_lsn = checkpoint_lsn;
518 if (limit_lsn != LSN_MAX) {
522 finish_lsn = finish_lsn1;
525 finish_lsn = finish_lsn1 < finish_lsn2
526 ? finish_lsn1 : finish_lsn2;
529 ut_a(RECV_SCAN_SIZE <= log_sys->buf_size);
536 if (start_lsn != recovered_lsn) {
539 lsn_t diff = recovered_lsn - start_lsn;
541 ut_a(diff <= 0xFFFFUL);
548 if (start_lsn >= finish_lsn) {
558 if (end_lsn > finish_lsn) {
560 end_lsn = finish_lsn;
563 len = (ulint) (end_lsn - start_lsn);
566 if (end_lsn >= finish_lsn) {
571 memset(log_sys->
buf, 0, RECV_SCAN_SIZE);
599 ut_a(RECV_SCAN_SIZE <= log_sys->buf_size);
608 if (end_lsn > recovered_lsn) {
614 up_to_date_group, start_lsn, end_lsn);
616 len = (ulint) (end_lsn - start_lsn);
620 if (end_lsn >= recovered_lsn) {
637 recv_synchronize_groups(
639 #ifdef UNIV_LOG_ARCHIVE
658 ut_a(start_lsn != end_lsn);
661 #ifdef UNIV_LOG_ARCHIVE
671 #ifdef UNIV_LOG_ARCHIVE
672 if (group != up_to_date_group) {
676 recv_copy_group(group, up_to_date_group,
693 mutex_exit(&(log_sys->
mutex));
699 mutex_enter(&(log_sys->
mutex));
708 recv_check_cp_is_consistent(
717 buf + LOG_CHECKPOINT_CHECKSUM_1)) {
722 LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
725 buf + LOG_CHECKPOINT_CHECKSUM_2)) {
732 #ifndef UNIV_HOTBACKUP
736 static __attribute__((nonnull, warn_unused_result))
738 recv_find_max_checkpoint(
746 ib_uint64_t checkpoint_no;
759 group->
state = LOG_GROUP_CORRUPTED;
761 for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
762 field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
766 if (!recv_check_cp_is_consistent(buf)) {
768 if (log_debug_writes) {
770 "InnoDB: Checkpoint in group"
771 " %lu at %lu invalid, %lu\n",
776 + LOG_CHECKPOINT_CHECKSUM_1));
783 group->
state = LOG_GROUP_OK;
786 buf + LOG_CHECKPOINT_LSN);
788 buf + LOG_CHECKPOINT_OFFSET_LOW32);
790 buf + LOG_CHECKPOINT_OFFSET_HIGH32)) << 32;
792 buf + LOG_CHECKPOINT_NO);
795 if (log_debug_writes) {
797 "InnoDB: Checkpoint number %lu"
798 " found in group %lu\n",
799 (ulong) checkpoint_no,
804 if (checkpoint_no >= max_no) {
807 max_no = checkpoint_no;
817 if (*max_group == NULL) {
820 "InnoDB: No valid checkpoint found.\n"
821 "InnoDB: If this error appears when you are"
822 " creating an InnoDB database,\n"
823 "InnoDB: the problem may be that during"
824 " an earlier attempt you managed\n"
825 "InnoDB: to create the InnoDB data files,"
826 " but log file creation failed.\n"
827 "InnoDB: If that is the case, please refer to\n"
828 "InnoDB: " REFMAN
"error-creating-innodb.html\n");
840 recv_read_checkpoint_info_for_backup(
847 lsn_t* first_header_lsn)
852 ib_uint64_t max_cp_no = 0;
855 cp_buf = hdr + LOG_CHECKPOINT_1;
857 if (recv_check_cp_is_consistent(cp_buf)) {
859 max_cp = LOG_CHECKPOINT_1;
862 cp_buf = hdr + LOG_CHECKPOINT_2;
864 if (recv_check_cp_is_consistent(cp_buf)) {
866 max_cp = LOG_CHECKPOINT_2;
874 cp_buf = hdr + max_cp;
878 cp_buf + LOG_CHECKPOINT_OFFSET_LOW32);
880 cp_buf + LOG_CHECKPOINT_OFFSET_HIGH32)) << 32;
898 log_block_checksum_is_ok_or_old_format(
902 #ifdef UNIV_LOG_DEBUG
916 "InnoDB: Scanned old format < InnoDB-3.23.52"
917 " log block number %lu\n",
926 #ifdef UNIV_HOTBACKUP
932 recv_scan_log_seg_for_backup(
938 ulint* scanned_checkpoint_no,
942 ulint* n_bytes_scanned)
950 *n_bytes_scanned = 0;
952 for (log_block = buf; log_block < buf + buf_len;
958 fprintf(stderr,
"Log block header no %lu\n", no);
962 || !log_block_checksum_is_ok_or_old_format(log_block)) {
965 "Log block n:o %lu, scanned lsn n:o %lu\n",
973 "Next log block n:o %lu\n",
979 if (*scanned_checkpoint_no > 0
981 < *scanned_checkpoint_no
982 && *scanned_checkpoint_no
990 "Scanned cp n:o %lu, block cp n:o %lu\n",
991 *scanned_checkpoint_no,
999 *scanned_checkpoint_no
1001 *scanned_lsn += data_len;
1003 *n_bytes_scanned += data_len;
1009 fprintf(stderr,
"Log block data len %lu\n",
1024 recv_parse_or_apply_log_rec_body(
1046 ut_ad(!block == !mtr);
1049 page = block->
frame;
1059 #ifdef UNIV_LOG_LSN_DEBUG
1067 && end_ptr >= ptr + 2) {
1087 || offs == IBUF_TREE_SEG_HEADER
1088 + IBUF_HEADER + FSEG_HDR_OFFSET
1089 || offs == PAGE_BTR_IBUF_FREE_LIST
1090 + PAGE_HEADER + FIL_ADDR_BYTE
1091 || offs == PAGE_BTR_IBUF_FREE_LIST
1092 + PAGE_HEADER + FIL_ADDR_BYTE
1094 || offs == PAGE_BTR_SEG_LEAF
1095 + PAGE_HEADER + FSEG_HDR_OFFSET
1096 || offs == PAGE_BTR_SEG_TOP
1097 + PAGE_HEADER + FSEG_HDR_OFFSET
1098 || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
1099 + PAGE_HEADER + FIL_ADDR_BYTE
1101 || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
1102 + PAGE_HEADER + FIL_ADDR_BYTE
1110 || offs == IBUF_TREE_SEG_HEADER
1111 + IBUF_HEADER + FSEG_HDR_SPACE
1112 || offs == IBUF_TREE_SEG_HEADER
1113 + IBUF_HEADER + FSEG_HDR_PAGE_NO
1114 || offs == PAGE_BTR_IBUF_FREE_LIST
1116 || offs == PAGE_BTR_IBUF_FREE_LIST
1117 + PAGE_HEADER + FIL_ADDR_PAGE
1118 || offs == PAGE_BTR_IBUF_FREE_LIST
1119 + PAGE_HEADER + FIL_ADDR_PAGE
1121 || offs == PAGE_BTR_SEG_LEAF
1122 + PAGE_HEADER + FSEG_HDR_PAGE_NO
1123 || offs == PAGE_BTR_SEG_LEAF
1124 + PAGE_HEADER + FSEG_HDR_SPACE
1125 || offs == PAGE_BTR_SEG_TOP
1126 + PAGE_HEADER + FSEG_HDR_PAGE_NO
1127 || offs == PAGE_BTR_SEG_TOP
1128 + PAGE_HEADER + FSEG_HDR_SPACE
1129 || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
1130 + PAGE_HEADER + FIL_ADDR_PAGE
1132 || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
1133 + PAGE_HEADER + FIL_ADDR_PAGE
1166 ptr, end_ptr, page, page_zip, index);
1226 ptr, end_ptr, block, index, mtr);
1242 ptr, end_ptr, index,
1344 ptr, end_ptr, TRUE, &index))) {
1349 ptr, end_ptr, page, page_zip, index);
1400 recv_get_fil_addr_struct(
1407 for (recv_addr = static_cast<recv_addr_t*>(
1414 if (recv_addr->
space == space
1415 && recv_addr->
page_no == page_no) {
1428 recv_add_to_hash_table(
1451 len = rec_end - body;
1453 recv =
static_cast<recv_t*
>(
1457 recv->
len = rec_end - body;
1461 recv_addr = recv_get_fil_addr_struct(space, page_no);
1463 if (recv_addr == NULL) {
1477 fprintf(stderr,
"Inserting log rec for space %lu, page %lu\n",
1484 prev_field = &(recv->
data);
1490 while (rec_end > body) {
1492 len = rec_end - body;
1502 *prev_field = recv_data;
1504 memcpy(recv_data + 1, body, len);
1506 prev_field = &(recv_data->
next);
1518 recv_data_copy_to_buf(
1528 recv_data = recv->
data;
1542 recv_data = recv_data->
next;
1554 #ifndef UNIV_HOTBACKUP
1569 lsn_t page_newest_lsn;
1570 ibool modification_to_page;
1571 #ifndef UNIV_HOTBACKUP
1590 if ((recv_addr == NULL)
1600 fprintf(stderr,
"Recovering space %lu, page %lu\n",
1611 page = block->frame;
1614 #ifndef UNIV_HOTBACKUP
1630 buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
1636 #ifndef UNIV_HOTBACKUP
1642 if (page_newest_lsn) {
1644 page_lsn = page_newest_lsn;
1648 page_newest_lsn = 0;
1651 modification_to_page = FALSE;
1652 start_lsn = end_lsn = 0;
1663 buf =
static_cast<byte*
>(mem_alloc(recv->
len));
1665 recv_data_copy_to_buf(buf, recv);
1671 page_lsn = page_newest_lsn;
1686 if (!modification_to_page) {
1688 modification_to_page = TRUE;
1692 DBUG_PRINT(
"ib_log",
1693 (
"apply " DBUG_LSN_PF
": %u len %u "
1695 (
unsigned) recv->
type,
1696 (
unsigned) recv->
len,
1697 (
unsigned) recv_addr->
space,
1698 (
unsigned) recv_addr->
page_no));
1700 recv_parse_or_apply_log_rec_body(recv->
type, buf,
1713 + page_zip->
data, end_lsn);
1724 #ifdef UNIV_ZIP_DEBUG
1729 || page_zip_validate_low(page_zip, page, NULL, FALSE));
1733 #ifndef UNIV_HOTBACKUP
1734 if (modification_to_page) {
1765 #ifndef UNIV_HOTBACKUP
1789 recv_addr = recv_get_fil_addr_struct(space, page_no);
1798 page_nos[
n] = page_no;
1833 ibool has_printed = FALSE;
1847 ut_ad(!allow_ibuf == mutex_own(&log_sys->
mutex));
1858 for (recv_addr = static_cast<recv_addr_t*>(
1864 ulint space = recv_addr->
space;
1866 ulint page_no = recv_addr->
page_no;
1871 "Starting an apply batch"
1873 " to the database...");
1874 fputs(
"InnoDB: Progress in percent: ",
1887 space, zip_size, page_no,
1889 buf_block_dbg_add_level(
1890 block, SYNC_NO_ORDER_CHECK);
1895 recv_read_in_area(space, zip_size,
1908 fprintf(stderr,
"%lu ", (ulong)
1927 fprintf(stderr,
"\n");
1936 ut_d(recv_no_log_write = TRUE);
1938 mutex_exit(&(log_sys->
mutex));
1958 mutex_enter(&(log_sys->
mutex));
1960 ut_d(recv_no_log_write = FALSE);
1968 recv_sys_empty_hash();
1971 fprintf(stderr,
"InnoDB: Apply batch completed\n");
1981 recv_apply_log_recs_for_backup(
void)
1995 block = back_block1;
1998 "Starting an apply batch of log records to the database...");
2000 fputs(
"InnoDB: Progress in percent: ", stderr);
2004 for (i = 0; i < n_hash_cells; i++) {
2008 while (recv_addr != NULL) {
2013 if (zip_size == ULINT_UNDEFINED) {
2016 "InnoDB: Warning: cannot apply"
2018 " tablespace %lu page %lu,\n"
2019 "InnoDB: because tablespace with"
2020 " that id does not exist.\n",
2028 goto skip_this_recv_addr;
2035 buf_page_init_for_backup_restore(
2049 "InnoDB: Fatal error: cannot extend"
2050 " tablespace %u to hold %u pages\n",
2061 recv_addr->
space, zip_size,
2062 recv_addr->
page_no, 0, zip_size,
2064 if (error == DB_SUCCESS
2070 recv_addr->
space, 0,
2073 block->
frame, NULL);
2076 if (error != DB_SUCCESS) {
2078 "InnoDB: Fatal error: cannot read"
2080 " %lu page number %lu\n",
2081 (ulong) recv_addr->
space,
2098 error =
fil_io(OS_FILE_WRITE,
true,
2099 recv_addr->
space, zip_size,
2104 error =
fil_io(OS_FILE_WRITE,
true,
2105 recv_addr->
space, 0,
2108 block->
frame, NULL);
2110 skip_this_recv_addr:
2114 if ((100 * i) / n_hash_cells
2115 != (100 * (i + 1)) / n_hash_cells) {
2116 fprintf(stderr,
"%lu ",
2117 (ulong) ((100 * i) / n_hash_cells));
2122 recv_sys_empty_hash();
2144 if (ptr == end_ptr) {
2159 *space = ULINT_UNDEFINED - 1;
2168 if (UNIV_UNLIKELY(!new_ptr)) {
2173 #ifdef UNIV_LOG_LSN_DEBUG
2174 if (*type == MLOG_LSN) {
2175 lsn_t lsn = (lsn_t) *space << 32 | *page_no;
2176 # ifdef UNIV_LOG_DEBUG
2177 ut_a(lsn == log_sys->old_lsn);
2184 new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
2185 NULL, NULL, *space);
2186 if (UNIV_UNLIKELY(new_ptr == NULL)) {
2195 return(new_ptr - ptr);
2202 recv_calc_lsn_on_data_add(
2209 ib_uint64_t lsn_len;
2213 - LOG_BLOCK_TRL_SIZE);
2215 lsn_len += (lsn_len + frag_len)
2217 - LOG_BLOCK_TRL_SIZE)
2218 * (LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE);
2220 return(lsn + lsn_len);
2223 #ifdef UNIV_LOG_DEBUG
2229 recv_check_incomplete_log_recs(
2240 for (i = 0; i < len; i++) {
2241 ut_a(0 == recv_parse_log_rec(ptr, ptr + i, &type, &space,
2251 recv_report_corrupt_log(
2259 "InnoDB: ############### CORRUPT LOG RECORD FOUND\n"
2260 "InnoDB: Log record type %lu, space id %lu, page number %lu\n"
2261 "InnoDB: Log parsing proceeded successfully up to " LSN_PF
"\n"
2262 "InnoDB: Previous log record type %lu, is multi %lu\n"
2263 "InnoDB: Recv offset %lu, prev %lu\n",
2264 (ulong) type, (ulong) space, (ulong) page_no,
2266 (ulong) recv_previous_parsed_rec_type,
2267 (ulong) recv_previous_parsed_rec_is_multi,
2269 (ulong) recv_previous_parsed_rec_offset);
2272 > recv_previous_parsed_rec_offset
2274 - recv_previous_parsed_rec_offset)
2276 fputs(
"InnoDB: Hex dump of corrupt log starting"
2277 " 100 bytes before the start\n"
2278 "InnoDB: of the previous log rec,\n"
2279 "InnoDB: and ending 100 bytes after the start"
2280 " of the corrupt rec:\n",
2285 + recv_previous_parsed_rec_offset - 100,
2287 - recv_previous_parsed_rec_offset);
2291 #ifndef UNIV_HOTBACKUP
2293 fputs(
"InnoDB: Set innodb_force_recovery"
2294 " to ignore this error.\n", stderr);
2299 fputs(
"InnoDB: WARNING: the log file may have been corrupt and it\n"
2300 "InnoDB: is possible that the log scan did not proceed\n"
2301 "InnoDB: far enough in recovery! Please run CHECK TABLE\n"
2302 "InnoDB: on your InnoDB tables to check that they are ok!\n"
2303 "InnoDB: If mysqld crashes after this recovery, look at\n"
2304 "InnoDB: " REFMAN
"forcing-innodb-recovery.html\n"
2305 "InnoDB: about forcing recovery.\n", stderr);
2316 recv_parse_log_recs(
2318 ibool store_to_hash)
2327 lsn_t new_recovered_lsn;
2342 if (ptr == end_ptr) {
2357 len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
2363 recv_report_corrupt_log(ptr,
2364 type, space, page_no);
2370 new_recovered_lsn = recv_calc_lsn_on_data_add(old_lsn, len);
2380 recv_previous_parsed_rec_type = (ulint) type;
2382 recv_previous_parsed_rec_is_multi = 0;
2387 DBUG_PRINT(
"ib_log",
2388 (
"scan " DBUG_LSN_PF
": log rec %u len %u "
2389 "page %u:%u", old_lsn,
2390 (
unsigned) type, (
unsigned) len,
2391 (
unsigned) space, (
unsigned) page_no));
2396 }
else if (!store_to_hash) {
2400 #ifdef UNIV_LOG_DEBUG
2401 recv_check_incomplete_log_recs(ptr, len);
2409 #ifdef UNIV_HOTBACKUP
2410 if (recv_replay_file_ops) {
2418 body, end_ptr, type,
2421 "InnoDB: Error: file op"
2422 " log record of type %lu"
2423 " space %lu not complete in\n"
2424 "InnoDB: the replay phase."
2426 (ulint) type, space,
2435 #ifdef UNIV_LOG_LSN_DEBUG
2436 }
else if (type == MLOG_LSN) {
2442 recv_add_to_hash_table(type, space, page_no, body,
2454 len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
2460 recv_report_corrupt_log(
2461 ptr, type, space, page_no);
2467 recv_previous_parsed_rec_type = (ulint) type;
2468 recv_previous_parsed_rec_offset
2470 recv_previous_parsed_rec_is_multi = 1;
2472 #ifdef UNIV_LOG_DEBUG
2474 recv_check_incomplete_log_recs(ptr, len);
2478 DBUG_PRINT(
"ib_log",
2479 (
"scan " DBUG_LSN_PF
": multi-log rec %u "
2480 "len %u page %u:%u",
2482 (
unsigned) type, (
unsigned) len,
2483 (
unsigned) space, (
unsigned) page_no));
2498 new_recovered_lsn = recv_calc_lsn_on_data_add(
2515 len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
2519 recv_report_corrupt_log(ptr,
2520 type, space, page_no);
2528 = recv_calc_lsn_on_data_add(old_lsn, len);
2537 #ifdef UNIV_LOG_LSN_DEBUG
2541 recv_add_to_hash_table(type, space, page_no,
2560 recv_sys_add_to_parsing_buf(
2562 const byte* log_block,
2596 if (more_len == 0) {
2601 ut_ad(data_len >= more_len);
2603 start_offset = data_len - more_len;
2605 if (start_offset < LOG_BLOCK_HDR_SIZE) {
2606 start_offset = LOG_BLOCK_HDR_SIZE;
2609 end_offset = data_len;
2615 ut_ad(start_offset <= end_offset);
2617 if (start_offset < end_offset) {
2619 log_block + start_offset, end_offset - start_offset);
2633 recv_sys_justify_left_parsing_buf(
void)
2655 ulint available_memory,
2657 ibool store_to_hash,
2665 lsn_t* contiguous_lsn,
2668 lsn_t* group_scanned_lsn)
2671 const byte* log_block;
2681 ut_a(store_to_hash <= TRUE);
2686 scanned_lsn = start_lsn;
2698 || !log_block_checksum_is_ok_or_old_format(log_block)) {
2701 && !log_block_checksum_is_ok_or_old_format(
2704 "InnoDB: Log block no %lu at"
2705 " lsn " LSN_PF
" has\n"
2706 "InnoDB: ok header, but checksum field"
2707 " contains %lu, should be %lu\n",
2731 if (scanned_lsn > *contiguous_lsn) {
2732 *contiguous_lsn = scanned_lsn;
2751 #ifdef UNIV_LOG_DEBUG
2772 scanned_lsn += data_len;
2780 #ifndef UNIV_HOTBACKUP
2781 if (recv_log_scan_is_startup_type
2786 "Log scan progressed past the "
2787 "checkpoint lsn " LSN_PF
"",
2790 recv_init_crash_recovery();
2794 "Recovery skipped, "
2795 "--innodb-read-only set!");
2809 "InnoDB: Error: log parsing"
2811 " Recovery may have failed!\n");
2815 #ifndef UNIV_HOTBACKUP
2818 " innodb_force_recovery"
2819 " to ignore this error.\n",
2826 more_data = recv_sys_add_to_parsing_buf(
2827 log_block, scanned_lsn);
2843 }
while (log_block < buf + len && !finished);
2845 *group_scanned_lsn = scanned_lsn;
2849 recv_scan_print_counter++;
2851 if (finished || (recv_scan_print_counter % 80 == 0)) {
2854 "InnoDB: Doing recovery: scanned up to"
2855 " log sequence number " LSN_PF
"\n",
2856 *group_scanned_lsn);
2863 recv_parse_log_recs(store_to_hash);
2865 #ifndef UNIV_HOTBACKUP
2882 recv_sys_justify_left_parsing_buf();
2889 #ifndef UNIV_HOTBACKUP
2895 recv_group_scan_log_recs(
2898 lsn_t* contiguous_lsn,
2901 lsn_t* group_scanned_lsn)
2910 start_lsn = *contiguous_lsn;
2916 group, start_lsn, end_lsn);
2922 TRUE, log_sys->
buf, RECV_SCAN_SIZE,
2923 start_lsn, contiguous_lsn, group_scanned_lsn);
2924 start_lsn = end_lsn;
2928 if (log_debug_writes) {
2930 "InnoDB: Scanned group %lu up to"
2931 " log sequence number " LSN_PF
"\n",
2933 *group_scanned_lsn);
2943 recv_init_crash_recovery(
void)
2951 ib_logf(IB_LOG_LEVEL_INFO,
"Database was not shutdown normally!");
2952 ib_logf(IB_LOG_LEVEL_INFO,
"Starting crash recovery.");
2954 "Reading tablespace information from the .ibd files...");
2966 "Restoring possible half-written data pages ");
2969 "from the doublewrite buffer...");
2975 recv_writer_thread_handle = os_thread_create(
2990 #ifdef UNIV_LOG_ARCHIVE
2994 lsn_t min_flushed_lsn,
2995 lsn_t max_flushed_lsn)
3000 lsn_t checkpoint_lsn;
3001 ib_uint64_t checkpoint_no;
3002 lsn_t group_scanned_lsn = 0;
3003 lsn_t contiguous_lsn;
3004 #ifdef UNIV_LOG_ARCHIVE
3009 byte log_hdr_buf[LOG_FILE_HDR_SIZE];
3012 #ifdef UNIV_LOG_ARCHIVE
3013 ut_ad(type != LOG_CHECKPOINT || limit_lsn == LSN_MAX);
3015 # define TYPE_CHECKPOINT (type == LOG_CHECKPOINT)
3017 # define LIMIT_LSN limit_lsn
3020 # define TYPE_CHECKPOINT 1
3022 # define LIMIT_LSN LSN_MAX
3025 if (TYPE_CHECKPOINT) {
3033 "The user has set SRV_FORCE_NO_LOG_REDO on, "
3034 "skipping log redo");
3043 mutex_enter(&(log_sys->
mutex));
3047 err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
3049 if (err != DB_SUCCESS) {
3051 mutex_exit(&(log_sys->
mutex));
3062 #ifdef UNIV_LOG_ARCHIVE
3070 0, 0, LOG_FILE_HDR_SIZE,
3071 log_hdr_buf, max_cp_group);
3073 if (0 ==
ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3074 (byte*)
"ibbackup", (
sizeof "ibbackup") - 1)) {
3079 "Cannot restore from ibbackup, InnoDB running "
3080 "in read-only mode!");
3089 "The log file was created by ibbackup --apply-log "
3090 "at %s. The following crash recovery is part of a "
3092 log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP);
3096 memset(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3099 fil_io(OS_FILE_WRITE | OS_FILE_LOG,
true,
3102 log_hdr_buf, max_cp_group);
3105 #ifdef UNIV_LOG_ARCHIVE
3110 &(group->archived_file_no),
3111 &(group->archived_offset));
3117 if (TYPE_CHECKPOINT) {
3132 #ifdef UNIV_LOG_ARCHIVE
3133 if (TYPE_CHECKPOINT) {
3134 up_to_date_group = max_cp_group;
3147 mutex_exit(&(log_sys->
mutex));
3155 recv_group_scan_log_recs(group, &contiguous_lsn,
3156 &group_scanned_lsn);
3159 mutex_exit(&(log_sys->
mutex));
3169 up_to_date_group =
group;
3173 ut_ad(RECV_SCAN_SIZE <= log_sys->buf_size);
3177 #ifdef UNIV_LOG_ARCHIVE
3178 if ((type == LOG_ARCHIVE) && (group ==
recv_sys->archive_group)) {
3184 recv_log_scan_is_startup_type = TYPE_CHECKPOINT;
3186 #ifdef UNIV_LOG_ARCHIVE
3190 recv_group_scan_log_recs(group, &contiguous_lsn,
3191 &group_scanned_lsn);
3194 #ifdef UNIV_LOG_ARCHIVE
3195 if (old_scanned_lsn < group_scanned_lsn) {
3198 up_to_date_group =
group;
3201 if ((type == LOG_ARCHIVE)
3202 && (group ==
recv_sys->archive_group)) {
3211 recv_log_scan_is_startup_type = FALSE;
3212 if (TYPE_CHECKPOINT) {
3217 if (checkpoint_lsn != max_flushed_lsn
3218 || checkpoint_lsn != min_flushed_lsn) {
3220 if (checkpoint_lsn < max_flushed_lsn) {
3223 "The log sequence number "
3224 "in the ibdata files is higher "
3225 "than the log sequence number "
3226 "in the ib_logfiles! Are you sure "
3227 "you are using the right "
3228 "ib_logfiles to start up the database. "
3229 "Log sequence number in the "
3230 "ib_logfiles is " LSN_PF
", log"
3231 "sequence numbers stamped "
3232 "to ibdata file headers are between "
3233 "" LSN_PF
" and " LSN_PF
".",
3241 "The log sequence numbers "
3242 LSN_PF
" and " LSN_PF
3243 " in ibdata files do not match"
3244 " the log sequence number "
3246 " in the ib_logfiles!",
3252 recv_init_crash_recovery();
3255 "Can't initiate database "
3256 "recovery, running "
3257 "in read-only-mode.");
3270 if (group_scanned_lsn < checkpoint_lsn
3273 "We scanned the log up to "
3274 LSN_PF
". A checkpoint was at " LSN_PF
3275 " and the maximum LSN on a database page was " LSN_PF
3276 ". It is possible that the database is now corrupt!",
3282 mutex_exit(&(log_sys->
mutex));
3303 #ifdef UNIV_LOG_ARCHIVE
3304 log_sys->archived_lsn = archived_lsn;
3306 recv_synchronize_groups(up_to_date_group);
3308 recv_synchronize_groups();
3333 #ifdef UNIV_LOG_ARCHIVE
3334 if (archived_lsn == LSN_MAX) {
3336 log_sys->archiving_state = LOG_ARCH_OFF;
3346 mutex_exit(&log_sys->
mutex);
3356 #undef TYPE_CHECKPOINT
3374 DBUG_PRINT(
"ib_log", (
"apply completed"));
3384 "InnoDB: WARNING: the log file may have been"
3386 "InnoDB: is possible that the log scan or parsing"
3387 " did not proceed\n"
3388 "InnoDB: far enough in recovery. Please run"
3390 "InnoDB: on your InnoDB tables to check that"
3392 "InnoDB: It may be safest to recover your"
3393 " InnoDB database from\n"
3394 "InnoDB: a backup!\n");
3417 if (srv_print_verbose_log && count > 600) {
3419 "Waiting for recv_writer to "
3420 "finish flushing of buffer pool");
3426 if (recv_writer_thread_handle) {
3427 CloseHandle(recv_writer_thread_handle);
3431 #ifndef UNIV_LOG_DEBUG
3432 recv_sys_debug_free();
3450 #ifdef UNIV_SYNC_DEBUG
3458 sync_order_checks_on = TRUE;
3490 #ifdef UNIV_LOG_ARCHIVE
3492 ibool new_logs_created,
3512 group->
lsn = log_sys->
lsn;
3514 #ifdef UNIV_LOG_ARCHIVE
3515 group->archived_file_no = arch_log_no;
3516 group->archived_offset = 0;
3518 if (!new_logs_created) {
3519 recv_truncate_group(group, group->
lsn, group->
lsn,
3534 #ifdef UNIV_LOG_ARCHIVE
3535 log_sys->archived_lsn = log_sys->
lsn;
3541 log_sys->
buf_free = LOG_BLOCK_HDR_SIZE;
3542 log_sys->
lsn += LOG_BLOCK_HDR_SIZE;
3547 mutex_exit(&(log_sys->
mutex));
3553 mutex_enter(&(log_sys->
mutex));
3557 #ifdef UNIV_HOTBACKUP
3562 recv_reset_log_files_for_backup(
3564 const char* log_dir,
3566 lsn_t log_file_size,
3576 static const char ib_logfile_basename[] =
"ib_logfile";
3578 log_dir_len = strlen(log_dir);
3582 ut_a(log_dir_len + strlen(ib_logfile_basename) + 11 <
sizeof(name));
3587 for (i = 0; i < n_log_files; i++) {
3589 sprintf(name,
"%s%s%lu", log_dir,
3590 ib_logfile_basename, (ulong) i);
3592 log_file = os_file_create_simple(innodb_file_log_key,
3598 "InnoDB: Cannot create %s. Check that"
3599 " the file does not exist yet.\n", name);
3605 "Setting log file size to %llu\n",
3612 "InnoDB: Cannot set %s size to %llu\n",
3613 name, log_file_size);
3617 os_file_flush(log_file);
3618 os_file_close(log_file);
3623 log_reset_first_header_and_checkpoint(buf, lsn);
3627 LOG_BLOCK_HDR_SIZE);
3628 sprintf(name,
"%s%s%lu", log_dir, ib_logfile_basename, (ulong)0);
3630 log_file = os_file_create_simple(innodb_file_log_key,
3632 OS_FILE_READ_WRITE, &success);
3634 fprintf(stderr,
"InnoDB: Cannot open %s.\n", name);
3639 os_file_write(name, log_file, buf, 0,
3641 os_file_flush(log_file);
3642 os_file_close(log_file);
3648 #ifdef UNIV_LOG_ARCHIVE
3655 log_group_recover_from_archive_file(
3660 ib_uint64_t start_lsn;
3661 ib_uint64_t file_end_lsn;
3662 ib_uint64_t dummy_lsn;
3663 ib_uint64_t scanned_lsn;
3681 file_handle = os_file_create(innodb_file_log_key,
3683 OS_FILE_LOG, OS_FILE_AIO, &ret);
3688 "InnoDB: Do you want to copy additional"
3689 " archived log files\n"
3690 "InnoDB: to the directory\n");
3692 "InnoDB: or were these all the files needed"
3695 "InnoDB: (Y == copy more files; N == this is all)?");
3697 input_char = getchar();
3699 if (input_char == (
int)
'N') {
3702 }
else if (input_char == (
int)
'Y') {
3704 goto try_open_again;
3713 fprintf(stderr,
"InnoDB: Opened archived log file %s\n", name);
3715 ret = os_file_close(file_handle);
3717 if (file_size < LOG_FILE_HDR_SIZE) {
3719 "InnoDB: Archive file header incomplete %s\n", name);
3729 group->archive_space_id, FALSE);
3730 #if RECV_SCAN_SIZE < LOG_FILE_HDR_SIZE
3731 # error "RECV_SCAN_SIZE < LOG_FILE_HDR_SIZE"
3736 LOG_FILE_HDR_SIZE, buf, NULL);
3742 != group->archived_file_no) {
3744 "InnoDB: Archive file header inconsistent %s\n", name);
3751 "InnoDB: Archive file not completely written %s\n",
3764 "InnoDB: Archive log file %s"
3765 " starts from too big a lsn\n",
3776 "InnoDB: Archive log file %s starts from"
3782 read_offset = LOG_FILE_HDR_SIZE;
3787 if (read_offset + len > file_size) {
3798 if (log_debug_writes) {
3800 "InnoDB: Archive read starting at"
3801 " lsn %llu, len %lu from file %s\n",
3808 group->archive_space_id, read_offset / UNIV_PAGE_SIZE,
3809 read_offset % UNIV_PAGE_SIZE, len, buf, NULL);
3814 * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
3815 &dummy_lsn, &scanned_lsn);
3817 if (scanned_lsn == file_end_lsn) {
3824 "InnoDB: Archive log file %s"
3825 " does not scan right\n",
3833 ut_ad(start_lsn == scanned_lsn);
3844 recv_recovery_from_archive_start(
3846 ib_uint64_t min_flushed_lsn,
3848 ib_uint64_t limit_lsn,
3868 recv_recovery_from_backup_on = TRUE;
3877 if (group->
id == group_id) {
3887 "InnoDB: There is no log group defined with id %lu!\n",
3892 group->archived_file_no = first_log_no;
3904 mutex_enter(&(log_sys->
mutex));
3907 ret = log_group_recover_from_archive_file(group);
3912 trunc_len = UNIV_PAGE_SIZE
3914 if (trunc_len > 0) {
3915 fil_space_truncate_start(group->archive_space_id,
3919 group->archived_file_no++;
3929 mutex_exit(&(log_sys->
mutex));
3935 if (err != DB_SUCCESS) {
3940 mutex_enter(&(log_sys->
mutex));
3943 if (limit_lsn != LSN_MAX) {
3950 mutex_exit(&(log_sys->
mutex));
3959 recv_recovery_from_archive_finish(
void)
3964 recv_recovery_from_backup_on = FALSE;