From 2061e00c200cc994130c00d58632aecba336273b Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 17 Jan 2019 22:56:12 +0200 Subject: MDEV-14440: Assertion `inited==RND' failed in handler::ha_rnd_end In the function QUICK_RANGE_SELECT::init_ror_merged_scan we create a seperate handler if the handler in head->file cannot be reused. The flag free_file tells us if we have a seperate handler or not. There are cases where you might create a handler and then there might be a failure(running ALTER) and then we have to revert the handler back to the original one. The code does that but it does not reset the flag 'free_file' in this case. Also backported f2c418079def. --- mysql-test/r/range_innodb.result | 24 ++++++++++++++++++++++++ mysql-test/t/range_innodb.test | 25 +++++++++++++++++++++++++ sql/opt_range.cc | 3 +++ 3 files changed, 52 insertions(+) diff --git a/mysql-test/r/range_innodb.result b/mysql-test/r/range_innodb.result index 8bb1c833a56..6572b248911 100644 --- a/mysql-test/r/range_innodb.result +++ b/mysql-test/r/range_innodb.result @@ -55,3 +55,27 @@ pk f1 f2 f3 pk f1 f2 f3 f4 f5 2 6 v NULL 14 1 q NULL 4 q 3 7 c NULL 14 1 q NULL 4 q drop table t1,t2; +# +# MDEV-14440: Server crash in in handler::ha_external_lock or Assertion `inited==RND' +# failed in handler::ha_rnd_end upon SELECT from partitioned table +# +set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='index_merge_sort_intersection=off'; +create table t0 (a int)engine=innodb; +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 ( +a int, b int, c int, +key(a),key(b),key(c) +)engine=innodb; +insert into t1 +select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a +from t0 A, t0 B, t0 C, t0 D where D.a<5; +set @@global.debug_dbug="+d,ha_index_init_fail"; +explain select * from t1 where a=10 and b=10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where +select * from t1 where a=10 and b=10; +ERROR HY000: Table definition has changed, please retry transaction +DROP TABLE t0,t1; +set @@global.debug_dbug="-d"; +set @@optimizer_switch= @optimizer_switch_save; diff --git a/mysql-test/t/range_innodb.test b/mysql-test/t/range_innodb.test index 605006587cc..a17ef3f1146 100644 --- a/mysql-test/t/range_innodb.test +++ b/mysql-test/t/range_innodb.test @@ -3,6 +3,7 @@ --echo # --source include/have_innodb.inc +--source include/have_debug.inc --disable_warnings drop table if exists t0, t1, t2; @@ -62,3 +63,27 @@ INSERT INTO t2 VALUES (4,'q'),(NULL,'j'); SELECT * FROM t1 AS t1_1, t1 AS t1_2, t2 WHERE f5 = t1_2.f2 AND ( t1_1.f1 = 103 AND t1_1.f2 = 'o' OR t1_1.pk < f4 ); drop table t1,t2; + +--echo # +--echo # MDEV-14440: Server crash in in handler::ha_external_lock or Assertion `inited==RND' +--echo # failed in handler::ha_rnd_end upon SELECT from partitioned table +--echo # + +set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='index_merge_sort_intersection=off'; +create table t0 (a int)engine=innodb; +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 ( + a int, b int, c int, + key(a),key(b),key(c) +)engine=innodb; +insert into t1 +select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a +from t0 A, t0 B, t0 C, t0 D where D.a<5; +set @@global.debug_dbug="+d,ha_index_init_fail"; +explain select * from t1 where a=10 and b=10; +--error ER_TABLE_DEF_CHANGED +select * from t1 where a=10 and b=10; +DROP TABLE t0,t1; +set @@global.debug_dbug="-d"; +set @@optimizer_switch= @optimizer_switch_save; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b1f8366d83b..ef40e0b6daa 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2161,6 +2161,7 @@ failure: head->column_bitmaps_set(save_read_set, save_write_set); delete file; file= save_file; + free_file= false; DBUG_RETURN(1); } @@ -7140,6 +7141,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, if (ror_intersect_add(intersect, cpk_scan, TRUE) && (intersect->total_cost < min_cost)) intersect_best= intersect; //just set pointer here + else + cpk_scan= 0; // Don't use cpk_scan } else cpk_scan= 0; // Don't use cpk_scan -- cgit v1.2.1 From 2084cd542275db4b1ed178dd3160535c71a2314a Mon Sep 17 00:00:00 2001 From: Geoff Montee Date: Mon, 21 Jan 2019 05:42:00 -0500 Subject: MDEV-17973: Don't overwrite xtrabackup-v2/mariabackup SST logs by default --- scripts/wsrep_sst_mariabackup.sh | 78 +++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index d9fbae8c5e8..70bd76a36eb 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -90,6 +90,9 @@ DATA="${WSREP_SST_OPT_DATA}" INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" MAGIC_FILE="${DATA}/${INFO_FILE}" +INNOAPPLYLOG="${DATA}/mariabackup.prepare.log" +INNOMOVELOG="${DATA}/mariabackup.move.log" +INNOBACKUPLOG="${DATA}/mariabackup.backup.log" # Setting the path for ss and ip export PATH="/usr/sbin:/sbin:$PATH" @@ -356,6 +359,8 @@ read_cnf() ssyslog=$(parse_cnf sst sst-syslog 0) ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}") ssystag+="-" + sstlogarchive=$(parse_cnf sst sst-log-archive 1) + sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir "/tmp/sst_log_archive") if [[ $speciald -eq 0 ]];then wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" @@ -712,10 +717,68 @@ if [[ $ssyslog -eq 1 ]];then INNOBACKUP="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi -else - INNOAPPLY="${INNOBACKUPEX_BIN} --innobackupex $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log" - INNOMOVE="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log" - INNOBACKUP="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log" +else + +if [[ "$sstlogarchive" -eq 1 ]] +then + ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S") + newfile="" + + if [[ ! -z "$sstlogarchivedir" ]] + then + if [[ ! -d "$sstlogarchivedir" ]] + then + mkdir -p "$sstlogarchivedir" + fi + fi + + if [ -e "${INNOAPPLYLOG}" ] + then + if [[ ! -z "$sstlogarchivedir" ]] + then + newfile=$sstlogarchivedir/$(basename "${INNOAPPLYLOG}").${ARCHIVETIMESTAMP} + else + newfile=${INNOAPPLYLOG}.${ARCHIVETIMESTAMP} + fi + + wsrep_log_info "Moving ${INNOAPPLYLOG} to ${newfile}" + mv "${INNOAPPLYLOG}" "${newfile}" + gzip "${newfile}" + fi + + if [ -e "${INNOMOVELOG}" ] + then + if [[ ! -z "$sstlogarchivedir" ]] + then + newfile=$sstlogarchivedir/$(basename "${INNOMOVELOG}").${ARCHIVETIMESTAMP} + else + newfile=${INNOMOVELOG}.${ARCHIVETIMESTAMP} + fi + + wsrep_log_info "Moving ${INNOMOVELOG} to ${newfile}" + mv "${INNOMOVELOG}" "${newfile}" + gzip "${newfile}" + fi + + if [ -e "${INNOBACKUPLOG}" ] + then + if [[ ! -z "$sstlogarchivedir" ]] + then + newfile=$sstlogarchivedir/$(basename "${INNOBACKUPLOG}").${ARCHIVETIMESTAMP} + else + newfile=${INNOBACKUPLOG}.${ARCHIVETIMESTAMP} + fi + + wsrep_log_info "Moving ${INNOBACKUPLOG} to ${newfile}" + mv "${INNOBACKUPLOG}" "${newfile}" + gzip "${newfile}" + fi + +fi + + INNOAPPLY="${INNOBACKUPEX_BIN} --innobackupex $disver $iapts --apply-log \$rebuildcmd \${DATA} &> ${INNOAPPLYLOG}" + INNOMOVE="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &> ${INNOMOVELOG}" + INNOBACKUP="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> ${INNOBACKUPLOG}" fi get_stream @@ -812,7 +875,7 @@ then if [ ${RC[0]} -ne 0 ]; then wsrep_log_error "${INNOBACKUPEX_BIN} finished with error: ${RC[0]}. " \ - "Check ${DATA}/innobackup.backup.log" + "Check syslog or ${INNOBACKUPLOG} for details" exit 22 elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then wsrep_log_error "$tcmd finished with error: ${RC[1]}" @@ -1033,13 +1096,12 @@ then if [ $? -ne 0 ]; then - wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check ${DATA}/innobackup.prepare.log" + wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" exit 22 fi MAGIC_FILE="${TDATA}/${INFO_FILE}" set +e - rm $TDATA/innobackup.prepare.log $TDATA/innobackup.move.log set -e wsrep_log_info "Moving the backup to ${TDATA}" timeit "Xtrabackup move stage" "$INNOMOVE" @@ -1049,7 +1111,7 @@ then DATA=${TDATA} else wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" - wsrep_log_error "Check ${DATA}/innobackup.move.log for details" + wsrep_log_error "Check syslog or ${INNOMOVELOG} for details" exit 22 fi -- cgit v1.2.1 From 6786fb004c5f88f2d4da6534c49456e90676274d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 16 Jan 2019 14:46:36 +0100 Subject: MDEV-15925 FRM_MAX_SIZE too low for some use cases increase to 1M --- mysql-test/r/huge_frm-6224.result | 2 ++ mysql-test/t/huge_frm-6224.test | 11 +++++++++-- sql/unireg.h | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/huge_frm-6224.result b/mysql-test/r/huge_frm-6224.result index 3772317c04d..0d6dd968295 100644 --- a/mysql-test/r/huge_frm-6224.result +++ b/mysql-test/r/huge_frm-6224.result @@ -1 +1,3 @@ +set global max_allowed_packet=1024*1024*10; ERROR HY000: The definition for table `t1` is too big +set global max_allowed_packet=default; diff --git a/mysql-test/t/huge_frm-6224.test b/mysql-test/t/huge_frm-6224.test index 418722a7b51..322abd01738 100644 --- a/mysql-test/t/huge_frm-6224.test +++ b/mysql-test/t/huge_frm-6224.test @@ -4,17 +4,24 @@ # verify that huge frms are rejected during creation, not on opening # --source include/have_partition.inc +set global max_allowed_packet=1024*1024*10; +connect con1,localhost,root; -let $n=5646; +let $n=8164; let $a=create table t1 (a int) engine=myisam partition by hash(a) partitions $n (; dec $n; while ($n) { - let $a=$a partition p01234567890123456789012345678901234567890123456789012345678$n,; + let $a=$a partition p01234567890123456789012345678901234567890123456789012345678$n COMMENT 'partition p01234567890123456789012345678901234567890123456789012345678$n',; dec $n; } --disable_query_log --error ER_TABLE_DEFINITION_TOO_BIG eval $a partition foo); +--enable_query_log + +connection default; +disconnect con1; +set global max_allowed_packet=default; diff --git a/sql/unireg.h b/sql/unireg.h index b13dd494c74..f32a2fdfe12 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -202,7 +202,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, #define FRM_HEADER_SIZE 64 #define FRM_FORMINFO_SIZE 288 -#define FRM_MAX_SIZE (512*1024) +#define FRM_MAX_SIZE (1024*1024) static inline bool is_binary_frm_header(uchar *head) { -- cgit v1.2.1 From 31d592ba7d3a2d2d227e5d4bf36f0866c9932c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 23 Jan 2019 12:05:24 +0200 Subject: MDEV-18349 InnoDB file size changes are not safe when file system crashes When InnoDB is invoking posix_fallocate() to extend data files, it was missing a call to fsync() to update the file system metadata. If file system recovery is needed, the file size could be incorrect. When the setting innodb_flush_method=O_DIRECT_NO_FSYNC that was introduced in MariaDB 10.0.11 (and MySQL 5.6) is enabled, InnoDB would wrongly skip fsync() after extending files. Furthermore, the merge commit d8b45b0c004edc0b91029b232d7cc9aad02cc822 inadvertently removed XtraDB error checking for posix_fallocate() which this fix is restoring. fil_flush(): Add the parameter bool metadata=false to request that fil_buffering_disabled() be ignored. fil_extend_space_to_desired_size(): Invoke fil_flush() with the extra parameter. After successful posix_fallocate(), invoke os_file_flush(). Note: The bookkeeping for fil_flush() would not be updated the posix_fallocate() code path, so the "redundant" fil_flush() should be a no-op. --- storage/innobase/fil/fil0fil.cc | 27 +++++++++++++-------------- storage/innobase/include/fil0fil.h | 16 ++++++---------- storage/xtradb/fil/fil0fil.cc | 36 ++++++++++++++++++++++-------------- storage/xtradb/include/fil0fil.h | 16 ++++++---------- 4 files changed, 47 insertions(+), 48 deletions(-) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index f852a64e2e9..e05d9565507 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2019, 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 @@ -4914,6 +4914,8 @@ retry: " failed with error %d", node->name, start_offset, len + start_offset, err); + } else { + os_file_flush(node->handle); } DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", @@ -5025,7 +5027,7 @@ file_extended: size_after_extend, *actual_size); */ mutex_exit(&fil_system->mutex); - fil_flush(space_id); + fil_flush(space_id, true); return(success); } @@ -5641,21 +5643,16 @@ fil_aio_wait( } #endif /* UNIV_HOTBACKUP */ -/**********************************************************************//** -Flushes to disk possible writes cached by the OS. If the space does not exist -or is being dropped, does not do anything. */ -UNIV_INTERN -void -fil_flush( -/*======*/ - ulint space_id) /*!< in: file space id (this can be a group of - log files or a tablespace of the database) */ +/** Make persistent possible writes cached by the OS. +If the space does not exist or is being dropped, do nothing. +@param[in] space_id tablespace identifier +@param[in] metadata whether to update file system metadata */ +UNIV_INTERN void fil_flush(ulint space_id, bool metadata) { fil_space_t* space; fil_node_t* node; pfs_os_file_t file; - mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(space_id); @@ -5684,8 +5681,10 @@ fil_flush( } #endif /* UNIV_DEBUG */ - mutex_exit(&fil_system->mutex); - return; + if (!metadata) { + mutex_exit(&fil_system->mutex); + return; + } } space->n_pending_flushes++; /*!< prevent dropping of the space while diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 7c0f623d890..ad279487a3d 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -972,15 +972,11 @@ fil_aio_wait( /*=========*/ ulint segment); /*!< in: the number of the segment in the aio array to wait for */ -/**********************************************************************//** -Flushes to disk possible writes cached by the OS. If the space does not exist -or is being dropped, does not do anything. */ -UNIV_INTERN -void -fil_flush( -/*======*/ - ulint space_id); /*!< in: file space id (this can be a group of - log files or a tablespace of the database) */ +/** Make persistent possible writes cached by the OS. +If the space does not exist or is being dropped, do nothing. +@param[in] space_id tablespace identifier +@param[in] metadata whether to update file system metadata */ +UNIV_INTERN void fil_flush(ulint space_id, bool metadata = false); /**********************************************************************//** Flushes to disk writes in file spaces of the given type possibly cached by the OS. */ diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 49c5f4b090b..755672d9962 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2019, 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 @@ -4947,6 +4947,17 @@ retry: } while (err == EINTR && srv_shutdown_state == SRV_SHUTDOWN_NONE); + success = !err; + if (!success) { + ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s" + " from " INT64PF " to " INT64PF " bytes" + " failed with error %d", + node->name, start_offset, len + start_offset, + err); + } else { + os_file_flush(node->handle); + } + DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", success = FALSE; os_has_said_disk_full = TRUE;); @@ -5056,7 +5067,7 @@ file_extended: size_after_extend, *actual_size); */ mutex_exit(&fil_system->mutex); - fil_flush(space_id); + fil_flush(space_id, true); return(success); } @@ -5705,21 +5716,16 @@ fil_aio_wait( } #endif /* UNIV_HOTBACKUP */ -/**********************************************************************//** -Flushes to disk possible writes cached by the OS. If the space does not exist -or is being dropped, does not do anything. */ -UNIV_INTERN -void -fil_flush( -/*======*/ - ulint space_id) /*!< in: file space id (this can be a group of - log files or a tablespace of the database) */ +/** Make persistent possible writes cached by the OS. +If the space does not exist or is being dropped, do nothing. +@param[in] space_id tablespace identifier +@param[in] metadata whether to update file system metadata */ +UNIV_INTERN void fil_flush(ulint space_id, bool metadata) { fil_space_t* space; fil_node_t* node; pfs_os_file_t file; - mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(space_id); @@ -5748,8 +5754,10 @@ fil_flush( } #endif /* UNIV_DEBUG */ - mutex_exit(&fil_system->mutex); - return; + if (!metadata) { + mutex_exit(&fil_system->mutex); + return; + } } space->n_pending_flushes++; /*!< prevent dropping of the space while diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 1f3574d4f71..8e737f8fb0e 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -976,15 +976,11 @@ fil_aio_wait( /*=========*/ ulint segment); /*!< in: the number of the segment in the aio array to wait for */ -/**********************************************************************//** -Flushes to disk possible writes cached by the OS. If the space does not exist -or is being dropped, does not do anything. */ -UNIV_INTERN -void -fil_flush( -/*======*/ - ulint space_id); /*!< in: file space id (this can be a group of - log files or a tablespace of the database) */ +/** Make persistent possible writes cached by the OS. +If the space does not exist or is being dropped, do nothing. +@param[in] space_id tablespace identifier +@param[in] metadata whether to update file system metadata */ +UNIV_INTERN void fil_flush(ulint space_id, bool metadata = false); /**********************************************************************//** Flushes to disk writes in file spaces of the given type possibly cached by the OS. */ -- cgit v1.2.1 From 2a0f1d613219ad7962c3394b9c1996ece40926df Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 22 Jan 2019 11:06:15 +0100 Subject: Bug#28867993: POSSIBLE ISSUE WITH MYSQL SERVER RESTART on startup innodb is checking whether files "ib_logfileN" (for N from 1 to 100) exist, and whether they're readable. A non-existent file aborted the scan. A directory instead of a file made InnoDB to fail. Now it treats "directory exists" as "file doesn't exist". --- mysql-test/suite/innodb/r/innodb_28867993.result | 9 +++++++++ mysql-test/suite/innodb/t/innodb_28867993.test | 12 ++++++++++++ storage/innobase/srv/srv0start.cc | 4 ++++ storage/xtradb/srv/srv0start.cc | 3 +++ 4 files changed, 28 insertions(+) create mode 100644 mysql-test/suite/innodb/r/innodb_28867993.result create mode 100644 mysql-test/suite/innodb/t/innodb_28867993.test diff --git a/mysql-test/suite/innodb/r/innodb_28867993.result b/mysql-test/suite/innodb/r/innodb_28867993.result new file mode 100644 index 00000000000..acc6734eaee --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_28867993.result @@ -0,0 +1,9 @@ +create table t1 (a int) engine=innodb; +insert t1 values (1),(2); +create database ib_logfile2; +select * from t1; +a +1 +2 +drop table t1; +drop database ib_logfile2; diff --git a/mysql-test/suite/innodb/t/innodb_28867993.test b/mysql-test/suite/innodb/t/innodb_28867993.test new file mode 100644 index 00000000000..61e9578df7b --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_28867993.test @@ -0,0 +1,12 @@ +# +# Bug#28867993: POSSIBLE ISSUE WITH MYSQL SERVER RESTART +# + +source include/have_innodb.inc; +create table t1 (a int) engine=innodb; +insert t1 values (1),(2); +create database ib_logfile2; +source include/restart_mysqld.inc; +select * from t1; +drop table t1; +drop database ib_logfile2; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 789fe50d337..8412f941588 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2255,6 +2255,10 @@ innobase_start_or_create_for_mysql() break; } + if (stat_info.type != OS_FILE_TYPE_FILE) { + break; + } + if (!srv_file_check_mode(logfilename)) { return(DB_ERROR); } diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 04f40d039b1..ddf618420d9 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -2335,6 +2335,9 @@ innobase_start_or_create_for_mysql() break; } + if (stat_info.type != OS_FILE_TYPE_FILE) { + break; + } if (!srv_file_check_mode(logfilename)) { return(DB_ERROR); } -- cgit v1.2.1 From 52d13036d81fdaa277c9894784dfefd85cf41287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 23 Jan 2019 13:44:20 +0200 Subject: MDEV-17933 slow server status - dict_sys_get_size() dict_sys_get_size(): Replace the time-consuming loop with a crude estimate that can be computed without holding any mutex. Even before dict_sys->size was removed in MDEV-13325, not all memory allocations by the InnoDB data dictionary cache were being accounted for. One example is foreign key constraints. Another example is virtual column metadata, starting with 10.2. --- storage/innobase/dict/dict0dict.cc | 38 +++++++++++--------------------------- storage/innobase/srv/srv0srv.cc | 4 +--- storage/xtradb/dict/dict0dict.cc | 38 +++++++++++--------------------------- storage/xtradb/srv/srv0srv.cc | 6 ++---- 4 files changed, 25 insertions(+), 61 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index b48d51c15a7..2a37db4e076 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -7250,30 +7250,14 @@ UNIV_INTERN ulint dict_sys_get_size() { - ulint size = 0; - - ut_ad(dict_sys); - - mutex_enter(&dict_sys->mutex); - - for(ulint i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) { - dict_table_t* table; - - for (table = static_cast(HASH_GET_FIRST(dict_sys->table_hash,i)); - table != NULL; - table = static_cast(HASH_GET_NEXT(name_hash, table))) { - dict_index_t* index; - size += mem_heap_get_size(table->heap) + strlen(table->name) +1; - - for(index = dict_table_get_first_index(table); - index != NULL; - index = dict_table_get_next_index(index)) { - size += mem_heap_get_size(index->heap); - } - } - } - - mutex_exit(&dict_sys->mutex); - - return (size); + /* No mutex; this is a very crude approximation anyway */ + ulint size = UT_LIST_GET_LEN(dict_sys->table_LRU) + + UT_LIST_GET_LEN(dict_sys->table_non_LRU); + size *= sizeof(dict_table_t) + + sizeof(dict_index_t) * 2 + + (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10 + + sizeof(dict_field_t) * 5 /* total number of key fields */ + + 200; /* arbitrary, covering names and overhead */ + + return size; } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 87f9064c14e..f17a6ddd94b 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -3,7 +3,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1341,8 +1341,6 @@ srv_printf_innodb_monitor( "; in additional pool allocated " ULINTPF "\n", ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); - fprintf(file, "Dictionary memory allocated " ULINTPF "\n", - dict_sys_get_size()); buf_print_io(file); diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 23082e53ec7..1eb0a53e0b0 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -7252,30 +7252,14 @@ UNIV_INTERN ulint dict_sys_get_size() { - ulint size = 0; - - ut_ad(dict_sys); - - mutex_enter(&dict_sys->mutex); - - for(ulint i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) { - dict_table_t* table; - - for (table = static_cast(HASH_GET_FIRST(dict_sys->table_hash,i)); - table != NULL; - table = static_cast(HASH_GET_NEXT(name_hash, table))) { - dict_index_t* index; - size += mem_heap_get_size(table->heap) + strlen(table->name) +1; - - for(index = dict_table_get_first_index(table); - index != NULL; - index = dict_table_get_next_index(index)) { - size += mem_heap_get_size(index->heap); - } - } - } - - mutex_exit(&dict_sys->mutex); - - return (size); + /* No mutex; this is a very crude approximation anyway */ + ulint size = UT_LIST_GET_LEN(dict_sys->table_LRU) + + UT_LIST_GET_LEN(dict_sys->table_non_LRU); + size *= sizeof(dict_table_t) + + sizeof(dict_index_t) * 2 + + (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10 + + sizeof(dict_field_t) * 5 /* total number of key fields */ + + 200; /* arbitrary, covering names and overhead */ + + return size; } diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 0133b17fada..c05b667dcf4 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -3,7 +3,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1642,9 +1642,7 @@ srv_printf_innodb_monitor( ? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0), recv_sys_subtotal); - - fprintf(file, "Dictionary memory allocated " ULINTPF "\n", - dict_sys ? dict_sys_get_size() : 0); + fprintf(file, "Dictionary memory allocated " ULINTPF "\n", dict_size); buf_print_io(file); -- cgit v1.2.1