From 58bc83e1a72b50dd009d5e6c370803b7c3578f9c Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 27 Aug 2024 15:36:39 +1000 Subject: [PATCH 1/3] [fixup] Spider: Restored lines accidentally deleted in MDEV-32157 Also restored a change that resulted in off-by-one, as well as appending the correctly indexed key_hint. --- storage/spider/spd_db_conn.cc | 4 +++- storage/spider/spd_db_mysql.cc | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 22989bf88b9..401774ed508 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -1512,6 +1512,7 @@ int spider_db_append_key_hint( if (str->reserve( hint_str_len - 2 + SPIDER_SQL_INDEX_USE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); hint_str += 2; str->q_append(SPIDER_SQL_INDEX_USE_STR, SPIDER_SQL_INDEX_USE_LEN); str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); @@ -1524,10 +1525,11 @@ int spider_db_append_key_hint( if (str->reserve( hint_str_len - 3 + SPIDER_SQL_INDEX_IGNORE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); hint_str += 3; str->q_append(SPIDER_SQL_INDEX_IGNORE_STR, SPIDER_SQL_INDEX_IGNORE_LEN); str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - str->q_append(hint_str, hint_str_len - 2); + str->q_append(hint_str, hint_str_len - 3); str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN); } else if (str->reserve(hint_str_len + SPIDER_SQL_SPACE_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 7ea91073cf2..04f4bfd22ee 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -7612,8 +7612,8 @@ int spider_mbase_share::convert_key_hint_str() roop_count < (int) table_share->keys; roop_count++, tmp_key_hint++) { tmp_key_hint->length(0); - if (tmp_key_hint->append(spider_share->key_hint->ptr(), - spider_share->key_hint->length(), system_charset_info)) + if (tmp_key_hint->append(spider_share->key_hint[roop_count].ptr(), + spider_share->key_hint[roop_count].length(), system_charset_info)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } else { From e7bb9b7c556e91b9ac7ddedf279d5db75d5e3a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 27 Aug 2024 18:06:24 +0300 Subject: [PATCH 2/3] MDEV-24923 fixup: Correct a function comment --- storage/innobase/lock/lock0lock.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 3dd4b5fa6f6..0a125bf15c7 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -608,14 +608,13 @@ lock_rec_get_insert_intention( return(lock->type_mode & LOCK_INSERT_INTENTION); } -#ifdef UNIV_DEBUG -#ifdef WITH_WSREP +#if defined UNIV_DEBUG && defined WITH_WSREP /** Check if both conflicting lock transaction and other transaction requesting record lock are brute force (BF). If they are check is this BF-BF wait correct and if not report BF wait and assert. -@param[in] lock_rec other waiting record lock -@param[in] trx trx requesting conflicting record lock +@param lock other waiting lock +@param trx transaction requesting conflicting lock */ static void wsrep_assert_no_bf_bf_wait(const lock_t *lock, const trx_t *trx) { @@ -682,8 +681,7 @@ static void wsrep_assert_no_bf_bf_wait(const lock_t *lock, const trx_t *trx) /* BF-BF wait is a bug */ ut_error; } -#endif /* WITH_WSREP */ -#endif /* UNIV_DEBUG */ +#endif /*********************************************************************//** Checks if a lock request for a new lock has to wait for request lock2. From 1ff6b6f0b43b4e028f2763eab95fab7b6e99791f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 28 Aug 2024 15:44:42 +0300 Subject: [PATCH 3/3] MDEV-34802 Recovery fails to note some log corruption recv_recovery_from_checkpoint_start(): Abort startup due to log corruption if we were unable to parse the entire log between the latest log checkpoint and the corresponding FILE_CHECKPOINT record. Also, reduce some code bloat related to log output and log_sys.mutex. Reviewed by: Debarun Banerjee --- storage/innobase/log/log0recv.cc | 120 ++++++++++++++----------------- 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 366cf524f41..e605a082fb5 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3474,10 +3474,9 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex)); if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) { - - ib::info() << "innodb_force_recovery=6 skips redo log apply"; - - return(DB_SUCCESS); + sql_print_information("InnoDB: innodb_force_recovery=6" + " skips redo log apply"); + return err; } mysql_mutex_lock(&log_sys.mutex); @@ -3493,13 +3492,9 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) ut_ad(RECV_SCAN_SIZE <= srv_log_buffer_size); - ut_ad(recv_sys.pages.empty()); contiguous_lsn = checkpoint_lsn; switch (log_sys.log.format) { - case 0: - mysql_mutex_unlock(&log_sys.mutex); - return DB_SUCCESS; default: if (end_lsn == 0) { break; @@ -3509,8 +3504,13 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) break; } recv_sys.found_corrupt_log = true; + err_exit: + err = DB_ERROR; + /* fall through */ + func_exit: + case 0: mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); + return err; } size_t sizeof_checkpoint; @@ -3527,14 +3527,15 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) ut_ad(!recv_sys.found_corrupt_fs || !srv_force_recovery); if (srv_read_only_mode && recv_needed_recovery) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_READ_ONLY); + read_only: + err = DB_READ_ONLY; + goto func_exit; } if (recv_sys.found_corrupt_log && !srv_force_recovery) { - mysql_mutex_unlock(&log_sys.mutex); - ib::warn() << "Log scan aborted at LSN " << contiguous_lsn; - return(DB_ERROR); + sql_print_warning("InnoDB: Log scan aborted at LSN " LSN_PF, + contiguous_lsn); + goto err_exit; } /* If we fail to open a tablespace while looking for FILE_CHECKPOINT, we @@ -3542,14 +3543,12 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) would not be able to open an encrypted tablespace and the flag could be set. */ if (recv_sys.found_corrupt_fs) { - mysql_mutex_unlock(&log_sys.mutex); - return DB_ERROR; + goto err_exit; } if (recv_sys.mlog_checkpoint_lsn == 0) { lsn_t scan_lsn = log_sys.log.scanned_lsn; if (!srv_read_only_mode && scan_lsn != checkpoint_lsn) { - mysql_mutex_unlock(&log_sys.mutex); ib::error err; err << "Missing FILE_CHECKPOINT"; if (end_lsn) { @@ -3557,7 +3556,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) } err << " between the checkpoint " << checkpoint_lsn << " and the end " << scan_lsn << "."; - return(DB_ERROR); + goto err_exit; } log_sys.log.scanned_lsn = checkpoint_lsn; @@ -3568,8 +3567,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) if ((recv_sys.found_corrupt_log && !srv_force_recovery) || recv_sys.found_corrupt_fs) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); + goto err_exit; } } @@ -3599,19 +3597,17 @@ completed: } if (!recv_needed_recovery) { - - ib::info() - << "The log sequence number " << flush_lsn - << " in the system tablespace does not match" - " the log sequence number " - << checkpoint_lsn << " in the " - << LOG_FILE_NAME << "!"; + sql_print_information( + "InnoDB: The log sequence number " LSN_PF + " in the system tablespace does not match" + " the log sequence number " LSN_PF + " in the ib_logfile0!", + flush_lsn, checkpoint_lsn); if (srv_read_only_mode) { - ib::error() << "innodb_read_only" - " prevents crash recovery"; - mysql_mutex_unlock(&log_sys.mutex); - return(DB_READ_ONLY); + sql_print_error("InnoDB: innodb_read_only" + " prevents crash recovery"); + goto read_only; } recv_needed_recovery = true; @@ -3632,8 +3628,7 @@ completed: rescan, missing_tablespace); if (err != DB_SUCCESS) { - mysql_mutex_unlock(&log_sys.mutex); - return(err); + goto func_exit; } /* If there is any missing tablespace and rescan is needed @@ -3662,8 +3657,7 @@ completed: rescan, missing_tablespace); if (err != DB_SUCCESS) { - mysql_mutex_unlock(&log_sys.mutex); - return err; + goto func_exit; } rescan = true; @@ -3686,8 +3680,7 @@ completed: if ((recv_sys.found_corrupt_log && !srv_force_recovery) || recv_sys.found_corrupt_fs) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); + goto err_exit; } /* In case of multi-batch recovery, @@ -3699,26 +3692,26 @@ completed: ut_ad(!rescan || recv_sys.pages.empty()); } - if (log_sys.is_physical() - && (log_sys.log.scanned_lsn < checkpoint_lsn - || log_sys.log.scanned_lsn < recv_max_page_lsn)) { - - ib::error() << "We scanned the log up to " - << log_sys.log.scanned_lsn - << ". A checkpoint was at " << checkpoint_lsn << " and" - " the maximum LSN on a database page was " - << recv_max_page_lsn << ". It is possible that the" - " database is now corrupt!"; - } - - if (recv_sys.recovered_lsn < checkpoint_lsn) { - mysql_mutex_unlock(&log_sys.mutex); - - ib::error() << "Recovered only to lsn:" - << recv_sys.recovered_lsn - << " checkpoint_lsn: " << checkpoint_lsn; - - return(DB_ERROR); + if (!log_sys.is_physical()) { + } else if (recv_sys.recovered_lsn < checkpoint_lsn + || recv_sys.recovered_lsn < end_lsn) { + sql_print_error("InnoDB: The log was only scanned up to " + LSN_PF ", while the current LSN at the " + "time of the latest checkpoint " LSN_PF + " was " LSN_PF "!", + recv_sys.recovered_lsn, + checkpoint_lsn, end_lsn); + goto err_exit; + } else if (log_sys.log.scanned_lsn < checkpoint_lsn + || log_sys.log.scanned_lsn < end_lsn + || log_sys.log.scanned_lsn < recv_max_page_lsn) { + sql_print_error("InnoDB: We scanned the log up to " LSN_PF + ". A checkpoint was at " LSN_PF + " and the maximum LSN on a database page was " + LSN_PF ". It is possible that the" + " database is now corrupt!", + log_sys.log.scanned_lsn, checkpoint_lsn, + recv_max_page_lsn); } log_sys.next_checkpoint_lsn = checkpoint_lsn; @@ -3750,9 +3743,7 @@ completed: log_sys.next_checkpoint_no = ++checkpoint_no; - DBUG_EXECUTE_IF("before_final_redo_apply", - mysql_mutex_unlock(&log_sys.mutex); - return DB_ERROR;); + DBUG_EXECUTE_IF("before_final_redo_apply", goto err_exit;); mutex_enter(&recv_sys.mutex); recv_sys.apply_log_recs = true; @@ -3760,17 +3751,14 @@ completed: ut_d(recv_no_log_write = srv_operation == SRV_OPERATION_RESTORE || srv_operation == SRV_OPERATION_RESTORE_EXPORT); - mutex_exit(&recv_sys.mutex); - - mysql_mutex_unlock(&log_sys.mutex); - recv_lsn_checks_on = true; + mutex_exit(&recv_sys.mutex); /* The database is now ready to start almost normal processing of user transactions: transaction rollbacks and the application of the log records in the hash table can be run in background. */ - - return(DB_SUCCESS); + ut_ad(err == DB_SUCCESS); + goto func_exit; } bool recv_dblwr_t::validate_page(const page_id_t page_id,