From 35ee4aa4e3bf391b7de78b3e95f3e484394fd1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 31 Mar 2021 09:06:44 +0300 Subject: [PATCH 01/12] MDEV-13103 fixup: Actually fix a crash during IMPORT TABLESPACE --- storage/innobase/ibuf/ibuf0ibuf.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index ee6fd235d5e..46649187ca0 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -4922,6 +4922,13 @@ ibuf_check_bitmap_on_import( bitmap_page = ibuf_bitmap_get_map_page( page_id_t(space_id, page_no), page_size, &mtr); + if (!bitmap_page) { + mutex_exit(&ibuf_mutex); + ibuf_exit(&mtr); + mtr_commit(&mtr); + return DB_CORRUPTION; + } + if (buf_is_zeroes(span(bitmap_page, page_size.physical()))) { /* This means we got all-zero page instead of @@ -4945,11 +4952,6 @@ ibuf_check_bitmap_on_import( continue; } - if (!bitmap_page) { - mutex_exit(&ibuf_mutex); - return DB_CORRUPTION; - } - for (i = FSP_IBUF_BITMAP_OFFSET + 1; i < page_size.physical(); i++) { From 08cb5d848314006111b0c379db6a1fce220579aa Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 31 Mar 2021 14:23:56 +0200 Subject: [PATCH 02/12] MDEV-25221 Do not remove source file, if copy_file() fails in mariabackup --move-back Remove an incompletely copied destination file. --- extra/mariabackup/backup_copy.cc | 14 +++++++---- extra/mariabackup/datasink.h | 6 +++++ extra/mariabackup/ds_archive.cc | 1 + extra/mariabackup/ds_buffer.cc | 1 + extra/mariabackup/ds_compress.cc | 1 + extra/mariabackup/ds_local.cc | 6 +++++ extra/mariabackup/ds_stdout.cc | 1 + extra/mariabackup/ds_tmpfile.cc | 1 + extra/mariabackup/ds_xbstream.cc | 1 + .../mariabackup/error_during_copyback.result | 9 +++++++ .../mariabackup/error_during_copyback.test | 25 +++++++++++++++++++ 11 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/mariabackup/error_during_copyback.result create mode 100644 mysql-test/suite/mariabackup/error_during_copyback.test diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index d3fa3605c21..5637ec3d4d7 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -1066,6 +1066,7 @@ copy_file(ds_ctxt_t *datasink, ds_file_t *dstfile = NULL; datafile_cur_t cursor; xb_fil_cur_result_t res; + DBUG_ASSERT(datasink->datasink->remove); const char *dst_path = (xtrabackup_copy_back || xtrabackup_move_back)? dst_file_path : trim_dotslash(dst_file_path); @@ -1091,6 +1092,7 @@ copy_file(ds_ctxt_t *datasink, if (ds_write(dstfile, cursor.buf, cursor.buf_read)) { goto error; } + DBUG_EXECUTE_IF("copy_file_error", errno=ENOSPC;goto error;); } if (res == XB_FIL_CUR_ERROR) { @@ -1112,6 +1114,7 @@ copy_file(ds_ctxt_t *datasink, error: datafile_close(&cursor); if (dstfile != NULL) { + datasink->datasink->remove(dstfile->path); ds_close(dstfile); } @@ -1156,17 +1159,18 @@ move_file(ds_ctxt_t *datasink, if (my_rename(src_file_path, dst_file_path_abs, MYF(0)) != 0) { if (my_errno == EXDEV) { - bool ret; - ret = copy_file(datasink, src_file_path, - dst_file_path, thread_n); + /* Fallback to copy/unlink */ + if(!copy_file(datasink, src_file_path, + dst_file_path, thread_n)) + return false; msg(thread_n,"Removing %s", src_file_path); if (unlink(src_file_path) != 0) { my_strerror(errbuf, sizeof(errbuf), errno); - msg("Error: unlink %s failed: %s", + msg("Warning: unlink %s failed: %s", src_file_path, errbuf); } - return(ret); + return true; } my_strerror(errbuf, sizeof(errbuf), my_errno); msg("Can not move file %s to %s: %s", diff --git a/extra/mariabackup/datasink.h b/extra/mariabackup/datasink.h index 201bbfd3267..5c82556b9ba 100644 --- a/extra/mariabackup/datasink.h +++ b/extra/mariabackup/datasink.h @@ -50,9 +50,15 @@ struct datasink_struct { ds_file_t *(*open)(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat); int (*write)(ds_file_t *file, const unsigned char *buf, size_t len); int (*close)(ds_file_t *file); + int (*remove)(const char *path); void (*deinit)(ds_ctxt_t *ctxt); }; + +static inline int dummy_remove(const char *) { + return 0; +} + /* Supported datasink types */ typedef enum { DS_TYPE_STDOUT, diff --git a/extra/mariabackup/ds_archive.cc b/extra/mariabackup/ds_archive.cc index 3826029e120..18f13fbcf3a 100644 --- a/extra/mariabackup/ds_archive.cc +++ b/extra/mariabackup/ds_archive.cc @@ -56,6 +56,7 @@ datasink_t datasink_archive = { &archive_open, &archive_write, &archive_close, + &dummy_remove, &archive_deinit }; diff --git a/extra/mariabackup/ds_buffer.cc b/extra/mariabackup/ds_buffer.cc index e906edc9e84..9dc040d533b 100644 --- a/extra/mariabackup/ds_buffer.cc +++ b/extra/mariabackup/ds_buffer.cc @@ -54,6 +54,7 @@ datasink_t datasink_buffer = { &buffer_open, &buffer_write, &buffer_close, + &dummy_remove, &buffer_deinit }; diff --git a/extra/mariabackup/ds_compress.cc b/extra/mariabackup/ds_compress.cc index fb4f3a75bb6..23de4d85116 100644 --- a/extra/mariabackup/ds_compress.cc +++ b/extra/mariabackup/ds_compress.cc @@ -74,6 +74,7 @@ datasink_t datasink_compress = { &compress_open, &compress_write, &compress_close, + &dummy_remove, &compress_deinit }; diff --git a/extra/mariabackup/ds_local.cc b/extra/mariabackup/ds_local.cc index 0f13ddfe9a9..2f0ad2d8705 100644 --- a/extra/mariabackup/ds_local.cc +++ b/extra/mariabackup/ds_local.cc @@ -44,12 +44,18 @@ static int local_write(ds_file_t *file, const uchar *buf, size_t len); static int local_close(ds_file_t *file); static void local_deinit(ds_ctxt_t *ctxt); +static int local_remove(const char *path) +{ + return unlink(path); +} + extern "C" { datasink_t datasink_local = { &local_init, &local_open, &local_write, &local_close, + &local_remove, &local_deinit }; } diff --git a/extra/mariabackup/ds_stdout.cc b/extra/mariabackup/ds_stdout.cc index 9398482feb9..a4abbe426b6 100644 --- a/extra/mariabackup/ds_stdout.cc +++ b/extra/mariabackup/ds_stdout.cc @@ -39,6 +39,7 @@ datasink_t datasink_stdout = { &stdout_open, &stdout_write, &stdout_close, + &dummy_remove, &stdout_deinit }; diff --git a/extra/mariabackup/ds_tmpfile.cc b/extra/mariabackup/ds_tmpfile.cc index ddb23bf469d..9eadd36bec0 100644 --- a/extra/mariabackup/ds_tmpfile.cc +++ b/extra/mariabackup/ds_tmpfile.cc @@ -50,6 +50,7 @@ datasink_t datasink_tmpfile = { &tmpfile_open, &tmpfile_write, &tmpfile_close, + &dummy_remove, &tmpfile_deinit }; diff --git a/extra/mariabackup/ds_xbstream.cc b/extra/mariabackup/ds_xbstream.cc index 105c89d05f7..3b60456f8ed 100644 --- a/extra/mariabackup/ds_xbstream.cc +++ b/extra/mariabackup/ds_xbstream.cc @@ -50,6 +50,7 @@ datasink_t datasink_xbstream = { &xbstream_open, &xbstream_write, &xbstream_close, + &dummy_remove, &xbstream_deinit }; diff --git a/mysql-test/suite/mariabackup/error_during_copyback.result b/mysql-test/suite/mariabackup/error_during_copyback.result new file mode 100644 index 00000000000..9b12c1135d2 --- /dev/null +++ b/mysql-test/suite/mariabackup/error_during_copyback.result @@ -0,0 +1,9 @@ +CREATE TABLE t(i INT) ENGINE INNODB; +INSERT INTO t VALUES(1); +# xtrabackup backup +# xtrabackup prepare +# restart server +SELECT * FROM t; +i +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/error_during_copyback.test b/mysql-test/suite/mariabackup/error_during_copyback.test new file mode 100644 index 00000000000..3ec9fbfc3c3 --- /dev/null +++ b/mysql-test/suite/mariabackup/error_during_copyback.test @@ -0,0 +1,25 @@ +--source include/have_debug.inc +CREATE TABLE t(i INT) ENGINE INNODB; +INSERT INTO t VALUES(1); +echo # xtrabackup backup; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; +let $_datadir= `SELECT @@datadir`; +--source include/shutdown_mysqld.inc +rmdir $_datadir; +error 1; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --copy-back --datadir=$_datadir --target-dir=$targetdir --dbug=+d,copy_file_error; +list_files $_datadir; +rmdir $_datadir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --copy-back --datadir=$_datadir --target-dir=$targetdir; +echo # restart server; +--source include/start_mysqld.inc +SELECT * FROM t; +DROP TABLE t; +rmdir $targetdir; + From 453bac08c265046f2aba4589c5a7f2f8287cb352 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 31 Mar 2021 14:26:10 +0200 Subject: [PATCH 03/12] CMake - when searching bison, look also for win_bison win_bison belongs winflexbison project, which is Windows most up-to-date bison distro. --- cmake/bison.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/bison.cmake b/cmake/bison.cmake index 717cd50dedd..1b2d1c38bae 100644 --- a/cmake/bison.cmake +++ b/cmake/bison.cmake @@ -27,7 +27,7 @@ IF(WIN32) C:/cygwin64/bin C:/cygwin/bin) ENDIF() -FIND_PROGRAM(BISON_EXECUTABLE bison +FIND_PROGRAM(BISON_EXECUTABLE NAMES bison win_bison ${BISON_PATH_HINTS} DOC "path to the bison executable") MARK_AS_ADVANCED(BISON_EXECUTABLE "") From f93e087d745a0c24e30aa144c0f9d34fa042e21b Mon Sep 17 00:00:00 2001 From: mkaruza Date: Wed, 31 Mar 2021 11:29:51 +0200 Subject: [PATCH 04/12] MDEV-25047: SIGSEGV in mach_read_from_n_little_endian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Virtual column fields are not found in prebuilt data type, so we should match InnoDB fields with `get_innobase_type_from_mysql_type` method. Reviewed-by: Jan Lindström --- .../suite/galera/r/galera_virtual_blob.result | 19 +++++++++++++++++++ .../suite/galera/t/galera_virtual_blob.test | 10 ++++++++++ storage/innobase/handler/ha_innodb.cc | 5 ++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_virtual_blob.result create mode 100644 mysql-test/suite/galera/t/galera_virtual_blob.test diff --git a/mysql-test/suite/galera/r/galera_virtual_blob.result b/mysql-test/suite/galera/r/galera_virtual_blob.result new file mode 100644 index 00000000000..91952b1d52d --- /dev/null +++ b/mysql-test/suite/galera/r/galera_virtual_blob.result @@ -0,0 +1,19 @@ +CREATE TABLE t (f INT GENERATED ALWAYS AS (a+b)VIRTUAL,a INT,b INT,h BLOB); +INSERT INTO t (a,b)VALUES(0,0), (0,0), (0,0), (0,0), (0,0); +SELECT * from t; +f a b h +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +connection node_2; +SELECT * from t; +f a b h +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +0 0 0 NULL +connection node_1; +DROP TABLE t; diff --git a/mysql-test/suite/galera/t/galera_virtual_blob.test b/mysql-test/suite/galera/t/galera_virtual_blob.test new file mode 100644 index 00000000000..a10e3025668 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_virtual_blob.test @@ -0,0 +1,10 @@ +--source include/galera_cluster.inc + +CREATE TABLE t (f INT GENERATED ALWAYS AS (a+b)VIRTUAL,a INT,b INT,h BLOB); +INSERT INTO t (a,b)VALUES(0,0), (0,0), (0,0), (0,0), (0,0); +SELECT * from t; + +--connection node_2 +SELECT * from t; +--connection node_1 +DROP TABLE t; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 445103e0550..fc876e6f753 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8874,6 +8874,8 @@ wsrep_calc_row_hash( for (uint i = 0; i < table->s->fields; i++) { byte null_byte=0; byte true_byte=1; + ulint col_type; + ulint is_unsigned; const Field* field = table->field[i]; if (!field->stored_in_db()) { @@ -8882,8 +8884,9 @@ wsrep_calc_row_hash( ptr = (const byte*) row + get_field_offset(table, field); len = field->pack_length(); + col_type = get_innobase_type_from_mysql_type(&is_unsigned, field); - switch (prebuilt->table->cols[i].mtype) { + switch (col_type) { case DATA_BLOB: ptr = row_mysql_read_blob_ref(&len, ptr, len); From 5bc5ecce081d235ac6faed0e22885b3a22e6edee Mon Sep 17 00:00:00 2001 From: Srinidhi Kaushik Date: Thu, 1 Apr 2021 15:03:59 +0530 Subject: [PATCH 05/12] MDEV-24197: Add "innodb_force_recovery" for "mariabackup --prepare" During the prepare phase of restoring backups, "mariabackup" does not seem to allow (or recognize) the option "innodb_force_recovery" for the embedded InnoDB server instance that it starts. If page corruption observed during page recovery, the prepare step fails. While this is indeed the correct behavior ideally, allowing this option to be set in case of emergencies might be useful when the current backup is the only copy available. Some error messages during "--prepare" suggest to set "innodb_force_recovery" to 1: [ERROR] InnoDB: Set innodb_force_recovery=1 to ignore corruption. For backwards compatibility, "mariabackup --innobackupex --apply-log" should also have this option. Signed-off-by: Srinidhi Kaushik --- extra/mariabackup/innobackupex.cc | 14 +- extra/mariabackup/xtrabackup.cc | 60 +++++++- extra/mariabackup/xtrabackup.h | 2 + .../mariabackup/innodb_force_recovery.result | 26 ++++ .../mariabackup/innodb_force_recovery.test | 138 ++++++++++++++++++ storage/innobase/srv/srv0start.cc | 2 +- 6 files changed, 233 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/mariabackup/innodb_force_recovery.result create mode 100644 mysql-test/suite/mariabackup/innodb_force_recovery.test diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index f1627dd1bc5..fefd81dc1be 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -206,7 +206,8 @@ enum innobackupex_options OPT_STREAM, OPT_TABLES_FILE, OPT_THROTTLE, - OPT_USE_MEMORY + OPT_USE_MEMORY, + OPT_INNODB_FORCE_RECOVERY, }; ibx_mode_t ibx_mode = IBX_MODE_BACKUP; @@ -624,6 +625,16 @@ static struct my_option ibx_long_options[] = 0, GET_LL, REQUIRED_ARG, 100*1024*1024L, 1024*1024L, LONGLONG_MAX, 0, 1024*1024L, 0}, + {"innodb-force-recovery", OPT_INNODB_FORCE_RECOVERY, + "This option starts up the embedded InnoDB instance in crash " + "recovery mode to ignore page corruption; should be used " + "with the \"--apply-log\" option, in emergencies only. The " + "default value is 0. Refer to \"innodb_force_recovery\" server " + "system variable documentation for more details.", + (uchar*)&xtrabackup_innodb_force_recovery, + (uchar*)&xtrabackup_innodb_force_recovery, + 0, GET_ULONG, OPT_ARG, 0, 0, SRV_FORCE_IGNORE_CORRUPT, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -669,6 +680,7 @@ innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chu innobackupex --apply-log [--use-memory=B]\n\ [--defaults-file=MY.CNF]\n\ [--export] [--ibbackup=IBBACKUP-BINARY]\n\ + [--innodb-force-recovery=1]\n\ BACKUP-DIR\n\ \n\ innobackupex --copy-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\ diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ffb09c73edb..59551a7d044 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -271,6 +271,12 @@ static char *xtrabackup_debug_sync = NULL; my_bool xtrabackup_incremental_force_scan = FALSE; +/* + * Ignore corrupt pages (disabled by default; used + * by "innobackupex" as a command line argument). + */ +ulong xtrabackup_innodb_force_recovery = 0; + /* The flushed lsn which is read from data files */ lsn_t flushed_lsn= 0; @@ -1046,7 +1052,8 @@ enum options_xtrabackup OPT_ROCKSDB_DATADIR, OPT_BACKUP_ROCKSDB, OPT_XTRA_CHECK_PRIVILEGES, - OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION + OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION, + OPT_INNODB_FORCE_RECOVERY }; struct my_option xb_client_options[]= { @@ -1677,6 +1684,13 @@ struct my_option xb_server_options[] = &opt_check_privileges, &opt_check_privileges, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, + {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY, + "(for --prepare): Crash recovery mode (ignores " + "page corruption; for emergencies only).", + (G_PTR*)&srv_force_recovery, + (G_PTR*)&srv_force_recovery, + 0, GET_ULONG, OPT_ARG, 0, 0, SRV_FORCE_IGNORE_CORRUPT, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1808,24 +1822,26 @@ static int prepare_export() " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" - " --console --skip-log-error --skip-log-bin --bootstrap < " + " --console --skip-log-error --skip-log-bin --bootstrap %s < " BOOTSTRAP_FILENAME IF_WIN("\"",""), - mariabackup_exe, + mariabackup_exe, orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""), - xtrabackup_use_memory); + xtrabackup_use_memory, + (srv_force_recovery ? "--innodb-force-recovery=1" : "")); } else { - sprintf(cmdline, + snprintf(cmdline, sizeof cmdline, IF_WIN("\"","") "\"%s\" --mysqld" " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" - " --console --log-error= --skip-log-bin --bootstrap < " + " --console --log-error= --skip-log-bin --bootstrap %s < " BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, (my_defaults_group_suffix?my_defaults_group_suffix:""), - xtrabackup_use_memory); + xtrabackup_use_memory, + (srv_force_recovery ? "--innodb-force-recovery=1" : "")); } msg("Prepare export : executing %s\n", cmdline); @@ -1985,6 +2001,13 @@ xb_get_one_option(int optid, ADD_PRINT_PARAM_OPT(innobase_buffer_pool_filename); break; + case OPT_INNODB_FORCE_RECOVERY: + + if (srv_force_recovery) { + ADD_PRINT_PARAM_OPT(srv_force_recovery); + } + break; + case OPT_XTRA_TARGET_DIR: strmake(xtrabackup_real_target_dir,argument, sizeof(xtrabackup_real_target_dir)-1); xtrabackup_target_dir= xtrabackup_real_target_dir; @@ -2250,6 +2273,29 @@ innodb_init_param(void) srv_undo_dir = (char*) "."; } + compile_time_assert(SRV_FORCE_IGNORE_CORRUPT == 1); + + /* + * This option can be read both from the command line, and the + * defaults file. The assignment should account for both cases, + * and for "--innobackupex". Since the command line argument is + * parsed after the defaults file, it takes precedence. + */ + if (xtrabackup_innodb_force_recovery) { + srv_force_recovery = xtrabackup_innodb_force_recovery; + } + + if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { + if (!xtrabackup_prepare) { + msg("mariabackup: The option \"innodb_force_recovery\"" + " should only be used with \"%s\".", + (innobackupex_mode ? "--apply-log" : "--prepare")); + goto error; + } else { + msg("innodb_force_recovery = %lu", srv_force_recovery); + } + } + return(FALSE); error: diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index 15d53d00db4..e2955f58d6a 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -172,6 +172,8 @@ enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_ON, extern ulong opt_binlog_info; +extern ulong xtrabackup_innodb_force_recovery; + void xtrabackup_io_throttling(void); my_bool xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info); diff --git a/mysql-test/suite/mariabackup/innodb_force_recovery.result b/mysql-test/suite/mariabackup/innodb_force_recovery.result new file mode 100644 index 00000000000..94a265cfabe --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_force_recovery.result @@ -0,0 +1,26 @@ +CREATE TABLE t(i INT) ENGINE INNODB; +INSERT INTO t VALUES(1); +# "innodb_force_recovery=1" should be allowed with "--prepare" only (mariabackup) +FOUND 1 /should only be used with "--prepare"/ in backup.log +# "innodb_force_recovery=1" should be allowed with "--apply-log" only (innobackupex) +FOUND 1 /should only be used with "--apply-log"/ in backup.log +# "innodb_force_recovery" should be limited to "SRV_FORCE_IGNORE_CORRUPT" (mariabackup) +FOUND 1 /innodb_force_recovery = 1/ in backup.log +# "innodb_force_recovery" should be limited to "SRV_FORCE_IGNORE_CORRUPT" (innobackupex) +FOUND 1 /innodb_force_recovery = 1/ in backup.log +# "innodb_force_recovery" should be read from "backup-my.cnf" (mariabackup) +FOUND 1 /innodb_force_recovery = 1/ in backup.log +# "innodb_force_recovery=1" should be read from "backup-my.cnf" (innobackupex) +FOUND 1 /innodb_force_recovery = 1/ in backup.log +# "innodb_force_recovery" from the command line should override "backup-my.cnf" (mariabackup) +NOT FOUND /innodb_force_recovery = 1/ in backup.log +# "innodb_force_recovery" from the command line should override "backup-my.cnf" (innobackupex) +NOT FOUND /innodb_force_recovery = 1/ in backup.log +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t; +i +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/innodb_force_recovery.test b/mysql-test/suite/mariabackup/innodb_force_recovery.test new file mode 100644 index 00000000000..3a7b3c6106c --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_force_recovery.test @@ -0,0 +1,138 @@ +# This test checks if "innodb_force_recovery" is only allowed with "--prepare" +# (for mariabackup) and "--apply-log" (for innobackupex), and is limited to +# "SRV_FORCE_IGNORE_CORRUPT" only. + +# Setup. +--source include/have_innodb.inc + +--let targetdir=$MYSQLTEST_VARDIR/tmp/backup +--let backuplog=$MYSQLTEST_VARDIR/tmp/backup.log + +CREATE TABLE t(i INT) ENGINE INNODB; +INSERT INTO t VALUES(1); + +# Check for command line arguments. +--echo # "innodb_force_recovery=1" should be allowed with "--prepare" only (mariabackup) +--disable_result_log +--error 1 +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --innodb-force-recovery=1 --target-dir=$targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=should only be used with "--prepare" +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc + +--echo # "innodb_force_recovery=1" should be allowed with "--apply-log" only (innobackupex) +--disable_result_log +--error 1 +exec $XTRABACKUP --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --no-timestamp --innodb-force-recovery=1 $targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=should only be used with "--apply-log" +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log +--echo # "innodb_force_recovery" should be limited to "SRV_FORCE_IGNORE_CORRUPT" (mariabackup) +--disable_result_log +exec $XTRABACKUP --prepare --innodb-force-recovery=2 --target-dir=$targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $targetdir; + +--disable_result_log +exec $XTRABACKUP --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --no-timestamp $targetdir; +--enable_result_log +--echo # "innodb_force_recovery" should be limited to "SRV_FORCE_IGNORE_CORRUPT" (innobackupex) +--disable_result_log +exec $XTRABACKUP --innobackupex --apply-log --innodb-force-recovery=2 $targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $targetdir; + +# Check for default file ("backup-my.cnf"). +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log +perl; +my $cfg_path="$ENV{'targetdir'}/backup-my.cnf"; +open(my $fd, '>>', "$cfg_path"); +print $fd "innodb_force_recovery=1\n"; +close $fd; +EOF +--echo # "innodb_force_recovery" should be read from "backup-my.cnf" (mariabackup) +--disable_result_log +exec $XTRABACKUP --defaults-file=$targetdir/backup-my.cnf --prepare --export --target-dir=$targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $targetdir; + +--disable_result_log +exec $XTRABACKUP --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --no-timestamp $targetdir; +--enable_result_log +perl; +my $cfg_path="$ENV{'targetdir'}/backup-my.cnf"; +open(my $fd, '>>', "$cfg_path"); +print $fd "innodb_force_recovery=2\n"; +close $fd; +EOF +--echo # "innodb_force_recovery=1" should be read from "backup-my.cnf" (innobackupex) +--disable_result_log +exec $XTRABACKUP --innobackupex --defaults-file=$targetdir/backup-my.cnf --apply-log --export $targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $targetdir; + +# Check for command line argument precedence. +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log +perl; +my $cfg_path="$ENV{'targetdir'}/backup-my.cnf"; +open(my $fd, '>>', "$cfg_path"); +print $fd "innodb_force_recovery=1\n"; +close $fd; +EOF +--echo # "innodb_force_recovery" from the command line should override "backup-my.cnf" (mariabackup) +--disable_result_log +exec $XTRABACKUP --defaults-file=$targetdir/backup-my.cnf --prepare --innodb-force-recovery=0 --target-dir=$targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $targetdir; + +--disable_result_log +exec $XTRABACKUP --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --no-timestamp $targetdir; +--enable_result_log +perl; +my $cfg_path="$ENV{'targetdir'}/backup-my.cnf"; +open(my $fd, '>>', "$cfg_path"); +print $fd "innodb_force_recovery=2\n"; +close $fd; +EOF +--echo # "innodb_force_recovery" from the command line should override "backup-my.cnf" (innobackupex) +--disable_result_log +exec $XTRABACKUP --innobackupex --defaults-file=$targetdir/backup-my.cnf --apply-log --innodb-force-recovery=0 --export $targetdir >$backuplog; +--enable_result_log +--let SEARCH_PATTERN=innodb_force_recovery = 1 +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc + +--source include/restart_and_restore.inc + +# Check for restore. +SELECT * FROM t; + +# Clean-up. +DROP TABLE t; +--rmdir $targetdir +--remove_file $backuplog diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index a7be1cdbf21..9548730b359 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2322,7 +2322,7 @@ files_checked: to the data files and truncate or delete the log. Unless --export is specified, no further change to InnoDB files is needed. */ - ut_ad(!srv_force_recovery); + ut_ad(srv_force_recovery <= SRV_FORCE_IGNORE_CORRUPT); ut_ad(srv_n_log_files_found <= 1); ut_ad(recv_no_log_write); buf_flush_sync_all_buf_pools(); From fb9d151934c3444e55eb3ea505e2403d082c9a85 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Thu, 1 Apr 2021 21:47:30 +0200 Subject: [PATCH 06/12] MDEV-25321: mariabackup failed if password is passed via environment variable The mariabackup interface currently supports passing a password through an explicit command line variable, but does not support passing a password through the MYSQL_PWD environment variable. At the same time, the Galera SST script for mariabackup uses the environment variable to pass the password, which leads (in some cases) to an unsuccessful launch of mariabackup and to the inability to start the cluster. This patch fixes this issue. It does not need a separate test, as the problem is visible in general testing on buildbot. --- extra/mariabackup/innobackupex.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index fefd81dc1be..5bc320264e4 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -41,6 +41,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include +#include #include #include #include @@ -904,6 +905,12 @@ ibx_init() opt_user = opt_ibx_user; opt_password = opt_ibx_password; +#if !defined(DONT_USE_MYSQL_PWD) + if (!opt_password) + { + opt_password=getenv("MYSQL_PWD"); + } +#endif opt_host = opt_ibx_host; opt_defaults_group = opt_ibx_defaults_group; opt_socket = opt_ibx_socket; From 6fe624b5acf51383d39eb0e547a03779d41cf4a8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 3 Apr 2021 12:12:15 +0200 Subject: [PATCH 07/12] MDEV-25242 Server crashes in check_grant upon invoking function with userstat enabled also fix index_stats table. followup for 5a798071199 --- mysql-test/r/userstat.result | 2 ++ mysql-test/t/userstat.test | 2 ++ plugin/userstat/index_stats.cc | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/userstat.result b/mysql-test/r/userstat.result index 804d5451252..8aad76c3750 100644 --- a/mysql-test/r/userstat.result +++ b/mysql-test/r/userstat.result @@ -240,6 +240,8 @@ create function f() returns int return (select 1 from performance_schema.threads set global userstat= 1; select f() from information_schema.table_statistics; ERROR 21000: Subquery returns more than 1 row +select f() from information_schema.index_statistics; +ERROR 21000: Subquery returns more than 1 row set global userstat= 0; drop function f; # diff --git a/mysql-test/t/userstat.test b/mysql-test/t/userstat.test index cc7ddd58e11..6d486810db1 100644 --- a/mysql-test/t/userstat.test +++ b/mysql-test/t/userstat.test @@ -121,6 +121,8 @@ create function f() returns int return (select 1 from performance_schema.threads set global userstat= 1; --error ER_SUBQUERY_NO_1_ROW select f() from information_schema.table_statistics; +--error ER_SUBQUERY_NO_1_ROW +select f() from information_schema.index_statistics; set global userstat= 0; drop function f; diff --git a/plugin/userstat/index_stats.cc b/plugin/userstat/index_stats.cc index 87e6da63e38..1a7b0bbfcbd 100644 --- a/plugin/userstat/index_stats.cc +++ b/plugin/userstat/index_stats.cc @@ -26,7 +26,7 @@ static int index_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) tmp_table.grant.privilege= 0; if (check_access(thd, SELECT_ACL, tmp_table.db, &tmp_table.grant.privilege, NULL, 0, 1) || - check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) + check_grant(thd, SELECT_ACL, &tmp_table, 1, 1, 1)) continue; index_name= strend(tmp_table.table_name)+1; From c32edd75155129fbfe353aed6402374d40e63b65 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 6 Apr 2021 18:51:41 +0530 Subject: [PATCH 08/12] MDEV-25295 Aborted FTS_DOC_ID_INDEX considered as existing FTS_DOC_ID_INDEX during DDL InnoDB should skip the dropped aborted FTS_DOC_ID_INDEX while checking the existing FTS_DOC_ID_INDEX in the table. InnoDB should able to create new FTS_DOC_ID_INDEX if the fulltext index is being added for the first time. --- mysql-test/suite/innodb_fts/r/fulltext.result | 13 +++++++++++++ mysql-test/suite/innodb_fts/t/fulltext.test | 14 ++++++++++++++ storage/innobase/handler/handler0alter.cc | 6 ++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index 42e294b3293..90deb48a223 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -691,3 +691,16 @@ FTS_DOC_ID t 2 foo bar 3 foo DROP TABLE t; +# +# MDEV-25295 Aborted FTS_DOC_ID_INDEX considered as +# existing FTS_DOC_ID_INDEX during DDL +# +SET sql_mode=''; +CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL,title CHAR(1),body TEXT)engine=innodb; +INSERT INTO t1 (FTS_DOC_ID,title,body)VALUES(1,0,0), (1,0,0); +CREATE FULLTEXT INDEX idx1 ON t1 (title,body); +ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +CREATE FULLTEXT INDEX idx1 ON t1 (title,body); +ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +DROP TABLE t1; +SET sql_mode = DEFAULT; diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 663b202265b..1533c573ebf 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -717,3 +717,17 @@ while ($N) } DROP TABLE t; + +--echo # +--echo # MDEV-25295 Aborted FTS_DOC_ID_INDEX considered as +--echo # existing FTS_DOC_ID_INDEX during DDL +--echo # +SET sql_mode=''; +CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL,title CHAR(1),body TEXT)engine=innodb; +INSERT INTO t1 (FTS_DOC_ID,title,body)VALUES(1,0,0), (1,0,0); +--error ER_DUP_ENTRY +CREATE FULLTEXT INDEX idx1 ON t1 (title,body); +--error ER_DUP_ENTRY +CREATE FULLTEXT INDEX idx1 ON t1 (title,body); +DROP TABLE t1; +SET sql_mode = DEFAULT; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index e03621795ba..ccc3fe3b921 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2404,9 +2404,11 @@ innobase_fts_check_doc_id_index( for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { + /* Check if there exists a unique index with the name of - FTS_DOC_ID_INDEX_NAME */ - if (innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) { + FTS_DOC_ID_INDEX_NAME and ignore the corrupted index */ + if (index->type & DICT_CORRUPT + || innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) { continue; } From 82a2ea64b47ba7d4f10019418f84a0f3131d1c11 Mon Sep 17 00:00:00 2001 From: Arnaud Rebillout Date: Fri, 19 Mar 2021 17:11:04 +0700 Subject: [PATCH 09/12] Fix postinst trigger when systemd is not running (Closes: #983563) Checking for the existence of the systemctl command only tells us that systemd is installed, however it does not tell us if systemd is running. What we really want to do here is reload systemd if it's installed AND if it's running. The usual way to check if systemd is running is to check for the existence of '/run/systemd/system'. Why would systemd be installed but not running? This is something that happens when one sets up or upgrade a system in a chroot or container. For more details refer to the bug report: Closes PR #1787 --- debian/mariadb-server-10.2.postinst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/mariadb-server-10.2.postinst b/debian/mariadb-server-10.2.postinst index 063f0d8c58b..057b1bf540e 100644 --- a/debian/mariadb-server-10.2.postinst +++ b/debian/mariadb-server-10.2.postinst @@ -247,8 +247,8 @@ EOF ;; triggered) - if [ -x "$(command -v systemctl)" ]; then - systemctl daemon-reload + if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload fi invoke restart ;; From 72da83ff99860878fc28a1f26bfd893baa153368 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 30 Mar 2021 18:42:28 +0530 Subject: [PATCH 10/12] MDEV-25019 memory allocation failures during startup because server failure in different, confusing ways InnoDB fails to free the buffer pool instance mutex and zip mutex If the allocation of buffer pool instance chunk fails. So it leads to freeing of buffer pool before freeing the mutexes and leads to double freeing of memory while freeing the mutex during shutdown. --- .../suite/innodb/r/innodb_buffer_pool_fail.result | 7 +++++++ .../suite/innodb/t/innodb_buffer_pool_fail.test | 11 +++++++++++ storage/innobase/buf/buf0buf.cc | 4 ++++ 3 files changed, 22 insertions(+) create mode 100644 mysql-test/suite/innodb/r/innodb_buffer_pool_fail.result create mode 100644 mysql-test/suite/innodb/t/innodb_buffer_pool_fail.test diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_fail.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_fail.result new file mode 100644 index 00000000000..9f6959cb993 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_fail.result @@ -0,0 +1,7 @@ +call mtr.add_suppression("InnoDB: Cannot allocate memory for the buffer pool"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted at srv0start.cc.*"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +# +# MDEV-25019 memory allocation failures during startup cause server failure in different, confusing ways +# diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_fail.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_fail.test new file mode 100644 index 00000000000..1d938e12e78 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_fail.test @@ -0,0 +1,11 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +call mtr.add_suppression("InnoDB: Cannot allocate memory for the buffer pool"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted at srv0start.cc.*"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +--echo # +--echo # MDEV-25019 memory allocation failures during startup cause server failure in different, confusing ways +--echo # +let restart_parameters=--debug_dbug="+d,ib_buf_chunk_init_fails"; +--source include/restart_mysqld.inc diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 9f3d743ada1..070789288b6 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1864,6 +1864,10 @@ buf_pool_init_instance( ut_free(buf_pool->chunks); buf_pool_mutex_exit(buf_pool); + /* InnoDB should free the mutex which was + created so far before freeing the instance */ + mutex_free(&buf_pool->mutex); + mutex_free(&buf_pool->zip_mutex); return(DB_ERROR); } From c6d0531cad096e6b85ee34209f1b083e6f77a42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 8 Apr 2021 09:46:56 +0300 Subject: [PATCH 11/12] MDEV-13467 fixup: Improve error handling --- sql/spatial.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sql/spatial.cc b/sql/spatial.cc index 711efa91394..7bb3ecff948 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2013, Monty Program Ab. + Copyright (c) 2011, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1050,7 +1050,7 @@ double Gis_point::calculate_haversine(const Geometry *g, int *error) { DBUG_ASSERT(sphere_radius > 0); - double x1r, x2r, y1r, y2r, dlong, dlat, res; + double x1r, x2r, y1r, y2r; // This check is done only for optimization purposes where we know it will // be one and only one point in Multipoint @@ -1067,31 +1067,39 @@ double Gis_point::calculate_haversine(const Geometry *g, Geometry *gg= Geometry::construct(&gbuff, point_temp, point_size-1); DBUG_ASSERT(gg); if (static_cast(gg)->get_xy_radian(&x2r, &y2r)) + { DBUG_ASSERT(0); + return -1; + } } else { if (static_cast(g)->get_xy_radian(&x2r, &y2r)) + { DBUG_ASSERT(0); + return -1; + } } if (this->get_xy_radian(&x1r, &y1r)) + { DBUG_ASSERT(0); + return -1; + } // Check boundary conditions: longitude[-180,180] if (!((x2r >= -M_PI && x2r <= M_PI) && (x1r >= -M_PI && x1r <= M_PI))) { *error=1; return -1; } - // Check boundary conditions: lattitude[-90,90] + // Check boundary conditions: latitude[-90,90] if (!((y2r >= -M_PI/2 && y2r <= M_PI/2) && (y1r >= -M_PI/2 && y1r <= M_PI/2))) { *error=-1; return -1; } - dlat= sin((y2r - y1r)/2)*sin((y2r - y1r)/2); - dlong= sin((x2r - x1r)/2)*sin((x2r - x1r)/2); - res= 2*sphere_radius*asin((sqrt(dlat + cos(y1r)*cos(y2r)*dlong))); - return res; + double dlat= sin((y2r - y1r)/2)*sin((y2r - y1r)/2); + double dlong= sin((x2r - x1r)/2)*sin((x2r - x1r)/2); + return 2*sphere_radius*asin((sqrt(dlat + cos(y1r)*cos(y2r)*dlong))); } From 5a3151bcda2f279091a1e2f049a7d11cd91065d6 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 9 Apr 2021 12:01:42 +0530 Subject: [PATCH 12/12] Improve diagnostics in order to catch MDEV-18868 and similar bugs --- storage/innobase/fts/fts0fts.cc | 18 ++++++++++++------ storage/innobase/include/btr0bulk.h | 2 ++ storage/innobase/row/row0ftsort.cc | 6 ++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 1bdfbddca04..a74b5083128 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2546,7 +2546,8 @@ fts_get_max_cache_size( } } else { ib::error() << "(" << error << ") reading max" - " cache config value from config table"; + " cache config value from config table " + << fts_table->table->name; } ut_free(value.f_str); @@ -2719,7 +2720,8 @@ func_exit: } else { *doc_id = 0; - ib::error() << "(" << error << ") while getting next doc id."; + ib::error() << "(" << error << ") while getting next doc id " + "for table " << table->name; fts_sql_rollback(trx); if (error == DB_DEADLOCK) { @@ -2799,7 +2801,8 @@ fts_update_sync_doc_id( cache->synced_doc_id = doc_id; } else { ib::error() << "(" << error << ") while" - " updating last doc id."; + " updating last doc id for table" + << table->name; fts_sql_rollback(trx); } @@ -4044,7 +4047,8 @@ fts_sync_write_words( if (UNIV_UNLIKELY(error != DB_SUCCESS) && !print_error) { ib::error() << "(" << error << ") writing" - " word node to FTS auxiliary index table."; + " word node to FTS auxiliary index table " + << table->name; print_error = TRUE; } } @@ -4199,7 +4203,8 @@ fts_sync_commit( fts_sql_commit(trx); } else { fts_sql_rollback(trx); - ib::error() << "(" << error << ") during SYNC."; + ib::error() << "(" << error << ") during SYNC of " + "table " << sync->table->name; } if (UNIV_UNLIKELY(fts_enable_diag_print) && elapsed_time) { @@ -4970,7 +4975,8 @@ fts_get_rows_count( trx->error_state = DB_SUCCESS; } else { ib::error() << "(" << error - << ") while reading FTS table."; + << ") while reading FTS table " + << table_name; break; /* Exit the loop. */ } diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h index 854414d504d..6687d29593a 100644 --- a/storage/innobase/include/btr0bulk.h +++ b/storage/innobase/include/btr0bulk.h @@ -326,6 +326,8 @@ public: /** Re-latch all latches */ void latch(); + dict_index_t* index() { return m_index; } + private: /** Insert a tuple to a page in a level @param[in] tuple tuple to insert diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 4085ff17bd3..39b31c153ad 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -924,7 +924,7 @@ loop: << " records, the sort queue has " << UT_LIST_GET_LEN(psort_info->fts_doc_list) << " records. But sort cannot get the next" - " records"; + " records during alter table " << table->name; goto exit; } } else if (psort_info->state == FTS_PARENT_EXITING) { @@ -1220,7 +1220,9 @@ row_merge_write_fts_word( if (UNIV_UNLIKELY(error != DB_SUCCESS)) { ib::error() << "Failed to write word to FTS auxiliary" - " index table, error " << error; + " index table " + << ins_ctx->btr_bulk->index()->table->name + << ", error " << error; ret = error; }