Commit c13f4091 authored by Jan Lindström's avatar Jan Lindström

MDEV-8815: InnoDB should refuse to start if crash recovery fails instead of asserting

Added error handling to crash recovery so that we stop instead of
asserting.
parent a4e59020
......@@ -275,7 +275,7 @@ recv_sys_var_init(void);
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
dberr_t
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
......
......@@ -442,9 +442,10 @@ recv_sys_init(
}
/********************************************************//**
Empties the hash table when it has been fully processed. */
Empties the hash table when it has been fully processed.
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
static
void
dberr_t
recv_sys_empty_hash(void)
/*=====================*/
{
......@@ -458,13 +459,15 @@ recv_sys_empty_hash(void)
" log records on it %lu\n",
(ulong) recv_sys->n_addrs,
(ulong) recv_max_parsed_page_no);
ut_error;
return DB_ERROR;
}
hash_table_free(recv_sys->addr_hash);
mem_heap_empty(recv_sys->heap);
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
return DB_SUCCESS;
}
#ifndef UNIV_HOTBACKUP
......@@ -1779,9 +1782,10 @@ recv_read_in_area(
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
pages.
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
UNIV_INTERN
void
dberr_t
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
......@@ -1798,6 +1802,7 @@ recv_apply_hashed_log_recs(
ulint i;
ibool has_printed = FALSE;
mtr_t mtr;
dberr_t err = DB_SUCCESS;
loop:
mutex_enter(&(recv_sys->mutex));
......@@ -1931,13 +1936,15 @@ recv_apply_hashed_log_recs(
recv_sys->apply_log_recs = FALSE;
recv_sys->apply_batch_on = FALSE;
recv_sys_empty_hash();
err = recv_sys_empty_hash();
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
}
mutex_exit(&(recv_sys->mutex));
return err;
}
#else /* !UNIV_HOTBACKUP */
/*******************************************************************//**
......@@ -2258,7 +2265,6 @@ recv_report_corrupt_log(
if (!srv_force_recovery) {
fputs("InnoDB: Set innodb_force_recovery"
" to ignore this error.\n", stderr);
ut_error;
}
#endif /* !UNIV_HOTBACKUP */
......@@ -2281,9 +2287,11 @@ static
ibool
recv_parse_log_recs(
/*================*/
ibool store_to_hash) /*!< in: TRUE if the records should be stored
ibool store_to_hash, /*!< in: TRUE if the records should be stored
to the hash table; this is set to FALSE if just
debug checking is needed */
dberr_t* err) /*!< out: DB_SUCCESS if successfull,
DB_ERROR if parsing fails. */
{
byte* ptr;
byte* end_ptr;
......@@ -2392,7 +2400,8 @@ recv_parse_log_recs(
(ulint) type, space,
(char*)(body + 2));
ut_error;
*err = DB_ERROR;
return(FALSE);
}
}
#endif
......@@ -2688,17 +2697,18 @@ recv_scan_log_recs(
if (log_crypt_block_maybe_encrypted(log_block,
&log_crypt_err)) {
/* Log block maybe encrypted */
/* Log block maybe encrypted finish processing*/
log_crypt_print_error(log_crypt_err);
*err = DB_ERROR;
return (TRUE);
}
/* Crash if we encounter a garbage log block */
/* Stop if we encounter a garbage log block */
if (!srv_force_recovery) {
fputs("InnoDB: Set innodb_force_recovery"
" to ignore this error.\n", stderr);
ut_error;
*err = DB_ERROR;
return (TRUE);
}
break;
......@@ -2736,7 +2746,8 @@ recv_scan_log_recs(
/* This is not really an error, but currently
we stop here in the debug version: */
ut_error;
*err = DB_ERROR;
return (TRUE);
#endif
break;
}
......@@ -2802,7 +2813,8 @@ recv_scan_log_recs(
" innodb_force_recovery"
" to ignore this error.\n",
stderr);
ut_error;
*err = DB_ERROR;
return (TRUE);
}
#endif /* !UNIV_HOTBACKUP */
......@@ -2844,7 +2856,11 @@ recv_scan_log_recs(
if (more_data && !recv_sys->found_corrupt_log) {
/* Try to parse more log records */
recv_parse_log_recs(store_to_hash);
recv_parse_log_recs(store_to_hash, err);
if (*err != DB_SUCCESS) {
return (TRUE);
}
#ifndef UNIV_HOTBACKUP
if (store_to_hash
......@@ -2856,7 +2872,12 @@ recv_scan_log_recs(
log yet: they would be produced by ibuf
operations */
recv_apply_hashed_log_recs(FALSE);
*err = recv_apply_hashed_log_recs(FALSE);
if (*err != DB_SUCCESS) {
/* Finish processing because of error */
return (TRUE);
}
}
#endif /* !UNIV_HOTBACKUP */
......@@ -3174,7 +3195,7 @@ recv_recovery_from_checkpoint_start_func(
#ifdef UNIV_LOG_ARCHIVE
lsn_t old_scanned_lsn = recv_sys->scanned_lsn;
#endif /* UNIV_LOG_ARCHIVE */
dberr_t err;
dberr_t err = DB_SUCCESS;
recv_group_scan_log_recs(group, &contiguous_lsn,
&group_scanned_lsn, &err);
......@@ -3276,7 +3297,7 @@ recv_recovery_from_checkpoint_start_func(
/* No harm in trying to do RO access. */
if (!srv_read_only_mode) {
ut_error;
return (DB_READ_ONLY);
}
return(DB_ERROR);
......
......@@ -312,7 +312,7 @@ recv_sys_var_init(void);
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
dberr_t
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
......
......@@ -446,9 +446,10 @@ recv_sys_init(
}
/********************************************************//**
Empties the hash table when it has been fully processed. */
Empties the hash table when it has been fully processed.
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
static
void
dberr_t
recv_sys_empty_hash(void)
/*=====================*/
{
......@@ -462,13 +463,15 @@ recv_sys_empty_hash(void)
" log records on it %lu\n",
(ulong) recv_sys->n_addrs,
(ulong) recv_max_parsed_page_no);
ut_error;
return DB_ERROR;
}
hash_table_free(recv_sys->addr_hash);
mem_heap_empty(recv_sys->heap);
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
return DB_SUCCESS;
}
#ifndef UNIV_HOTBACKUP
......@@ -1847,9 +1850,10 @@ recv_read_in_area(
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
pages.
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
UNIV_INTERN
void
dberr_t
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
......@@ -1866,6 +1870,7 @@ recv_apply_hashed_log_recs(
ulint i;
ibool has_printed = FALSE;
mtr_t mtr;
dberr_t err = DB_SUCCESS;
loop:
mutex_enter(&(recv_sys->mutex));
......@@ -1999,13 +2004,15 @@ recv_apply_hashed_log_recs(
recv_sys->apply_log_recs = FALSE;
recv_sys->apply_batch_on = FALSE;
recv_sys_empty_hash();
err = recv_sys_empty_hash();
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
}
mutex_exit(&(recv_sys->mutex));
return err;
}
#else /* !UNIV_HOTBACKUP */
/*******************************************************************//**
......@@ -2328,7 +2335,6 @@ recv_report_corrupt_log(
if (!srv_force_recovery) {
fputs("InnoDB: Set innodb_force_recovery"
" to ignore this error.\n", stderr);
ut_error;
}
#endif /* !UNIV_HOTBACKUP */
......@@ -2351,9 +2357,11 @@ static
ibool
recv_parse_log_recs(
/*================*/
ibool store_to_hash) /*!< in: TRUE if the records should be stored
ibool store_to_hash, /*!< in: TRUE if the records should be stored
to the hash table; this is set to FALSE if just
debug checking is needed */
dberr_t* err) /*!< out: DB_SUCCESS if successfull,
DB_ERROR if parsing fails. */
{
byte* ptr;
byte* end_ptr;
......@@ -2462,7 +2470,8 @@ recv_parse_log_recs(
(ulint) type, space,
(char*)(body + 2));
ut_error;
*err = DB_ERROR;
return(FALSE);
}
}
#endif
......@@ -2758,17 +2767,18 @@ recv_scan_log_recs(
if (log_crypt_block_maybe_encrypted(log_block,
&log_crypt_err)) {
/* Log block maybe encrypted */
/* Log block maybe encrypted finish processing*/
log_crypt_print_error(log_crypt_err);
*err = DB_ERROR;
return (TRUE);
}
/* Crash if we encounter a garbage log block */
/* Stop if we encounter a garbage log block */
if (!srv_force_recovery) {
fputs("InnoDB: Set innodb_force_recovery"
" to ignore this error.\n", stderr);
ut_error;
*err = DB_ERROR;
return (TRUE);
}
break;
......@@ -2806,7 +2816,8 @@ recv_scan_log_recs(
/* This is not really an error, but currently
we stop here in the debug version: */
ut_error;
*err = DB_ERROR;
return (TRUE);
#endif
break;
}
......@@ -2872,7 +2883,8 @@ recv_scan_log_recs(
" innodb_force_recovery"
" to ignore this error.\n",
stderr);
ut_error;
*err = DB_ERROR;
return (TRUE);
}
#endif /* !UNIV_HOTBACKUP */
......@@ -2914,7 +2926,11 @@ recv_scan_log_recs(
if (more_data && !recv_sys->found_corrupt_log) {
/* Try to parse more log records */
recv_parse_log_recs(store_to_hash);
recv_parse_log_recs(store_to_hash, err);
if (*err != DB_SUCCESS) {
return (TRUE);
}
#ifndef UNIV_HOTBACKUP
if (store_to_hash
......@@ -2926,7 +2942,12 @@ recv_scan_log_recs(
log yet: they would be produced by ibuf
operations */
recv_apply_hashed_log_recs(FALSE);
*err = recv_apply_hashed_log_recs(FALSE);
if (*err != DB_SUCCESS) {
/* Finish processing because of error */
return (TRUE);
}
}
#endif /* !UNIV_HOTBACKUP */
......@@ -3267,7 +3288,7 @@ recv_recovery_from_checkpoint_start_func(
#ifdef UNIV_LOG_ARCHIVE
lsn_t old_scanned_lsn = recv_sys->scanned_lsn;
#endif /* UNIV_LOG_ARCHIVE */
dberr_t err;
dberr_t err = DB_SUCCESS;
recv_group_scan_log_recs(group, &contiguous_lsn,
&group_scanned_lsn, &err);
......@@ -3369,7 +3390,7 @@ recv_recovery_from_checkpoint_start_func(
/* No harm in trying to do RO access. */
if (!srv_read_only_mode) {
ut_error;
return (DB_READ_ONLY);
}
return(DB_ERROR);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment