Skip to content

Commit c13f409

Browse files
committed
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.
1 parent a4e5902 commit c13f409

File tree

4 files changed

+80
-38
lines changed

4 files changed

+80
-38
lines changed

storage/innobase/include/log0recv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ recv_sys_var_init(void);
275275
Empties the hash table of stored log records, applying them to appropriate
276276
pages. */
277277
UNIV_INTERN
278-
void
278+
dberr_t
279279
recv_apply_hashed_log_recs(
280280
/*=======================*/
281281
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are

storage/innobase/log/log0recv.cc

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,10 @@ recv_sys_init(
442442
}
443443

444444
/********************************************************//**
445-
Empties the hash table when it has been fully processed. */
445+
Empties the hash table when it has been fully processed.
446+
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
446447
static
447-
void
448+
dberr_t
448449
recv_sys_empty_hash(void)
449450
/*=====================*/
450451
{
@@ -458,13 +459,15 @@ recv_sys_empty_hash(void)
458459
" log records on it %lu\n",
459460
(ulong) recv_sys->n_addrs,
460461
(ulong) recv_max_parsed_page_no);
461-
ut_error;
462+
return DB_ERROR;
462463
}
463464

464465
hash_table_free(recv_sys->addr_hash);
465466
mem_heap_empty(recv_sys->heap);
466467

467468
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
469+
470+
return DB_SUCCESS;
468471
}
469472

470473
#ifndef UNIV_HOTBACKUP
@@ -1779,9 +1782,10 @@ recv_read_in_area(
17791782

17801783
/*******************************************************************//**
17811784
Empties the hash table of stored log records, applying them to appropriate
1782-
pages. */
1785+
pages.
1786+
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
17831787
UNIV_INTERN
1784-
void
1788+
dberr_t
17851789
recv_apply_hashed_log_recs(
17861790
/*=======================*/
17871791
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
@@ -1798,6 +1802,7 @@ recv_apply_hashed_log_recs(
17981802
ulint i;
17991803
ibool has_printed = FALSE;
18001804
mtr_t mtr;
1805+
dberr_t err = DB_SUCCESS;
18011806
loop:
18021807
mutex_enter(&(recv_sys->mutex));
18031808

@@ -1931,13 +1936,15 @@ recv_apply_hashed_log_recs(
19311936
recv_sys->apply_log_recs = FALSE;
19321937
recv_sys->apply_batch_on = FALSE;
19331938

1934-
recv_sys_empty_hash();
1939+
err = recv_sys_empty_hash();
19351940

19361941
if (has_printed) {
19371942
fprintf(stderr, "InnoDB: Apply batch completed\n");
19381943
}
19391944

19401945
mutex_exit(&(recv_sys->mutex));
1946+
1947+
return err;
19411948
}
19421949
#else /* !UNIV_HOTBACKUP */
19431950
/*******************************************************************//**
@@ -2258,7 +2265,6 @@ recv_report_corrupt_log(
22582265
if (!srv_force_recovery) {
22592266
fputs("InnoDB: Set innodb_force_recovery"
22602267
" to ignore this error.\n", stderr);
2261-
ut_error;
22622268
}
22632269
#endif /* !UNIV_HOTBACKUP */
22642270

@@ -2281,9 +2287,11 @@ static
22812287
ibool
22822288
recv_parse_log_recs(
22832289
/*================*/
2284-
ibool store_to_hash) /*!< in: TRUE if the records should be stored
2290+
ibool store_to_hash, /*!< in: TRUE if the records should be stored
22852291
to the hash table; this is set to FALSE if just
22862292
debug checking is needed */
2293+
dberr_t* err) /*!< out: DB_SUCCESS if successfull,
2294+
DB_ERROR if parsing fails. */
22872295
{
22882296
byte* ptr;
22892297
byte* end_ptr;
@@ -2392,7 +2400,8 @@ recv_parse_log_recs(
23922400
(ulint) type, space,
23932401
(char*)(body + 2));
23942402

2395-
ut_error;
2403+
*err = DB_ERROR;
2404+
return(FALSE);
23962405
}
23972406
}
23982407
#endif
@@ -2688,17 +2697,18 @@ recv_scan_log_recs(
26882697

26892698
if (log_crypt_block_maybe_encrypted(log_block,
26902699
&log_crypt_err)) {
2691-
/* Log block maybe encrypted */
2700+
/* Log block maybe encrypted finish processing*/
26922701
log_crypt_print_error(log_crypt_err);
26932702
*err = DB_ERROR;
26942703
return (TRUE);
26952704
}
26962705

2697-
/* Crash if we encounter a garbage log block */
2706+
/* Stop if we encounter a garbage log block */
26982707
if (!srv_force_recovery) {
26992708
fputs("InnoDB: Set innodb_force_recovery"
27002709
" to ignore this error.\n", stderr);
2701-
ut_error;
2710+
*err = DB_ERROR;
2711+
return (TRUE);
27022712
}
27032713

27042714
break;
@@ -2736,7 +2746,8 @@ recv_scan_log_recs(
27362746
/* This is not really an error, but currently
27372747
we stop here in the debug version: */
27382748

2739-
ut_error;
2749+
*err = DB_ERROR;
2750+
return (TRUE);
27402751
#endif
27412752
break;
27422753
}
@@ -2802,7 +2813,8 @@ recv_scan_log_recs(
28022813
" innodb_force_recovery"
28032814
" to ignore this error.\n",
28042815
stderr);
2805-
ut_error;
2816+
*err = DB_ERROR;
2817+
return (TRUE);
28062818
}
28072819
#endif /* !UNIV_HOTBACKUP */
28082820

@@ -2844,7 +2856,11 @@ recv_scan_log_recs(
28442856
if (more_data && !recv_sys->found_corrupt_log) {
28452857
/* Try to parse more log records */
28462858

2847-
recv_parse_log_recs(store_to_hash);
2859+
recv_parse_log_recs(store_to_hash, err);
2860+
2861+
if (*err != DB_SUCCESS) {
2862+
return (TRUE);
2863+
}
28482864

28492865
#ifndef UNIV_HOTBACKUP
28502866
if (store_to_hash
@@ -2856,7 +2872,12 @@ recv_scan_log_recs(
28562872
log yet: they would be produced by ibuf
28572873
operations */
28582874

2859-
recv_apply_hashed_log_recs(FALSE);
2875+
*err = recv_apply_hashed_log_recs(FALSE);
2876+
2877+
if (*err != DB_SUCCESS) {
2878+
/* Finish processing because of error */
2879+
return (TRUE);
2880+
}
28602881
}
28612882
#endif /* !UNIV_HOTBACKUP */
28622883

@@ -3174,7 +3195,7 @@ recv_recovery_from_checkpoint_start_func(
31743195
#ifdef UNIV_LOG_ARCHIVE
31753196
lsn_t old_scanned_lsn = recv_sys->scanned_lsn;
31763197
#endif /* UNIV_LOG_ARCHIVE */
3177-
dberr_t err;
3198+
dberr_t err = DB_SUCCESS;
31783199

31793200
recv_group_scan_log_recs(group, &contiguous_lsn,
31803201
&group_scanned_lsn, &err);
@@ -3276,7 +3297,7 @@ recv_recovery_from_checkpoint_start_func(
32763297

32773298
/* No harm in trying to do RO access. */
32783299
if (!srv_read_only_mode) {
3279-
ut_error;
3300+
return (DB_READ_ONLY);
32803301
}
32813302

32823303
return(DB_ERROR);

storage/xtradb/include/log0recv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ recv_sys_var_init(void);
312312
Empties the hash table of stored log records, applying them to appropriate
313313
pages. */
314314
UNIV_INTERN
315-
void
315+
dberr_t
316316
recv_apply_hashed_log_recs(
317317
/*=======================*/
318318
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are

storage/xtradb/log/log0recv.cc

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,10 @@ recv_sys_init(
446446
}
447447

448448
/********************************************************//**
449-
Empties the hash table when it has been fully processed. */
449+
Empties the hash table when it has been fully processed.
450+
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
450451
static
451-
void
452+
dberr_t
452453
recv_sys_empty_hash(void)
453454
/*=====================*/
454455
{
@@ -462,13 +463,15 @@ recv_sys_empty_hash(void)
462463
" log records on it %lu\n",
463464
(ulong) recv_sys->n_addrs,
464465
(ulong) recv_max_parsed_page_no);
465-
ut_error;
466+
return DB_ERROR;
466467
}
467468

468469
hash_table_free(recv_sys->addr_hash);
469470
mem_heap_empty(recv_sys->heap);
470471

471472
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
473+
474+
return DB_SUCCESS;
472475
}
473476

474477
#ifndef UNIV_HOTBACKUP
@@ -1847,9 +1850,10 @@ recv_read_in_area(
18471850

18481851
/*******************************************************************//**
18491852
Empties the hash table of stored log records, applying them to appropriate
1850-
pages. */
1853+
pages.
1854+
@return DB_SUCCESS when successfull or DB_ERROR when fails. */
18511855
UNIV_INTERN
1852-
void
1856+
dberr_t
18531857
recv_apply_hashed_log_recs(
18541858
/*=======================*/
18551859
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
@@ -1866,6 +1870,7 @@ recv_apply_hashed_log_recs(
18661870
ulint i;
18671871
ibool has_printed = FALSE;
18681872
mtr_t mtr;
1873+
dberr_t err = DB_SUCCESS;
18691874
loop:
18701875
mutex_enter(&(recv_sys->mutex));
18711876

@@ -1999,13 +2004,15 @@ recv_apply_hashed_log_recs(
19992004
recv_sys->apply_log_recs = FALSE;
20002005
recv_sys->apply_batch_on = FALSE;
20012006

2002-
recv_sys_empty_hash();
2007+
err = recv_sys_empty_hash();
20032008

20042009
if (has_printed) {
20052010
fprintf(stderr, "InnoDB: Apply batch completed\n");
20062011
}
20072012

20082013
mutex_exit(&(recv_sys->mutex));
2014+
2015+
return err;
20092016
}
20102017
#else /* !UNIV_HOTBACKUP */
20112018
/*******************************************************************//**
@@ -2328,7 +2335,6 @@ recv_report_corrupt_log(
23282335
if (!srv_force_recovery) {
23292336
fputs("InnoDB: Set innodb_force_recovery"
23302337
" to ignore this error.\n", stderr);
2331-
ut_error;
23322338
}
23332339
#endif /* !UNIV_HOTBACKUP */
23342340

@@ -2351,9 +2357,11 @@ static
23512357
ibool
23522358
recv_parse_log_recs(
23532359
/*================*/
2354-
ibool store_to_hash) /*!< in: TRUE if the records should be stored
2360+
ibool store_to_hash, /*!< in: TRUE if the records should be stored
23552361
to the hash table; this is set to FALSE if just
23562362
debug checking is needed */
2363+
dberr_t* err) /*!< out: DB_SUCCESS if successfull,
2364+
DB_ERROR if parsing fails. */
23572365
{
23582366
byte* ptr;
23592367
byte* end_ptr;
@@ -2462,7 +2470,8 @@ recv_parse_log_recs(
24622470
(ulint) type, space,
24632471
(char*)(body + 2));
24642472

2465-
ut_error;
2473+
*err = DB_ERROR;
2474+
return(FALSE);
24662475
}
24672476
}
24682477
#endif
@@ -2758,17 +2767,18 @@ recv_scan_log_recs(
27582767

27592768
if (log_crypt_block_maybe_encrypted(log_block,
27602769
&log_crypt_err)) {
2761-
/* Log block maybe encrypted */
2770+
/* Log block maybe encrypted finish processing*/
27622771
log_crypt_print_error(log_crypt_err);
27632772
*err = DB_ERROR;
27642773
return (TRUE);
27652774
}
27662775

2767-
/* Crash if we encounter a garbage log block */
2776+
/* Stop if we encounter a garbage log block */
27682777
if (!srv_force_recovery) {
27692778
fputs("InnoDB: Set innodb_force_recovery"
27702779
" to ignore this error.\n", stderr);
2771-
ut_error;
2780+
*err = DB_ERROR;
2781+
return (TRUE);
27722782
}
27732783

27742784
break;
@@ -2806,7 +2816,8 @@ recv_scan_log_recs(
28062816
/* This is not really an error, but currently
28072817
we stop here in the debug version: */
28082818

2809-
ut_error;
2819+
*err = DB_ERROR;
2820+
return (TRUE);
28102821
#endif
28112822
break;
28122823
}
@@ -2872,7 +2883,8 @@ recv_scan_log_recs(
28722883
" innodb_force_recovery"
28732884
" to ignore this error.\n",
28742885
stderr);
2875-
ut_error;
2886+
*err = DB_ERROR;
2887+
return (TRUE);
28762888
}
28772889
#endif /* !UNIV_HOTBACKUP */
28782890

@@ -2914,7 +2926,11 @@ recv_scan_log_recs(
29142926
if (more_data && !recv_sys->found_corrupt_log) {
29152927
/* Try to parse more log records */
29162928

2917-
recv_parse_log_recs(store_to_hash);
2929+
recv_parse_log_recs(store_to_hash, err);
2930+
2931+
if (*err != DB_SUCCESS) {
2932+
return (TRUE);
2933+
}
29182934

29192935
#ifndef UNIV_HOTBACKUP
29202936
if (store_to_hash
@@ -2926,7 +2942,12 @@ recv_scan_log_recs(
29262942
log yet: they would be produced by ibuf
29272943
operations */
29282944

2929-
recv_apply_hashed_log_recs(FALSE);
2945+
*err = recv_apply_hashed_log_recs(FALSE);
2946+
2947+
if (*err != DB_SUCCESS) {
2948+
/* Finish processing because of error */
2949+
return (TRUE);
2950+
}
29302951
}
29312952
#endif /* !UNIV_HOTBACKUP */
29322953

@@ -3267,7 +3288,7 @@ recv_recovery_from_checkpoint_start_func(
32673288
#ifdef UNIV_LOG_ARCHIVE
32683289
lsn_t old_scanned_lsn = recv_sys->scanned_lsn;
32693290
#endif /* UNIV_LOG_ARCHIVE */
3270-
dberr_t err;
3291+
dberr_t err = DB_SUCCESS;
32713292

32723293
recv_group_scan_log_recs(group, &contiguous_lsn,
32733294
&group_scanned_lsn, &err);
@@ -3369,7 +3390,7 @@ recv_recovery_from_checkpoint_start_func(
33693390

33703391
/* No harm in trying to do RO access. */
33713392
if (!srv_read_only_mode) {
3372-
ut_error;
3393+
return (DB_READ_ONLY);
33733394
}
33743395

33753396
return(DB_ERROR);

0 commit comments

Comments
 (0)