diff --git a/client/mysqltest.cc b/client/mysqltest.cc index e059c102ca7..b5a771ec248 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -879,8 +879,7 @@ LogFile progress_file; void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input, - bool keep_header); +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input); static int match_expected_error(struct st_command *command, unsigned int err_errno, @@ -3490,7 +3489,7 @@ void do_exec(struct st_command *command) if (display_result_sorted) { - dynstr_append_sorted(&ds_res, &ds_sorted, 0); + dynstr_append_sorted(&ds_res, &ds_sorted); dynstr_free(&ds_sorted); } #ifdef _WIN32 @@ -7833,16 +7832,29 @@ void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) uint num_fields= mysql_num_fields(res); MYSQL_FIELD *fields= mysql_fetch_fields(res); ulong *lengths; + DYNAMIC_STRING rs_unsorted, *rs= ds; + + if (display_result_sorted) + { + init_dynamic_string(&rs_unsorted, "", 1024, 1024); + rs= &rs_unsorted; + } while ((row = mysql_fetch_row(res))) { uint i; lengths = mysql_fetch_lengths(res); for (i = 0; i < num_fields; i++) - append_field(ds, i, &fields[i], + append_field(rs, i, &fields[i], row[i], lengths[i], !row[i]); if (!display_result_vertically) - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(rs, "\n", 1); + } + + if (display_result_sorted) + { + dynstr_append_sorted(ds, &rs_unsorted); + dynstr_free(&rs_unsorted); } } @@ -7860,6 +7872,13 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, ulong *length; uint i; int error; + DYNAMIC_STRING rs_unsorted, *rs= ds; + + if (display_result_sorted) + { + init_dynamic_string(&rs_unsorted, "", 1024, 1024); + rs= &rs_unsorted; + } /* Allocate array with bind structs, lengths and NULL flags */ my_bind= (MYSQL_BIND*) my_malloc(PSI_NOT_INSTRUMENTED, num_fields * sizeof(MYSQL_BIND), @@ -7891,10 +7910,10 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, while ((error=mysql_stmt_fetch(stmt)) == 0) { for (i= 0; i < num_fields; i++) - append_field(ds, i, &fields[i], (char*)my_bind[i].buffer, + append_field(rs, i, &fields[i], (char*)my_bind[i].buffer, *my_bind[i].length, *my_bind[i].is_null); if (!display_result_vertically) - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(rs, "\n", 1); } if (error != MYSQL_NO_DATA) @@ -7913,6 +7932,12 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, my_free(my_bind); my_free(length); my_free(is_null); + + if (display_result_sorted) + { + dynstr_append_sorted(ds, &rs_unsorted); + dynstr_free(&rs_unsorted); + } } @@ -8113,7 +8138,7 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) if (type == SESSION_TRACK_SYSTEM_VARIABLES) { dynstr_append_mem(ds_type, STRING_WITH_LEN("\n")); - dynstr_append_sorted(ds, ds_type, false); + dynstr_append_sorted(ds, ds_type); dynstr_append_mem(ds, STRING_WITH_LEN("\n")); dynstr_free(&ds_sort); } @@ -8155,7 +8180,6 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) { uint count; MYSQL_RES *warn_res; - DYNAMIC_STRING res; DBUG_ENTER("append_warnings"); if (!(count= mysql_warning_count(mysql))) @@ -8176,18 +8200,8 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) die("Warning count is %u but didn't get any warnings", count); - init_dynamic_string(&res, "", 1024, 1024); - - append_result(&res, warn_res); + append_result(ds, warn_res); mysql_free_result(warn_res); - - DBUG_PRINT("warnings", ("%s", res.str)); - - if (display_result_sorted) - dynstr_append_sorted(ds, &res, 0); - else - dynstr_append_mem(ds, res.str, res.length); - dynstr_free(&res); DBUG_RETURN(count); } @@ -8702,8 +8716,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, DYNAMIC_STRING ds_prepare_warnings; DYNAMIC_STRING ds_execute_warnings; DYNAMIC_STRING ds_res_1st_execution; - DYNAMIC_STRING ds_res_2_execution_unsorted; - DYNAMIC_STRING *ds_res_2_output; my_bool ds_res_1st_execution_init = FALSE; my_bool compare_2nd_execution = TRUE; int query_match_ps2_re; @@ -8765,7 +8777,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, parameter markers. */ -#if MYSQL_VERSION_ID >= 50000 if (cursor_protocol_enabled) { ps2_protocol_enabled = 0; @@ -8785,7 +8796,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } } -#endif query_match_ps2_re = match_re(&ps2_re, query); @@ -8852,29 +8862,8 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, !disable_warnings) append_warnings(&ds_execute_warnings, mysql); - if (!disable_result_log && - compare_2nd_execution && - ps2_protocol_enabled && - query_match_ps2_re && - display_result_sorted) - { - init_dynamic_string(&ds_res_2_execution_unsorted, "", - RESULT_STRING_INIT_MEM, - RESULT_STRING_INCREMENT_MEM); - ds_res_2_output= &ds_res_2_execution_unsorted; - } - else - ds_res_2_output= ds; - - if (read_stmt_results(stmt, ds_res_2_output, command)) - { - if (ds_res_2_output != ds) - { - dynstr_append_mem(ds, ds_res_2_output->str, ds_res_2_output->length); - dynstr_free(ds_res_2_output); - } + if (read_stmt_results(stmt, ds, command)) goto end; - } if (!disable_result_log) { @@ -8884,35 +8873,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, */ if (compare_2nd_execution && ps2_protocol_enabled && query_match_ps2_re) { - DYNAMIC_STRING *ds_res_1_execution_compare; - DYNAMIC_STRING ds_res_1_execution_sorted; - if (display_result_sorted) - { - init_dynamic_string(&ds_res_1_execution_sorted, "", - RESULT_STRING_INIT_MEM, - RESULT_STRING_INCREMENT_MEM); - dynstr_append_sorted(&ds_res_1_execution_sorted, - &ds_res_1st_execution, 1); - dynstr_append_sorted(ds, &ds_res_2_execution_unsorted, 1); - ds_res_1_execution_compare= &ds_res_1_execution_sorted; - } - else - { - ds_res_1_execution_compare= &ds_res_1st_execution; - } - if (ds->length != ds_res_1_execution_compare->length || - !(memcmp(ds_res_1_execution_compare->str, ds->str, ds->length) == 0)) + if (ds->length != ds_res_1st_execution.length || + !(memcmp(ds_res_1st_execution.str, ds->str, ds->length) == 0)) { die("The result of the 1st execution does not match with \n" "the result of the 2nd execution of ps-protocol:\n 1st:\n" - "%s\n 2nd:\n %s", - ds_res_1_execution_compare->str, - ds->str); - } - if (display_result_sorted) - { - dynstr_free(&ds_res_1_execution_sorted); - dynstr_free(&ds_res_2_execution_unsorted); + "%s\n 2nd:\n %s", ds_res_1st_execution.str, ds->str); } } @@ -9507,10 +9473,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) DYNAMIC_STRING *rs_output; /* where to put results */ DYNAMIC_STRING rs_cmp_result; /* here we put results to compare with pre-recrded file */ - DYNAMIC_STRING rs_unsorted; /* if we need sorted results, here we store - results before sorting them */ - DYNAMIC_STRING *rs_sorted_save= NULL; /* here we store where to put sorted - result if needed */ DYNAMIC_STRING rs_warnings; char *query; size_t query_len; @@ -9681,18 +9643,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&query_str); } - if (display_result_sorted) - { - /* - Collect the query output in a separate string - that can be sorted before it's added to the - global result string - */ - init_dynamic_string(&rs_unsorted, "", 1024, 1024); - rs_sorted_save= rs_output; /* Remember original ds */ - rs_output= &rs_unsorted; - } - /* Find out how to run this query @@ -9719,14 +9669,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&rs_warnings); ds_warn= 0; - if (display_result_sorted) - { - /* Sort the result set and append it to result */ - dynstr_append_sorted(rs_sorted_save, &rs_unsorted, 1); - rs_output= rs_sorted_save; - dynstr_free(&rs_unsorted); - } - if (sp_created) { if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp ")) @@ -12270,7 +12212,6 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) dynstr_append_sorted() ds string where the sorted output will be appended ds_input string to be sorted - keep_header If header should not be sorted */ static int comp_lines(const void *a_, const void *b_) @@ -12280,8 +12221,7 @@ static int comp_lines(const void *a_, const void *b_) return (strcmp(*a,*b)); } -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, - bool keep_header) +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) { unsigned i; char *start= ds_input->str; @@ -12293,15 +12233,6 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, my_init_dynamic_array(PSI_NOT_INSTRUMENTED, &lines, sizeof(const char*), 32, 32, MYF(0)); - if (keep_header) - { - /* First line is result header, skip past it */ - while (*start && *start != '\n') - start++; - start++; /* Skip past \n */ - dynstr_append_mem(ds, ds_input->str, start - ds_input->str); - } - /* Insert line(s) in array */ while (*start) { diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 3f915a2a9a1..d11a303539b 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -2,6 +2,8 @@ IF(RPM) MESSAGE(STATUS "CPackRPM building with RPM configuration: ${RPM}") +INCLUDE(check_linker_flag) + SET(CPACK_GENERATOR "RPM") SET(CPACK_RPM_PACKAGE_DEBUG 1) SET(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) @@ -51,6 +53,19 @@ SET(CPACK_PACKAGE_RELOCATABLE FALSE) SET(CPACK_RPM_PACKAGE_GROUP "Applications/Databases") SET(CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_URL}) +# The spec file depends on environment variables +SET(ENV{RPM_PACKAGE_NAME} ${CPACK_RPM_PACKAGE_NAME}) +EXECUTE_PROCESS(COMMAND rpm --eval ${CPACK_RPM_PACKAGE_RELEASE} OUTPUT_VARIABLE RPM_PACKAGE_RELEASE_EXPANDED) +STRING(STRIP "${RPM_PACKAGE_RELEASE_EXPANDED}" RPM_PACKAGE_RELEASE_EXPANDED) +SET(ENV{RPM_PACKAGE_RELEASE} ${RPM_PACKAGE_RELEASE_EXPANDED}) +SET(ENV{RPM_ARCH} ${CMAKE_SYSTEM_PROCESSOR}) +SET(ENV{RPM_PACKAGE_VERSION} ${SERVER_VERSION}) +MY_CHECK_AND_SET_LINKER_FLAG("-specs=/usr/lib/rpm/redhat/redhat-package-notes") +IF(HAVE_LINK_FLAG__specs_/usr/lib/rpm/redhat/redhat_package_notes) + SET(CMAKE_CXX_LINKER_LAUNCHER "env;RPM_PACKAGE_NAME=$ENV{RPM_PACKAGE_NAME};RPM_ARCH=$ENV{RPM_ARCH};RPM_PACKAGE_VERSION=$ENV{RPM_PACKAGE_VERSION};RPM_PACKAGE_RELEASE=$ENV{RPM_PACKAGE_RELEASE}") + SET(CMAKE_C_LINKER_LAUNCHER ${CMAKE_CXX_LINKER_LAUNCHER}) +ENDIF() + SET(CPACK_RPM_shared_PACKAGE_VENDOR "MariaDB Corporation Ab") SET(CPACK_RPM_shared_PACKAGE_LICENSE "LGPLv2.1") diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 3486473cf47..1a8233bec3f 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -57,6 +57,12 @@ disable_libfmt() sed '/libfmt-dev/d' -i debian/control } +remove_package_notes() +{ + # binutils >=2.39 + disto makefile /usr/share/debhelper/dh_package_notes/package-notes.mk + sed -e '/package.notes/d' -i debian/rules debian/control +} + architecture=$(dpkg-architecture -q DEB_BUILD_ARCH) uname_machine=$(uname -m) @@ -94,6 +100,7 @@ in ;& "bullseye") add_lsb_base_depends + remove_package_notes ;& "bookworm") # mariadb-plugin-rocksdb in control is 4 arches covered by the distro rocksdb-tools @@ -114,6 +121,7 @@ in ;& "jammy"|"kinetic") add_lsb_base_depends + remove_package_notes ;& "lunar"|"mantic") if [[ ! "$architecture" =~ amd64|arm64|armhf|ppc64el|s390x ]] diff --git a/debian/control b/debian/control index 3f34cb6f441..0f451a2a380 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Build-Depends: bison, debhelper (>= 11), default-jdk, dh-exec, + dh-package-notes, flex [amd64], gdb , libaio-dev [linux-any], diff --git a/debian/rules b/debian/rules index 64866631839..ac33739e752 100644 --- a/debian/rules +++ b/debian/rules @@ -4,14 +4,15 @@ # https://wiki.debian.org/Hardening export DEB_BUILD_MAINT_OPTIONS = hardening=+all -# Disable LTO on Ubuntu, see LP: #1970634 and https://jira.mariadb.org/browse/MDEV-25633 -ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes), yes) - export DEB_BUILD_MAINT_OPTIONS += optimize=-lto -endif +# LTO is generally enabled. Only ColumnStore doesn't support it (MCOL-5819) +# and disables it in storage/columnstore/CMakeLists.txt DPKG_EXPORT_BUILDFLAGS = 1 # Include all defaults, including buildflags.mk include /usr/share/dpkg/default.mk +# Include package notes in built executables +include /usr/share/debhelper/dh_package_notes/package-notes.mk + # CPPFLAGS are nor read by CMake, so copy them to CXXFLAGS # See why at https://cmake.org/Bug/view.php?id=12928 # This is needed for e.g. all automatic Debian hardening flags to apply on all cmake builds. diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc index 147563f243c..e7e8d95823c 100644 --- a/extra/mariabackup/encryption_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -230,6 +230,7 @@ void encryption_plugin_prepare_init(int argc, char **argv) char **new_argv = new char *[argc + 2]; new_argv[0] = XTRABACKUP_EXE; memcpy(&new_argv[1], argv, argc*sizeof(char *)); + new_argv[argc+1]= 0; encryption_plugin_init(argc+1, new_argv); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 78653e3fc78..543052f0e49 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1333,9 +1333,7 @@ enum options_xtrabackup OPT_INNODB_BUFFER_POOL_FILENAME, OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_LOG_BUFFER_SIZE, -#ifdef HAVE_INNODB_MMAP OPT_INNODB_LOG_FILE_MMAP, -#endif #if defined __linux__ || defined _WIN32 OPT_INNODB_LOG_FILE_BUFFERING, #endif @@ -1899,13 +1897,11 @@ struct my_option xb_server_options[] = (G_PTR*) &log_sys.buf_size, (G_PTR*) &log_sys.buf_size, 0, GET_UINT, REQUIRED_ARG, 2U << 20, 2U << 20, log_sys.buf_size_max, 0, 4096, 0}, -#ifdef HAVE_INNODB_MMAP {"innodb_log_file_mmap", OPT_INNODB_LOG_FILE_SIZE, "Whether ib_logfile0 should be memory-mapped", (G_PTR*) &log_sys.log_mmap, (G_PTR*) &log_sys.log_mmap, 0, GET_BOOL, NO_ARG, log_sys.log_mmap_default, 0, 0, 0, 0, 0}, -#endif #if defined __linux__ || defined _WIN32 {"innodb_log_file_buffering", OPT_INNODB_LOG_FILE_BUFFERING, "Whether the file system cache for ib_logfile0 is enabled during --backup", @@ -3392,7 +3388,6 @@ skip: return(FALSE); } -#ifdef HAVE_INNODB_MMAP static int xtrabackup_copy_mmap_snippet(ds_file_t *ds, const byte *start, const byte *end) { @@ -3431,7 +3426,7 @@ static bool xtrabackup_copy_mmap_logfile() /* Set the sequence bit (the backed-up log will not wrap around) */ size_t seqo= recv_sys.offset - seq_offset; if (seqo < log_sys.START_OFFSET) - seqo+= log_sys.file_size - log_sys.START_OFFSET; + seqo+= static_cast(log_sys.file_size - log_sys.START_OFFSET); const byte *seq= &log_sys.buf[seqo]; ut_ad(*seq == log_sys.get_sequence_bit(recv_sys.lsn - seq_offset)); if (!*seq) @@ -3492,7 +3487,6 @@ static bool xtrabackup_copy_mmap_logfile() msg(">> log scanned up to (" LSN_PF ")", recv_sys.lsn); return false; } -#endif /** Copy redo log until the current end of the log is reached @return whether the operation failed */ @@ -3504,10 +3498,9 @@ static bool xtrabackup_copy_logfile() ut_a(dst_log_file); ut_ad(recv_sys.is_initialised()); -#ifdef HAVE_INNODB_MMAP if (log_sys.is_mmap()) return xtrabackup_copy_mmap_logfile(); -#endif + const size_t sequence_offset{log_sys.is_encrypted() ? 8U + 5U : 5U}; const size_t block_size_1{log_sys.write_size - 1}; diff --git a/mysql-test/include/mtr_check.sql b/mysql-test/include/mtr_check.sql index 5d73d1f59f1..360f7b40bb8 100644 --- a/mysql-test/include/mtr_check.sql +++ b/mysql-test/include/mtr_check.sql @@ -31,6 +31,7 @@ BEGIN WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' + AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' diff --git a/mysql-test/main/commit.result b/mysql-test/main/commit.result index bf12f3e0ea0..44b87f20ce8 100644 --- a/mysql-test/main/commit.result +++ b/mysql-test/main/commit.result @@ -579,3 +579,23 @@ a # This statement should work, since last statement committed. INSERT INTO t1 VALUES (1); DROP TABLE t1; +# +# MDEV-35335 implicit commit at START TRANSACTION doesn't reset characteristics +# +create table t1 (a int) engine=innodb; +insert t1 values (1); +start transaction; +set session transaction isolation level serializable; +start transaction; +select * from t1; +a +1 +connect con1,localhost,root; +set session innodb_lock_wait_timeout=0; +update t1 set a=2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +disconnect con1; +connection default; +rollback; +drop table t1; +# End of 10.6 tests diff --git a/mysql-test/main/commit.test b/mysql-test/main/commit.test index 4fb86f5e8bc..7e333ba90da 100644 --- a/mysql-test/main/commit.test +++ b/mysql-test/main/commit.test @@ -677,3 +677,23 @@ SELECT * FROM t1; INSERT INTO t1 VALUES (1); DROP TABLE t1; + +--echo # +--echo # MDEV-35335 implicit commit at START TRANSACTION doesn't reset characteristics +--echo # +create table t1 (a int) engine=innodb; +insert t1 values (1); +start transaction; +set session transaction isolation level serializable; +start transaction; +select * from t1; +connect con1,localhost,root; +set session innodb_lock_wait_timeout=0; +--error ER_LOCK_WAIT_TIMEOUT +update t1 set a=2; +disconnect con1; +connection default; +rollback; +drop table t1; + +--echo # End of 10.6 tests diff --git a/mysql-test/main/log_slow.result b/mysql-test/main/log_slow.result index 6c53debdf66..1a5f5339bb1 100644 --- a/mysql-test/main/log_slow.result +++ b/mysql-test/main/log_slow.result @@ -198,7 +198,9 @@ create database `a b`; use `a b`; -select count(*) from mysql.global_priv where length(priv)>2; +create table t1 (a int); +insert t1 values (1),(2),(3),(4),(5),(6),(7); +select count(*) from t1 where a>2; count(*) 5 drop database `a @@ -211,7 +213,7 @@ set timestamp=default; use `a b`; SET timestamp=1234567890; -select count(*) from mysql.global_priv where length(priv)>2 +select count(*) from t1 where a>2 # # MDEV-31366 Assertion `thd->start_time' failed in bool LOGGER::slow_log_print(THD*, const char*, size_t, ulonglong) # diff --git a/mysql-test/main/log_slow.test b/mysql-test/main/log_slow.test index 73a3369f826..e08e58e3ac0 100644 --- a/mysql-test/main/log_slow.test +++ b/mysql-test/main/log_slow.test @@ -207,9 +207,11 @@ create database `a b`; use `a b`; +create table t1 (a int); +insert t1 values (1),(2),(3),(4),(5),(6),(7); --disable_ps_protocol --disable_view_protocol -select count(*) from mysql.global_priv where length(priv)>2; +select count(*) from t1 where a>2; --enable_view_protocol --enable_ps_protocol drop database `a diff --git a/mysql-test/main/log_state.result b/mysql-test/main/log_state.result index 72d4f1c6195..3172be9818f 100644 --- a/mysql-test/main/log_state.result +++ b/mysql-test/main/log_state.result @@ -310,9 +310,9 @@ select @s1 > 2.00 and @s1 < 10.00 as "should be true"; should be true 1 disconnect con2; -connection default; disconnect con1; connection default; +drop procedure p1; SET GLOBAL long_query_time = @save_long_query_time; SET GLOBAL log_output = @old_log_output; SET global general_log = @old_general_log; diff --git a/mysql-test/main/log_state.test b/mysql-test/main/log_state.test index 93e35854355..9686ace3f4b 100644 --- a/mysql-test/main/log_state.test +++ b/mysql-test/main/log_state.test @@ -328,7 +328,9 @@ SET GLOBAL general_log_file = @old_general_log_file; connect (con2,localhost,root,,); set @s1=(select variable_value from information_schema.session_status where variable_name='query_time'); +--disable_cursor_protocol select sleep(3) into @a; +--enable_cursor_protocol set @s2=(select variable_value from information_schema.session_status where variable_name='query_time'); set @s3=(select variable_value from information_schema.global_status where @@ -358,7 +360,6 @@ select @s1 > 2.00 and @s1 < 10.00 as "should be true"; # select @s1; disconnect con2; -connection default; # # Cleanup @@ -367,6 +368,7 @@ connection default; disconnect con1; # set back the saved default values connection default; +drop procedure p1; # Reset global system variables to initial values if forgotten somewhere above. SET GLOBAL long_query_time = @save_long_query_time; diff --git a/mysql-test/main/metadata.result b/mysql-test/main/metadata.result index 3bd9dde4a6c..77a6c010c9b 100644 --- a/mysql-test/main/metadata.result +++ b/mysql-test/main/metadata.result @@ -281,16 +281,16 @@ SELECT COALESCE(d, d), IFNULL(d, d), IF(i, d, d), CASE i WHEN i THEN d ELSE d END, GREATEST(d, d), LEAST(d, d) FROM t1 ORDER BY RAND(); Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def COALESCE(d, d) COALESCE(d, d) 10 10 10 Y 128 0 63 +def IFNULL(d, d) IFNULL(d, d) 10 10 10 Y 128 0 63 +def IF(i, d, d) IF(i, d, d) 10 10 10 Y 128 0 63 +def CASE i WHEN i THEN d ELSE d END CASE i WHEN i THEN d ELSE d END 10 10 10 Y 128 0 63 +def GREATEST(d, d) GREATEST(d, d) 10 10 10 Y 128 0 63 +def LEAST(d, d) LEAST(d, d) 10 10 10 Y 128 0 63 +COALESCE(d, d) IFNULL(d, d) IF(i, d, d) CASE i WHEN i THEN d ELSE d END GREATEST(d, d) LEAST(d, d) 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03 -COALESCE(d, d) IFNULL(d, d) IF(i, d, d) CASE i WHEN i THEN d ELSE d END GREATEST(d, d) LEAST(d, d) -def CASE i WHEN i THEN d ELSE d END CASE i WHEN i THEN d ELSE d END 10 10 10 Y 128 0 63 -def COALESCE(d, d) COALESCE(d, d) 10 10 10 Y 128 0 63 -def GREATEST(d, d) GREATEST(d, d) 10 10 10 Y 128 0 63 -def IF(i, d, d) IF(i, d, d) 10 10 10 Y 128 0 63 -def IFNULL(d, d) IFNULL(d, d) 10 10 10 Y 128 0 63 -def LEAST(d, d) LEAST(d, d) 10 10 10 Y 128 0 63 DROP TABLE t1; # # Bug#41788 mysql_fetch_field returns org_table == table by a view diff --git a/mysql-test/main/mysql_json_table_recreate.result b/mysql-test/main/mysql_json_table_recreate.result index a61377fe21d..c8c53c9036a 100644 --- a/mysql-test/main/mysql_json_table_recreate.result +++ b/mysql-test/main/mysql_json_table_recreate.result @@ -20,6 +20,15 @@ show create table tempty; ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! select * from tempty; ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! +select table_name, table_comment from information_schema.tables where table_schema='test' and table_comment!='VIEW'; +table_name table_comment +mysql_json_test Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it! +mysql_json_test_big Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it! +tempty Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! +Warnings: +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it! +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it! +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! alter table tempty force; show create table tempty; Table Create Table diff --git a/mysql-test/main/mysql_json_table_recreate.test b/mysql-test/main/mysql_json_table_recreate.test index a6f1d3194ae..94477d4f328 100644 --- a/mysql-test/main/mysql_json_table_recreate.test +++ b/mysql-test/main/mysql_json_table_recreate.test @@ -43,6 +43,9 @@ show create table tempty; --error ER_TABLE_NEEDS_REBUILD select * from tempty; +--sorted_result +select table_name, table_comment from information_schema.tables where table_schema='test' and table_comment!='VIEW'; + alter table tempty force; show create table tempty; diff --git a/mysql-test/main/mysqlbinlog_row_big.result b/mysql-test/main/mysqlbinlog_row_big.result index ecbb9df2be1..1f2a5bfa21e 100644 --- a/mysql-test/main/mysqlbinlog_row_big.result +++ b/mysql-test/main/mysqlbinlog_row_big.result @@ -52,10 +52,10 @@ affected rows: 1 # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; -LENGTH(c1) 67108864 LENGTH(c1) 33554432 LENGTH(c1) 4194304 LENGTH(c1) 524288 +LENGTH(c1) 67108864 affected rows: 4 # # Grow the rows by updating. @@ -68,8 +68,8 @@ info: Rows matched: 4 Changed: 4 Warnings: 0 # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; -LENGTH(c1) 134217728 LENGTH(c1) 1048576 +LENGTH(c1) 134217728 LENGTH(c1) 67108864 LENGTH(c1) 8388608 affected rows: 4 diff --git a/mysql-test/main/win_sum.result b/mysql-test/main/win_sum.result index a17c17845af..aa376ecf7ba 100644 --- a/mysql-test/main/win_sum.result +++ b/mysql-test/main/win_sum.result @@ -105,3 +105,12 @@ EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()) # # End of 10.4 tests # +# +# MDEV-32411 Item_sum arguments incorrectly reset to temp table fields which causes crash +# +CREATE TABLE t1 (a INT NOT NULL) ; +INSERT INTO t1 VALUES (EXISTS(SELECT avg(3) OVER (ORDER BY COUNT(DISTINCT a, HEX(a))))); +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/win_sum.test b/mysql-test/main/win_sum.test index 9800174f54c..d3924435949 100644 --- a/mysql-test/main/win_sum.test +++ b/mysql-test/main/win_sum.test @@ -57,3 +57,14 @@ SELECT EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()); --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-32411 Item_sum arguments incorrectly reset to temp table fields which causes crash +--echo # +CREATE TABLE t1 (a INT NOT NULL) ; +INSERT INTO t1 VALUES (EXISTS(SELECT avg(3) OVER (ORDER BY COUNT(DISTINCT a, HEX(a))))); +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/funcs_1/r/is_routines_embedded.result b/mysql-test/suite/funcs_1/r/is_routines_embedded.result index be2a3d45432..817817b01d2 100644 --- a/mysql-test/suite/funcs_1/r/is_routines_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_routines_embedded.result @@ -197,7 +197,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci @@ -213,7 +213,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci @@ -229,7 +229,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 5b92b282ece..e77af6477df 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -12,3 +12,4 @@ galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() +MDEV-26266 : MDEV-26266 diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result index 1b12e0a9bc6..a65ccd13778 100644 --- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result @@ -279,8 +279,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG() @@ -303,8 +303,8 @@ a b c 1 100 NULL 10 100 2 2 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; set sql_warnings = 1; @@ -323,8 +323,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG2() @@ -344,8 +344,8 @@ select * from t1; a b -100 NULL 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG10() @@ -367,8 +367,8 @@ a b -100 NULL 100 2 2 0.30103 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # - @@ -2722,8 +2722,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # Convert() @@ -2743,8 +2743,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result index 8553f87dc58..88637e92cb1 100644 --- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result @@ -279,8 +279,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG() @@ -303,8 +303,8 @@ a b c 1 100 NULL 10 100 2 2 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; set sql_warnings = 1; @@ -323,8 +323,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG2() @@ -344,8 +344,8 @@ select * from t1; a b -100 NULL 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG10() @@ -367,8 +367,8 @@ a b -100 NULL 100 2 2 0.30103 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # - @@ -2722,8 +2722,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # Convert() @@ -2743,8 +2743,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # diff --git a/mysql-test/suite/innodb/r/create_select.result b/mysql-test/suite/innodb/r/create_select.result index 183705680bd..e3c130c3ad1 100644 --- a/mysql-test/suite/innodb/r/create_select.result +++ b/mysql-test/suite/innodb/r/create_select.result @@ -3,7 +3,6 @@ connection default; CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000; connection con1; KILL QUERY @id; -disconnect con1; connection default; ERROR 70100: Query execution was interrupted CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; @@ -18,3 +17,26 @@ execute stmt; execute stmt; drop table t; # End of 10.5 tests +# +# MDEV-35647 Possible hang during CREATE TABLE…SELECT error handling +# +call mtr.add_suppression("InnoDB: DROP TABLE `test`\\.`t4`: Record changed"); +SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug; +SET GLOBAL innodb_evict_tables_on_commit_debug=on; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug; +connection con1; +CREATE TABLE t2 (b BLOB) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),('2025-01-21 00:00:00'); +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t3 ENGINE=InnoDB AS SELECT * FROM t1; +connection default; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t4 (b BLOB CHECK (b)) ENGINE=InnoDB AS SELECT b FROM t2; +ERROR 22007: Truncated incorrect DOUBLE value: '2025-01-21 00:00:00' +connection con1; +disconnect con1; +connection default; +DROP TABLE t3,t2,t1; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result index f7f87bd7898..8ed32cae3e7 100644 --- a/mysql-test/suite/innodb/r/foreign-keys.result +++ b/mysql-test/suite/innodb/r/foreign-keys.result @@ -243,3 +243,25 @@ Level Code Message Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=COMPRESSED Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +# End of 10.5 tests +# +# MDEV-35598 foreign key error is unnecessary truncated +# +set names utf8; +create table t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null primary key, +f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null +) engine=innodb; +create table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш varchar(100), +f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null, +index i2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) +) engine=innodb; +insert t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values(99, 2); +alter table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш add foreign key(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) references t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш); +insert t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values('g', 3); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш`, CONSTRAINT `t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш_ibfk_1` FOREIGN KEY (`f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш`) REFERENCES `t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш` (`f1яяяяяяяяяяььььььььььззззз +drop table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш, +t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/innodb_information_schema.result b/mysql-test/suite/innodb/r/innodb_information_schema.result index 921b062eae3..608db358802 100644 Binary files a/mysql-test/suite/innodb/r/innodb_information_schema.result and b/mysql-test/suite/innodb/r/innodb_information_schema.result differ diff --git a/mysql-test/suite/innodb/r/log_file_size_online.result b/mysql-test/suite/innodb/r/log_file_size_online.result index 7b2b23bd776..8dcd9a47b2f 100644 --- a/mysql-test/suite/innodb/r/log_file_size_online.result +++ b/mysql-test/suite/innodb/r/log_file_size_online.result @@ -25,8 +25,14 @@ SET GLOBAL innodb_log_file_buffering=ON; SET GLOBAL innodb_log_file_buffering=@save; SET GLOBAL innodb_log_file_mmap=OFF; Got one of the listed errors -SET GLOBAL innodb_log_file_size=5242880; connect con1,localhost,root; +SET GLOBAL innodb_log_file_size=7340032; +connection default; +KILL QUERY @id; +connection con1; +connection default; +SET GLOBAL innodb_log_file_size=5242880; +connection con1; UPDATE t SET b='' WHERE a<10; connection default; SHOW VARIABLES LIKE 'innodb_log_file_size'; diff --git a/mysql-test/suite/innodb/t/create_select.test b/mysql-test/suite/innodb/t/create_select.test index 053db79b8f4..46f793295bf 100644 --- a/mysql-test/suite/innodb/t/create_select.test +++ b/mysql-test/suite/innodb/t/create_select.test @@ -1,6 +1,7 @@ --source include/have_innodb.inc --source include/have_sequence.inc --source include/count_sessions.inc +--source include/maybe_debug.inc let $ID= `SELECT @id := CONNECTION_ID()`; @@ -17,7 +18,6 @@ let $wait_condition= and info = 'CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000'; --source include/wait_condition.inc KILL QUERY @id; -disconnect con1; connection default; --error ER_QUERY_INTERRUPTED @@ -25,7 +25,6 @@ reap; CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; DROP TABLE t1; ---source include/wait_until_count_sessions.inc --echo # End of 10.2 tests @@ -39,3 +38,38 @@ execute stmt; drop table t; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-35647 Possible hang during CREATE TABLE…SELECT error handling +--echo # +call mtr.add_suppression("InnoDB: DROP TABLE `test`\\.`t4`: Record changed"); + +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug; +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_evict_tables_on_commit_debug=on; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug; + +connection con1; +CREATE TABLE t2 (b BLOB) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),('2025-01-21 00:00:00'); +--send +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t3 ENGINE=InnoDB AS SELECT * FROM t1; + +connection default; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--error ER_TRUNCATED_WRONG_VALUE +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t4 (b BLOB CHECK (b)) ENGINE=InnoDB AS SELECT b FROM t2; +connection con1; +reap; +disconnect con1; +connection default; +DROP TABLE t3,t2,t1; + +--source include/wait_until_count_sessions.inc + +--echo # End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test index aeff7009402..6010ff0e3fc 100644 --- a/mysql-test/suite/innodb/t/foreign-keys.test +++ b/mysql-test/suite/innodb/t/foreign-keys.test @@ -272,3 +272,30 @@ SET FOREIGN_KEY_CHECKS=DEFAULT; --error ER_CANT_CREATE_TABLE CREATE TABLE t1(a SERIAL) ENGINE=InnoDB ROW_FORMAT=COMPRESSED PAGE_COMPRESSED=1; SHOW WARNINGS; + +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-35598 foreign key error is unnecessary truncated +--echo # +set names utf8; +create table t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null primary key, + f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null +) engine=innodb; +create table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш varchar(100), + f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null, + index i2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш + (f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) +) engine=innodb; + +insert t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values(99, 2); +alter table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш add foreign key(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) references t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш); + +--error ER_NO_REFERENCED_ROW_2 +insert t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values('g', 3); +drop table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш, + t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш; + +--echo # End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/innodb_information_schema.test b/mysql-test/suite/innodb/t/innodb_information_schema.test index 88e2d3601a6..1fbf9f7eb57 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema.test @@ -12,15 +12,8 @@ # get NULL -- source include/not_encrypted.inc --- disable_query_log --- disable_result_log - SET default_storage_engine=InnoDB; --- disable_warnings -DROP TABLE IF EXISTS t_min, t_max; --- enable_warnings - let $table_def = ( c01 TINYINT, @@ -118,7 +111,6 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE; -- send SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE; --- enable_result_log -- connection con_verify_innodb_locks # Wait for the above queries to execute before continuing. # Without this, it sometimes happens that the SELECT from innodb_locks @@ -161,7 +153,6 @@ SET SQL_MODE='ANSI_QUOTES'; SELECT lock_table,COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS GROUP BY lock_table; SET @@sql_mode=@save_sql_mode; --- disable_result_log -- connection default @@ -184,9 +175,7 @@ DROP TABLE t_min, t_max, ```t'\"_str`; # INFORMATION_SCHEMA.INNODB_TRX # --- enable_result_log DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- disable_warnings DROP TABLE IF EXISTS t1; @@ -222,17 +211,14 @@ SELECT * FROM t1 FOR UPDATE; let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log -- connection con_verify_innodb_trx --- enable_result_log SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, trx_isolation_level, trx_unique_checks, trx_foreign_key_checks FROM INFORMATION_SCHEMA.INNODB_TRX; -- connection con_trx --- disable_result_log ROLLBACK; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0; @@ -243,14 +229,11 @@ INSERT INTO t1 VALUES (6,12); let $wait_condition= SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log -- connection con_verify_innodb_trx --- enable_result_log SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks FROM INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- connection con_trx ROLLBACK; SET FOREIGN_KEY_CHECKS = 1; @@ -262,13 +245,10 @@ INSERT INTO t2 VALUES (4,10); let $wait_condition= SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log --- enable_result_log -- connection con_verify_innodb_trx SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error FROM INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- connection default diff --git a/mysql-test/suite/innodb/t/log_file_size_online.test b/mysql-test/suite/innodb/t/log_file_size_online.test index bf9f3510592..fb6722ee8d7 100644 --- a/mysql-test/suite/innodb/t/log_file_size_online.test +++ b/mysql-test/suite/innodb/t/log_file_size_online.test @@ -36,9 +36,19 @@ SET GLOBAL innodb_log_file_buffering=@save; --error ER_INCORRECT_GLOBAL_LOCAL_VAR,ER_UNKNOWN_SYSTEM_VARIABLE SET GLOBAL innodb_log_file_mmap=OFF; +--connect con1,localhost,root +let $ID= `SELECT @id := CONNECTION_ID()`; +send SET GLOBAL innodb_log_file_size=7340032; +--connection default +let $ignore= `SELECT @id := $ID`; +KILL QUERY @id; +--connection con1 +reap; + +--connection default send SET GLOBAL innodb_log_file_size=5242880; ---connect con1,localhost,root +--connection con1 send UPDATE t SET b='' WHERE a<10; --connection default diff --git a/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations new file mode 100644 index 00000000000..5221a9747be --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations @@ -0,0 +1,4 @@ +[pread] +--innodb-log-file-mmap=OFF +[mmap] +--innodb-log-file-mmap=ON diff --git a/mysql-test/suite/mariabackup/undo_truncate.combinations b/mysql-test/suite/mariabackup/undo_truncate.combinations new file mode 100644 index 00000000000..fe6a3ba58fd --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.combinations @@ -0,0 +1,4 @@ +[clear] +--innodb-encrypt-log=OFF +[crypt] +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/mariabackup/undo_truncate.opt b/mysql-test/suite/mariabackup/undo_truncate.opt new file mode 100644 index 00000000000..9b4f76ab5de --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.opt @@ -0,0 +1,6 @@ +--innodb-undo-tablespaces=2 +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc +--loose-file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/mariabackup/undo_truncate.result b/mysql-test/suite/mariabackup/undo_truncate.result new file mode 100644 index 00000000000..a3bfb182dd8 --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.result @@ -0,0 +1,39 @@ +SET GLOBAL innodb_undo_log_truncate = 0; +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN +DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; +DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; +DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; +EXECUTE IMMEDIATE REPLACE(i,'t1', t); +EXECUTE IMMEDIATE REPLACE(u1,'t1', t); +EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +connect con1,localhost,root,,; +begin; +call p('t1'); +connection default; +call p('t2'); +connection con1; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +# Prepare full backup +# shutdown server +# remove datadir +# xtrabackup move back +# restart +select count(*) from t1; +count(*) +20000 +select count(*) from t2; +count(*) +20000 +DROP TABLE t1,t2; diff --git a/mysql-test/suite/mariabackup/undo_truncate.test b/mysql-test/suite/mariabackup/undo_truncate.test new file mode 100644 index 00000000000..a23c9cf64ff --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.test @@ -0,0 +1,59 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/have_sequence.inc +--source include/have_file_key_management.inc + +SET GLOBAL innodb_undo_log_truncate = 0; + +# +# Perform DML action using multiple clients and multiple undo tablespace. +# + +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; + +DELIMITER $$; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN + DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; + DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; + DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; + EXECUTE IMMEDIATE REPLACE(i,'t1', t); + EXECUTE IMMEDIATE REPLACE(u1,'t1', t); + EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +DELIMITER ;$$ + +connect (con1,localhost,root,,); +begin; +send call p('t1'); + +connection default; +call p('t2'); + +connection con1; +reap; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; + +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --throttle=1000; +--echo # Prepare full backup +exec $XTRABACKUP --prepare --target-dir=$targetdir; +--enable_result_log + +source include/restart_and_restore.inc; +select count(*) from t1; +select count(*) from t2; +# Cleanup +rmdir $targetdir; +DROP TABLE t1,t2; diff --git a/mysql-test/suite/perfschema/r/grant.result b/mysql-test/suite/perfschema/r/grant.result index 4679499279f..985473c80f0 100644 --- a/mysql-test/suite/perfschema/r/grant.result +++ b/mysql-test/suite/perfschema/r/grant.result @@ -5,3 +5,19 @@ VARIABLE_NAME VARIABLE_VALUE connection default; disconnect a; drop user a@localhost; +# +# MDEV-35384 Table performance_schema.session_status and other two tables are not shown in information_schema.tables for normal users +# +create user foo@localhost; +connect foo,localhost,foo; +select table_schema,engine from information_schema.tables where table_name='session_status'; +table_schema engine +information_schema MEMORY +performance_schema PERFORMANCE_SCHEMA +select count(*) > 0 as 'table is readable' from performance_schema.session_status; +table is readable +1 +connection default; +disconnect foo; +drop user foo@localhost; +# End of 10.6 tests diff --git a/mysql-test/suite/perfschema/t/grant.test b/mysql-test/suite/perfschema/t/grant.test index 446965dfe9d..7c9bc31104e 100644 --- a/mysql-test/suite/perfschema/t/grant.test +++ b/mysql-test/suite/perfschema/t/grant.test @@ -10,3 +10,16 @@ connection default; disconnect a; drop user a@localhost; +--echo # +--echo # MDEV-35384 Table performance_schema.session_status and other two tables are not shown in information_schema.tables for normal users +--echo # +create user foo@localhost; +connect foo,localhost,foo; +sorted_result; +select table_schema,engine from information_schema.tables where table_name='session_status'; +select count(*) > 0 as 'table is readable' from performance_schema.session_status; +connection default; +disconnect foo; +drop user foo@localhost; + +--echo # End of 10.6 tests diff --git a/mysql-test/suite/period/r/create.result b/mysql-test/suite/period/r/create.result index 8ba5ce31ff2..865861e97a0 100644 --- a/mysql-test/suite/period/r/create.result +++ b/mysql-test/suite/period/r/create.result @@ -20,10 +20,10 @@ Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' select * from information_schema.key_period_usage; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' Warnings: +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' drop view v; create or replace table t (id int primary key, s timestamp(6), e timestamp(6), period for mytime(s,e)); @@ -145,11 +145,11 @@ create table t (a date) engine=myisam; create table t1 (a int) engine=merge union = (t) ; select 1 from information_schema.key_period_usage; 1 +Warnings: Warning 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' -Warnings: drop table t1; drop table t; create view v1 as select 1; @@ -157,9 +157,9 @@ create view v2 as select * from v1; drop view v1; select * from information_schema.key_period_usage; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME +Warnings: Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -Warnings: drop view v2; diff --git a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff index 495fd50b7c2..1a47adcbdc0 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_aria.result -+++ suite/sys_vars/r/sysvars_aria,32bit.reject +--- a/mysql-test/suite/sys_vars/r/sysvars_aria.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_aria.result @@ -5,7 +5,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 8192 @@ -97,7 +97,7 @@ @@ -224,7 +224,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index b3c18b2a195..ba7bbc70f6f 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -4,7 +4,6 @@ variable_name not in ( 'innodb_numa_interleave', # only available WITH_NUMA 'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_use_native_aio', # default value depends on OS -'innodb_log_file_mmap', # only available on 64-bit 'innodb_log_file_buffering', # only available on Linux and Windows 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing order by variable_name; @@ -932,6 +931,18 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST OFF,ON READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_LOG_FILE_MMAP +SESSION_VALUE NULL +DEFAULT_VALUE ON +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Whether ib_logfile0 resides in persistent memory (when supported) or should initially be memory-mapped +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY YES +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_LOG_FILE_SIZE SESSION_VALUE NULL DEFAULT_VALUE 100663296 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index 771fa906979..4e3e3445161 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- sysvars_server_embedded.result 2024-02-15 09:34:10.105925200 +0100 -+++ sysvars_server_embedded,32bit.result 2024-02-15 13:49:05.823558727 +0100 +--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -44,7 +44,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -97,7 +97,7 @@ @@ -227,7 +227,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 @@ -1383,7 +1383,7 @@ NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO @@ -3957,14 +3957,14 @@ @@ -1392,7 +1392,7 @@ NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index 31978fd0bf9..63a8b980e13 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- sysvars_server_notembedded.result 2024-02-15 09:34:10.109925277 +0100 -+++ sysvars_server_notembedded,32bit.result 2024-02-15 10:35:52.037016777 +0100 +--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -44,7 +44,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -97,7 +97,7 @@ @@ -227,7 +227,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 @@ -1492,7 +1492,7 @@ NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO @@ -4817,14 +4817,14 @@ @@ -1501,7 +1501,7 @@ NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test index 86f5ffddf1c..2680e442da4 100644 --- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test +++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test @@ -11,7 +11,6 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP 'innodb_numa_interleave', # only available WITH_NUMA 'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_use_native_aio', # default value depends on OS - 'innodb_log_file_mmap', # only available on 64-bit 'innodb_log_file_buffering', # only available on Linux and Windows 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing order by variable_name; diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index ca396573bc9..dd80a82aaf7 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -28,7 +28,7 @@ ulong debug_startup_interval, debug_first_interval, debug_interval; /* backing store for system variables */ static char *url, *http_proxy; -char *user_info; +char *user_info, *server_uid_ptr= server_uid; ulong send_timeout, send_retry_wait; /** @@ -356,6 +356,9 @@ static int free(void *p) #define DEFAULT_PROTO "http://" #endif +static MYSQL_SYSVAR_STR(server_uid, server_uid_ptr, + PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT, + "Automatically calculated server unique id hash.", NULL, NULL, 0); static MYSQL_SYSVAR_STR(user_info, user_info, PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG, "User specified string that will be included in the feedback report.", @@ -386,6 +389,7 @@ static MYSQL_SYSVAR_ULONG(debug_interval, debug_interval, #endif static struct st_mysql_sys_var* settings[] = { + MYSQL_SYSVAR(server_uid), MYSQL_SYSVAR(user_info), MYSQL_SYSVAR(url), MYSQL_SYSVAR(send_timeout), diff --git a/plugin/type_uuid/mysql-test/type_uuid/order.result b/plugin/type_uuid/mysql-test/type_uuid/order.result index 3dd799b6ae2..218d1cd247b 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/order.result +++ b/plugin/type_uuid/mysql-test/type_uuid/order.result @@ -625,6 +625,7 @@ a b a b 15901234-5566-e777-e888-99aabbccddee 59 15901234-5566-e777-e888-99aabbccddee 59 16101234-5566-f777-8888-99aabbccddee 61 16101234-5566-f777-8888-99aabbccddee 61 16301234-5566-f777-e888-99aabbccddee 63 16301234-5566-f777-e888-99aabbccddee 63 +Warnings: Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' @@ -689,7 +690,6 @@ Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' -Warnings: select * from t1 union select * from t2; a b 00001234-5566-0777-0888-99aabbccddee 0 diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 21f5eb607b4..91e22f68a13 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -546,35 +546,6 @@ void Item_sum::fix_num_length_and_dec() max_length=float_length(decimals); } -Item *Item_sum::get_tmp_table_item(THD *thd) -{ - Item_sum* sum_item= (Item_sum *) copy_or_same(thd); - if (sum_item && sum_item->result_field) // If not a const sum func - { - Field *result_field_tmp= sum_item->result_field; - for (uint i=0 ; i < sum_item->arg_count ; i++) - { - Item *arg= sum_item->args[i]; - if (!arg->const_item()) - { - if (arg->type() == Item::FIELD_ITEM) - { - ((Item_field*) arg)->field= result_field_tmp++; - } - else - { - auto item_field= - new (thd->mem_root) Item_field(thd, result_field_tmp++); - if (item_field) - item_field->set_refers_to_temp_table(); - sum_item->args[i]= item_field; - } - } - } - } - return sum_item; -} - void Item_sum::update_used_tables () { diff --git a/sql/item_sum.h b/sql/item_sum.h index 8724a2820ec..d0aedea2a59 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -525,7 +525,6 @@ public: aggregator_clear(); } virtual void make_unique() { force_copy_fields= TRUE; } - Item *get_tmp_table_item(THD *thd) override; virtual Field *create_tmp_field(MEM_ROOT *root, bool group, TABLE *table); Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, const Tmp_field_param *param) override diff --git a/sql/log.cc b/sql/log.cc index c351f30a0cf..0aff9ba5023 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3565,6 +3565,9 @@ void MYSQL_BIN_LOG::init_pthread_objects() &COND_binlog_background_thread, 0); mysql_cond_init(key_BINLOG_COND_binlog_background_thread_end, &COND_binlog_background_thread_end, 0); + + /* Fix correct mutex order to catch violations quicker (MDEV-35197). */ + mysql_mutex_record_order(&LOCK_log, &LOCK_global_system_variables); } @@ -12544,6 +12547,7 @@ binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var, bool check_purge= false; ulong UNINIT_VAR(prev_binlog_id); + mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(mysql_bin_log.get_log_lock()); if(mysql_bin_log.is_open()) { @@ -12562,6 +12566,7 @@ binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var, mysql_mutex_unlock(mysql_bin_log.get_log_lock()); if (check_purge) mysql_bin_log.checkpoint_and_purge(prev_binlog_id); + mysql_mutex_lock(&LOCK_global_system_variables); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 980eaedfd5b..4c98af9354d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3344,10 +3344,13 @@ void my_message_sql(uint error, const char *str, myf MyFlags) MyFlags)); DBUG_ASSERT(str != NULL); + DBUG_ASSERT(*str != '\0'); DBUG_ASSERT(error != 0); DBUG_ASSERT((MyFlags & ~(ME_BELL | ME_ERROR_LOG | ME_ERROR_LOG_ONLY | ME_NOTE | ME_WARNING | ME_FATAL)) == 0); + DBUG_ASSERT(str[strlen(str)-1] != '\n'); + if (MyFlags & ME_NOTE) { level= Sql_condition::WARN_LEVEL_NOTE; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 61f2747f976..681315ec7a7 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7208,19 +7208,19 @@ ER_FORBID_SCHEMA_CHANGE spa "Vd no está autorizado a cambiar el esquema de '%-.192s' a '%-.192s'" sw "Kubadilisha schema kutoka '%-.192s' hadi '%-.192s' hairuhusiwi" ER_ROW_IS_REFERENCED_2 23000 - chi "无法删除或更新父行:外键约束失败(%.192s)" - eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)" - ger "Kann Eltern-Zeile nicht löschen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%.192s)" - geo "მშობელი მწკრივის წაშლა ან განახლება შეუძლებელია: გარე გასაღების შეზღუდვა შეცდომას შეიცავს (%.192s)" - spa "No puedo borrar o actualizar una fila padre: falla una restricción de clave foránea (%.192s)" - sw "Haiwezi kufuta au kusasisha safu mlalo kuu: kizuizi cha ufunguo wa kigeni hakifaulu (%.192s)" + chi "无法删除或更新父行:外键约束失败(%s)" + eng "Cannot delete or update a parent row: a foreign key constraint fails (%s)" + ger "Kann Eltern-Zeile nicht löschen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%s)" + geo "მშობელი მწკრივის წაშლა ან განახლება შეუძლებელია: გარე გასაღების შეზღუდვა შეცდომას შეიცავს (%s)" + spa "No puedo borrar o actualizar una fila padre: falla una restricción de clave foránea (%s)" + sw "Haiwezi kufuta au kusasisha safu mlalo kuu: kizuizi cha ufunguo wa kigeni hakifaulu (%s)" ER_NO_REFERENCED_ROW_2 23000 - chi "无法添加或更新子行:外键约束失败(%.192s)" - eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" - ger "Kann Kind-Zeile nicht hinzufügen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%.192s)" - geo "შვილი მწკრივის წაშლა ან განახლება შეუძლებელია: გარე გასაღების შეზღუდვა შეცდომას შეიცავს (%.192s)" - spa "No puedo añadir o actualizar una fila hija: falla una restricción de clave foránea (%.192s)" - sw "Haiwezi kuongeza au kusasisha safu mlalo ya mtoto: kizuizi cha ufunguo wa kigeni hakifaulu (%.192s)" + chi "无法添加或更新子行:外键约束失败(%s)" + eng "Cannot add or update a child row: a foreign key constraint fails (%s)" + ger "Kann Kind-Zeile nicht hinzufügen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%s)" + geo "შვილი მწკრივის წაშლა ან განახლება შეუძლებელია: გარე გასაღების შეზღუდვა შეცდომას შეიცავს (%s)" + spa "No puedo añadir o actualizar una fila hija: falla una restricción de clave foránea (%s)" + sw "Haiwezi kuongeza au kusasisha safu mlalo ya mtoto: kizuizi cha ufunguo wa kigeni hakifaulu (%s)" ER_SP_BAD_VAR_SHADOW 42000 chi "变量'%-.64s'必须用`...`,或重命名" eng "Variable '%-.64s' must be quoted with `...`, or renamed" diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8610f985b94..6bd46dd2c6e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8458,7 +8458,8 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, if (access) { - switch(access->check(orig_want_access, &t_ref->grant.privilege)) + switch(access->check(orig_want_access, &t_ref->grant.privilege, + any_combination_will_do)) { case ACL_INTERNAL_ACCESS_GRANTED: t_ref->grant.privilege|= orig_want_access; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 1e82be24628..6688242f48f 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -206,7 +206,7 @@ public: in save_priv. */ virtual ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const= 0; + privilege_t *save_priv, bool any_combination_will_do) const= 0; }; /** diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 89dde3cf190..6a47e4b9cac 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -693,7 +693,6 @@ Sql_condition *Warning_info::push_warning(THD *thd, ulong current_row_number) { Sql_condition *cond= NULL; - DBUG_ASSERT(msg[strlen(msg)-1] != '\n'); if (! m_read_only) { @@ -753,6 +752,7 @@ void push_warning(THD *thd, Sql_condition::enum_warning_level level, if (level == Sql_condition::WARN_LEVEL_ERROR) level= Sql_condition::WARN_LEVEL_WARN; + DBUG_ASSERT(msg[strlen(msg)-1] != '\n'); (void) thd->raise_condition(code, "\0\0\0\0\0", level, msg); /* Make sure we also count warnings pushed after calling set_ok_status(). */ diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index a2992c19dc6..248e169cb5a 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3354,6 +3354,8 @@ err: } else if (info->errmsg != NULL) safe_strcpy(info->error_text, sizeof(info->error_text), info->errmsg); + else if (info->error_text[0] == 0) + safe_strcpy(info->error_text, sizeof(info->error_text), ER(info->error)); my_message(info->error, info->error_text, MYF(0)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6d84d510c5e..7bcdaead289 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4663,6 +4663,19 @@ static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl, } +/* + Hide error for a non-existing table. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist or + there is a view with the same name. +*/ +static bool hide_object_error(uint err) +{ + return err == ER_NO_SUCH_TABLE || err == ER_WRONG_OBJECT || + err == ER_NOT_SEQUENCE; +} + + /** Fill I_S table with data obtained by performing full-blown table open. @@ -4798,17 +4811,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, { if (!is_show_fields_or_keys) { - /* - Hide error for a non-existing table and skip processing. - For example, this error can occur when we use a where condition - with a db name and table, but the table does not exist or - there is a view with the same name. - Some errors, like ER_UNKNOWN_STORAGE_ENGINE, can still allow table - processing, if the information schema table supports that. - */ - run= run && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE - && thd->get_stmt_da()->sql_errno() != ER_WRONG_OBJECT - && thd->get_stmt_da()->sql_errno() != ER_NOT_SEQUENCE; + run= run && !hide_object_error(thd->get_stmt_da()->sql_errno()); if (!run) thd->clear_error(); else if (!ext_error_handling) @@ -4904,8 +4907,8 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, else table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); - if (unlikely(thd->is_error() && - thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE)) + if (unlikely(thd->is_error()) && + hide_object_error(thd->get_stmt_da()->sql_errno())) { thd->clear_error(); return 0; @@ -5142,9 +5145,7 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW); if (!share) { - if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || - thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE) + if (hide_object_error(thd->get_stmt_da()->sql_errno())) { res= 0; } @@ -5190,10 +5191,17 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, goto end_share; } - if (!open_table_from_share(thd, share, table_name, 0, - (EXTRA_RECORD | OPEN_FRM_FILE_ONLY), - thd->open_options, &tbl, FALSE)) + res= open_table_from_share(thd, share, table_name, 0, + EXTRA_RECORD | OPEN_FRM_FILE_ONLY, + thd->open_options, &tbl, FALSE); + if (res && hide_object_error(thd->get_stmt_da()->sql_errno())) + res= 0; + else { + char buf[NAME_CHAR_LEN + 1]; + if (unlikely(res)) + get_table_engine_for_i_s(thd, buf, &table_list, db_name, table_name); + tbl.s= share; table_list.table= &tbl; table_list.view= (LEX*) share->is_view; @@ -5327,7 +5335,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_ENTER("get_all_tables"); LEX *lex= thd->lex; TABLE *table= tables->table; - TABLE_LIST table_acl_check; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; IS_table_read_plan *plan= tables->is_table_read_plan; @@ -5470,8 +5477,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } } - bzero((char*) &table_acl_check, sizeof(table_acl_check)); - if (make_db_list(thd, &db_names, &plan->lookup_field_vals)) goto err; @@ -5480,9 +5485,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) LEX_CSTRING *db_name= db_names.at(i); DBUG_ASSERT(db_name->length <= NAME_LEN); #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!(check_access(thd, SELECT_ACL, db_name->str, - &thd->col_access, NULL, 0, 1) || - (!thd->col_access && check_grant_db(thd, db_name->str))) || + if (!check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, 0,0,1) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get_all3(sctx, db_name->str, 0)) #endif @@ -5504,6 +5507,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(thd->col_access & TABLE_ACLS)) { + TABLE_LIST table_acl_check; + table_acl_check.reset(); table_acl_check.db= *db_name; table_acl_check.table_name= *table_name; table_acl_check.grant.privilege= thd->col_access; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f3cca3c1527..4dcf2565569 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1255,10 +1255,14 @@ static bool update_binlog_space_limit(sys_var *, THD *, { #ifdef HAVE_REPLICATION /* Refresh summary of binlog sizes */ - mysql_bin_log.lock_index(); - binlog_space_limit= internal_binlog_space_limit; - slave_connections_needed_for_purge= + ulonglong loc_binlog_space_limit= internal_binlog_space_limit; + uint loc_slave_connections_needed_for_purge= internal_slave_connections_needed_for_purge; + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_bin_log.lock_index(); + binlog_space_limit= loc_binlog_space_limit; + slave_connections_needed_for_purge= + loc_slave_connections_needed_for_purge; if (opt_bin_log) { @@ -1268,9 +1272,11 @@ static bool update_binlog_space_limit(sys_var *, THD *, sending_new_binlog_file++; mysql_bin_log.unlock_index(); mysql_bin_log.purge(1); + mysql_mutex_lock(&LOCK_global_system_variables); return 0; } mysql_bin_log.unlock_index(); + mysql_mutex_lock(&LOCK_global_system_variables); #endif return 0; } @@ -1790,7 +1796,10 @@ Sys_max_binlog_stmt_cache_size( static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) { - mysql_bin_log.set_max_size(max_binlog_size); + ulong saved= max_binlog_size; + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_bin_log.set_max_size(saved); + mysql_mutex_lock(&LOCK_global_system_variables); return false; } static Sys_var_on_access_globalin_multi_stmt_transaction_mode() || (thd->variables.option_bits & OPTION_TABLE_LOCK)) { + bool was_in_trans= thd->server_status & + (SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); thd->variables.option_bits&= ~OPTION_TABLE_LOCK; thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= MY_TEST(ha_commit_trans(thd, TRUE)); + if (was_in_trans) + trans_reset_one_shot_chistics(thd); #ifdef WITH_WSREP if (wsrep_thd_is_local(thd)) { diff --git a/storage/columnstore/CMakeLists.txt b/storage/columnstore/CMakeLists.txt index 93065847c5c..cc4780d1cef 100644 --- a/storage/columnstore/CMakeLists.txt +++ b/storage/columnstore/CMakeLists.txt @@ -47,6 +47,7 @@ SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES "${dirs}") IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + MY_CHECK_AND_SET_COMPILER_FLAG("-fno-lto") SET(PCRE_INCLUDES "${PCRE_INCLUDE_DIRS}") add_subdirectory(columnstore) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 5552e53f115..5db9417cc38 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -49,7 +49,7 @@ IF(UNIX) LINK_LIBRARIES(numa) ENDIF() IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - IF(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch|AARCH|p(ower)?pc|x86_|amd)64") + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch|AARCH|p(ower)?pc|x86_|amd|loongarch|riscv)64") OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" ON) ELSE() # Disable by default on ISA that are not covered by our CI OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" OFF) diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 3463ac1c068..ef62fa93c8b 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -932,7 +932,7 @@ btr_search_failure(btr_search_t* info, btr_cur_t* cursor) } /** Clear the adaptive hash index on all pages in the buffer pool. */ -inline void buf_pool_t::clear_hash_index() +inline void buf_pool_t::clear_hash_index() noexcept { ut_ad(!resizing); ut_ad(!btr_search_enabled); @@ -984,7 +984,7 @@ inline void buf_pool_t::clear_hash_index() This function does not return if the block is not identified. @param ptr pointer to within a page frame @return pointer to block, never NULL */ -inline buf_block_t* buf_pool_t::block_from_ahi(const byte *ptr) const +inline buf_block_t* buf_pool_t::block_from_ahi(const byte *ptr) const noexcept { chunk_t::map *chunk_map = chunk_t::map_ref; ut_ad(chunk_t::map_ref == chunk_t::map_reg); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 70614750684..7651107bf0f 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -277,7 +277,7 @@ the read requests for the whole area. #ifndef UNIV_INNOCHECKSUM # ifdef SUX_LOCK_GENERIC -void page_hash_latch::read_lock_wait() +void page_hash_latch::read_lock_wait() noexcept { /* First, try busy spinning for a while. */ for (auto spin= srv_n_spin_wait_rounds; spin--; ) @@ -292,7 +292,7 @@ void page_hash_latch::read_lock_wait() while (!read_trylock()); } -void page_hash_latch::write_lock_wait() +void page_hash_latch::write_lock_wait() noexcept { write_lock_wait_start(); @@ -486,7 +486,7 @@ bool buf_page_is_checksum_valid_crc32( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2) + ulint checksum_field2) noexcept { const uint32_t crc32 = buf_calc_page_crc32(read_buf); @@ -554,7 +554,7 @@ static bool buf_page_check_lsn(bool check_lsn, const byte *read_buf) /** Check if a buffer is all zeroes. @param[in] buf data to check @return whether the buffer is all zeroes */ -bool buf_is_zeroes(span buf) +bool buf_is_zeroes(span buf) noexcept { ut_ad(buf.size() <= UNIV_PAGE_SIZE_MAX); return memcmp(buf.data(), field_ref_zero, buf.size()) == 0; @@ -566,7 +566,7 @@ bool buf_is_zeroes(span buf) @param fsp_flags contents of FIL_SPACE_FLAGS @return whether the page is corrupted */ buf_page_is_corrupted_reason -buf_page_is_corrupted(bool check_lsn, const byte *read_buf, uint32_t fsp_flags) +buf_page_is_corrupted(bool check_lsn, const byte *read_buf, uint32_t fsp_flags) noexcept { if (fil_space_t::full_crc32(fsp_flags)) { bool compressed = false, corrupted = false; @@ -1014,7 +1014,7 @@ static inline byte hex_to_ascii(byte hex_digit) @param[in] read_buf database page @param[in] zip_size compressed page size, or 0 */ ATTRIBUTE_COLD -void buf_page_print(const byte *read_buf, ulint zip_size) +void buf_page_print(const byte *read_buf, ulint zip_size) noexcept { #ifndef UNIV_DEBUG const size_t size = zip_size ? zip_size : srv_page_size; @@ -1073,7 +1073,7 @@ buf_block_init(buf_block_t* block, byte* frame) /** Allocate a chunk of buffer frames. @param bytes requested size @return whether the allocation succeeded */ -inline bool buf_pool_t::chunk_t::create(size_t bytes) +inline bool buf_pool_t::chunk_t::create(size_t bytes) noexcept { DBUG_EXECUTE_IF("ib_buf_chunk_init_fails", return false;); /* Round down to a multiple of page size, although it already should be. */ @@ -1159,7 +1159,7 @@ inline bool buf_pool_t::chunk_t::create(size_t bytes) /** Check that all file pages in the buffer chunk are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ -inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const +inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const noexcept { buf_block_t *block= blocks; for (auto i= size; i--; block++) @@ -1199,7 +1199,7 @@ inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const /** Create the hash table. @param n the lower bound of n_cells */ -void buf_pool_t::page_hash_table::create(ulint n) +void buf_pool_t::page_hash_table::create(ulint n) noexcept { n_cells= ut_find_prime(n); const size_t size= MY_ALIGN(pad(n_cells) * sizeof *array, @@ -1337,7 +1337,7 @@ bool buf_pool_t::create() } /** Clean up after successful create() */ -void buf_pool_t::close() +void buf_pool_t::close() noexcept { ut_ad(this == &buf_pool); if (!is_initialised()) @@ -1397,7 +1397,7 @@ void buf_pool_t::close() /** Try to reallocate a control block. @param block control block to reallocate @return whether the reallocation succeeded */ -inline bool buf_pool_t::realloc(buf_block_t *block) +inline bool buf_pool_t::realloc(buf_block_t *block) noexcept { buf_block_t* new_block; @@ -1513,7 +1513,7 @@ inline bool buf_pool_t::realloc(buf_block_t *block) return(true); /* free_list was enough */ } -void buf_pool_t::io_buf_t::create(ulint n_slots) +void buf_pool_t::io_buf_t::create(ulint n_slots) noexcept { this->n_slots= n_slots; slots= static_cast @@ -1521,7 +1521,7 @@ void buf_pool_t::io_buf_t::create(ulint n_slots) memset((void*) slots, 0, n_slots * sizeof *slots); } -void buf_pool_t::io_buf_t::close() +void buf_pool_t::io_buf_t::close() noexcept { for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) { @@ -1533,7 +1533,7 @@ void buf_pool_t::io_buf_t::close() n_slots= 0; } -buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) +buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) noexcept { for (;;) { @@ -1578,7 +1578,7 @@ buf_resize_status( /** Withdraw blocks from the buffer pool until meeting withdraw_target. @return whether retry is needed */ -inline bool buf_pool_t::withdraw_blocks() +inline bool buf_pool_t::withdraw_blocks() noexcept { buf_block_t* block; ulint loop_count = 0; @@ -1707,7 +1707,7 @@ realloc_frame: -inline void buf_pool_t::page_hash_table::write_lock_all() +inline void buf_pool_t::page_hash_table::write_lock_all() noexcept { for (auto n= pad(n_cells) & ~ELEMENTS_PER_LATCH;; n-= ELEMENTS_PER_LATCH + 1) { @@ -1718,7 +1718,7 @@ inline void buf_pool_t::page_hash_table::write_lock_all() } -inline void buf_pool_t::page_hash_table::write_unlock_all() +inline void buf_pool_t::page_hash_table::write_unlock_all() noexcept { for (auto n= pad(n_cells) & ~ELEMENTS_PER_LATCH;; n-= ELEMENTS_PER_LATCH + 1) { @@ -2367,7 +2367,7 @@ static void buf_inc_get(ha_handler_stats *stats) } TRANSACTIONAL_TARGET -buf_page_t *buf_page_get_zip(const page_id_t page_id) +buf_page_t *buf_page_get_zip(const page_id_t page_id) noexcept { ha_handler_stats *const stats= mariadb_stats; buf_inc_get(stats); @@ -2476,14 +2476,7 @@ buf_block_init_low( #endif /* BTR_CUR_HASH_ADAPT */ } -/********************************************************************//** -Decompress a block. -@return true if successful */ -bool -buf_zip_decompress( -/*===============*/ - buf_block_t* block, /*!< in/out: block */ - ibool check) /*!< in: TRUE=verify the page checksum */ +bool buf_zip_decompress(buf_block_t *block, bool check) noexcept { const byte* frame = block->page.zip.data; ulint size = page_zip_get_size(&block->page.zip); @@ -2562,6 +2555,7 @@ err_exit: ATTRIBUTE_COLD buf_block_t *buf_pool_t::unzip(buf_page_t *b, buf_pool_t::hash_chain &chain) + noexcept { buf_block_t *block= buf_LRU_get_free_block(have_no_mutex); buf_block_init_low(block); @@ -2651,7 +2645,7 @@ buf_block_t *buf_pool_t::unzip(buf_page_t *b, buf_pool_t::hash_chain &chain) buf_block_t *buf_pool_t::page_fix(const page_id_t id, dberr_t *err, - buf_pool_t::page_fix_conflicts c) + buf_pool_t::page_fix_conflicts c) noexcept { ha_handler_stats *const stats= mariadb_stats; buf_inc_get(stats); @@ -2768,7 +2762,7 @@ buf_page_get_gen( buf_block_t* guess, ulint mode, mtr_t* mtr, - dberr_t* err) + dberr_t* err) noexcept { ulint retries = 0; @@ -3038,7 +3032,7 @@ wait_for_unzip: } TRANSACTIONAL_TARGET -buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) noexcept { buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id.fold()); transactional_shared_lock_guard g @@ -3056,7 +3050,8 @@ buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) buf_block_t *buf_page_optimistic_get(buf_block_t *block, rw_lock_type_t rw_latch, - uint64_t modify_clock, mtr_t *mtr) + uint64_t modify_clock, + mtr_t *mtr) noexcept { ut_ad(mtr->is_active()); ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); @@ -3121,7 +3116,7 @@ Suitable for using when holding the lock_sys latches (as it avoids deadlock). @return the block @retval nullptr if an S-latch cannot be granted immediately */ TRANSACTIONAL_TARGET -buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) +buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) noexcept { ut_ad(mtr); ut_ad(mtr->is_active()); @@ -3156,7 +3151,7 @@ buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) @param zip_size ROW_FORMAT=COMPRESSED page size, or 0 @param fix initial buf_fix_count() */ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size, - uint32_t fix) + uint32_t fix) noexcept { ut_ad(!page.in_file()); buf_block_init_low(this); @@ -3168,6 +3163,7 @@ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size, TRANSACTIONAL_TARGET static buf_block_t *buf_page_create_low(page_id_t page_id, ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + noexcept { ut_ad(mtr->is_active()); ut_ad(page_id.space() != 0 || !zip_size); @@ -3367,7 +3363,7 @@ FILE_PAGE (the other is buf_page_get_gen). @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create(fil_space_t *space, uint32_t offset, - ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + ulint zip_size, mtr_t *mtr, buf_block_t *free_block) noexcept { space->free_page(offset, false); return buf_page_create_low({space->id, offset}, zip_size, mtr, free_block); @@ -3381,7 +3377,8 @@ deferred tablespace @param free_block pre-allocated buffer block @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, - mtr_t *mtr, buf_block_t *free_block) + mtr_t *mtr, + buf_block_t *free_block) noexcept { return buf_page_create_low({space_id, 0}, zip_size, mtr, free_block); } @@ -3390,7 +3387,8 @@ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, counter value in MONITOR_MODULE_BUF_PAGE. @param bpage buffer page whose read or write was completed @param read true=read, false=write */ -ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) +ATTRIBUTE_COLD +void buf_page_monitor(const buf_page_t &bpage, bool read) noexcept { monitor_id_t counter; @@ -3458,7 +3456,7 @@ ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) @param[in] is_compressed compressed page @return true if page is corrupted or false if it isn't */ static bool buf_page_full_crc32_is_corrupted(ulint space_id, const byte* d, - bool is_compressed) + bool is_compressed) noexcept { if (space_id != mach_read_from_4(d + FIL_PAGE_SPACE_ID)) return true; @@ -3548,7 +3546,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t *bpage, @return whether the operation succeeded @retval DB_PAGE_CORRUPTED if the checksum or the page ID is incorrect @retval DB_DECRYPTION_FAILED if the page cannot be decrypted */ -dberr_t buf_page_t::read_complete(const fil_node_t &node) +dberr_t buf_page_t::read_complete(const fil_node_t &node) noexcept { const page_id_t expected_id{id()}; ut_ad(is_read_fixed()); @@ -3693,7 +3691,7 @@ success_page: /** Check that all blocks are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ -void buf_pool_t::assert_all_freed() +void buf_pool_t::assert_all_freed() noexcept { mysql_mutex_lock(&mutex); const chunk_t *chunk= chunks; @@ -3705,7 +3703,7 @@ void buf_pool_t::assert_all_freed() #endif /* UNIV_DEBUG */ /** Refresh the statistics used to print per-second averages. */ -void buf_refresh_io_stats() +void buf_refresh_io_stats() noexcept { buf_pool.last_printout_time = time(NULL); buf_pool.old_stat = buf_pool.stat; @@ -3713,7 +3711,7 @@ void buf_refresh_io_stats() /** Invalidate all pages in the buffer pool. All pages must be in a replaceable state (not modified or latched). */ -void buf_pool_invalidate() +void buf_pool_invalidate() noexcept { /* It is possible that a write batch that has been posted earlier is still not complete. For buffer pool invalidation to @@ -3740,7 +3738,7 @@ void buf_pool_invalidate() #ifdef UNIV_DEBUG /** Validate the buffer pool. */ -void buf_pool_t::validate() +void buf_pool_t::validate() noexcept { ulint n_lru = 0; ulint n_flushing = 0; @@ -3835,7 +3833,7 @@ void buf_pool_t::validate() #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG /** Write information of the buf_pool to the error log. */ -void buf_pool_t::print() +void buf_pool_t::print() noexcept { index_id_t* index_ids; ulint* counts; @@ -3939,7 +3937,7 @@ void buf_pool_t::print() #ifdef UNIV_DEBUG /** @return the number of latched pages in the buffer pool */ -ulint buf_get_latched_pages_number() +ulint buf_get_latched_pages_number() noexcept { ulint fixed_pages_number= 0; @@ -3958,7 +3956,7 @@ ulint buf_get_latched_pages_number() /** Collect buffer pool metadata. @param[out] pool_info buffer pool metadata */ -void buf_stats_get_pool_info(buf_pool_info_t *pool_info) +void buf_stats_get_pool_info(buf_pool_info_t *pool_info) noexcept { time_t current_time; double time_elapsed; @@ -4191,7 +4189,7 @@ This function should be called only if tablespace contains crypt data metadata. @param page page frame @param fsp_flags contents of FSP_SPACE_FLAGS @return whether the page is encrypted and valid */ -bool buf_page_verify_crypt_checksum(const byte *page, uint32_t fsp_flags) +bool buf_page_verify_crypt_checksum(const byte *page, uint32_t fsp_flags) noexcept { if (!fil_space_t::full_crc32(fsp_flags)) { return fil_space_verify_crypt_checksum( diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e9021afd644..51ccadd2612 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -41,13 +41,13 @@ using st_::span; buf_dblwr_t buf_dblwr; /** @return the TRX_SYS page */ -inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr) +inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr) noexcept { return buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO), 0, RW_X_LATCH, mtr); } -void buf_dblwr_t::init() +void buf_dblwr_t::init() noexcept { if (!active_slot) { @@ -60,7 +60,7 @@ void buf_dblwr_t::init() /** Initialise the persistent storage of the doublewrite buffer. @param header doublewrite page header in the TRX_SYS page */ -inline void buf_dblwr_t::init(const byte *header) +inline void buf_dblwr_t::init(const byte *header) noexcept { ut_ad(!active_slot->first_free); ut_ad(!active_slot->reserved); @@ -82,7 +82,7 @@ inline void buf_dblwr_t::init(const byte *header) /** Create or restore the doublewrite buffer in the TRX_SYS page. @return whether the operation succeeded */ -bool buf_dblwr_t::create() +bool buf_dblwr_t::create() noexcept { if (is_created()) return true; @@ -114,9 +114,9 @@ start_again: if (UT_LIST_GET_FIRST(fil_system.sys_space->chain)->size < 3 * size) { - ib::error() << "Cannot create doublewrite buffer: " - "the first file in innodb_data_file_path must be at least " - << (3 * (size >> (20U - srv_page_size_shift))) << "M."; + sql_print_error("InnoDB: Cannot create doublewrite buffer: " + "the first file in innodb_data_file_path must be at least " + "%zuM.", 3 * (size >> (20U - srv_page_size_shift))); fail: mtr.commit(); return false; @@ -128,11 +128,13 @@ fail: &mtr, &err, false, trx_sys_block); if (!b) { - ib::error() << "Cannot create doublewrite buffer: " << err; + sql_print_error("InnoDB: Cannot create doublewrite buffer: %s", + ut_strerr(err)); goto fail; } - ib::info() << "Doublewrite buffer not found: creating new"; + sql_print_information("InnoDB: Doublewrite buffer not found:" + " creating new"); /* FIXME: After this point, the doublewrite buffer creation is not atomic. The doublewrite buffer should not exist in @@ -151,9 +153,9 @@ fail: false, &mtr, &mtr, &err); if (!new_block) { - ib::error() << "Cannot create doublewrite buffer: " + sql_print_error("InnoDB: Cannot create doublewrite buffer: " " you must increase your tablespace size." - " Cannot continue operation."; + " Cannot continue operation."); /* This may essentially corrupt the doublewrite buffer. However, usually the doublewrite buffer is created at database initialization, and it @@ -239,6 +241,8 @@ fail: /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); + + sql_print_information("InnoDB: Doublewrite buffer created"); goto start_again; } @@ -251,6 +255,7 @@ loads the pages from double write buffer into memory. @param path Path name of file @return DB_SUCCESS or error code */ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path) + noexcept { ut_ad(this == &buf_dblwr); const uint32_t size= block_size; @@ -265,7 +270,8 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path) if (err != DB_SUCCESS) { - ib::error() << "Failed to read the system tablespace header page"; + sql_print_error("InnoDB: Failed to read the system tablespace" + " header page"); func_exit: aligned_free(read_buf); return err; @@ -298,7 +304,8 @@ func_exit: if (err != DB_SUCCESS) { - ib::error() << "Failed to read the first double write buffer extent"; + sql_print_error("InnoDB: Failed to read" + " the first double write buffer extent"); goto func_exit; } @@ -308,7 +315,8 @@ func_exit: size << srv_page_size_shift, nullptr); if (err != DB_SUCCESS) { - ib::error() << "Failed to read the second double write buffer extent"; + sql_print_error("InnoDB: Failed to read" + " the second double write buffer extent"); goto func_exit; } @@ -316,7 +324,8 @@ func_exit: if (UNIV_UNLIKELY(upgrade_to_innodb_file_per_table)) { - ib::info() << "Resetting space id's in the doublewrite buffer"; + sql_print_information("InnoDB: Resetting space id's in " + "the doublewrite buffer"); for (ulint i= 0; i < size * 2; i++, page += srv_page_size) { @@ -332,7 +341,7 @@ func_exit: source_page_no << srv_page_size_shift, srv_page_size); if (err != DB_SUCCESS) { - ib::error() << "Failed to upgrade the double write buffer"; + sql_print_error("InnoDB: Failed to upgrade the double write buffer"); goto func_exit; } } @@ -352,7 +361,7 @@ func_exit: } /** Process and remove the double write buffer pages for all tablespaces. */ -void buf_dblwr_t::recover() +void buf_dblwr_t::recover() noexcept { ut_ad(log_sys.last_checkpoint_lsn); if (!is_created()) @@ -477,7 +486,7 @@ next_page: } /** Free the doublewrite buffer. */ -void buf_dblwr_t::close() +void buf_dblwr_t::close() noexcept { if (!active_slot) return; @@ -498,7 +507,7 @@ void buf_dblwr_t::close() } /** Update the doublewrite buffer on write completion. */ -void buf_dblwr_t::write_completed() +void buf_dblwr_t::write_completed() noexcept { ut_ad(this == &buf_dblwr); ut_ad(!srv_read_only_mode); @@ -532,6 +541,7 @@ void buf_dblwr_t::write_completed() @param[in] page page to check @param[in] s tablespace */ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s) + noexcept { /* Ignore page_compressed or encrypted pages */ if (s.is_compressed() || buf_page_get_key_version(page, s.flags)) @@ -547,6 +557,7 @@ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s) } static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page) + noexcept { if (fil_space_t *space= fil_space_t::get_for_write(b.id().space())) { @@ -556,7 +567,7 @@ static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page) } /** Check the LSN values on the page with which this block is associated. */ -static void buf_dblwr_check_block(const buf_page_t *bpage) +static void buf_dblwr_check_block(const buf_page_t *bpage) noexcept { ut_ad(bpage->in_file()); const page_t *page= bpage->frame; @@ -588,7 +599,7 @@ static void buf_dblwr_check_block(const buf_page_t *bpage) } #endif /* UNIV_DEBUG */ -bool buf_dblwr_t::flush_buffered_writes(const ulint size) +bool buf_dblwr_t::flush_buffered_writes(const ulint size) noexcept { mysql_mutex_assert_owner(&mutex); ut_ad(size == block_size); @@ -653,7 +664,7 @@ bool buf_dblwr_t::flush_buffered_writes(const ulint size) return true; } -static void *get_frame(const IORequest &request) +static void *get_frame(const IORequest &request) noexcept { if (request.slot) return request.slot->out_buf; @@ -662,6 +673,7 @@ static void *get_frame(const IORequest &request) } void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) + noexcept { ut_ad(this == &buf_dblwr); ut_ad(is_created()); @@ -734,7 +746,7 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) It is very important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ -void buf_dblwr_t::flush_buffered_writes() +void buf_dblwr_t::flush_buffered_writes() noexcept { mysql_mutex_lock(&mutex); @@ -755,7 +767,7 @@ void buf_dblwr_t::flush_buffered_writes() flush_buffered_writes() will be invoked to make space. @param request asynchronous write request @param size payload size in bytes */ -void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) +void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) noexcept { ut_ad(request.bpage); ut_ad(request.bpage->in_file()); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index fc3d26783e8..82d9496b9dc 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -85,10 +85,10 @@ static struct #ifdef UNIV_DEBUG /** Validate the flush list. */ -static void buf_flush_validate_low(); +static void buf_flush_validate_low() noexcept; /** Validates the flush list some of the time. */ -static void buf_flush_validate_skip() +static void buf_flush_validate_skip() noexcept { /** Try buf_flush_validate_low() every this many times */ # define BUF_FLUSH_VALIDATE_SKIP 23 @@ -110,7 +110,7 @@ static void buf_flush_validate_skip() } #endif /* UNIV_DEBUG */ -void buf_pool_t::page_cleaner_wakeup(bool for_LRU) +void buf_pool_t::page_cleaner_wakeup(bool for_LRU) noexcept { ut_d(buf_flush_validate_skip()); if (!page_cleaner_idle()) @@ -179,7 +179,7 @@ deleting the data file of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. @param id tablespace identifier */ -void buf_flush_remove_pages(uint32_t id) +void buf_flush_remove_pages(uint32_t id) noexcept { const page_id_t first(id, 0), end(id + 1, 0); ut_ad(id); @@ -236,6 +236,7 @@ buf_flush_relocate_on_flush_list( /*=============================*/ buf_page_t* bpage, /*!< in/out: control block being moved */ buf_page_t* dpage) /*!< in/out: destination block */ + noexcept { buf_page_t* prev; @@ -276,6 +277,7 @@ buf_flush_relocate_on_flush_list( } void buf_page_t::write_complete(bool persistent, bool error, uint32_t state) + noexcept { ut_ad(!persistent == fsp_is_system_temporary(id().space())); ut_ad(state >= WRITE_FIX); @@ -296,13 +298,13 @@ void buf_page_t::write_complete(bool persistent, bool error, uint32_t state) lock.u_unlock(true); } -inline void buf_pool_t::n_flush_inc() +inline void buf_pool_t::n_flush_inc() noexcept { mysql_mutex_assert_owner(&flush_list_mutex); page_cleaner_status+= LRU_FLUSH; } -inline void buf_pool_t::n_flush_dec() +inline void buf_pool_t::n_flush_dec() noexcept { mysql_mutex_assert_owner(&flush_list_mutex); ut_ad(page_cleaner_status >= LRU_FLUSH); @@ -313,7 +315,7 @@ inline void buf_pool_t::n_flush_dec() /** Complete write of a file page from buf_pool. @param request write request @param error whether the write may have failed */ -void buf_page_write_complete(const IORequest &request, bool error) +void buf_page_write_complete(const IORequest &request, bool error) noexcept { ut_ad(request.is_write()); ut_ad(!srv_read_only_mode); @@ -363,7 +365,7 @@ void buf_page_write_complete(const IORequest &request, bool error) /** Calculate a ROW_FORMAT=COMPRESSED page checksum and update the page. @param[in,out] page page to update @param[in] size compressed page size */ -void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) +void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) noexcept { ut_ad(size > 0); mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, @@ -372,7 +374,7 @@ void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) /** Assign the full crc32 checksum for non-compressed page. @param[in,out] page page to be updated */ -void buf_flush_assign_full_crc32_checksum(byte* page) +void buf_flush_assign_full_crc32_checksum(byte* page) noexcept { ut_d(bool compressed = false); ut_d(bool corrupted = false); @@ -397,7 +399,7 @@ buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - bool use_full_checksum) + bool use_full_checksum) noexcept { if (block && block->page.frame != page) { /* If page is encrypted in full crc32 format then @@ -465,8 +467,8 @@ buf_flush_init_for_writing( /* The page type could be garbage in old files created before MySQL 5.5. Such files always had a page size of 16 kilobytes. */ - ulint page_type = fil_page_get_type(page); - ulint reset_type = page_type; + uint16_t page_type = fil_page_get_type(page); + uint16_t reset_type = page_type; switch (block->page.id().page_no() % 16384) { case 0: @@ -529,7 +531,7 @@ buf_flush_init_for_writing( /** Reserve a buffer for compression. @param[in,out] slot reserved slot */ -static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) +static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) noexcept { if (slot->comp_buf) return; @@ -548,7 +550,8 @@ static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) @param[in] s Page to encrypt @param[in,out] d Output buffer @return encrypted buffer or NULL */ -static byte* buf_tmp_page_encrypt(ulint offset, const byte* s, byte* d) +static byte *buf_tmp_page_encrypt(ulint offset, const byte *s, byte *d) + noexcept { /* Calculate the start offset in a page */ uint srclen= static_cast(srv_page_size) - @@ -578,8 +581,8 @@ a page is written to disk. @param[in,out] size payload size in bytes @return page frame to be written to file (may be src_frame or an encrypted/compressed copy of it) */ -static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s, - buf_tmp_buffer_t **slot, size_t *size) +static byte *buf_page_encrypt(fil_space_t *space, buf_page_t *bpage, byte *s, + buf_tmp_buffer_t **slot, size_t *size) noexcept { ut_ad(!bpage->is_freed()); ut_ad(space->id == bpage->id().space()); @@ -725,7 +728,7 @@ ATTRIBUTE_COLD void buf_pool_t::release_freed_page(buf_page_t *bpage) noexcept /** Write a flushable page to a file or free a freeable block. @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ -bool buf_page_t::flush(fil_space_t *space) +bool buf_page_t::flush(fil_space_t *space) noexcept { mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); ut_ad(in_file()); @@ -862,7 +865,7 @@ bool buf_page_t::flush(fil_space_t *space) @param id page identifier @param fold id.fold() @return whether the page can be flushed */ -static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) +static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(fold == id.fold()); @@ -881,6 +884,7 @@ static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) @return last page number that can be flushed */ static page_id_t buf_flush_check_neighbors(const fil_space_t &space, page_id_t &id, bool contiguous) + noexcept { ut_ad(id.page_no() < space.size + (space.physical_size() == 2048 ? 1 @@ -941,7 +945,7 @@ MY_ATTRIBUTE((warn_unused_result)) /** Apply freed_ranges to the file. @param writable whether the file is writable @return number of pages written or hole-punched */ -uint32_t fil_space_t::flush_freed(bool writable) +uint32_t fil_space_t::flush_freed(bool writable) noexcept { const bool punch_hole= chain.start->punch_hole == 1; if (!punch_hole && !srv_immediate_scrub_data_uncompressed) @@ -1013,7 +1017,8 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, const page_id_t page_id, buf_page_t *bpage, bool contiguous, - ulint n_flushed, ulint n_to_flush) + ulint n_flushed, + ulint n_to_flush) noexcept { ut_ad(space->id == page_id.space()); ut_ad(bpage->id() == page_id); @@ -1109,7 +1114,7 @@ Note that this function does not actually flush any data to disk. It just detaches the uncompressed frames from the compressed pages at the tail of the unzip_LRU and puts those freed frames in the free list. @return number of blocks moved to the free list. */ -static ulint buf_free_from_unzip_LRU_list_batch() +static ulint buf_free_from_unzip_LRU_list_batch() noexcept { ulint scanned = 0; ulint count = 0; @@ -1151,7 +1156,7 @@ static ulint buf_free_from_unzip_LRU_list_batch() @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ -fil_space_t *fil_space_t::get_for_write(uint32_t id) +fil_space_t *fil_space_t::get_for_write(uint32_t id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); @@ -1170,6 +1175,7 @@ fil_space_t *fil_space_t::get_for_write(uint32_t id) @param id tablespace identifier @return tablespace and number of pages written */ static std::pair buf_flush_space(const uint32_t id) + noexcept { if (fil_space_t *space= fil_space_t::get_for_write(id)) return {space, space->flush_freed(true)}; @@ -1186,7 +1192,7 @@ struct flush_counters_t /** Discard a dirty page, and release buf_pool.flush_list_mutex. @param bpage dirty page whose tablespace is not accessible */ -static void buf_flush_discard_page(buf_page_t *bpage) +static void buf_flush_discard_page(buf_page_t *bpage) noexcept { ut_ad(bpage->in_file()); ut_ad(bpage->oldest_modification()); @@ -1205,7 +1211,7 @@ static void buf_flush_discard_page(buf_page_t *bpage) and move clean blocks to buf_pool.free. @param max maximum number of blocks to flush @param n counts of flushed and evicted pages */ -static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) +static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) noexcept { ulint scanned= 0; mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1362,7 +1368,7 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) Whether LRU or unzip_LRU is used depends on the state of the system. @param max maximum number of blocks to flush @param n counts of flushed and evicted pages */ -static void buf_do_LRU_batch(ulint max, flush_counters_t *n) +static void buf_do_LRU_batch(ulint max, flush_counters_t *n) noexcept { if (buf_LRU_evict_from_unzip_LRU()) buf_free_from_unzip_LRU_list_batch(); @@ -1381,7 +1387,7 @@ The calling thread is not allowed to own any latches on pages! @param max_n maximum mumber of blocks to flush @param lsn once an oldest_modification>=lsn is found, terminate the batch @return number of blocks for which the write request was queued */ -static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) +static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) noexcept { ulint count= 0; ulint scanned= 0; @@ -1511,7 +1517,7 @@ static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) } /** Wait until a LRU flush batch ends. */ -void buf_flush_wait_LRU_batch_end() +void buf_flush_wait_LRU_batch_end() noexcept { mysql_mutex_assert_owner(&buf_pool.flush_list_mutex); mysql_mutex_assert_not_owner(&buf_pool.mutex); @@ -1537,7 +1543,7 @@ after releasing buf_pool.mutex. @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ static ulint buf_flush_list_holding_mutex(ulint max_n= ULINT_UNDEFINED, - lsn_t lsn= LSN_MAX) + lsn_t lsn= LSN_MAX) noexcept { ut_ad(lsn); mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1578,7 +1584,7 @@ nothing_to_do: @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, - lsn_t lsn= LSN_MAX) + lsn_t lsn= LSN_MAX) noexcept { mysql_mutex_lock(&buf_pool.mutex); ulint n= buf_flush_list_holding_mutex(max_n, lsn); @@ -1591,7 +1597,7 @@ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, @param space tablespace @param n_flushed number of pages written @return whether the flush for some pages might not have been initiated */ -bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) +bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) noexcept { const auto space_id= space->id; ut_ad(space_id < SRV_SPACE_ID_UPPER_BOUND); @@ -1709,7 +1715,7 @@ The caller must invoke buf_dblwr.flush_buffered_writes() after releasing buf_pool.mutex. @param max_n wished maximum mumber of blocks flushed @return number of pages written */ -static ulint buf_flush_LRU(ulint max_n) +static ulint buf_flush_LRU(ulint max_n) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1923,7 +1929,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept @param oldest_lsn the checkpoint LSN @param end_lsn log_sys.get_lsn() @return true if success, false if a checkpoint write was already running */ -static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) +static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) noexcept { ut_ad(!srv_read_only_mode); ut_ad(log_sys.latch_have_wr()); @@ -1986,7 +1992,7 @@ modification in the pool, and writes information about the lsn in log file. Use log_make_checkpoint() to flush also the pool. @retval true if the checkpoint was or had been made @retval false if a checkpoint write was already running */ -static bool log_checkpoint() +static bool log_checkpoint() noexcept { if (recv_recovery_is_on()) recv_sys.apply(true); @@ -2010,7 +2016,7 @@ ATTRIBUTE_COLD void log_make_checkpoint() /** Wait for all dirty pages up to an LSN to be written out. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -static void buf_flush_wait(lsn_t lsn) +static void buf_flush_wait(lsn_t lsn) noexcept { ut_ad(lsn <= log_sys.get_lsn()); @@ -2043,7 +2049,7 @@ static void buf_flush_wait(lsn_t lsn) /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ -ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) +ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) noexcept { ut_ad(sync_lsn); ut_ad(sync_lsn < LSN_MAX); @@ -2104,7 +2110,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) /** Initiate more eager page flushing if the log checkpoint age is too old. @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @param furious true=furious flushing, false=limit to innodb_io_capacity */ -ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) +ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) noexcept { ut_ad(!srv_read_only_mode); @@ -2135,7 +2141,7 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) and try to initiate checkpoints until the target is met. @param lsn minimum value of buf_pool.get_oldest_modification(LSN_MAX) */ ATTRIBUTE_COLD ATTRIBUTE_NOINLINE -static void buf_flush_sync_for_checkpoint(lsn_t lsn) +static void buf_flush_sync_for_checkpoint(lsn_t lsn) noexcept { ut_ad(!srv_read_only_mode); mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); @@ -2218,7 +2224,7 @@ static void buf_flush_sync_for_checkpoint(lsn_t lsn) redo log capacity filled threshold. @param oldest_lsn buf_pool.get_oldest_modification() @return true if adaptive flushing is recommended. */ -static bool af_needed_for_redo(lsn_t oldest_lsn) +static bool af_needed_for_redo(lsn_t oldest_lsn) noexcept { lsn_t age= (log_sys.get_lsn() - oldest_lsn); lsn_t af_lwm= static_cast(srv_adaptive_flushing_lwm * @@ -2270,7 +2276,7 @@ static ulint page_cleaner_flush_pages_recommendation(ulint last_pages_in, lsn_t oldest_lsn, double pct_lwm, ulint dirty_blocks, - double dirty_pct) + double dirty_pct) noexcept { static lsn_t prev_lsn = 0; static ulint sum_pages = 0; @@ -2392,7 +2398,7 @@ func_exit: } TPOOL_SUPPRESS_TSAN -bool buf_pool_t::need_LRU_eviction() const +bool buf_pool_t::need_LRU_eviction() const noexcept { /* try_LRU_scan==false means that buf_LRU_get_free_block() is waiting for buf_flush_page_cleaner() to evict some blocks */ @@ -2407,7 +2413,7 @@ __attribute__((optimize(0))) #endif /** page_cleaner thread tasked with flushing dirty pages from the buffer pools. As of now we'll have only one coordinator. */ -static void buf_flush_page_cleaner() +static void buf_flush_page_cleaner() noexcept { my_thread_init(); #ifdef UNIV_PFS_THREAD @@ -2665,7 +2671,7 @@ static void buf_flush_page_cleaner() #endif } -ATTRIBUTE_COLD void buf_pool_t::LRU_warn() +ATTRIBUTE_COLD void buf_pool_t::LRU_warn() noexcept { mysql_mutex_assert_owner(&mutex); try_LRU_scan= false; @@ -2677,7 +2683,7 @@ ATTRIBUTE_COLD void buf_pool_t::LRU_warn() } /** Initialize page_cleaner. */ -ATTRIBUTE_COLD void buf_flush_page_cleaner_init() +ATTRIBUTE_COLD void buf_flush_page_cleaner_init() noexcept { ut_ad(!buf_page_cleaner_is_active); ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || @@ -2690,7 +2696,7 @@ ATTRIBUTE_COLD void buf_flush_page_cleaner_init() } /** Flush the buffer pool on shutdown. */ -ATTRIBUTE_COLD void buf_flush_buffer_pool() +ATTRIBUTE_COLD void buf_flush_buffer_pool() noexcept { ut_ad(!buf_page_cleaner_is_active); ut_ad(!buf_flush_sync_lsn); @@ -2718,7 +2724,7 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() /** Synchronously flush dirty blocks during recv_sys_t::apply(). NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync_batch(lsn_t lsn) +void buf_flush_sync_batch(lsn_t lsn) noexcept { lsn= std::max(lsn, log_sys.get_lsn()); mysql_mutex_lock(&buf_pool.flush_list_mutex); @@ -2728,7 +2734,7 @@ void buf_flush_sync_batch(lsn_t lsn) /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync() +void buf_flush_sync() noexcept { if (recv_recovery_is_on()) { @@ -2760,7 +2766,7 @@ void buf_flush_sync() #ifdef UNIV_DEBUG /** Functor to validate the flush list. */ struct Check { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_ad(elem->oldest_modification()); ut_ad(!fsp_is_system_temporary(elem->id().space())); @@ -2768,7 +2774,7 @@ struct Check { }; /** Validate the flush list. */ -static void buf_flush_validate_low() +static void buf_flush_validate_low() noexcept { buf_page_t* bpage; @@ -2797,7 +2803,7 @@ static void buf_flush_validate_low() } /** Validate the flush list. */ -void buf_flush_validate() +void buf_flush_validate() noexcept { mysql_mutex_lock(&buf_pool.flush_list_mutex); buf_flush_validate_low(); diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 139154e6baa..a00f6873bbd 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -46,6 +46,7 @@ Created 11/5/1995 Heikki Tuuri TRANSACTIONAL_TARGET bool buf_pool_t::page_hash_contains(const page_id_t page_id, hash_chain &chain) + noexcept { transactional_shared_lock_guard g {page_hash.lock_get(chain)}; @@ -219,7 +220,7 @@ buf_read_page_low( buf_pool_t::hash_chain& chain, fil_space_t* space, buf_block_t*& block, - bool sync = false) + bool sync = false) noexcept { buf_page_t* bpage; @@ -303,7 +304,7 @@ end up waiting for these latches! wants to access @return number of page read requests issued */ TRANSACTIONAL_TARGET -ulint buf_read_ahead_random(const page_id_t page_id) +ulint buf_read_ahead_random(const page_id_t page_id) noexcept { if (!srv_random_read_ahead || page_id.space() >= SRV_TMP_SPACE_ID) /* Disable the read-ahead for temporary tablespace */ @@ -444,7 +445,7 @@ released by the i/o-handler thread. @param[in] page_id page id @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 */ void buf_read_page_background(fil_space_t *space, const page_id_t page_id, - ulint zip_size) + ulint zip_size) noexcept { buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(page_id.fold()); if (buf_pool.page_hash_contains(page_id, chain)) @@ -503,7 +504,7 @@ latches! @param[in] page_id page id; see NOTE 3 above @return number of page read requests issued */ TRANSACTIONAL_TARGET -ulint buf_read_ahead_linear(const page_id_t page_id) +ulint buf_read_ahead_linear(const page_id_t page_id) noexcept { /* check if readahead is disabled. Disable the read ahead logic for temporary tablespace */ @@ -697,7 +698,7 @@ failed: @param recs log records @param init_lsn page initialization, or 0 if the page needs to be read */ void buf_read_recover(fil_space_t *space, const page_id_t page_id, - page_recv_t &recs, lsn_t init_lsn) + page_recv_t &recs, lsn_t init_lsn) noexcept { ut_ad(space->id == page_id.space()); space->reacquire(); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 35c6f65ddef..62945bfd53e 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1365,7 +1365,7 @@ the encryption parameters were changed @retval nullptr upon reaching the end of the iteration */ inline fil_space_t *fil_system_t::default_encrypt_next(fil_space_t *space, bool recheck, - bool encrypt) + bool encrypt) noexcept { mysql_mutex_assert_owner(&mutex); @@ -1432,7 +1432,7 @@ encryption parameters were changed @retval fil_system.temp_space if there is no work to do @retval end() upon reaching the end of the iteration */ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, - bool recheck, bool encrypt) + bool recheck, bool encrypt) noexcept { mysql_mutex_lock(&fil_system.mutex); @@ -1481,7 +1481,7 @@ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, static bool fil_crypt_find_space_to_rotate( key_state_t* key_state, rotate_thread_t* state, - bool* recheck) + bool* recheck) noexcept { /* we need iops to start rotating */ do { diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 7a0338ab26e..2c64a6b7b10 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -74,6 +74,7 @@ ATTRIBUTE_COLD bool fil_space_t::set_corrupted() const noexcept @param print_info whether to diagnose why a file cannot be closed @return whether a file was closed */ bool fil_space_t::try_to_close(fil_space_t *ignore_space, bool print_info) + noexcept { mysql_mutex_assert_owner(&fil_system.mutex); for (fil_space_t &space : fil_system.space_list) @@ -204,10 +205,7 @@ extern uint srv_fil_crypt_rotate_key_age; /******************************************************************//** Checks the consistency of the tablespace cache some of the time. @return true if ok or the check was skipped */ -static -bool -fil_validate_skip(void) -/*===================*/ +static bool fil_validate_skip() noexcept { /** The fil_validate() call skip counter. */ static Atomic_counter fil_validate_count; @@ -234,7 +232,7 @@ or the caller should be in single-threaded crash recovery mode Normally, fil_space_t::get() should be used instead. @param[in] id tablespace ID @return tablespace, or NULL if not found */ -fil_space_t *fil_space_get(uint32_t id) +fil_space_t *fil_space_get(uint32_t id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); @@ -245,7 +243,7 @@ fil_space_t *fil_space_get(uint32_t id) /** Check if the compression algorithm is loaded @param[in] comp_algo ulint compression algorithm @return whether the compression algorithm is loaded */ -bool fil_comp_algo_loaded(ulint comp_algo) +bool fil_comp_algo_loaded(ulint comp_algo) noexcept { switch (comp_algo) { case PAGE_UNCOMPRESSED: @@ -282,7 +280,7 @@ or UINT32_MAX for unlimited @return file object */ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle, uint32_t size, bool is_raw, bool atomic_write, - uint32_t max_pages) + uint32_t max_pages) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); @@ -464,7 +462,7 @@ static bool fil_node_open_file(fil_node_t *node, const byte *page, bool no_lsn) } /** Close the file handle. */ -void fil_node_t::close() +void fil_node_t::close() noexcept { prepare_to_close_or_detach(); @@ -474,7 +472,7 @@ void fil_node_t::close() handle= OS_FILE_CLOSED; } -pfs_os_file_t fil_node_t::detach() +pfs_os_file_t fil_node_t::detach() noexcept { prepare_to_close_or_detach(); @@ -483,7 +481,7 @@ pfs_os_file_t fil_node_t::detach() return result; } -void fil_node_t::prepare_to_close_or_detach() +void fil_node_t::prepare_to_close_or_detach() noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_ad(space->is_ready_to_close() || srv_operation == SRV_OPERATION_BACKUP || @@ -498,7 +496,7 @@ void fil_node_t::prepare_to_close_or_detach() } /** Flush any writes cached by the file system. */ -void fil_space_t::flush_low() +void fil_space_t::flush_low() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); @@ -558,7 +556,7 @@ fil_space_extend_must_retry( fil_space_t* space, fil_node_t* node, uint32_t size, - bool* success) + bool* success) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_ad(UT_LIST_GET_LAST(space->chain) == node); @@ -679,7 +677,7 @@ bool recv_sys_t::check_sys_truncate() } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() +ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() noexcept { ut_ad(referenced()); mysql_mutex_assert_owner(&fil_system.mutex); @@ -733,7 +731,7 @@ clear: } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() +ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() noexcept { mysql_mutex_lock(&fil_system.mutex); const auto flags= acquire_low() & (STOPPING | CLOSING); @@ -746,7 +744,7 @@ ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() @param[in,out] space tablespace @param[in] size desired size in pages @return whether the tablespace is at least as big as requested */ -bool fil_space_extend(fil_space_t *space, uint32_t size) +bool fil_space_extend(fil_space_t *space, uint32_t size) noexcept { ut_ad(!srv_read_only_mode || space->is_temporary()); bool success= false; @@ -763,7 +761,7 @@ bool fil_space_extend(fil_space_t *space, uint32_t size) } /** Prepare to free a file from fil_system. */ -inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) +inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_a(!being_extended); @@ -809,6 +807,7 @@ inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) @return detached handle @retval OS_FILE_CLOSED if no handle was detached */ pfs_os_file_t fil_system_t::detach(fil_space_t *space, bool detach_handle) + noexcept { mysql_mutex_assert_owner(&fil_system.mutex); spaces.cell_get(space->id)->remove(*space, &fil_space_t::hash); @@ -873,10 +872,7 @@ pfs_os_file_t fil_system_t::detach(fil_space_t *space, bool detach_handle) /** Free a tablespace object on which fil_system_t::detach() was invoked. There must not be any pending i/o's or flushes on the files. @param[in,out] space tablespace */ -static -void -fil_space_free_low( - fil_space_t* space) +static void fil_space_free_low(fil_space_t *space) noexcept { /* The tablespace must not be in fil_system.named_spaces. */ ut_ad(srv_fast_shutdown == 2 || !srv_was_started @@ -912,7 +908,7 @@ There must not be any pending i/o's or flushes on the files. @param id tablespace identifier @param x_latched whether the caller holds exclusive fil_space_t::latch @return true if success */ -bool fil_space_free(uint32_t id, bool x_latched) +bool fil_space_free(uint32_t id, bool x_latched) noexcept { ut_ad(id != TRX_SYS_SPACE); @@ -1039,7 +1035,7 @@ Assigns a new space id for a new single-table tablespace. This works simply by incrementing the global counter. If 4 billion id's is not enough, we may need to recycle id's. @return true if assigned, false if not */ -bool fil_assign_new_space_id(uint32_t *space_id) +bool fil_assign_new_space_id(uint32_t *space_id) noexcept { uint32_t id = *space_id; bool success; @@ -1106,7 +1102,7 @@ bool fil_space_t::read_page0(const byte *dpage, bool no_lsn) noexcept } void fil_space_set_recv_size_and_flags(uint32_t id, uint32_t size, - uint32_t flags) + uint32_t flags) noexcept { ut_ad(id < SRV_SPACE_ID_UPPER_BOUND); mysql_mutex_assert_owner(&recv_sys.mutex); @@ -1284,7 +1280,7 @@ void fil_system_t::create(ulint hash_size) #endif } -void fil_system_t::close() +void fil_system_t::close() noexcept { ut_ad(this == &fil_system); ut_a(unflushed_spaces.empty()); @@ -1307,7 +1303,7 @@ void fil_system_t::close() #endif /* __linux__ */ } -void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) +void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) noexcept { if (UNIV_LIKELY(space_list_last_opened != nullptr)) space_list.insert(++space_list_t::iterator(space_list_last_opened), *space); @@ -1317,7 +1313,7 @@ void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) } /** Extend all open data files to the recovered size */ -ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() +ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() noexcept { ut_ad(is_initialised()); mysql_mutex_lock(&mutex); @@ -1460,7 +1456,7 @@ void fil_system_t::set_buffered(bool buffered) } /** Close all tablespace files at shutdown */ -void fil_space_t::close_all() +void fil_space_t::close_all() noexcept { if (!fil_system.is_initialised()) return; @@ -1519,7 +1515,7 @@ void fil_space_t::close_all() /*******************************************************************//** Sets the max tablespace id counter if the given number is bigger than the previous value. */ -void fil_set_max_space_id_if_bigger(uint32_t max_id) +void fil_set_max_space_id_if_bigger(uint32_t max_id) noexcept { ut_a(max_id < SRV_SPACE_ID_UPPER_BOUND); @@ -1537,7 +1533,7 @@ void fil_set_max_space_id_if_bigger(uint32_t max_id) @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ -fil_space_t *fil_space_t::get(uint32_t id) +fil_space_t *fil_space_t::get(uint32_t id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); @@ -1736,7 +1732,7 @@ fil_space_t *fil_space_t::drop(uint32_t id, pfs_os_file_t *detached_handle) /** Close a single-table tablespace on failed IMPORT TABLESPACE. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. */ -void fil_close_tablespace(uint32_t id) +void fil_close_tablespace(uint32_t id) noexcept { ut_ad(!is_system_tablespace(id)); fil_space_t* space = fil_space_t::drop(id, nullptr); @@ -1768,7 +1764,7 @@ void fil_close_tablespace(uint32_t id) @param id tablespace identifier @return detached file handle (to be closed by the caller) @return OS_FILE_CLOSED if no file existed */ -pfs_os_file_t fil_delete_tablespace(uint32_t id) +pfs_os_file_t fil_delete_tablespace(uint32_t id) noexcept { ut_ad(!is_system_tablespace(id)); pfs_os_file_t handle= OS_FILE_CLOSED; @@ -1777,17 +1773,9 @@ pfs_os_file_t fil_delete_tablespace(uint32_t id) return handle; } -/*******************************************************************//** -Allocates and builds a file name from a path, a table or tablespace name -and a suffix. The string must be freed by caller with ut_free(). -@param[in] path nullptr or the directory path or the full path and filename -@param[in] name {} if path is full, or Table/Tablespace name -@param[in] extension the file extension to use -@param[in] trim_name true if the last name on the path should be trimmed -@return own: file name */ char* fil_make_filepath_low(const char *path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name) + ib_extention extension, bool trim_name) noexcept { /* The path may contain the basename of the file, if so we do not need the name. If the path is NULL, we can use the default path, @@ -1881,7 +1869,7 @@ char* fil_make_filepath_low(const char *path, } char *fil_make_filepath(const char* path, const table_name_t name, - ib_extention suffix, bool strip_name) + ib_extention suffix, bool strip_name) noexcept { return fil_make_filepath_low(path, {name.m_name, strlen(name.m_name)}, suffix, strip_name); @@ -1890,12 +1878,12 @@ char *fil_make_filepath(const char* path, const table_name_t name, /** Wrapper function over fil_make_filepath_low() to build directory name. @param path the directory path or the full path and filename @return own: directory name */ -static inline char *fil_make_dirpath(const char *path) +static inline char *fil_make_dirpath(const char *path) noexcept { return fil_make_filepath_low(path, fil_space_t::name_type{}, NO_EXT, true); } -dberr_t fil_space_t::rename(const char *path, bool log, bool replace) +dberr_t fil_space_t::rename(const char *path, bool log, bool replace) noexcept { ut_ad(UT_LIST_GET_LEN(chain) == 1); ut_ad(!is_predefined_tablespace(id)); @@ -2500,6 +2488,7 @@ fil_ibd_discover( } bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name) + noexcept { if (crypt_data->is_key_found()) return true; @@ -2523,7 +2512,7 @@ of the file in validate_for_recovery(). @param[out] space the tablespace, or NULL on error @return status of the operation */ enum fil_load_status -fil_ibd_load(uint32_t space_id, const char *filename, fil_space_t *&space) +fil_ibd_load(uint32_t space_id, const char *filename, fil_space_t *&space) noexcept { /* If the a space is already in the file system cache with this space ID, then there is nothing to do. */ @@ -2728,7 +2717,7 @@ startup, there may be many tablespaces which are not yet in the memory cache. @return the tablespace @retval NULL if no matching tablespace exists in the memory cache */ fil_space_t *fil_space_for_table_exists_in_mem(uint32_t id, - uint32_t table_flags) + uint32_t table_flags) noexcept { const uint32_t expected_flags = dict_tf_to_fsp_flags(table_flags); @@ -2765,7 +2754,7 @@ func_exit: ATTRIBUTE_COLD static void fil_invalid_page_access_msg(const char *name, os_offset_t offset, ulint len, - bool is_read) + bool is_read) noexcept { sql_print_error("%s %zu bytes at " UINT64PF " outside the bounds of the file: %s", @@ -2777,7 +2766,7 @@ static void fil_invalid_page_access_msg(const char *name, } /** Update the data structures on write completion */ -void fil_space_t::complete_write() +void fil_space_t::complete_write() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); @@ -2802,7 +2791,7 @@ void fil_space_t::complete_write() @param bpage buffer block (for type.is_async() completion callback) @return status and file descriptor */ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len, - void *buf, buf_page_t *bpage) + void *buf, buf_page_t *bpage) noexcept { ut_ad(referenced()); ut_ad(offset % UNIV_ZIP_SIZE_MIN == 0); @@ -2904,7 +2893,7 @@ func_exit: #include -void IORequest::write_complete(int io_error) const +void IORequest::write_complete(int io_error) const noexcept { ut_ad(fil_validate_skip()); ut_ad(node); @@ -2932,7 +2921,7 @@ void IORequest::write_complete(int io_error) const space->release(); } -void IORequest::read_complete(int io_error) const +void IORequest::read_complete(int io_error) const noexcept { ut_ad(fil_validate_skip()); ut_ad(node); @@ -2963,7 +2952,7 @@ void IORequest::read_complete(int io_error) const /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. */ -void fil_flush_file_spaces() +void fil_flush_file_spaces() noexcept { rescan: mysql_mutex_lock(&fil_system.mutex); @@ -2995,7 +2984,7 @@ struct Check { /** Visit a file node @param[in] elem file node to visit */ - void operator()(const fil_node_t* elem) + void operator()(const fil_node_t* elem) noexcept { n_open += elem->is_open(); size += elem->size; @@ -3004,7 +2993,7 @@ struct Check { /** Validate a tablespace. @param[in] space tablespace to validate @return number of open file nodes */ - static ulint validate(const fil_space_t* space) + static ulint validate(const fil_space_t* space) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); Check check; @@ -3031,7 +3020,7 @@ struct Check { /******************************************************************//** Checks the consistency of the tablespace cache. @return true if ok */ -bool fil_validate() +bool fil_validate() noexcept { ulint n_open = 0; @@ -3048,24 +3037,11 @@ bool fil_validate() return(true); } -/*********************************************************************//** -Sets the file page type. */ -void -fil_page_set_type( -/*==============*/ - byte* page, /*!< in/out: file page */ - ulint type) /*!< in: type */ -{ - ut_ad(page); - - mach_write_to_2(page + FIL_PAGE_TYPE, type); -} - /********************************************************************//** Delete the tablespace file and any related files like .cfg. This should not be called for temporary tables. @param[in] ibd_filepath File path of the IBD tablespace */ -void fil_delete_file(const char *ibd_filepath) +void fil_delete_file(const char *ibd_filepath) noexcept { ib::info() << "Deleting " << ibd_filepath; os_file_delete_if_exists(innodb_data_file_key, ibd_filepath, nullptr); @@ -3083,9 +3059,7 @@ void fil_delete_file(const char *ibd_filepath) /** Check that a tablespace is valid for mtr_commit(). @param[in] space persistent tablespace that has been changed */ static -void -fil_space_validate_for_mtr_commit( - const fil_space_t* space) +void fil_space_validate_for_mtr_commit(const fil_space_t *space) noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); ut_ad(space != NULL); @@ -3102,9 +3076,7 @@ fil_space_validate_for_mtr_commit( /** Note that a non-predefined persistent tablespace has been modified by redo log. @param[in,out] space tablespace */ -void -fil_names_dirty( - fil_space_t* space) +void fil_names_dirty(fil_space_t *space) noexcept { ut_ad(log_sys.latch_have_wr()); ut_ad(recv_recovery_is_on()); @@ -3118,7 +3090,7 @@ fil_names_dirty( /** Write a FILE_MODIFY record when a non-predefined persistent tablespace was modified for the first time since fil_names_clear(). */ -ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() +ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() noexcept { ut_ad(log_sys.latch_have_wr()); ut_d(fil_space_validate_for_mtr_commit(m_user_space)); @@ -3140,7 +3112,7 @@ ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. @param lsn checkpoint LSN @return current LSN */ -ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) +ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) noexcept { mtr_t mtr; @@ -3237,6 +3209,7 @@ test_make_filepath() @param[in] offset page number @return block size */ ulint fil_space_get_block_size(const fil_space_t *space, unsigned offset) + noexcept { ulint block_size = 512; @@ -3261,7 +3234,7 @@ ulint fil_space_get_block_size(const fil_space_t *space, unsigned offset) } /** @return the tablespace name (databasename/tablename) */ -fil_space_t::name_type fil_space_t::name() const +fil_space_t::name_type fil_space_t::name() const noexcept { switch (id) { case 0: @@ -3299,7 +3272,7 @@ fil_space_t::name_type fil_space_t::name() const #ifdef UNIV_DEBUG -fil_space_t *fil_space_t::next_in_space_list() +fil_space_t *fil_space_t::next_in_space_list() noexcept { space_list_t::iterator it(this); auto end= fil_system.space_list.end(); @@ -3309,7 +3282,7 @@ fil_space_t *fil_space_t::next_in_space_list() return it == end ? nullptr : &*it; } -fil_space_t *fil_space_t::prev_in_space_list() +fil_space_t *fil_space_t::prev_in_space_list() noexcept { space_list_t::iterator it(this); if (it == fil_system.space_list.begin()) @@ -3318,7 +3291,7 @@ fil_space_t *fil_space_t::prev_in_space_list() return &*it; } -fil_space_t *fil_space_t::next_in_unflushed_spaces() +fil_space_t *fil_space_t::next_in_unflushed_spaces() noexcept { sized_ilist::iterator it(this); auto end= fil_system.unflushed_spaces.end(); @@ -3328,7 +3301,7 @@ fil_space_t *fil_space_t::next_in_unflushed_spaces() return it == end ? nullptr : &*it; } -fil_space_t *fil_space_t::prev_in_unflushed_spaces() +fil_space_t *fil_space_t::prev_in_unflushed_spaces() noexcept { sized_ilist::iterator it(this); if (it == fil_system.unflushed_spaces.begin()) diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index bae862f1ce2..63cbc2babd7 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -253,7 +253,7 @@ dberr_t Datafile::read_first_page_flags(const page_t *page) noexcept if (cflags == UINT32_MAX) switch (fsp_flags_is_incompatible_mysql(m_flags)) { case 0: - sql_print_error("InnoDB: Invalid flags 0x%zx in %s", + sql_print_error("InnoDB: Invalid flags 0x%" PRIx32 " in %s", m_flags, m_filepath); return DB_CORRUPTION; case 3: diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 13074f77993..137d555476d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2258,14 +2258,12 @@ void innobase_mysql_print_thd( /*=====================*/ FILE* f, /*!< in: output stream */ - THD* thd, /*!< in: MySQL THD object */ - uint max_query_len) /*!< in: max query length to print, or 0 to - use the default max length */ + THD* thd) /*!< in: MySQL THD object */ { - char buffer[1024]; + char buffer[3072]; fputs(thd_get_error_context_description(thd, buffer, sizeof buffer, - max_query_len), f); + 0), f); putc('\n', f); } @@ -13767,7 +13765,6 @@ int ha_innobase::delete_table(const char *name) if (err != DB_SUCCESS) { err_exit: - trx->dict_operation_lock_mode= false; trx->rollback(); switch (err) { case DB_CANNOT_DROP_CONSTRAINT: @@ -13789,7 +13786,7 @@ err_exit: dict_table_close(table_stats, true, thd, mdl_table); if (index_stats) dict_table_close(index_stats, true, thd, mdl_index); - dict_sys.unlock(); + row_mysql_unlock_data_dictionary(trx); if (trx != parent_trx) trx->free(); DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL)); @@ -19436,18 +19433,14 @@ static MYSQL_SYSVAR_UINT(log_buffer_size, log_sys.buf_size, "Redo log buffer size in bytes.", NULL, NULL, 16U << 20, 2U << 20, log_sys.buf_size_max, 4096); -#ifdef HAVE_INNODB_MMAP static constexpr const char *innodb_log_file_mmap_description= "Whether ib_logfile0" -# ifdef HAVE_PMEM - " resides in persistent memory or" -# endif + " resides in persistent memory (when supported) or" " should initially be memory-mapped"; static MYSQL_SYSVAR_BOOL(log_file_mmap, log_sys.log_mmap, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, innodb_log_file_mmap_description, nullptr, nullptr, log_sys.log_mmap_default); -#endif #if defined __linux__ || defined _WIN32 static MYSQL_SYSVAR_BOOL(log_file_buffering, log_sys.log_buffered, @@ -19921,9 +19914,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(deadlock_report), MYSQL_SYSVAR(page_size), MYSQL_SYSVAR(log_buffer_size), -#ifdef HAVE_INNODB_MMAP MYSQL_SYSVAR(log_file_mmap), -#endif #if defined __linux__ || defined _WIN32 MYSQL_SYSVAR(log_file_buffering), #endif @@ -21377,9 +21368,7 @@ void ins_node_t::vers_update_end(row_prebuilt_t *prebuilt, bool history_row) if needed. @param[in] size size in bytes @return aligned size */ -ulint -buf_pool_size_align( - ulint size) +ulint buf_pool_size_align(ulint size) noexcept { const size_t m = srv_buf_pool_chunk_unit; size = ut_max(size, (size_t) MYSQL_SYSVAR_NAME(buffer_pool_size).min_val); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 450fe0e2b82..8383bc9a9ec 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -150,7 +150,7 @@ operator<<( @param id expected block->page.id() @return block if it was buffer-fixed @retval nullptr if the block no longer is valid */ -buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) noexcept MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Try to acquire a page latch after buf_page_optimistic_fix(). @@ -162,7 +162,8 @@ buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) @retval nullptr if block->unfix() was called because it no longer is valid */ buf_block_t *buf_page_optimistic_get(buf_block_t *block, rw_lock_type_t rw_latch, - uint64_t modify_clock, mtr_t *mtr) + uint64_t modify_clock, + mtr_t *mtr) noexcept MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Try to S-latch a page. @@ -171,14 +172,14 @@ Suitable for using when holding the lock_sys latches (as it avoids deadlock). @param[in,out] mtr mini-transaction @return the block @retval nullptr if an S-latch cannot be granted immediately */ -buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr); +buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) noexcept; /** Get read access to a compressed page (usually of type FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2). The page must be released with s_unlock(). @param page_id page identifier @return pointer to the block, s-latched */ -buf_page_t *buf_page_get_zip(const page_id_t page_id); +buf_page_t *buf_page_get_zip(const page_id_t page_id) noexcept; /** Get access to a database page. Buffered redo log may be applied. @param[in] page_id page id @@ -199,7 +200,7 @@ buf_page_get_gen( buf_block_t* guess, ulint mode, mtr_t* mtr, - dberr_t* err = nullptr); + dberr_t* err = nullptr) noexcept; /** Initialize a page in the buffer pool. The page is usually not read from a file even if it cannot be found in the buffer buf_pool. This is one @@ -213,7 +214,8 @@ of the functions which perform to a block a state transition NOT_USED => LRU @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create(fil_space_t *space, uint32_t offset, - ulint zip_size, mtr_t *mtr, buf_block_t *free_block); + ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + noexcept; /** Initialize a page in buffer pool while initializing the deferred tablespace @@ -224,7 +226,7 @@ deferred tablespace @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, mtr_t *mtr, - buf_block_t *free_block); + buf_block_t *free_block) noexcept; /** Mark the page status as FREED for the given tablespace and page number. @param[in,out] space tablespace @@ -261,7 +263,7 @@ buf_block_modify_clock_inc( /** Check if a buffer is all zeroes. @param[in] buf data to check @return whether the buffer is all zeroes */ -bool buf_is_zeroes(st_::span buf); +bool buf_is_zeroes(st_::span buf) noexcept; /** Reason why buf_page_is_corrupted() fails */ enum buf_page_is_corrupted_reason @@ -278,7 +280,7 @@ enum buf_page_is_corrupted_reason @return whether the page is corrupted */ buf_page_is_corrupted_reason buf_page_is_corrupted(bool check_lsn, const byte *read_buf, uint32_t fsp_flags) - MY_ATTRIBUTE((warn_unused_result)); + noexcept MY_ATTRIBUTE((warn_unused_result)); /** Read the key version from the page. In full crc32 format, key version is stored at {0-3th} bytes. In other format, it is @@ -287,7 +289,7 @@ stored in 26th position. @param[in] fsp_flags tablespace flags @return key version of the page. */ inline uint32_t buf_page_get_key_version(const byte* read_buf, - uint32_t fsp_flags) + uint32_t fsp_flags) noexcept { static_assert(FIL_PAGE_FCRC32_KEY_VERSION == 0, "compatibility"); return fil_space_t::full_crc32(fsp_flags) @@ -302,7 +304,7 @@ stored in page type. @param[in] read_buf database page @param[in] fsp_flags tablespace flags @return true if page is compressed. */ -inline bool buf_page_is_compressed(const byte* read_buf, uint32_t fsp_flags) +inline bool buf_page_is_compressed(const byte* read_buf, uint32_t fsp_flags) noexcept { uint16_t page_type= fil_page_get_type(read_buf); return fil_space_t::full_crc32(fsp_flags) @@ -315,7 +317,8 @@ inline bool buf_page_is_compressed(const byte* read_buf, uint32_t fsp_flags) @param[out] comp whether the page could be compressed @param[out] cr whether the page could be corrupted @return the payload size in the file page */ -inline uint buf_page_full_crc32_size(const byte* buf, bool* comp, bool* cr) +inline uint buf_page_full_crc32_size(const byte *buf, bool *comp, bool *cr) + noexcept { uint t = fil_page_get_type(buf); uint page_size = uint(srv_page_size); @@ -343,20 +346,17 @@ inline uint buf_page_full_crc32_size(const byte* buf, bool* comp, bool* cr) /** Dump a page to stderr. @param[in] read_buf database page @param[in] zip_size compressed page size, or 0 */ -void buf_page_print(const byte* read_buf, ulint zip_size = 0) +void buf_page_print(const byte* read_buf, ulint zip_size = 0) noexcept ATTRIBUTE_COLD __attribute__((nonnull)); -/********************************************************************//** -Decompress a block. +/** Decompress a ROW_FORMAT=COMPRESSED block. +@param block buffer page +@param check whether to verify the page checksum @return true if successful */ -bool -buf_zip_decompress( -/*===============*/ - buf_block_t* block, /*!< in/out: block */ - ibool check); /*!< in: TRUE=verify the page checksum */ +bool buf_zip_decompress(buf_block_t *block, bool check) noexcept; #ifdef UNIV_DEBUG /** @return the number of latched pages in the buffer pool */ -ulint buf_get_latched_pages_number(); +ulint buf_get_latched_pages_number() noexcept; #endif /* UNIV_DEBUG */ /*********************************************************************//** Prints info of the buffer i/o. */ @@ -366,14 +366,14 @@ buf_print_io( FILE* file); /*!< in: file where to print */ /** Collect buffer pool metadata. @param[out] pool_info buffer pool metadata */ -void buf_stats_get_pool_info(buf_pool_info_t *pool_info); +void buf_stats_get_pool_info(buf_pool_info_t *pool_info) noexcept; /** Refresh the statistics used to print per-second averages. */ -void buf_refresh_io_stats(); +void buf_refresh_io_stats() noexcept; /** Invalidate all pages in the buffer pool. All pages must be in a replaceable state (not modified or latched). */ -void buf_pool_invalidate(); +void buf_pool_invalidate() noexcept; /*======================================================================== --------------------------- LOWER LEVEL ROUTINES ------------------------- @@ -393,27 +393,26 @@ if applicable. */ counter value in MONITOR_MODULE_BUF_PAGE. @param bpage buffer page whose read or write was completed @param read true=read, false=write */ -ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read); +ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) + noexcept; /** Calculate aligned buffer pool size based on srv_buf_pool_chunk_unit, if needed. @param[in] size size in bytes @return aligned size */ -ulint -buf_pool_size_align( - ulint size); +ulint buf_pool_size_align(ulint size) noexcept; /** Verify that post encryption checksum match with the calculated checksum. This function should be called only if tablespace contains crypt data metadata. @param page page frame @param fsp_flags contents of FSP_SPACE_FLAGS @return whether the page is encrypted and valid */ -bool buf_page_verify_crypt_checksum(const byte *page, uint32_t fsp_flags); +bool buf_page_verify_crypt_checksum(const byte *page, uint32_t fsp_flags) noexcept; /** Calculate a ROW_FORMAT=COMPRESSED page checksum and update the page. @param[in,out] page page to update @param[in] size compressed page size */ -void buf_flush_update_zip_checksum(buf_frame_t* page, ulint size); +void buf_flush_update_zip_checksum(buf_frame_t* page, ulint size) noexcept; /** @brief The temporary memory structure. @@ -436,14 +435,15 @@ public: byte *out_buf; /** Release the slot */ - void release() { reserved.store(false, std::memory_order_relaxed); } + void release() noexcept { reserved.store(false, std::memory_order_relaxed); } /** Acquire the slot @return whether the slot was acquired */ - bool acquire() { return !reserved.exchange(true, std::memory_order_relaxed);} + bool acquire() noexcept + { return !reserved.exchange(true, std::memory_order_relaxed);} /** Allocate a buffer for encryption, decryption or decompression. */ - void allocate() + void allocate() noexcept { if (!crypt_buf) crypt_buf= static_cast @@ -591,7 +591,7 @@ public: } /** Initialize some more fields */ - void init(uint32_t state, page_id_t id) + void init(uint32_t state, page_id_t id) noexcept { ut_ad(state < REMOVE_HASH || state >= UNFIXED); ut_ad(!lock.is_locked_or_waiting()); @@ -617,47 +617,48 @@ public: MEM_MAKE_ADDRESSABLE(frame, srv_page_size); } public: - const page_id_t &id() const { return id_; } - uint32_t state() const { return zip.fix; } - static uint32_t buf_fix_count(uint32_t s) + const page_id_t &id() const noexcept { return id_; } + uint32_t state() const noexcept { return zip.fix; } + static uint32_t buf_fix_count(uint32_t s) noexcept { ut_ad(s >= FREED); return s < UNFIXED ? (s - FREED) : (~LRU_MASK & s); } uint32_t buf_fix_count() const { return buf_fix_count(state()); } /** Check if a file block is io-fixed. @param s state() @return whether s corresponds to an io-fixed block */ - static bool is_io_fixed(uint32_t s) + static bool is_io_fixed(uint32_t s) noexcept { ut_ad(s >= FREED); return s >= READ_FIX; } /** Check if a file block is read-fixed. @param s state() @return whether s corresponds to a read-fixed block */ - static bool is_read_fixed(uint32_t s) + static bool is_read_fixed(uint32_t s) noexcept { return is_io_fixed(s) && s < WRITE_FIX; } /** Check if a file block is write-fixed. @param s state() @return whether s corresponds to a write-fixed block */ - static bool is_write_fixed(uint32_t s) + static bool is_write_fixed(uint32_t s) noexcept { ut_ad(s >= FREED); return s >= WRITE_FIX; } /** @return whether this block is read or write fixed; read_complete() or write_complete() will always release the io-fix before releasing U-lock or X-lock */ - bool is_io_fixed() const { return is_io_fixed(state()); } + bool is_io_fixed() const noexcept { return is_io_fixed(state()); } /** @return whether this block is write fixed; write_complete() will always release the write-fix before releasing U-lock */ - bool is_write_fixed() const { return is_write_fixed(state()); } + bool is_write_fixed() const noexcept { return is_write_fixed(state()); } /** @return whether this block is read fixed */ - bool is_read_fixed() const { return is_read_fixed(state()); } + bool is_read_fixed() const noexcept { return is_read_fixed(state()); } /** @return if this belongs to buf_pool.unzip_LRU */ - bool belongs_to_unzip_LRU() const + bool belongs_to_unzip_LRU() const noexcept { return UNIV_LIKELY_NULL(zip.data) && frame; } - static bool is_freed(uint32_t s) { ut_ad(s >= FREED); return s < UNFIXED; } - bool is_freed() const { return is_freed(state()); } + static bool is_freed(uint32_t s) noexcept + { ut_ad(s >= FREED); return s < UNFIXED; } + bool is_freed() const noexcept { return is_freed(state()); } bool is_reinit() const { return !(~state() & REINIT); } - void set_reinit(uint32_t prev_state) + void set_reinit(uint32_t prev_state) noexcept { ut_ad(prev_state < READ_FIX); ut_d(const auto s=) zip.fix.fetch_add(REINIT - prev_state); @@ -665,7 +666,7 @@ public: ut_ad(s < prev_state + UNFIXED); } - uint32_t read_unfix(uint32_t s) + uint32_t read_unfix(uint32_t s) noexcept { ut_ad(lock.is_write_locked()); ut_ad(s == UNFIXED + 1 || s == REINIT + 1); @@ -675,7 +676,7 @@ public: return old_state + (s - READ_FIX); } - void set_freed(uint32_t prev_state, uint32_t count= 0) + void set_freed(uint32_t prev_state, uint32_t count= 0) noexcept { ut_ad(lock.is_write_locked()); ut_ad(prev_state >= UNFIXED); @@ -684,28 +685,28 @@ public: ut_ad(!((prev_state ^ s) & LRU_MASK)); } - inline void set_state(uint32_t s); - inline void set_corrupt_id(); + inline void set_state(uint32_t s) noexcept; + inline void set_corrupt_id() noexcept; /** @return the log sequence number of the oldest pending modification @retval 0 if the block is being removed from (or not in) buf_pool.flush_list @retval 1 if the block is in buf_pool.flush_list but not modified @retval 2 if the block belongs to the temporary tablespace and has unwritten changes */ - lsn_t oldest_modification() const { return oldest_modification_; } + lsn_t oldest_modification() const noexcept { return oldest_modification_; } /** @return the log sequence number of the oldest pending modification, @retval 0 if the block is definitely not in buf_pool.flush_list @retval 1 if the block is in buf_pool.flush_list but not modified @retval 2 if the block belongs to the temporary tablespace and has unwritten changes */ - lsn_t oldest_modification_acquire() const + lsn_t oldest_modification_acquire() const noexcept { return oldest_modification_.load(std::memory_order_acquire); } /** Set oldest_modification when adding to buf_pool.flush_list */ - inline void set_oldest_modification(lsn_t lsn); + inline void set_oldest_modification(lsn_t lsn) noexcept; /** Clear oldest_modification after removing from buf_pool.flush_list */ - inline void clear_oldest_modification(); + inline void clear_oldest_modification() noexcept; /** Reset the oldest_modification when marking a persistent page freed */ - void reset_oldest_modification() + void reset_oldest_modification() noexcept { ut_ad(oldest_modification() > 2); oldest_modification_.store(1, std::memory_order_release); @@ -716,21 +717,21 @@ public: @return whether the operation succeeded @retval DB_PAGE_CORRUPTED if the checksum or the page ID is incorrect @retval DB_DECRYPTION_FAILED if the page cannot be decrypted */ - dberr_t read_complete(const fil_node_t &node); + dberr_t read_complete(const fil_node_t &node) noexcept; /** Release a write fix after a page write was completed. @param persistent whether the page belongs to a persistent tablespace @param error whether an error may have occurred while writing @param state recently read state() value with the correct io-fix */ - void write_complete(bool persistent, bool error, uint32_t state); + void write_complete(bool persistent, bool error, uint32_t state) noexcept; /** Write a flushable page to a file or free a freeable block. @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ - bool flush(fil_space_t *space); + bool flush(fil_space_t *space) noexcept; /** Notify that a page in a temporary tablespace has been modified. */ - void set_temp_modified() + void set_temp_modified() noexcept { ut_ad(fsp_is_system_temporary(id().space())); ut_ad(in_file()); @@ -739,22 +740,22 @@ public: } /** Prepare to release a file page to buf_pool.free. */ - void free_file_page() + void free_file_page() noexcept { - ut_ad((zip.fix.fetch_sub(REMOVE_HASH - MEMORY)) == REMOVE_HASH); + assert((zip.fix.fetch_sub(REMOVE_HASH - MEMORY)) == REMOVE_HASH); /* buf_LRU_block_free_non_file_page() asserts !oldest_modification() */ ut_d(oldest_modification_= 0;) id_= page_id_t(~0ULL); } - void fix_on_recovery() + void fix_on_recovery() noexcept { ut_d(const auto f=) zip.fix.fetch_sub(READ_FIX - UNFIXED - 1); ut_ad(f >= READ_FIX); ut_ad(f < WRITE_FIX); } - uint32_t fix(uint32_t count= 1) + uint32_t fix(uint32_t count= 1) noexcept { ut_ad(count); ut_ad(count < REINIT); @@ -764,7 +765,7 @@ public: return f; } - uint32_t unfix() + uint32_t unfix() noexcept { uint32_t f= zip.fix.fetch_sub(1); ut_ad(f > FREED); @@ -773,20 +774,20 @@ public: } /** @return the physical size, in bytes */ - ulint physical_size() const + ulint physical_size() const noexcept { return zip.ssize ? (UNIV_ZIP_SIZE_MIN >> 1) << zip.ssize : srv_page_size; } /** @return the ROW_FORMAT=COMPRESSED physical size, in bytes @retval 0 if not compressed */ - ulint zip_size() const + ulint zip_size() const noexcept { return zip.ssize ? (UNIV_ZIP_SIZE_MIN >> 1) << zip.ssize : 0; } /** @return the byte offset of the page within a file */ - os_offset_t physical_offset() const + os_offset_t physical_offset() const noexcept { os_offset_t o= id().page_no(); return zip.ssize @@ -795,18 +796,18 @@ public: } /** @return whether the block is mapped to a data file */ - bool in_file() const { return state() >= FREED; } + bool in_file() const noexcept { return state() >= FREED; } /** @return whether the block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ - inline bool can_relocate() const; + inline bool can_relocate() const noexcept; /** @return whether the block has been flagged old in buf_pool.LRU */ - inline bool is_old() const; + inline bool is_old() const noexcept; /** Set whether a block is old in buf_pool.LRU */ - inline void set_old(bool old); + inline void set_old(bool old) noexcept; /** Flag a page accessed in buf_pool @return whether this is not the first access */ - bool set_accessed() + bool set_accessed() noexcept { if (is_accessed()) return true; access_time= static_cast(ut_time_ms()); @@ -814,7 +815,8 @@ public: } /** @return ut_time_ms() at the time of first access of a block in buf_pool @retval 0 if not accessed */ - unsigned is_accessed() const { ut_ad(in_file()); return access_time; } + unsigned is_accessed() const noexcept + { ut_ad(in_file()); return access_time; } }; /** The buffer control block structure */ @@ -944,21 +946,22 @@ struct buf_block_t{ # define assert_block_ahi_empty_on_init(block) /* nothing */ # define assert_block_ahi_valid(block) /* nothing */ #endif /* BTR_CUR_HASH_ADAPT */ - void fix() { page.fix(); } - uint32_t unfix() { return page.unfix(); } + void fix() noexcept { page.fix(); } + uint32_t unfix() noexcept { return page.unfix(); } /** @return the physical size, in bytes */ - ulint physical_size() const { return page.physical_size(); } + ulint physical_size() const noexcept { return page.physical_size(); } /** @return the ROW_FORMAT=COMPRESSED physical size, in bytes @retval 0 if not compressed */ - ulint zip_size() const { return page.zip_size(); } + ulint zip_size() const noexcept { return page.zip_size(); } /** Initialize the block. @param page_id page identifier @param zip_size ROW_FORMAT=COMPRESSED page size, or 0 @param state initial state() */ - void initialise(const page_id_t page_id, ulint zip_size, uint32_t state); + void initialise(const page_id_t page_id, ulint zip_size, uint32_t state) + noexcept; }; /**********************************************************************//** @@ -979,11 +982,12 @@ public: virtual ~HazardPointer() = default; /** @return current value */ - buf_page_t *get() const { mysql_mutex_assert_owner(m_mutex); return m_hp; } + buf_page_t *get() const noexcept + { mysql_mutex_assert_owner(m_mutex); return m_hp; } /** Set current value @param bpage buffer block to be set as hp */ - void set(buf_page_t *bpage) + void set(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(m_mutex); ut_ad(!bpage || bpage->in_file()); @@ -993,13 +997,13 @@ public: /** Checks if a bpage is the hp @param bpage buffer block to be compared @return true if it is hp */ - bool is_hp(const buf_page_t *bpage) const + bool is_hp(const buf_page_t *bpage) const noexcept { mysql_mutex_assert_owner(m_mutex); return bpage == m_hp; } /** Adjust the value of hp. This happens when some other thread working on the same list attempts to remove the hp from the list. */ - virtual void adjust(const buf_page_t*) = 0; + virtual void adjust(const buf_page_t*) noexcept = 0; #ifdef UNIV_DEBUG /** mutex that protects access to the m_hp. */ @@ -1022,7 +1026,7 @@ public: remove the hp from the list. @param bpage buffer block to be compared */ MY_ATTRIBUTE((nonnull)) - void adjust(const buf_page_t *bpage) override + void adjust(const buf_page_t *bpage) noexcept override { /* We only support reverse traversal for now. */ if (is_hp(bpage)) @@ -1042,7 +1046,7 @@ public: remove the hp from the list. @param bpage buffer block to be compared */ MY_ATTRIBUTE((nonnull)) - void adjust(const buf_page_t *bpage) override + void adjust(const buf_page_t *bpage) noexcept override { /** We only support reverse traversal for now. */ if (is_hp(bpage)) @@ -1064,7 +1068,7 @@ public: too deep into the LRU list it resets the value to the tail of the LRU list. @return buf_page_t from where to start scan. */ - inline buf_page_t *start(); + inline buf_page_t *start() noexcept; }; /** Struct that is embedded in the free zip blocks */ @@ -1091,7 +1095,7 @@ struct buf_buddy_free_t { protected by buf_pool.mutex unless otherwise noted. */ struct buf_pool_stat_t{ /** Initialize the counters */ - void init() { memset((void*) this, 0, sizeof *this); } + void init() noexcept { memset((void*) this, 0, sizeof *this); } ib_counter_t n_page_gets; /*!< number of page gets performed; @@ -1155,22 +1159,23 @@ class buf_pool_t static map *map_ref; /** @return the memory size bytes. */ - size_t mem_size() const { return mem_pfx.m_size; } + size_t mem_size() const noexcept { return mem_pfx.m_size; } /** Register the chunk */ - void reg() { map_reg->emplace(map::value_type(blocks->page.frame, this)); } + void reg() noexcept + { map_reg->emplace(map::value_type(blocks->page.frame, this)); } /** Allocate a chunk of buffer frames. @param bytes requested size @return whether the allocation succeeded */ - inline bool create(size_t bytes); + inline bool create(size_t bytes) noexcept; #ifdef UNIV_DEBUG /** Find a block that points to a ROW_FORMAT=COMPRESSED page @param data pointer to the start of a ROW_FORMAT=COMPRESSED page frame @return the block @retval nullptr if not found */ - const buf_block_t *contains_zip(const void *data) const + const buf_block_t *contains_zip(const void *data) const noexcept { const buf_block_t *block= blocks; for (auto i= size; i--; block++) @@ -1182,7 +1187,7 @@ class buf_pool_t /** Check that all blocks are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ - inline const buf_block_t *not_freed() const; + inline const buf_block_t *not_freed() const noexcept; #endif /* UNIV_DEBUG */ }; public: @@ -1195,13 +1200,13 @@ public: private: /** Withdraw blocks from the buffer pool until meeting withdraw_target. @return whether retry is needed */ - inline bool withdraw_blocks(); + inline bool withdraw_blocks() noexcept; /** Determine if a pointer belongs to a buf_block_t. It can be a pointer to the buf_block_t itself or a member of it. @param ptr a pointer that will not be dereferenced @return whether the ptr belongs to a buf_block_t struct */ - bool is_block_field(const void *ptr) const + bool is_block_field(const void *ptr) const noexcept { const chunk_t *chunk= chunks; const chunk_t *const echunk= chunk + ut_min(n_chunks, n_chunks_new); @@ -1218,17 +1223,17 @@ private: /** Try to reallocate a control block. @param block control block to reallocate @return whether the reallocation succeeded */ - inline bool realloc(buf_block_t *block); + inline bool realloc(buf_block_t *block) noexcept; public: - bool is_initialised() const { return chunks != nullptr; } + bool is_initialised() const noexcept { return chunks != nullptr; } /** Create the buffer pool. @return whether the creation failed */ bool create(); /** Clean up after successful create() */ - void close(); + void close() noexcept; /** Resize from srv_buf_pool_old_size to srv_buf_pool_size. */ inline void resize(); @@ -1239,13 +1244,13 @@ public: #endif /** @return whether resize() is in progress */ - bool resize_in_progress() const + bool resize_in_progress() const noexcept { return UNIV_UNLIKELY(resizing.load(std::memory_order_relaxed)); } /** @return the current size in blocks */ - size_t get_n_pages() const + size_t get_n_pages() const noexcept { ut_ad(is_initialised()); size_t size= 0; @@ -1257,7 +1262,7 @@ public: /** Determine whether a frame is intended to be withdrawn during resize(). @param ptr pointer within a buf_page_t::frame @return whether the frame will be withdrawn */ - bool will_be_withdrawn(const byte *ptr) const + bool will_be_withdrawn(const byte *ptr) const noexcept { ut_ad(n_chunks_new < n_chunks); #ifdef SAFE_MUTEX @@ -1277,7 +1282,7 @@ public: /** Determine whether a block is intended to be withdrawn during resize(). @param bpage buffer pool block @return whether the frame will be withdrawn */ - bool will_be_withdrawn(const buf_page_t &bpage) const + bool will_be_withdrawn(const buf_page_t &bpage) const noexcept { ut_ad(n_chunks_new < n_chunks); #ifdef SAFE_MUTEX @@ -1308,7 +1313,7 @@ public: @param data pointer to the start of a ROW_FORMAT=COMPRESSED page frame @return the block @retval nullptr if not found */ - const buf_block_t *contains_zip(const void *data) const + const buf_block_t *contains_zip(const void *data) const noexcept { mysql_mutex_assert_owner(&mutex); for (const chunk_t *chunk= chunks, * const end= chunks + n_chunks; @@ -1319,24 +1324,24 @@ public: } /** Assert that all buffer pool pages are in a replaceable state */ - void assert_all_freed(); + void assert_all_freed() noexcept; #endif /* UNIV_DEBUG */ #ifdef BTR_CUR_HASH_ADAPT /** Clear the adaptive hash index on all pages in the buffer pool. */ - inline void clear_hash_index(); + inline void clear_hash_index() noexcept; /** Get a buffer block from an adaptive hash index pointer. This function does not return if the block is not identified. @param ptr pointer to within a page frame @return pointer to block, never NULL */ - inline buf_block_t *block_from_ahi(const byte *ptr) const; + inline buf_block_t *block_from_ahi(const byte *ptr) const noexcept; #endif /* BTR_CUR_HASH_ADAPT */ /** @return the smallest oldest_modification lsn for any page @retval empty_lsn if all modified persistent pages have been flushed */ - lsn_t get_oldest_modification(lsn_t empty_lsn) + lsn_t get_oldest_modification(lsn_t empty_lsn) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); while (buf_page_t *bpage= UT_LIST_GET_LAST(flush_list)) @@ -1356,7 +1361,7 @@ public: /** Determine if a buffer block was created by chunk_t::create(). @param block block descriptor (not dereferenced) @return whether block has been created by chunk_t::create() */ - bool is_uncompressed(const buf_block_t *block) const + bool is_uncompressed(const buf_block_t *block) const noexcept { return is_block_field(reinterpret_cast(block)); } @@ -1386,29 +1391,28 @@ public: @retval -1 if c=FIX_NOWAIT and buffer-fixing would require waiting @retval nullptr if the undo page was corrupted or freed */ buf_block_t *page_fix(const page_id_t id, dberr_t *err, - page_fix_conflicts c); + page_fix_conflicts c) noexcept; - buf_block_t *page_fix(const page_id_t id) + buf_block_t *page_fix(const page_id_t id) noexcept { return page_fix(id, nullptr, FIX_WAIT_READ); } - /** Decompress a page and relocate the block descriptor @param b buffer-fixed compressed-only ROW_FORMAT=COMPRESSED page @param chain hash table chain for b->id().fold() @return the decompressed block, x-latched and read-fixed @retval nullptr if the decompression failed (b->unfix() will be invoked) */ ATTRIBUTE_COLD __attribute__((nonnull, warn_unused_result)) - buf_block_t *unzip(buf_page_t *b, hash_chain &chain); + buf_block_t *unzip(buf_page_t *b, hash_chain &chain) noexcept; /** @return whether the buffer pool contains a page @param page_id page identifier @param chain hash table chain for page_id.fold() */ TRANSACTIONAL_TARGET - bool page_hash_contains(const page_id_t page_id, hash_chain &chain); + bool page_hash_contains(const page_id_t page_id, hash_chain &chain) noexcept; /** @return whether less than 1/4 of the buffer pool is available */ TPOOL_SUPPRESS_TSAN - bool running_out() const + bool running_out() const noexcept { return !recv_recovery_is_on() && UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) < @@ -1416,26 +1420,26 @@ public: } /** @return whether the buffer pool is running low */ - bool need_LRU_eviction() const; + bool need_LRU_eviction() const noexcept; /** @return whether the buffer pool is shrinking */ - inline bool is_shrinking() const + inline bool is_shrinking() const noexcept { return n_chunks_new < n_chunks; } #ifdef UNIV_DEBUG /** Validate the buffer pool. */ - void validate(); + void validate() noexcept; #endif /* UNIV_DEBUG */ #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG /** Write information of the buf_pool to the error log. */ - void print(); + void print() noexcept; #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG */ /** Remove a block from the LRU list. @return the predecessor in the LRU list */ - buf_page_t *LRU_remove(buf_page_t *bpage) + buf_page_t *LRU_remove(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(&mutex); ut_ad(bpage->in_LRU_list); @@ -1503,15 +1507,16 @@ public: /** Create the hash table. @param n the lower bound of n_cells */ - void create(ulint n); + void create(ulint n) noexcept; /** Free the hash table. */ - void free() { aligned_free(array); array= nullptr; } + void free() noexcept { aligned_free(array); array= nullptr; } /** @return the index of an array element */ - ulint calc_hash(ulint fold) const { return calc_hash(fold, n_cells); } + ulint calc_hash(ulint fold) const noexcept + { return calc_hash(fold, n_cells); } /** @return raw array index converted to padded index */ - static ulint pad(ulint h) + static ulint pad(ulint h) noexcept { ulint latches= h / ELEMENTS_PER_LATCH; ulint empty_slots= latches * EMPTY_SLOTS_PER_LATCH; @@ -1525,7 +1530,7 @@ public: } public: /** @return the latch covering a hash table chain */ - static page_hash_latch &lock_get(hash_chain &chain) + static page_hash_latch &lock_get(hash_chain &chain) noexcept { static_assert(!((ELEMENTS_PER_LATCH + 1) & ELEMENTS_PER_LATCH), "must be one less than a power of 2"); @@ -1540,7 +1545,7 @@ public: { return array[calc_hash(fold, n_cells)]; } /** Append a block descriptor to a hash bucket chain. */ - void append(hash_chain &chain, buf_page_t *bpage) + void append(hash_chain &chain, buf_page_t *bpage) noexcept { ut_ad(!bpage->in_page_hash); ut_ad(!bpage->hash); @@ -1555,7 +1560,7 @@ public: } /** Remove a block descriptor from a hash bucket chain. */ - void remove(hash_chain &chain, buf_page_t *bpage) + void remove(hash_chain &chain, buf_page_t *bpage) noexcept { ut_ad(bpage->in_page_hash); buf_page_t **prev= &chain.first; @@ -1571,6 +1576,7 @@ public: /** Replace a block descriptor with another. */ void replace(hash_chain &chain, buf_page_t *old, buf_page_t *bpage) + noexcept { ut_ad(old->in_page_hash); ut_ad(bpage->in_page_hash); @@ -1587,13 +1593,14 @@ public: } /** Look up a page in a hash bucket chain. */ - inline buf_page_t *get(const page_id_t id, const hash_chain &chain) const; + inline buf_page_t *get(const page_id_t id, const hash_chain &chain) const + noexcept; /** Exclusively aqcuire all latches */ - inline void write_lock_all(); + inline void write_lock_all() noexcept; /** Release all latches */ - inline void write_unlock_all(); + inline void write_unlock_all() noexcept; }; /** Buffer pool mutex */ @@ -1666,31 +1673,31 @@ public: pthread_cond_t done_flush_list; /** @return number of pending LRU flush */ - unsigned n_flush() const + unsigned n_flush() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_status / LRU_FLUSH; } /** Increment the number of pending LRU flush */ - inline void n_flush_inc(); + inline void n_flush_inc() noexcept; /** Decrement the number of pending LRU flush */ - inline void n_flush_dec(); + inline void n_flush_dec() noexcept; /** @return whether flush_list flushing is active */ - bool flush_list_active() const + bool flush_list_active() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_status & FLUSH_LIST_ACTIVE; } - void flush_list_set_active() + void flush_list_set_active() noexcept { ut_ad(!flush_list_active()); page_cleaner_status+= FLUSH_LIST_ACTIVE; } - void flush_list_set_inactive() + void flush_list_set_inactive() noexcept { ut_ad(flush_list_active()); page_cleaner_status-= FLUSH_LIST_ACTIVE; @@ -1704,7 +1711,7 @@ public: } /** @return whether the page cleaner may be initiating writes */ - bool page_cleaner_active() const + bool page_cleaner_active() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); static_assert(PAGE_CLEANER_IDLE == 1, "efficiency"); @@ -1713,10 +1720,10 @@ public: /** Wake up the page cleaner if needed. @param for_LRU whether to wake up for LRU eviction */ - void page_cleaner_wakeup(bool for_LRU= false); + void page_cleaner_wakeup(bool for_LRU= false) noexcept; /** Register whether an explicit wakeup of the page cleaner is needed */ - void page_cleaner_set_idle(bool deep_sleep) + void page_cleaner_set_idle(bool deep_sleep) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); page_cleaner_status= (page_cleaner_status & ~PAGE_CLEANER_IDLE) | @@ -1724,7 +1731,7 @@ public: } /** Update server last activity count */ - void update_last_activity_count(ulint activity_count) + void update_last_activity_count(ulint activity_count) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); last_activity_count= activity_count; @@ -1805,7 +1812,7 @@ public: #endif /** Reserve a buffer. */ - buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) + buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) noexcept { return io_buf.reserve(wait_for_reads); } /** Remove a block from flush_list. @@ -1828,7 +1835,7 @@ public: ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage) noexcept; /** Issue a warning that we could not free up buffer pool pages. */ - ATTRIBUTE_COLD void LRU_warn(); + ATTRIBUTE_COLD void LRU_warn() noexcept; private: /** Temporary memory for page_compressed and encrypted I/O */ @@ -1839,12 +1846,12 @@ private: /** array of slots */ buf_tmp_buffer_t *slots; - void create(ulint n_slots); + void create(ulint n_slots) noexcept; - void close(); + void close() noexcept; /** Reserve a buffer */ - buf_tmp_buffer_t *reserve(bool wait_for_reads); + buf_tmp_buffer_t *reserve(bool wait_for_reads) noexcept; } io_buf; /** whether resize() is in the critical path */ @@ -1856,7 +1863,7 @@ extern buf_pool_t buf_pool; inline buf_page_t *buf_pool_t::page_hash_table::get(const page_id_t id, const hash_chain &chain) - const + const noexcept { #ifdef SAFE_MUTEX DBUG_ASSERT(mysql_mutex_is_owner(&buf_pool.mutex) || @@ -1873,21 +1880,21 @@ inline buf_page_t *buf_pool_t::page_hash_table::get(const page_id_t id, } #ifdef SUX_LOCK_GENERIC -inline void page_hash_latch::lock_shared() +inline void page_hash_latch::lock_shared() noexcept { mysql_mutex_assert_not_owner(&buf_pool.mutex); if (!read_trylock()) read_lock_wait(); } -inline void page_hash_latch::lock() +inline void page_hash_latch::lock() noexcept { if (!write_trylock()) write_lock_wait(); } #endif /* SUX_LOCK_GENERIC */ -inline void buf_page_t::set_state(uint32_t s) +inline void buf_page_t::set_state(uint32_t s) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(s <= REMOVE_HASH || s >= UNFIXED); @@ -1896,7 +1903,7 @@ inline void buf_page_t::set_state(uint32_t s) zip.fix= s; } -inline void buf_page_t::set_corrupt_id() +inline void buf_page_t::set_corrupt_id() noexcept { #ifdef UNIV_DEBUG switch (oldest_modification()) { @@ -1922,7 +1929,7 @@ inline void buf_page_t::set_corrupt_id() } /** Set oldest_modification when adding to buf_pool.flush_list */ -inline void buf_page_t::set_oldest_modification(lsn_t lsn) +inline void buf_page_t::set_oldest_modification(lsn_t lsn) noexcept { mysql_mutex_assert_owner(&buf_pool.flush_list_mutex); ut_ad(oldest_modification() <= 1); @@ -1931,7 +1938,7 @@ inline void buf_page_t::set_oldest_modification(lsn_t lsn) } /** Clear oldest_modification after removing from buf_pool.flush_list */ -inline void buf_page_t::clear_oldest_modification() +inline void buf_page_t::clear_oldest_modification() noexcept { #ifdef SAFE_MUTEX if (oldest_modification() != 2) @@ -1950,7 +1957,7 @@ inline void buf_page_t::clear_oldest_modification() /** @return whether the block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ -inline bool buf_page_t::can_relocate() const +inline bool buf_page_t::can_relocate() const noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); const auto f= state(); @@ -1961,7 +1968,7 @@ inline bool buf_page_t::can_relocate() const } /** @return whether the block has been flagged old in buf_pool.LRU */ -inline bool buf_page_t::is_old() const +inline bool buf_page_t::is_old() const noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(in_file()); @@ -1970,7 +1977,7 @@ inline bool buf_page_t::is_old() const } /** Set whether a block is old in buf_pool.LRU */ -inline void buf_page_t::set_old(bool old) +inline void buf_page_t::set_old(bool old) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(in_LRU_list); @@ -2044,7 +2051,7 @@ REMOVE_HASH => NOT_USED (if and only if !oldest_modification()) too deep into the LRU list it resets the value to the tail of the LRU list. @return buf_page_t from where to start scan. */ -inline buf_page_t *LRUItr::start() +inline buf_page_t *LRUItr::start() noexcept { mysql_mutex_assert_owner(m_mutex); @@ -2057,12 +2064,12 @@ inline buf_page_t *LRUItr::start() #ifdef UNIV_DEBUG /** Functor to validate the LRU list. */ struct CheckInLRUList { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_a(elem->in_LRU_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.LRU, CheckInLRUList()); } @@ -2070,25 +2077,25 @@ struct CheckInLRUList { /** Functor to validate the LRU list. */ struct CheckInFreeList { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_a(elem->in_free_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.free, CheckInFreeList()); } }; struct CheckUnzipLRUAndLRUList { - void operator()(const buf_block_t* elem) const + void operator()(const buf_block_t* elem) const noexcept { ut_a(elem->page.in_LRU_list); ut_a(elem->in_unzip_LRU_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.unzip_LRU, CheckUnzipLRUAndLRUList()); diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index f912775de59..d7fb1c609ee 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -92,30 +92,30 @@ public: private: /** Initialise the persistent storage of the doublewrite buffer. @param header doublewrite page header in the TRX_SYS page */ - inline void init(const byte *header); + inline void init(const byte *header) noexcept; /** Flush possible buffered writes to persistent storage. */ - bool flush_buffered_writes(const ulint size); + bool flush_buffered_writes(const ulint size) noexcept; public: /** Initialise the doublewrite buffer data structures. */ - void init(); + void init() noexcept; /** Create or restore the doublewrite buffer in the TRX_SYS page. @return whether the operation succeeded */ - bool create(); + bool create() noexcept; /** Free the doublewrite buffer. */ - void close(); + void close() noexcept; /** Acquire the mutex */ - void lock() { mysql_mutex_lock(&mutex); } + void lock() noexcept { mysql_mutex_lock(&mutex); } /** @return the number of completed batches */ - ulint batches() const + ulint batches() const noexcept { mysql_mutex_assert_owner(&mutex); return writes_completed; } /** @return the number of final pages written */ - ulint written() const + ulint written() const noexcept { mysql_mutex_assert_owner(&mutex); return pages_written; } /** Release the mutex */ - void unlock() { mysql_mutex_unlock(&mutex); } + void unlock() noexcept { mysql_mutex_unlock(&mutex); } /** Initialize the doublewrite buffer memory structure on recovery. If we are upgrading from a version before MySQL 4.1, then this @@ -126,30 +126,30 @@ public: @param file File handle @param path Path name of file @return DB_SUCCESS or error code */ - dberr_t init_or_load_pages(pfs_os_file_t file, const char *path); + dberr_t init_or_load_pages(pfs_os_file_t file, const char *path) noexcept; /** Process and remove the double write buffer pages for all tablespaces. */ - void recover(); + void recover() noexcept; /** Update the doublewrite buffer on data page write completion. */ - void write_completed(); + void write_completed() noexcept; /** Flush possible buffered writes to persistent storage. It is very important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ - void flush_buffered_writes(); + void flush_buffered_writes() noexcept; /** Update the doublewrite buffer on write batch completion @param request the completed batch write request */ - void flush_buffered_writes_completed(const IORequest &request); + void flush_buffered_writes_completed(const IORequest &request) noexcept; /** Schedule a page write. If the doublewrite memory buffer is full, flush_buffered_writes() will be invoked to make space. @param request asynchronous write request @param size payload size in bytes */ - void add_to_batch(const IORequest &request, size_t size); + void add_to_batch(const IORequest &request, size_t size) noexcept; /** Determine whether the doublewrite buffer has been created */ - bool is_created() const + bool is_created() const noexcept { return UNIV_LIKELY(block1 != page_id_t(0, 0)); } /** @return whether the doublewrite buffer is in use */ @@ -166,7 +166,7 @@ public: } /** @return whether a page identifier is part of the doublewrite buffer */ - bool is_inside(const page_id_t id) const + bool is_inside(const page_id_t id) const noexcept { if (!is_created()) return false; @@ -178,7 +178,7 @@ public: } /** Wait for flush_buffered_writes() to be fully completed */ - void wait_flush_buffered_writes() + void wait_flush_buffered_writes() noexcept { mysql_mutex_lock(&mutex); while (batch_running) diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index cc32a38a4ef..5d01d38ba21 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -44,27 +44,22 @@ deleting the data file of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. @param id tablespace identifier */ -void buf_flush_remove_pages(uint32_t id); +void buf_flush_remove_pages(uint32_t id) noexcept; -/*******************************************************************//** -Relocates a buffer control block on the flush_list. -Note that it is assumed that the contents of bpage has already been -copied to dpage. */ +/** Relocate a buffer control block in buf_pool.flush_list. +@param bpage control block being moved +@param dpage destination block; the page contents has already been copied */ ATTRIBUTE_COLD -void -buf_flush_relocate_on_flush_list( -/*=============================*/ - buf_page_t* bpage, /*!< in/out: control block being moved */ - buf_page_t* dpage); /*!< in/out: destination block */ - +void buf_flush_relocate_on_flush_list(buf_page_t *bpage, buf_page_t *dpage) + noexcept; /** Complete write of a file page from buf_pool. @param request write request @param error whether the write may have failed */ -void buf_page_write_complete(const IORequest &request, bool error); +void buf_page_write_complete(const IORequest &request, bool error) noexcept; /** Assign the full crc32 checksum for non-compressed page. @param[in,out] page page to be updated */ -void buf_flush_assign_full_crc32_checksum(byte* page); +void buf_flush_assign_full_crc32_checksum(byte* page) noexcept; /** Initialize a page for writing to the tablespace. @param[in] block buffer block; NULL if bypassing the buffer pool @@ -76,40 +71,41 @@ buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - bool use_full_checksum); + bool use_full_checksum) noexcept; /** Try to flush dirty pages that belong to a given tablespace. @param space tablespace @param n_flushed number of pages written @return whether the flush for some pages might not have been initiated */ bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr) + noexcept MY_ATTRIBUTE((warn_unused_result)); /** Wait until a LRU flush batch ends. */ -void buf_flush_wait_LRU_batch_end(); +void buf_flush_wait_LRU_batch_end() noexcept; /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ -ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn); +ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) noexcept; /** Initiate more eager page flushing if the log checkpoint age is too old. @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @param furious true=furious flushing, false=limit to innodb_io_capacity */ -ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious); +ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) noexcept; /** Initialize page_cleaner. */ -ATTRIBUTE_COLD void buf_flush_page_cleaner_init(); +ATTRIBUTE_COLD void buf_flush_page_cleaner_init() noexcept; /** Flush the buffer pool on shutdown. */ -ATTRIBUTE_COLD void buf_flush_buffer_pool(); +ATTRIBUTE_COLD void buf_flush_buffer_pool() noexcept; #ifdef UNIV_DEBUG /** Validate the flush list. */ -void buf_flush_validate(); +void buf_flush_validate() noexcept; #endif /* UNIV_DEBUG */ /** Synchronously flush dirty blocks during recv_sys_t::apply(). NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync_batch(lsn_t lsn); +void buf_flush_sync_batch(lsn_t lsn) noexcept; /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync(); +void buf_flush_sync() noexcept; diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index 78537606f2d..b11feed36ce 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -51,7 +51,7 @@ released by the i/o-handler thread. @param[in] page_id page id @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 */ void buf_read_page_background(fil_space_t *space, const page_id_t page_id, - ulint zip_size) + ulint zip_size) noexcept MY_ATTRIBUTE((nonnull)); /** Applies a random read-ahead in buf_pool if there are at least a threshold @@ -63,7 +63,7 @@ end up waiting for these latches! @param[in] page_id page id of a page which the current thread wants to access @return number of page read requests issued */ -ulint buf_read_ahead_random(const page_id_t page_id); +ulint buf_read_ahead_random(const page_id_t page_id) noexcept; /** Applies linear read-ahead if in the buf_pool the page is a border page of a linear read-ahead area and all the pages in the area have been accessed. @@ -86,7 +86,7 @@ function must be written such that it cannot end up waiting for these latches! @param[in] page_id page id; see NOTE 3 above @return number of page read requests issued */ -ulint buf_read_ahead_linear(const page_id_t page_id); +ulint buf_read_ahead_linear(const page_id_t page_id) noexcept; /** Schedule a page for recovery. @param space tablespace @@ -94,4 +94,4 @@ ulint buf_read_ahead_linear(const page_id_t page_id); @param recs log records @param init_lsn page initialization, or 0 if the page needs to be read */ void buf_read_recover(fil_space_t *space, const page_id_t page_id, - page_recv_t &recs, lsn_t init_lsn); + page_recv_t &recs, lsn_t init_lsn) noexcept; diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index 6c13f5ee308..0f00d416ae3 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -54,12 +54,12 @@ enum srv_checksum_algorithm_t { SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32 }; -inline bool is_checksum_strict(srv_checksum_algorithm_t algo) +inline bool is_checksum_strict(srv_checksum_algorithm_t algo) noexcept { return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32; } -inline bool is_checksum_strict(ulint algo) +inline bool is_checksum_strict(ulint algo) noexcept { return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32; } @@ -96,31 +96,31 @@ public: m_id(uint64_t{space} << 32 | page_no) {} constexpr page_id_t(uint64_t id) : m_id(id) {} - constexpr bool operator==(const page_id_t& rhs) const + constexpr bool operator==(const page_id_t& rhs) const noexcept { return m_id == rhs.m_id; } - constexpr bool operator!=(const page_id_t& rhs) const + constexpr bool operator!=(const page_id_t& rhs) const noexcept { return m_id != rhs.m_id; } - constexpr bool operator<(const page_id_t& rhs) const + constexpr bool operator<(const page_id_t& rhs) const noexcept { return m_id < rhs.m_id; } - constexpr bool operator>(const page_id_t& rhs) const + constexpr bool operator>(const page_id_t& rhs) const noexcept { return m_id > rhs.m_id; } - constexpr bool operator<=(const page_id_t& rhs) const + constexpr bool operator<=(const page_id_t& rhs) const noexcept { return m_id <= rhs.m_id; } - constexpr bool operator>=(const page_id_t& rhs) const + constexpr bool operator>=(const page_id_t& rhs) const noexcept { return m_id >= rhs.m_id; } - page_id_t &operator--() { ut_ad(page_no()); m_id--; return *this; } - page_id_t &operator++() + page_id_t &operator--() noexcept { ut_ad(page_no()); m_id--; return *this; } + page_id_t &operator++() noexcept { ut_ad(page_no() < 0xFFFFFFFFU); m_id++; return *this; } - page_id_t operator-(uint32_t i) const + page_id_t operator-(uint32_t i) const noexcept { ut_ad(page_no() >= i); return page_id_t(m_id - i); } - page_id_t operator+(uint32_t i) const + page_id_t operator+(uint32_t i) const noexcept { ut_ad(page_no() < ~i); return page_id_t(m_id + i); @@ -128,28 +128,30 @@ public: /** Retrieve the tablespace id. @return tablespace id */ - constexpr uint32_t space() const { return static_cast(m_id >> 32); } + constexpr uint32_t space() const noexcept + { return static_cast(m_id >> 32); } /** Retrieve the page number. @return page number */ - constexpr uint32_t page_no() const { return static_cast(m_id); } + constexpr uint32_t page_no() const noexcept + { return static_cast(m_id); } /** Retrieve the fold value. @return fold value */ - constexpr ulint fold() const + constexpr ulint fold() const noexcept { return (ulint{space()} << 20) + space() + page_no(); } /** Reset the page number only. @param[in] page_no page number */ - void set_page_no(uint32_t page_no) + void set_page_no(uint32_t page_no) noexcept { m_id= (m_id & ~uint64_t{0} << 32) | page_no; } - constexpr ulonglong raw() const { return m_id; } + constexpr ulonglong raw() const noexcept { return m_id; } /** Flag the page identifier as corrupted. */ - void set_corrupted() { m_id= ~0ULL; } + void set_corrupted() noexcept { m_id= ~0ULL; } /** @return whether the page identifier belongs to a corrupted page */ constexpr bool is_corrupted() const { return m_id == ~0ULL; } @@ -182,53 +184,55 @@ enum rw_lock_type_t class page_hash_latch : private rw_lock { /** Wait for a shared lock */ - void read_lock_wait(); + void read_lock_wait() noexcept; /** Wait for an exclusive lock */ - void write_lock_wait(); + void write_lock_wait() noexcept; public: /** Acquire a shared lock */ - inline void lock_shared(); + inline void lock_shared() noexcept; /** Acquire an exclusive lock */ - inline void lock(); + inline void lock() noexcept; /** @return whether an exclusive lock is being held by any thread */ - bool is_write_locked() const { return rw_lock::is_write_locked(); } + bool is_write_locked() const noexcept { return rw_lock::is_write_locked(); } /** @return whether any lock is being held by any thread */ - bool is_locked() const { return rw_lock::is_locked(); } + bool is_locked() const noexcept { return rw_lock::is_locked(); } /** @return whether any lock is being held or waited for by any thread */ - bool is_locked_or_waiting() const { return rw_lock::is_locked_or_waiting(); } + bool is_locked_or_waiting() const noexcept + { return rw_lock::is_locked_or_waiting(); } /** Release a shared lock */ - void unlock_shared() { read_unlock(); } + void unlock_shared() noexcept { read_unlock(); } /** Release an exclusive lock */ - void unlock() { write_unlock(); } + void unlock() noexcept { write_unlock(); } }; #elif defined _WIN32 || SIZEOF_SIZE_T >= 8 class page_hash_latch { srw_spin_lock_low lk; public: - void lock_shared() { lk.rd_lock(); } - void unlock_shared() { lk.rd_unlock(); } - void lock() { lk.wr_lock(); } - void unlock() { lk.wr_unlock(); } - bool is_write_locked() const { return lk.is_write_locked(); } - bool is_locked() const { return lk.is_locked(); } - bool is_locked_or_waiting() const { return lk.is_locked_or_waiting(); } + void lock_shared() noexcept { lk.rd_lock(); } + void unlock_shared() noexcept { lk.rd_unlock(); } + void lock() noexcept { lk.wr_lock(); } + void unlock() noexcept { lk.wr_unlock(); } + bool is_write_locked() const noexcept { return lk.is_write_locked(); } + bool is_locked() const noexcept { return lk.is_locked(); } + bool is_locked_or_waiting() const noexcept + { return lk.is_locked_or_waiting(); } }; #else class page_hash_latch { srw_spin_mutex lk; public: - void lock_shared() { lock(); } - void unlock_shared() { unlock(); } - void lock() { lk.wr_lock(); } - void unlock() { lk.wr_unlock(); } - bool is_locked() const { return lk.is_locked(); } - bool is_write_locked() const { return is_locked(); } - bool is_locked_or_waiting() const { return is_locked(); } + void lock_shared() noexcept { lock(); } + void unlock_shared() noexcept { unlock(); } + void lock() noexcept { lk.wr_lock(); } + void unlock() noexcept { lk.wr_unlock(); } + bool is_locked() const noexcept { return lk.is_locked(); } + bool is_write_locked() const noexcept { return is_locked(); } + bool is_locked_or_waiting() const noexcept { return is_locked(); } }; #endif diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index a25f535a072..cd1aa8ca336 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -341,11 +341,11 @@ struct fil_space_t final uint32_t n_reserved_extents= 0; private: #ifdef UNIV_DEBUG - fil_space_t *next_in_space_list(); - fil_space_t *prev_in_space_list(); + fil_space_t *next_in_space_list() noexcept; + fil_space_t *prev_in_space_list() noexcept; - fil_space_t *next_in_unflushed_spaces(); - fil_space_t *prev_in_unflushed_spaces(); + fil_space_t *next_in_unflushed_spaces() noexcept; + fil_space_t *prev_in_unflushed_spaces() noexcept; #endif /** the committed size of the tablespace in pages */ @@ -413,21 +413,21 @@ public: { return UNIV_UNLIKELY(being_imported); } /** @return whether doublewrite buffering is needed */ - inline bool use_doublewrite() const; + inline bool use_doublewrite() const noexcept; /** @return whether a page has been freed */ - inline bool is_freed(uint32_t page); + inline bool is_freed(uint32_t page) noexcept; /** Set create_lsn. */ - inline void set_create_lsn(lsn_t lsn); + inline void set_create_lsn(lsn_t lsn) noexcept; /** @return the latest tablespace rebuild LSN, or 0 */ - lsn_t get_create_lsn() const { return create_lsn; } + lsn_t get_create_lsn() const noexcept { return create_lsn; } /** Apply freed_ranges to the file. @param writable whether the file is writable @return number of pages written or hole-punched */ - uint32_t flush_freed(bool writable); + uint32_t flush_freed(bool writable) noexcept; /** Append a file to the chain of files of a space. @param[in] name file name of a file that is not open @@ -440,7 +440,7 @@ public: @return file object */ fil_node_t* add(const char* name, pfs_os_file_t handle, uint32_t size, bool is_raw, bool atomic_write, - uint32_t max_pages = UINT32_MAX); + uint32_t max_pages = UINT32_MAX) noexcept; #ifdef UNIV_DEBUG /** Assert that the mini-transaction is compatible with updating an allocation bitmap page. @@ -453,6 +453,7 @@ public: @param[in] n_to_reserve number of extents to reserve @return whether the reservation succeeded */ bool reserve_free_extents(uint32_t n_free_now, uint32_t n_to_reserve) + noexcept { if (n_reserved_extents + n_to_reserve > n_free_now) { return false; @@ -464,7 +465,7 @@ public: /** Release the reserved free extents. @param[in] n_reserved number of reserved extents */ - void release_free_extents(uint32_t n_reserved) + void release_free_extents(uint32_t n_reserved) noexcept { if (!n_reserved) return; ut_a(n_reserved_extents >= n_reserved); @@ -477,20 +478,20 @@ public: @param[in] replace whether to ignore the existence of path @return error code @retval DB_SUCCESS on success */ - dberr_t rename(const char *path, bool log, bool replace= false) + dberr_t rename(const char *path, bool log, bool replace= false) noexcept MY_ATTRIBUTE((nonnull)); /** Note that the tablespace has been imported. Initially, purpose=IMPORT so that no redo log is written while the space ID is being updated in each page. */ - inline void set_imported(); + inline void set_imported() noexcept; /** Report the tablespace as corrupted @return whether this was the first call */ ATTRIBUTE_COLD bool set_corrupted() const noexcept; /** @return whether the storage device is rotational (HDD, not SSD) */ - inline bool is_rotational() const; + inline bool is_rotational() const noexcept; /** Open each file. Never invoked on .ibd files. @param create_new_db whether to skip the call to fil_node_t::read_page0() @@ -531,7 +532,7 @@ public: /** Acquire a tablespace reference for I/O. @param avoid when these flags are set, nothing will be acquired @return whether the file is usable */ - bool acquire(uint32_t avoid= STOPPING | CLOSING) + bool acquire(uint32_t avoid= STOPPING | CLOSING) noexcept { const auto flags= acquire_low(avoid) & (avoid); return UNIV_LIKELY(!flags) || (flags == CLOSING && acquire_and_prepare()); @@ -540,14 +541,15 @@ public: /** Acquire a tablespace reference for writing. @param avoid when these flags are set, nothing will be acquired @return whether the file is writable */ - bool acquire_for_write() { return acquire(STOPPING_WRITES | CLOSING); } + bool acquire_for_write() noexcept + { return acquire(STOPPING_WRITES | CLOSING); } /** Acquire another tablespace reference for I/O. */ - inline void reacquire(); + inline void reacquire() noexcept; /** Release a tablespace reference. @return whether this was the last reference */ - bool release() + bool release() noexcept { uint32_t n= n_pending.fetch_sub(1, std::memory_order_release); ut_ad(n & PENDING); @@ -555,43 +557,45 @@ public: } /** Clear the NEEDS_FSYNC flag */ - void clear_flush() + void clear_flush() noexcept { n_pending.fetch_and(~NEEDS_FSYNC, std::memory_order_release); } private: /** Clear the CLOSING flag */ - void clear_closing() + void clear_closing() noexcept { n_pending.fetch_and(~CLOSING, std::memory_order_relaxed); } /** @return pending operations (and flags) */ - uint32_t pending()const { return n_pending.load(std::memory_order_acquire); } + uint32_t pending() const noexcept + { return n_pending.load(std::memory_order_acquire); } public: /** @return whether close() of the file handle has been requested */ - bool is_closing() const { return pending() & CLOSING; } + bool is_closing() const noexcept { return pending() & CLOSING; } /** @return whether the tablespace is about to be dropped */ - bool is_stopping() const { return pending() & STOPPING; } + bool is_stopping() const noexcept { return pending() & STOPPING; } /** @return whether the tablespace is going to be dropped */ - bool is_stopping_writes() const { return pending() & STOPPING_WRITES; } + bool is_stopping_writes() const noexcept + { return pending() & STOPPING_WRITES; } /** @return number of pending operations */ - bool is_ready_to_close() const + bool is_ready_to_close() const noexcept { return (pending() & (PENDING | CLOSING)) == CLOSING; } /** @return whether fsync() or similar is needed */ - bool needs_flush() const { return pending() & NEEDS_FSYNC; } + bool needs_flush() const noexcept { return pending() & NEEDS_FSYNC; } /** @return whether fsync() or similar is needed, and the tablespace is not being dropped */ - bool needs_flush_not_stopping() const + bool needs_flush_not_stopping() const noexcept { return (pending() & (NEEDS_FSYNC | STOPPING_WRITES)) == NEEDS_FSYNC; } - uint32_t referenced() const { return pending() & PENDING; } + uint32_t referenced() const noexcept { return pending() & PENDING; } private: MY_ATTRIBUTE((warn_unused_result)) /** Prepare to close the file handle. @return number of pending operations, possibly with NEEDS_FSYNC flag */ - uint32_t set_closing() + uint32_t set_closing() noexcept { return n_pending.fetch_or(CLOSING, std::memory_order_acquire); } @@ -603,17 +607,18 @@ public: @param ignore_space Ignore the tablespace which is acquired by caller @param print_info whether to diagnose why a file cannot be closed @return whether a file was closed */ - static bool try_to_close(fil_space_t *ignore_space, bool print_info); + static bool try_to_close(fil_space_t *ignore_space, bool print_info) + noexcept; /** Close all tablespace files at shutdown */ - static void close_all(); + static void close_all() noexcept; /** Update last_freed_lsn */ void update_last_freed_lsn(lsn_t lsn) { last_freed_lsn= lsn; } /** Note that the file will need fsync(). @return whether this needs to be added to fil_system.unflushed_spaces */ - bool set_needs_flush() + bool set_needs_flush() noexcept { uint32_t n= 1; while (!n_pending.compare_exchange_strong(n, n | NEEDS_FSYNC, @@ -630,7 +635,7 @@ public: /** Clear all freed ranges for undo tablespace when InnoDB encounters TRIM redo log record */ - void clear_freed_ranges() { freed_ranges.clear(); } + void clear_freed_ranges() noexcept { freed_ranges.clear(); } #endif /* !UNIV_INNOCHECKSUM */ /** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; check fsp0types.h to more info about flags. */ @@ -639,12 +644,12 @@ public: /** Determine if full_crc32 is used for a data file @param[in] flags tablespace flags (FSP_SPACE_FLAGS) @return whether the full_crc32 algorithm is active */ - static bool full_crc32(uint32_t flags) + static bool full_crc32(uint32_t flags) noexcept { return flags & FSP_FLAGS_FCRC32_MASK_MARKER; } /** @return whether innodb_checksum_algorithm=full_crc32 is active */ - bool full_crc32() const { return full_crc32(flags); } + bool full_crc32() const noexcept { return full_crc32(flags); } /** Determine if full_crc32 is used along with PAGE_COMPRESSED */ - static bool is_full_crc32_compressed(uint32_t flags) + static bool is_full_crc32_compressed(uint32_t flags) noexcept { if (!full_crc32(flags)) return false; @@ -656,7 +661,7 @@ public: @param flags tablespace flags (FSP_SPACE_FLAGS) @return the logical page size @retval 0 if the flags are invalid */ - static unsigned logical_size(uint32_t flags) + static unsigned logical_size(uint32_t flags) noexcept { switch (full_crc32(flags) ? FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags) @@ -674,7 +679,7 @@ public: @param flags tablespace flags (FSP_SPACE_FLAGS) @return the ROW_FORMAT=COMPRESSED page size @retval 0 if ROW_FORMAT=COMPRESSED is not used */ - static unsigned zip_size(uint32_t flags) + static unsigned zip_size(uint32_t flags) noexcept { if (full_crc32(flags)) return 0; @@ -684,7 +689,7 @@ public: /** Determine the physical page size. @param flags tablespace flags (FSP_SPACE_FLAGS) @return the physical page size */ - static unsigned physical_size(uint32_t flags) + static unsigned physical_size(uint32_t flags) noexcept { if (full_crc32(flags)) return logical_size(flags); @@ -697,25 +702,25 @@ public: /** @return the ROW_FORMAT=COMPRESSED page size @retval 0 if ROW_FORMAT=COMPRESSED is not used */ - unsigned zip_size() const { return zip_size(flags); } + unsigned zip_size() const noexcept { return zip_size(flags); } /** @return the physical page size */ - unsigned physical_size() const { return physical_size(flags); } + unsigned physical_size() const noexcept { return physical_size(flags); } /** Check whether PAGE_COMPRESSED is enabled. @param[in] flags tablespace flags */ - static bool is_compressed(uint32_t flags) + static bool is_compressed(uint32_t flags) noexcept { return is_full_crc32_compressed(flags) || FSP_FLAGS_HAS_PAGE_COMPRESSION(flags); } /** @return whether the compression enabled for the tablespace. */ - bool is_compressed() const { return is_compressed(flags); } + bool is_compressed() const noexcept { return is_compressed(flags); } /** Get the compression algorithm for full crc32 format. @param flags contents of FSP_SPACE_FLAGS @return PAGE_COMPRESSED algorithm of full_crc32 tablespace @retval 0 if not PAGE_COMPRESSED or not full_crc32 */ - static unsigned get_compression_algo(uint32_t flags) + static unsigned get_compression_algo(uint32_t flags) noexcept { return full_crc32(flags) ? FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO(flags) @@ -723,12 +728,12 @@ public: } /** @return the page_compressed algorithm @retval 0 if not page_compressed */ - unsigned get_compression_algo() const { return get_compression_algo(flags); } + unsigned get_compression_algo() const noexcept { return get_compression_algo(flags); } /** Determine if the page_compressed page contains an extra byte for exact compressed stream length @param flags contents of FSP_SPACE_FLAGS @return whether the extra byte is needed */ - static bool full_crc32_page_compressed_len(uint32_t flags) + static bool full_crc32_page_compressed_len(uint32_t flags) noexcept { DBUG_ASSERT(full_crc32(flags)); switch (get_compression_algo(flags)) { @@ -744,7 +749,7 @@ public: @param flags contents of FSP_SPACE_FLAGS @param expected expected flags @return true if it is equivalent */ - static bool is_flags_full_crc32_equal(uint32_t flags, uint32_t expected) + static bool is_flags_full_crc32_equal(uint32_t flags, uint32_t expected) noexcept { ut_ad(full_crc32(flags)); uint32_t fcrc32_psize= FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags); @@ -765,7 +770,7 @@ public: @param flags contents of FSP_SPACE_FLAGS @param expected expected flags @return true if it is equivalent */ - static bool is_flags_non_full_crc32_equal(uint32_t flags, uint32_t expected) + static bool is_flags_non_full_crc32_equal(uint32_t flags, uint32_t expected) noexcept { ut_ad(!full_crc32(flags)); if (!full_crc32(expected)) @@ -780,7 +785,7 @@ public: } /** Whether both fsp flags are equivalent */ - static bool is_flags_equal(uint32_t flags, uint32_t expected) + static bool is_flags_equal(uint32_t flags, uint32_t expected) noexcept { if (!((flags ^ expected) & ~(1U << FSP_FLAGS_POS_RESERVED))) return true; @@ -792,7 +797,7 @@ public: /** Validate the tablespace flags for full crc32 format. @param flags contents of FSP_SPACE_FLAGS @return whether the flags are correct in full crc32 format */ - static bool is_fcrc32_valid_flags(uint32_t flags) + static bool is_fcrc32_valid_flags(uint32_t flags) noexcept { ut_ad(flags & FSP_FLAGS_FCRC32_MASK_MARKER); const ulint page_ssize= physical_size(flags); @@ -805,7 +810,7 @@ public: @param flags contents of FSP_SPACE_FLAGS @param is_ibd whether this is an .ibd file (not system tablespace) @return whether the flags are correct */ - static bool is_valid_flags(uint32_t flags, bool is_ibd) + static bool is_valid_flags(uint32_t flags, bool is_ibd) noexcept { DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return false;); if (full_crc32(flags)) @@ -878,17 +883,17 @@ public: @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ - static fil_space_t *get(uint32_t id); + static fil_space_t *get(uint32_t id) noexcept; /** Acquire a tablespace reference for writing. @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ - static fil_space_t *get_for_write(uint32_t id); + static fil_space_t *get_for_write(uint32_t id) noexcept; /** Add/remove the free page in the freed ranges list. @param[in] offset page number to be added @param[in] free true if page to be freed */ - void free_page(uint32_t offset, bool add=true) + void free_page(uint32_t offset, bool add=true) noexcept { std::lock_guard freed_lock(freed_range_mutex); if (add) @@ -901,14 +906,14 @@ public: } /** Add the range of freed pages */ - void add_free_ranges(range_set ranges) + void add_free_ranges(range_set ranges) noexcept { std::lock_guard freed_lock(freed_range_mutex); freed_ranges= std::move(ranges); } /** Add the set of freed page ranges */ - void add_free_range(const range_t range) + void add_free_range(const range_t range) noexcept { freed_ranges.add_range(range); } @@ -919,20 +924,20 @@ public: inline void clear_freed_ranges(uint32_t threshold); /** Set the tablespace size in pages */ - void set_sizes(uint32_t s) + void set_sizes(uint32_t s) noexcept { ut_ad(id ? !size : (size >= s)); size= s; committed_size= s; } /** Update committed_size in mtr_t::commit() */ - void set_committed_size() { committed_size= size; } + void set_committed_size() noexcept { committed_size= size; } /** @return the last persisted page number */ - uint32_t last_page_number() const { return committed_size - 1; } + uint32_t last_page_number() const noexcept { return committed_size - 1; } /** @return the size in pages (0 if unreadable) */ - inline uint32_t get_size(); + inline uint32_t get_size() noexcept; /** Read or write data. @param type I/O context @@ -942,11 +947,11 @@ public: @param bpage buffer block (for type.is_async() completion callback) @return status and file descriptor */ fil_io_t io(const IORequest &type, os_offset_t offset, size_t len, - void *buf, buf_page_t *bpage= nullptr); + void *buf, buf_page_t *bpage= nullptr) noexcept; /** Flush pending writes from the file system cache to the file. */ - template inline void flush(); + template inline void flush() noexcept; /** Flush pending writes from the file system cache to the file. */ - void flush_low(); + void flush_low() noexcept; /** Read the first page of a data file. @param dpage copy of a first page, from the doublewrite buffer, or nullptr @@ -962,19 +967,19 @@ public: @return the next tablespace @retval nullptr upon reaching the end of the iteration */ static space_list_t::iterator next(space_list_t::iterator space, - bool recheck, bool encrypt); + bool recheck, bool encrypt) noexcept; #ifdef UNIV_DEBUG - bool is_latched() const { return latch.have_any(); } + bool is_latched() const noexcept { return latch.have_any(); } #endif - bool is_owner() const + bool is_owner() const noexcept { const bool owner{latch_owner == pthread_self()}; ut_ad(owner == latch.have_wr()); return owner; } /** Acquire the allocation latch in exclusive mode */ - void x_lock() + void x_lock() noexcept { latch.wr_lock(SRW_LOCK_CALL); ut_ad(!latch_owner); @@ -988,14 +993,14 @@ public: latch.wr_unlock(); } /** Acquire the allocation latch in shared mode */ - void s_lock() { latch.rd_lock(SRW_LOCK_CALL); } + void s_lock() noexcept { latch.rd_lock(SRW_LOCK_CALL); } /** Release the allocation latch from shared mode */ - void s_unlock() { latch.rd_unlock(); } + void s_unlock() noexcept { latch.rd_unlock(); } typedef span name_type; /** @return the tablespace name (databasename/tablename) */ - name_type name() const; + name_type name() const noexcept; /** How to validate tablespace files that are being opened */ enum validate { @@ -1010,7 +1015,7 @@ public: }; /** Update the data structures on write completion */ - void complete_write(); + void complete_write() noexcept; /** Free the unused segment for the tablespace @param shutdown called during slow shutdown @@ -1018,9 +1023,9 @@ public: dberr_t garbage_collect(bool shutdown); private: /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool prepare_acquired(); + ATTRIBUTE_COLD bool prepare_acquired() noexcept; /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool acquire_and_prepare(); + ATTRIBUTE_COLD bool acquire_and_prepare() noexcept; #endif /*!UNIV_INNOCHECKSUM */ }; @@ -1065,7 +1070,7 @@ struct fil_node_t final ulint block_size; /** @return whether this file is open */ - bool is_open() const { return handle != OS_FILE_CLOSED; } + bool is_open() const noexcept { return handle != OS_FILE_CLOSED; } /** Read the first page of a data file. @param dpage copy of a first page, from the doublewrite buffer, or nullptr @@ -1076,32 +1081,32 @@ struct fil_node_t final void find_metadata(IF_WIN(,bool create= false)) noexcept; /** Close the file handle. */ - void close(); + void close() noexcept; /** Same as close() but returns file handle instead of closing it. */ - pfs_os_file_t detach() MY_ATTRIBUTE((warn_unused_result)); + pfs_os_file_t detach() noexcept MY_ATTRIBUTE((warn_unused_result)); /** Prepare to free a file from fil_system. @param detach_handle whether to detach instead of closing a handle @return detached handle or OS_FILE_CLOSED */ - inline pfs_os_file_t close_to_free(bool detach_handle= false); + inline pfs_os_file_t close_to_free(bool detach_handle= false) noexcept; private: /** Does stuff common for close() and detach() */ - void prepare_to_close_or_detach(); + void prepare_to_close_or_detach() noexcept; }; -inline bool fil_space_t::use_doublewrite() const +inline bool fil_space_t::use_doublewrite() const noexcept { return !UT_LIST_GET_FIRST(chain)->atomic_write && buf_dblwr.in_use(); } -inline void fil_space_t::set_imported() +inline void fil_space_t::set_imported() noexcept { ut_ad(being_imported); being_imported= false; UT_LIST_GET_FIRST(chain)->find_metadata(); } -inline bool fil_space_t::is_rotational() const +inline bool fil_space_t::is_rotational() const noexcept { for (const fil_node_t *node= UT_LIST_GET_FIRST(chain); node; node= UT_LIST_GET_NEXT(chain, node)) @@ -1303,7 +1308,7 @@ constexpr uint16_t FIL_PAGE_COMPRESS_FCRC32_MARKER= 15; /* @} */ /** @return whether the page type is B-tree or R-tree index */ -inline bool fil_page_type_is_index(uint16_t page_type) +inline bool fil_page_type_is_index(uint16_t page_type) noexcept { switch (page_type) { case FIL_PAGE_TYPE_INSTANT: @@ -1322,7 +1327,7 @@ index */ /** Get the file page type. @param[in] page file page @return page type */ -inline uint16_t fil_page_get_type(const byte *page) +inline uint16_t fil_page_get_type(const byte *page) noexcept { return mach_read_from_2(my_assume_aligned<2>(page + FIL_PAGE_TYPE)); } @@ -1340,7 +1345,7 @@ or the caller should be in single-threaded crash recovery mode Normally, fil_space_t::get() should be used instead. @param[in] id tablespace ID @return tablespace, or NULL if not found */ -fil_space_t *fil_space_get(uint32_t id) +fil_space_t *fil_space_get(uint32_t id) noexcept MY_ATTRIBUTE((warn_unused_result)); /** The tablespace memory cache */ @@ -1354,7 +1359,7 @@ struct fil_system_t */ fil_system_t() {} - bool is_initialised() const { return spaces.array; } + bool is_initialised() const noexcept { return spaces.array; } /** Create the file system interface at database start. @@ -1364,7 +1369,7 @@ struct fil_system_t void create(ulint hash_size); /** Close the file system interface at shutdown */ - void close(); + void close() noexcept; private: /** Points to the last opened space in space_list. Protected with @@ -1376,7 +1381,7 @@ private: std::vector ssd; public: /** @return whether a file system device is on non-rotational storage */ - bool is_ssd(dev_t dev) const + bool is_ssd(dev_t dev) const noexcept { /* Linux seems to allow up to 15 partitions per block device. If the detected ssd carries "partition number 0" (it is the whole device), @@ -1393,7 +1398,7 @@ public: @param detach_handle whether to detach the handle, instead of closing @return detached handle @retval OS_FILE_CLOSED if no handle was detached */ - pfs_os_file_t detach(fil_space_t *space, bool detach_handle= false); + pfs_os_file_t detach(fil_space_t *space, bool detach_handle= false) noexcept; /** the mutex protecting most data fields, and some fields of fil_space_t */ mysql_mutex_t mutex; @@ -1460,13 +1465,13 @@ public: fil_system.space_list, so that fil_space_t::try_to_close() should close it as a last resort. @param space space to add */ - void add_opened_last_to_space_list(fil_space_t *space); + void add_opened_last_to_space_list(fil_space_t *space) noexcept; /** Move the file to the end of opened spaces list in fil_system.space_list, so that fil_space_t::try_to_close() should close it as a last resort. @param space space to move */ - inline void move_opened_last_to_space_list(fil_space_t *space) + inline void move_opened_last_to_space_list(fil_space_t *space) noexcept { /* In the case when several files of the same space are added in a row, there is no need to remove and add a space to the same position @@ -1482,7 +1487,7 @@ public: fil_space_t::try_to_close() iterates opened files first in FIFO order, i.e. first opened, first closed. @param space space to move */ - void move_closed_last_to_space_list(fil_space_t *space) + void move_closed_last_to_space_list(fil_space_t *space) noexcept { if (UNIV_UNLIKELY(freeze_space_list)) return; @@ -1509,21 +1514,21 @@ public: @retval fil_system.temp_space if there is no work to do @retval nullptr upon reaching the end of the iteration */ inline fil_space_t* default_encrypt_next(fil_space_t *space, bool recheck, - bool encrypt); + bool encrypt) noexcept; /** Extend all open data files to the recovered size */ - ATTRIBUTE_COLD void extend_to_recv_size(); + ATTRIBUTE_COLD void extend_to_recv_size() noexcept; /** Determine if a tablespace associated with a file name exists. @param path tablespace file name to look for @return a matching tablespace */ - inline fil_space_t *find(const char *path) const; + inline fil_space_t *find(const char *path) const noexcept; }; /** The tablespace memory cache. */ extern fil_system_t fil_system; -inline void fil_space_t::reacquire() +inline void fil_space_t::reacquire() noexcept { ut_d(uint32_t n=) n_pending.fetch_add(1, std::memory_order_relaxed); #ifdef SAFE_MUTEX @@ -1534,7 +1539,7 @@ inline void fil_space_t::reacquire() } /** Flush pending writes from the file system cache to the file. */ -template inline void fil_space_t::flush() +template inline void fil_space_t::flush() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); ut_ad(!have_reference || (pending() & PENDING)); @@ -1552,7 +1557,7 @@ template inline void fil_space_t::flush() } /** @return the size in pages (0 if unreadable) */ -inline uint32_t fil_space_t::get_size() +inline uint32_t fil_space_t::get_size() noexcept { if (!size) { @@ -1570,7 +1575,7 @@ Assigns a new space id for a new single-table tablespace. This works simply by incrementing the global counter. If 4 billion id's is not enough, we may need to recycle id's. @return true if assigned, false if not */ -bool fil_assign_new_space_id(uint32_t *space_id); +bool fil_assign_new_space_id(uint32_t *space_id) noexcept; /** Frees a space object from the tablespace memory cache. Closes the files in the chain but does not delete them. @@ -1578,31 +1583,31 @@ There must not be any pending i/o's or flushes on the files. @param id tablespace identifier @param x_latched whether the caller holds exclusive fil_space_t::latch @return true if success */ -bool fil_space_free(uint32_t id, bool x_latched); +bool fil_space_free(uint32_t id, bool x_latched) noexcept; /** Set the recovered size of a tablespace in pages. @param id tablespace ID @param size recovered size in pages @param flags tablespace flags */ void fil_space_set_recv_size_and_flags(uint32_t id, uint32_t size, - uint32_t flags); + uint32_t flags) noexcept; /*******************************************************************//** Sets the max tablespace id counter if the given number is bigger than the previous value. */ -void fil_set_max_space_id_if_bigger(uint32_t max_id); +void fil_set_max_space_id_if_bigger(uint32_t max_id) noexcept; MY_ATTRIBUTE((warn_unused_result)) /** Delete a tablespace and associated .ibd file. @param id tablespace identifier @return detached file handle (to be closed by the caller) @return OS_FILE_CLOSED if no file existed */ -pfs_os_file_t fil_delete_tablespace(uint32_t id); +pfs_os_file_t fil_delete_tablespace(uint32_t id) noexcept; /** Close a single-table tablespace on failed IMPORT TABLESPACE. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. */ -void fil_close_tablespace(uint32_t id); +void fil_close_tablespace(uint32_t id) noexcept; /*******************************************************************//** Allocates and builds a file name from a path, a table or tablespace name @@ -1614,10 +1619,10 @@ and a suffix. The string must be freed by caller with ut_free(). @return own: file name */ char* fil_make_filepath_low(const char *path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name); + ib_extention extension, bool trim_name) noexcept; char *fil_make_filepath(const char* path, const table_name_t name, - ib_extention suffix, bool strip_name); + ib_extention suffix, bool strip_name) noexcept; /** Wrapper function over fil_make_filepath_low to build file name. @param path nullptr or the directory path or the full path and filename @@ -1627,7 +1632,7 @@ char *fil_make_filepath(const char* path, const table_name_t name, @return own: file name */ static inline char* fil_make_filepath(const char* path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name) + ib_extention extension, bool trim_name) noexcept { /* If we are going to strip a name off the path, there better be a path and a new name to put back on. */ @@ -1708,7 +1713,7 @@ enum fil_load_status { @return status of the operation */ enum fil_load_status fil_ibd_load(uint32_t space_id, const char *filename, fil_space_t *&space) - MY_ATTRIBUTE((warn_unused_result)); + noexcept MY_ATTRIBUTE((warn_unused_result)); /** Determine if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database @@ -1718,28 +1723,29 @@ startup, there may be many tablespaces which are not yet in the memory cache. @return the tablespace @retval NULL if no matching tablespace exists in the memory cache */ fil_space_t *fil_space_for_table_exists_in_mem(uint32_t id, - uint32_t table_flags); + uint32_t table_flags) noexcept; /** Try to extend a tablespace if it is smaller than the specified size. @param[in,out] space tablespace @param[in] size desired size in pages @return whether the tablespace is at least as big as requested */ -bool fil_space_extend(fil_space_t *space, uint32_t size); +bool fil_space_extend(fil_space_t *space, uint32_t size) noexcept; /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. */ -void fil_flush_file_spaces(); +void fil_flush_file_spaces() noexcept; /******************************************************************//** Checks the consistency of the tablespace cache. @return true if ok */ -bool fil_validate(); -/*********************************************************************//** -Sets the file page type. */ -void -fil_page_set_type( -/*==============*/ - byte* page, /*!< in/out: file page */ - ulint type); /*!< in: type */ +bool fil_validate() noexcept; + +/** Set the file page type. +@param page file page +@param type FIL_PAGE_TYPE value */ +inline void fil_page_set_type(byte *page, uint16_t type) noexcept +{ + mach_write_to_2(page + FIL_PAGE_TYPE, type); +} /********************************************************************//** Delete the tablespace file and any related files like .cfg. @@ -1747,7 +1753,8 @@ This should not be called for temporary tables. */ void fil_delete_file( /*============*/ - const char* path); /*!< in: filepath of the ibd tablespace */ + const char* path) /*!< in: filepath of the ibd tablespace */ + noexcept; /** Look up a table space by a given id. @param id tablespace identifier @@ -1758,18 +1765,16 @@ fil_space_t *fil_space_get_by_id(uint32_t id) noexcept; /** Note that a non-predefined persistent tablespace has been modified by redo log. @param[in,out] space tablespace */ -void -fil_names_dirty( - fil_space_t* space); +void fil_names_dirty(fil_space_t *space) noexcept; -bool fil_comp_algo_loaded(ulint comp_algo); +bool fil_comp_algo_loaded(ulint comp_algo) noexcept; /** On a log checkpoint, reset fil_names_dirty_and_write() flags and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. @param lsn checkpoint LSN @return current LSN */ -ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn); +ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) noexcept; #ifdef UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH void test_make_filepath(); @@ -1779,12 +1784,14 @@ void test_make_filepath(); @param[in] space tablespace @param[in] offset page number @return block size */ -ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset); +ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset) + noexcept; /** Check whether encryption key found @param crypt_data Encryption data @param f_name File name @return encryption key found */ -bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name); +bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name) + noexcept; #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 48ab763a2ac..96ce0cfe783 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -128,9 +128,7 @@ void innobase_mysql_print_thd( /*=====================*/ FILE* f, /*!< in: output stream */ - THD* thd, /*!< in: pointer to a MySQL THD object */ - uint max_query_len); /*!< in: max query length to print, or 0 to - use the default max length */ + THD* thd); /*!< in: pointer to a MySQL THD object */ /** Converts a MySQL type to an InnoDB type. Note that this function returns the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1 diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 6840b27f5d7..8b9278bf93f 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -282,7 +282,6 @@ public: uint write_size; /** format of the redo log: e.g., FORMAT_10_8 */ uint32_t format; -#ifdef HAVE_INNODB_MMAP /** whether the memory-mapped interface is enabled for the log */ my_bool log_mmap; /** the default value of log_mmap */ @@ -294,7 +293,6 @@ public: # else /* an unnecessary read-ahead of a large ib_logfile0 is a risk */ # endif false; -#endif #if defined __linux__ || defined _WIN32 /** whether file system caching is enabled for the log */ my_bool log_buffered; @@ -349,11 +347,7 @@ public: void set_buf_free(size_t f) noexcept { ut_ad(f < buf_free_LOCK); buf_free.store(f, std::memory_order_relaxed); } -#ifdef HAVE_INNODB_MMAP bool is_mmap() const noexcept { return !flush_buf; } -#else - static constexpr bool is_mmap() { return false; } -#endif /** @return whether a handle to the log is open; is_mmap() && !is_opened() holds for PMEM */ @@ -414,14 +408,9 @@ public: @return whether the memory allocation succeeded */ bool attach(log_file_t file, os_offset_t size); -#ifdef HAVE_INNODB_MMAP /** Disable memory-mapped access (update log_mmap) */ void clear_mmap(); void close_file(bool really_close= true); -#else - static void clear_mmap() {} - void close_file(); -#endif #if defined __linux__ || defined _WIN32 /** Try to enable or disable file system caching (update log_buffered) */ void set_buffered(bool buffered); @@ -466,9 +455,8 @@ public: #ifdef HAVE_PMEM /** Persist the log. - @param lsn desired new value of flushed_to_disk_lsn - @param holding_latch whether the caller is holding exclusive latch */ - void persist(lsn_t lsn, bool holding_latch) noexcept; + @param lsn desired new value of flushed_to_disk_lsn */ + void persist(lsn_t lsn) noexcept; #endif bool check_for_checkpoint() const diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 6121951ad90..6317b0e8710 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -420,12 +420,7 @@ public: @tparam storing whether to store the records @param if_exists storing=YES: whether to check if the tablespace exists */ template - static parse_mtr_result parse_mmap(bool if_exists) noexcept -#ifdef HAVE_INNODB_MMAP - ; -#else - { return parse_mtr(if_exists); } -#endif + static parse_mtr_result parse_mmap(bool if_exists) noexcept; /** Erase log records for a page. */ void erase(map::iterator p); diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index d086cfebffc..4ca431711e8 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -681,7 +681,7 @@ private: /** Write a FILE_MODIFY record when a non-predefined persistent tablespace was modified for the first time since fil_names_clear(). */ - ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void name_write(); + ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void name_write() noexcept; /** Encrypt the log */ ATTRIBUTE_NOINLINE void encrypt(); diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index b2c324f47e4..0108c89f449 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -214,27 +214,28 @@ public: buf_tmp_buffer_t *slot= nullptr) : bpage(bpage), slot(slot), type(type) {} - bool is_read() const { return (type & READ_SYNC) != 0; } - bool is_write() const { return (type & WRITE_SYNC) != 0; } - bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; } - bool is_doublewritten() const { return (type & 4) != 0; } + bool is_read() const noexcept { return (type & READ_SYNC) != 0; } + bool is_write() const noexcept { return (type & WRITE_SYNC) != 0; } + bool is_async() const noexcept + { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; } + bool is_doublewritten() const noexcept { return (type & 4) != 0; } /** Create a write request for the doublewrite buffer. */ - IORequest doublewritten() const + IORequest doublewritten() const noexcept { ut_ad(type == WRITE_ASYNC || type == PUNCH); return IORequest{bpage, slot, node, Type(type | 4)}; } - void write_complete(int io_error) const; - void read_complete(int io_error) const; - void fake_read_complete(os_offset_t offset) const; + void write_complete(int io_error) const noexcept; + void read_complete(int io_error) const noexcept; + void fake_read_complete(os_offset_t offset) const noexcept; /** If requested, free storage space associated with a section of the file. @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ - dberr_t maybe_punch_hole(os_offset_t off, ulint len) + dberr_t maybe_punch_hole(os_offset_t off, ulint len) noexcept { return off && len && node && (type & (PUNCH ^ WRITE_ASYNC)) ? punch_hole(off, len) @@ -246,7 +247,7 @@ private: @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ - dberr_t punch_hole(os_offset_t off, ulint len) const; + dberr_t punch_hole(os_offset_t off, ulint len) const noexcept; public: /** Page to be written on write operation */ @@ -329,8 +330,7 @@ struct os_file_stat_t { the temporary file is created in the in the mysql server configuration parameter (--tmpdir). @return temporary file handle, or NULL on error */ -FILE* -os_file_create_tmpfile(); +FILE *os_file_create_tmpfile() noexcept; /** This function attempts to create a directory named pathname. The new directory @@ -342,10 +342,8 @@ fail_if_exists arguments is true. @param[in] fail_if_exists if true, pre-existing directory is treated as an error. @return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists); +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept; /** NOTE! Use the corresponding macro os_file_create_simple(), not directly this function! @@ -364,7 +362,7 @@ os_file_create_simple_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success); + bool* success) noexcept; /** NOTE! Use the corresponding macro os_file_create_simple_no_error_handling(), not directly this function! @@ -384,7 +382,7 @@ os_file_create_simple_no_error_handling_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept MY_ATTRIBUTE((warn_unused_result)); #ifndef _WIN32 /* On Microsoft Windows, mandatory locking is used */ @@ -392,7 +390,7 @@ os_file_create_simple_no_error_handling_func( @param fd file descriptor @param name file name @return 0 on success */ -int os_file_lock(int fd, const char *name); +int os_file_lock(int fd, const char *name) noexcept; #endif /** NOTE! Use the corresponding macro os_file_create(), not directly @@ -412,7 +410,7 @@ os_file_create_func( os_file_create_t create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Deletes a file. The file has to be closed before calling this. @@ -853,9 +851,7 @@ to original un-instrumented file I/O APIs */ @param[in] file handle to a file @return file size if OK, else set m_total_size to ~0 and m_alloc_size to errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Determine the logical size of a file. @@ -870,9 +866,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept /** Truncates a file at its current position. @param[in/out] file file to be truncated @return true if success */ -bool -os_file_set_eof( - FILE* file); /*!< in: file to be truncated */ +bool os_file_set_eof(FILE *file) noexcept; /** Truncate a file to a specified size in bytes. @param[in] pathname file path @@ -885,16 +879,14 @@ os_file_truncate( const char* pathname, os_file_t file, os_offset_t size, - bool allow_shrink = false); + bool allow_shrink = false) noexcept; /** NOTE! Use the corresponding macro os_file_flush(), not directly this function! Flushes the write buffers of a given file to the disk. @param[in] file handle to a file @return true if success */ -bool -os_file_flush_func( - os_file_t file); +bool os_file_flush_func(os_file_t file) noexcept; /** Retrieves the last error number if an error occurs in a file io function. The number should be retrieved before any other OS calls (because they may @@ -906,7 +898,7 @@ the OS error number + OS_FILE_ERROR_MAX is returned. to the log @return error number, or OS error number + OS_FILE_ERROR_MAX */ ulint os_file_get_last_error(bool report_all_errors, - bool on_error_silent= false); + bool on_error_silent= false) noexcept; /** NOTE! Use the corresponding macro os_file_read(), not directly this function! @@ -925,7 +917,7 @@ os_file_read_func( void* buf, os_offset_t offset, ulint n, - ulint* o) + ulint* o) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Rewind file to its start, read at most size - 1 bytes from it to str, and @@ -938,7 +930,7 @@ void os_file_read_string( FILE* file, char* str, - ulint size); + ulint size) noexcept; /** NOTE! Use the corresponding macro os_file_write(), not directly this function! @@ -968,7 +960,7 @@ bool os_file_status( const char* path, bool* exists, - os_file_type_t* type); + os_file_type_t* type) noexcept; /** This function reduces a null-terminated full remote path name into the path that is sent by MySQL for DATA DIRECTORY clause. It replaces @@ -982,34 +974,30 @@ This function manipulates that path in place. If the path format is not as expected, just return. The result is used to inform a SHOW CREATE TABLE command. @param[in,out] data_dir_path Full path/data_dir_path */ -void -os_file_make_data_dir_path( - char* data_dir_path); +void os_file_make_data_dir_path(char *data_dir_path) noexcept; /** Create all missing subdirectories along the given path. @return DB_SUCCESS if OK, otherwise error code. */ -dberr_t -os_file_create_subdirs_if_needed( - const char* path); +dberr_t os_file_create_subdirs_if_needed(const char* path) noexcept; #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR /* Test the function os_file_get_parent_dir. */ void -unit_test_os_file_get_parent_dir(); +unit_test_os_file_get_parent_dir() noexcept; #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */ /** Initializes the asynchronous io system. */ -int os_aio_init(); +int os_aio_init() noexcept; /** Frees the asynchronous io system. */ -void os_aio_free(); +void os_aio_free() noexcept; /** Submit a fake read request during crash recovery. @param type fake read request @param offset additional context */ -void os_fake_read(const IORequest &type, os_offset_t offset); +void os_fake_read(const IORequest &type, os_offset_t offset) noexcept; /** Request a read or write. @param type I/O request @@ -1018,36 +1006,34 @@ void os_fake_read(const IORequest &type, os_offset_t offset); @param n number of bytes @retval DB_SUCCESS if request was queued successfully @retval DB_IO_ERROR on I/O error */ -dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n); +dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n) + noexcept; /** @return number of pending reads */ -size_t os_aio_pending_reads(); +size_t os_aio_pending_reads() noexcept; /** @return approximate number of pending reads */ -size_t os_aio_pending_reads_approx(); +size_t os_aio_pending_reads_approx() noexcept; /** @return number of pending writes */ -size_t os_aio_pending_writes(); +size_t os_aio_pending_writes() noexcept; /** Wait until there are no pending asynchronous writes. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_writes(bool declare); +void os_aio_wait_until_no_pending_writes(bool declare) noexcept; /** Wait until all pending asynchronous reads have completed. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_reads(bool declare); +void os_aio_wait_until_no_pending_reads(bool declare) noexcept; /** Prints info of the aio arrays. @param[in/out] file file where to print */ -void -os_aio_print(FILE* file); +void os_aio_print(FILE *file) noexcept; /** Refreshes the statistics used to print per-second averages. */ -void -os_aio_refresh_stats(); +void os_aio_refresh_stats() noexcept; /** Checks that all slots in the system have been freed, that is, there are no pending io operations. */ -bool -os_aio_all_slots_free(); +bool os_aio_all_slots_free() noexcept; /** This function returns information about the specified file @@ -1062,7 +1048,7 @@ os_file_get_status( const char* path, os_file_stat_t* stat_info, bool check_rw_perm, - bool read_only); + bool read_only) noexcept; #ifdef _WIN32 @@ -1073,7 +1059,7 @@ Make file sparse, on Windows. @param[in] is_sparse if true, make file sparse, otherwise "unsparse" the file @return true on success, false on error */ -bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true); +bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true) noexcept; /** Changes file size on Windows @@ -1090,14 +1076,12 @@ If file is normal, file system allocates storage. @param[in] file file handle @param[in] size size to preserve in bytes @return true if success */ -bool -os_file_set_size( - const char* pathname, - os_file_t file, - os_offset_t size); +bool os_file_set_size(const char *pathname, os_file_t file, os_offset_t size) + noexcept; inline bool os_file_set_size(const char* name, os_file_t file, os_offset_t size, bool) + noexcept { return os_file_set_size(name, file, size); } @@ -1121,14 +1105,14 @@ dberr_t os_file_punch_hole( os_file_t fh, os_offset_t off, - os_offset_t len) + os_offset_t len) noexcept MY_ATTRIBUTE((warn_unused_result)); /* Determine if a path is an absolute path or not. @param[in] OS directory or file path to evaluate @retval true if an absolute path @retval false if a relative path */ -inline bool is_absolute_path(const char *path) +inline bool is_absolute_path(const char *path) noexcept { switch (path[0]) { #ifdef _WIN32 diff --git a/storage/innobase/include/sux_lock.h b/storage/innobase/include/sux_lock.h index 4d9a50b528e..a5b09693107 100644 --- a/storage/innobase/include/sux_lock.h +++ b/storage/innobase/include/sux_lock.h @@ -121,15 +121,13 @@ private: @param id the new owner of the U or X lock */ void set_new_owner(pthread_t id) { - IF_DBUG(DBUG_ASSERT(writer.exchange(id, std::memory_order_relaxed)), - writer.store(id, std::memory_order_relaxed)); + writer.store(id, std::memory_order_relaxed); } /** Assign the ownership of a write lock to a thread @param id the owner of the U or X lock */ void set_first_owner(pthread_t id) { - IF_DBUG(DBUG_ASSERT(!writer.exchange(id, std::memory_order_relaxed)), - writer.store(id, std::memory_order_relaxed)); + writer.store(id, std::memory_order_relaxed); } #ifdef UNIV_DEBUG /** Register the current thread as a holder of a shared lock */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index c89509d7f92..8a9a093ad2c 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -211,9 +211,6 @@ trx_print_low( /*!< in: output stream */ const trx_t* trx, /*!< in: transaction */ - ulint max_query_len, - /*!< in: max query length to print, - or 0 to use the default max length */ ulint n_rec_locks, /*!< in: trx->lock.n_rec_locks */ ulint n_trx_locks, @@ -228,9 +225,7 @@ void trx_print_latched( /*==============*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len); /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx); /*!< in: transaction */ /**********************************************************************//** Prints info about a transaction. @@ -239,9 +234,7 @@ void trx_print( /*======*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len); /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx); /*!< in: transaction */ /**********************************************************************//** Determines if a transaction is in the given state. @@ -671,14 +664,14 @@ public: { ut_ad(!mutex_is_owner()); mutex.wr_lock(); - ut_ad(!mutex_owner.exchange(pthread_self(), - std::memory_order_relaxed)); + ut_d(assert(!mutex_owner.exchange(pthread_self(), + std::memory_order_relaxed))); } /** Release the mutex */ void mutex_unlock() { - ut_ad(mutex_owner.exchange(0, std::memory_order_relaxed) - == pthread_self()); + ut_d(assert(mutex_owner.exchange(0, std::memory_order_relaxed) == + pthread_self())); mutex.wr_unlock(); } #ifndef SUX_LOCK_GENERIC diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 91433e86fbd..490f71653f7 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -168,9 +168,6 @@ using the call command. */ #define UNIV_INLINE static inline #define UNIV_WORD_SIZE SIZEOF_SIZE_T -#if SIZEOF_SIZE_T == 8 -# define HAVE_INNODB_MMAP -#endif /** The following alignment is used in memory allocations in memory heap management to ensure correct alignment for doubles etc. */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1f5e9941fbb..ed9d6d2db02 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -5212,7 +5212,7 @@ void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx, { fprintf(file, "---"); - trx_print_latched(file, trx, 600); + trx_print_latched(file, trx); trx->read_view.print_limits(file); if (const lock_t* wait_lock = trx->lock.wait_lock) { @@ -6944,11 +6944,11 @@ namespace Deadlock ulint n_trx_locks= UT_LIST_GET_LEN(trx.lock.trx_locks); ulint heap_size= mem_heap_get_size(trx.lock.lock_heap); - trx_print_low(lock_latest_err_file, &trx, 3000, + trx_print_low(lock_latest_err_file, &trx, n_rec_locks, n_trx_locks, heap_size); if (srv_print_all_deadlocks) - trx_print_low(stderr, &trx, 3000, n_rec_locks, n_trx_locks, heap_size); + trx_print_low(stderr, &trx, n_rec_locks, n_trx_locks, heap_size); } /** Print lock data to the deadlock file and possibly to stderr. diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 5b0761e8dbe..3abdc2210e0 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -186,7 +186,6 @@ void log_file_t::write(os_offset_t offset, span buf) noexcept abort(); } -#ifdef HAVE_INNODB_MMAP # ifdef HAVE_PMEM # include "cache.h" # endif @@ -202,6 +201,10 @@ static void *log_mmap(os_file_t file, # endif os_offset_t size) { +#if SIZEOF_SIZE_T < 8 + if (size != os_offset_t(size_t(size))) + return MAP_FAILED; +#endif if (my_system_page_size > 4096) return MAP_FAILED; # ifndef HAVE_PMEM @@ -299,20 +302,17 @@ remap: # endif return ptr; } -#endif #if defined __linux__ || defined _WIN32 /** Display a message about opening the log */ ATTRIBUTE_COLD static void log_file_message() { sql_print_information("InnoDB: %s (block size=%u bytes)", -# ifdef HAVE_INNODB_MMAP log_sys.log_mmap ? (log_sys.log_buffered ? "Memory-mapped log" : "Memory-mapped unbuffered log") : -# endif log_sys.log_buffered ? "Buffered log writes" : "File system buffers for log disabled", @@ -331,7 +331,6 @@ bool log_t::attach(log_file_t file, os_offset_t size) ut_ad(!buf); ut_ad(!flush_buf); ut_ad(!writer); -#ifdef HAVE_INNODB_MMAP if (size) { # ifdef HAVE_PMEM @@ -362,7 +361,6 @@ bool log_t::attach(log_file_t file, os_offset_t size) } } log_mmap= false; -#endif buf= static_cast(ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME)); if (!buf) { @@ -399,9 +397,7 @@ bool log_t::attach(log_file_t file, os_offset_t size) writer_update(); memset_aligned<512>(checkpoint_buf, 0, write_size); -#ifdef HAVE_INNODB_MMAP func_exit: -#endif log_file_message(); return true; } @@ -476,25 +472,19 @@ ATTRIBUTE_COLD static void log_close_failed(dberr_t err) ib::fatal() << "closing ib_logfile0 failed: " << err; } -#ifdef HAVE_INNODB_MMAP void log_t::close_file(bool really_close) -#else -void log_t::close_file() -#endif { -#ifdef HAVE_INNODB_MMAP if (is_mmap()) { ut_ad(!checkpoint_buf); ut_ad(!flush_buf); if (buf) { - my_munmap(buf, file_size); + my_munmap(buf, size_t(file_size)); buf= nullptr; } } else -#endif { ut_ad(!buf == !flush_buf); ut_ad(!buf == !checkpoint_buf); @@ -511,9 +501,7 @@ void log_t::close_file() writer= nullptr; -#ifdef HAVE_INNODB_MMAP if (really_close) -#endif if (is_opened()) if (const dberr_t err= log.close()) log_close_failed(err); @@ -645,14 +633,10 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept void *ptr= nullptr, *ptr2= nullptr; success= os_file_set_size(path.c_str(), resize_log.m_file, size); if (!success); -#ifdef HAVE_INNODB_MMAP +#ifdef HAVE_PMEM else if (is_mmap()) { - ptr= ::log_mmap(resize_log.m_file, -#ifdef HAVE_PMEM - is_pmem, -#endif - size); + ptr= ::log_mmap(resize_log.m_file, is_pmem, size); if (ptr == MAP_FAILED) goto alloc_fail; @@ -660,6 +644,7 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept #endif else { + ut_ad(!is_mmap()); ptr= ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME); if (ptr) { @@ -702,9 +687,9 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept writer_update(); } - resize_lsn.store(start_lsn, std::memory_order_relaxed); status= success ? RESIZE_STARTED : RESIZE_FAILED; } + resize_lsn.store(start_lsn, std::memory_order_relaxed); } log_resize_release(); @@ -729,26 +714,33 @@ void log_t::resize_abort() noexcept if (resize_in_progress() > 1) { - if (!is_mmap()) +#ifdef HAVE_PMEM + const bool is_mmap{this->is_mmap()}; +#else + constexpr bool is_mmap{false}; +#endif + if (!is_mmap) { ut_free_dodump(resize_buf, buf_size); ut_free_dodump(resize_flush_buf, buf_size); resize_flush_buf= nullptr; } -#ifdef HAVE_INNODB_MMAP else { ut_ad(!resize_log.is_opened()); ut_ad(!resize_flush_buf); +#ifdef HAVE_PMEM if (resize_buf) my_munmap(resize_buf, resize_target); +#endif /* HAVE_PMEM */ } -#endif if (resize_log.is_opened()) resize_log.close(); resize_buf= nullptr; resize_target= 0; resize_lsn.store(0, std::memory_order_relaxed); + std::string path{get_log_file_path("ib_logfile101")}; + IF_WIN(DeleteFile(path.c_str()), unlink(path.c_str())); } writer_update(); @@ -909,13 +901,13 @@ static size_t log_pad(lsn_t lsn, size_t pad, byte *begin, byte *extra) #endif #ifdef HAVE_PMEM -void log_t::persist(lsn_t lsn, bool holding_latch) noexcept +void log_t::persist(lsn_t lsn) noexcept { ut_ad(!is_opened()); ut_ad(!write_lock.is_owner()); ut_ad(!flush_lock.is_owner()); #ifdef LOG_LATCH_DEBUG - ut_ad(holding_latch == latch_have_wr()); + ut_ad(latch_have_any()); #endif lsn_t old= flushed_to_disk_lsn.load(std::memory_order_relaxed); @@ -923,9 +915,6 @@ void log_t::persist(lsn_t lsn, bool holding_latch) noexcept if (old >= lsn) return; - const bool latching{!holding_latch && resize_in_progress()}; - if (UNIV_UNLIKELY(latching)) - latch.rd_lock(SRW_LOCK_CALL); const size_t start(calc_lsn_offset(old)); const size_t end(calc_lsn_offset(lsn)); @@ -949,9 +938,14 @@ void log_t::persist(lsn_t lsn, bool holding_latch) noexcept log_flush_notify(lsn); DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); } +} - if (UNIV_UNLIKELY(latching)) - latch.rd_unlock(); +ATTRIBUTE_NOINLINE +static void log_write_persist(lsn_t lsn) noexcept +{ + log_sys.latch.rd_lock(SRW_LOCK_CALL); + log_sys.persist(lsn); + log_sys.latch.rd_unlock(); } #endif @@ -1159,7 +1153,7 @@ void log_write_up_to(lsn_t lsn, bool durable, if (log_sys.is_mmap()) { if (durable) - log_sys.persist(lsn, false); + log_write_persist(lsn); else ut_ad(!callback); return; @@ -1241,7 +1235,6 @@ ATTRIBUTE_COLD void log_write_and_flush_prepare() group_commit_lock::ACQUIRED); } -#ifdef HAVE_INNODB_MMAP void log_t::clear_mmap() { if (!is_mmap() || @@ -1275,7 +1268,6 @@ void log_t::clear_mmap() } log_resize_release(); } -#endif /** Durably write the log up to log_sys.get_lsn(). */ ATTRIBUTE_COLD void log_write_and_flush() @@ -1283,7 +1275,7 @@ ATTRIBUTE_COLD void log_write_and_flush() ut_ad(!srv_read_only_mode); #ifdef HAVE_PMEM if (log_sys.is_mmap()) - log_sys.persist(log_sys.get_lsn(), true); + log_sys.persist(log_sys.get_lsn()); else #endif { diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index cb1ba9d855e..181a605d374 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2194,7 +2194,6 @@ struct recv_buf } }; -#ifdef HAVE_INNODB_MMAP /** Ring buffer wrapper for log_sys.buf[]; recv_sys.len == log_sys.file_size */ struct recv_ring : public recv_buf { @@ -2326,7 +2325,6 @@ struct recv_ring : public recv_buf return log_decrypt_buf(iv, tmp + s, b, static_cast(len)); } }; -#endif template void recv_sys_t::rewind(source &l, source &begin) noexcept @@ -2609,43 +2607,57 @@ restart: mach_write_to_4(iv + 8, space_id); mach_write_to_4(iv + 12, page_no); } - got_page_op= !(b & 0x80); - if (!got_page_op); - else if (storing == BACKUP && srv_operation == SRV_OPERATION_BACKUP) - { - if (page_no == 0 && (b & 0xf0) == INIT_PAGE && first_page_init) - first_page_init(space_id); - continue; - } - else if (storing == YES && file_checkpoint && - space_id != TRX_SYS_SPACE && !srv_is_undo_tablespace(space_id)) - { - recv_spaces_t::iterator i= recv_spaces.lower_bound(space_id); - if (i != recv_spaces.end() && i->first == space_id); - else if (lsn < file_checkpoint) - /* We have not seen all records between the checkpoint and - FILE_CHECKPOINT. There should be a FILE_DELETE for this - tablespace later. */ - recv_spaces.emplace_hint(i, space_id, file_name_t("", false)); - else - { - const page_id_t id(space_id, page_no); - if (!srv_force_recovery) - { - ib::error() << "Missing FILE_DELETE or FILE_MODIFY for " << id - << " at " << lsn - << "; set innodb_force_recovery=1 to ignore the record."; - goto corrupted; - } - ib::warn() << "Ignoring record for " << id << " at " << lsn; - continue; - } - } DBUG_PRINT("ib_log", ("scan " LSN_PF ": rec %x len %zu page %u:%u", lsn, b, l - recs + rlen, space_id, page_no)); + got_page_op= !(b & 0x80); if (got_page_op) { + if (storing == BACKUP) + { + if (page_no == 0 && (b & 0xf0) == INIT_PAGE && first_page_init) + first_page_init(space_id); + else if (rlen == 1 && undo_space_trunc) + { + mach_write_to_4(iv + 8, space_id); + mach_write_to_4(iv + 12, page_no); + byte eb[1/*type,length*/ + 5/*space_id*/ + 5/*page_no*/ + 1/*rlen*/]; + if (*l.copy_if_needed(iv, eb, recs, 1) == TRIM_PAGES) + undo_space_trunc(space_id); + } + continue; + } + if (storing == YES && UNIV_LIKELY(space_id != TRX_SYS_SPACE) && + !srv_is_undo_tablespace(space_id)) + { + ut_ad(file_checkpoint != 0); + recv_spaces_t::iterator i= recv_spaces.lower_bound(space_id); + if (i != recv_spaces.end() && i->first == space_id); + else if (lsn < file_checkpoint) + /* We have not seen all records between the checkpoint and + FILE_CHECKPOINT. There should be a FILE_DELETE for this + tablespace later. */ + recv_spaces.emplace_hint(i, space_id, file_name_t("", false)); + else + { + if (!srv_force_recovery) + { + sql_print_error("InnoDB: Missing FILE_DELETE or FILE_MODIFY for " + "[page id: space=" UINT32PF + ", page number=" UINT32PF "]" + " at " LSN_PF + "; set innodb_force_recovery=1 to" + " ignore the record.", + space_id, page_no, lsn); + goto corrupted; + } + sql_print_warning("InnoDB: Ignoring record for " + "[page id: space=" UINT32PF + ", page number=" UINT32PF "] at " LSN_PF, + space_id, page_no, lsn); + continue; + } + } same_page: if (!rlen); else if (UNIV_UNLIKELY(l - recs + rlen > srv_page_size)) @@ -2659,13 +2671,11 @@ restart: case FREE_PAGE: ut_ad(freed.emplace(id).second); /* the next record must not be same_page */ - if (storing != BACKUP) last_offset= 1; + last_offset= 1; goto free_or_init_page; case INIT_PAGE: - if (storing != BACKUP) last_offset= FIL_PAGE_TYPE; + last_offset= FIL_PAGE_TYPE; free_or_init_page: - if (storing == BACKUP) - continue; if (UNIV_UNLIKELY(rlen != 0)) goto record_corrupted; store_freed_or_init_rec(id, (b & 0x70) == FREE_PAGE); @@ -2710,17 +2720,6 @@ restart: continue; if (UNIV_UNLIKELY(!rlen)) goto record_corrupted; - if (storing == BACKUP) - { - if (rlen == 1 && undo_space_trunc) - { - cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); - if (*cl == TRIM_PAGES) - undo_space_trunc(space_id); - } - continue; - } - cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); if (rlen == 1 && *cl == TRIM_PAGES) { @@ -2768,8 +2767,6 @@ restart: case WRITE: case MEMMOVE: case MEMSET: - if (storing == BACKUP) - continue; if (storing == NO && UNIV_LIKELY(page_no != 0)) /* fil_space_set_recv_size_and_flags() is mandatory for storing==NO. It is only applicable to page_no == 0. Other than that, we can just @@ -3068,7 +3065,6 @@ template recv_sys_t::parse_mtr_result recv_sys_t::parse_mtr(bool) noexcept; -#ifdef HAVE_INNODB_MMAP template recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool if_exists) noexcept { @@ -3089,7 +3085,6 @@ recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool if_exists) noexcept template recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool) noexcept; -#endif /** Apply the hashed log records to the page, if the page lsn is less than the lsn of a log record. @@ -3407,7 +3402,7 @@ func_exit: return success; } -void IORequest::fake_read_complete(os_offset_t offset) const +void IORequest::fake_read_complete(os_offset_t offset) const noexcept { ut_ad(node); ut_ad(is_read()); @@ -3447,7 +3442,7 @@ void IORequest::fake_read_complete(os_offset_t offset) const } /** @return whether a page has been freed */ -inline bool fil_space_t::is_freed(uint32_t page) +inline bool fil_space_t::is_freed(uint32_t page) noexcept { std::lock_guard freed_lock(freed_range_mutex); return freed_ranges.contains(page); @@ -3781,7 +3776,7 @@ recv_sys_t::recover(const page_id_t page_id, mtr_t *mtr, dberr_t *err) return block; } -inline fil_space_t *fil_system_t::find(const char *path) const +inline fil_space_t *fil_system_t::find(const char *path) const noexcept { mysql_mutex_assert_owner(&mutex); for (fil_space_t &space : fil_system.space_list) @@ -3791,7 +3786,7 @@ inline fil_space_t *fil_system_t::find(const char *path) const } /** Thread-safe function which sorts flush_list by oldest_modification */ -static void log_sort_flush_list() +static void log_sort_flush_list() noexcept { /* Ensure that oldest_modification() cannot change during std::sort() */ { diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index c48e0288a7d..3f569513d61 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -547,7 +547,7 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end) } /** Set create_lsn. */ -inline void fil_space_t::set_create_lsn(lsn_t lsn) +inline void fil_space_t::set_create_lsn(lsn_t lsn) noexcept { /* Concurrent log_checkpoint_low() must be impossible. */ ut_ad(latch.have_wr()); @@ -1214,7 +1214,7 @@ inline void log_t::resize_write(lsn_t lsn, const byte *end, size_t len, end-= len; size_t s; -#ifdef HAVE_INNODB_MMAP +#ifdef HAVE_PMEM if (!resize_flush_buf) { ut_ad(is_mmap()); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 986f20080b3..c77b9df843b 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -186,7 +186,7 @@ os_file_handle_error_cond_exit( const char* name, const char* operation, bool should_abort, - bool on_error_silent); + bool on_error_silent) noexcept; /** Does error handling when a file operation fails. @param operation name of operation that failed */ @@ -322,7 +322,7 @@ private: @param fd file descriptor @param name file name @return 0 on success */ -int os_file_lock(int fd, const char *name) +int os_file_lock(int fd, const char *name) noexcept { struct flock lk; @@ -351,13 +351,7 @@ int os_file_lock(int fd, const char *name) } #endif /* !_WIN32 */ - -/** Create a temporary file. This function is like tmpfile(3), but -the temporary file is created in the in the mysql server configuration -parameter (--tmpdir). -@return temporary file handle, or NULL on error */ -FILE* -os_file_create_tmpfile() +FILE *os_file_create_tmpfile() noexcept { FILE* file = NULL; File fd = mysql_tmpfile("ib"); @@ -390,7 +384,7 @@ void os_file_read_string( FILE* file, char* str, - ulint size) + ulint size) noexcept { if (size != 0) { rewind(file); @@ -401,21 +395,7 @@ os_file_read_string( } } -/** This function reduces a null-terminated full remote path name into -the path that is sent by MySQL for DATA DIRECTORY clause. It replaces -the 'databasename/tablename.ibd' found at the end of the path with just -'tablename'. - -Since the result is always smaller than the path sent in, no new memory -is allocated. The caller should allocate memory for the path sent in. -This function manipulates that path in place. - -If the path format is not as expected, just return. The result is used -to inform a SHOW CREATE TABLE command. -@param[in,out] data_dir_path Full path/data_dir_path */ -void -os_file_make_data_dir_path( - char* data_dir_path) +void os_file_make_data_dir_path(char *data_dir_path) noexcept { /* Replace the period before the extension with a null byte. */ char* ptr = strrchr(data_dir_path, '.'); @@ -464,11 +444,7 @@ to the last directory separator that the caller has fixed. @param[in] path path name @param[in] path last directory separator in the path @return true if this path is a drive root, false if not */ -UNIV_INLINE -bool -os_file_is_root( - const char* path, - const char* last_slash) +static bool os_file_is_root(const char *path, const char *last_slash) noexcept { return( #ifdef _WIN32 @@ -563,7 +539,7 @@ os_file_get_parent_dir( void test_os_file_get_parent_dir( const char* child_dir, - const char* expected_dir) + const char* expected_dir) noexcept { char* child = mem_strdup(child_dir); char* expected = expected_dir == NULL ? NULL @@ -586,7 +562,7 @@ test_os_file_get_parent_dir( /* Test the function os_file_get_parent_dir. */ void -unit_test_os_file_get_parent_dir() +unit_test_os_file_get_parent_dir() noexcept { test_os_file_get_parent_dir("/usr/lib/a", "/usr/lib"); test_os_file_get_parent_dir("/usr/", NULL); @@ -615,12 +591,7 @@ unit_test_os_file_get_parent_dir() #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */ -/** Creates all missing subdirectories along the given path. -@param[in] path Path name -@return DB_SUCCESS if OK, otherwise error code. */ -dberr_t -os_file_create_subdirs_if_needed( - const char* path) +dberr_t os_file_create_subdirs_if_needed(const char *path) noexcept { if (srv_read_only_mode) { @@ -764,6 +735,7 @@ the OS error number + 100 is returned. to the log @return error number, or OS error number + 100 */ ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) + noexcept { int err = errno; @@ -831,7 +803,7 @@ Returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error. @param[in] file open file handle @return 0 if success, -1 otherwise */ -static int os_file_sync_posix(os_file_t file) +static int os_file_sync_posix(os_file_t file) noexcept { #if !defined(HAVE_FDATASYNC) || HAVE_DECL_FDATASYNC == 0 auto func= fsync; @@ -885,7 +857,7 @@ bool os_file_status_posix( const char* path, bool* exists, - os_file_type_t* type) + os_file_type_t* type) noexcept { struct stat statinfo; @@ -921,14 +893,7 @@ os_file_status_posix( return(true); } -/** NOTE! Use the corresponding macro os_file_flush(), not directly this -function! -Flushes the write buffers of a given file to the disk. -@param[in] file handle to a file -@return true if success */ -bool -os_file_flush_func( - os_file_t file) +bool os_file_flush_func(os_file_t file) noexcept { if (UNIV_UNLIKELY(my_disable_sync)) return true; @@ -976,7 +941,7 @@ os_file_create_simple_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { pfs_os_file_t file; @@ -1038,20 +1003,8 @@ os_file_create_simple_func( return(file); } -/** This function attempts to create a directory named pathname. The new -directory gets default permissions. On Unix the permissions are -(0770 & ~umask). If the directory exists already, nothing is done and -the call succeeds, unless the fail_if_exists arguments is true. -If another error occurs, such as a permission error, this does not crash, -but reports the error and returns false. -@param[in] pathname directory name as null-terminated string -@param[in] fail_if_exists if true, pre-existing directory is treated as - an error. -@return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists) +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept { int rcode; @@ -1134,7 +1087,7 @@ os_file_create_func( os_file_create_t create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept { *success = false; @@ -1307,7 +1260,7 @@ os_file_create_simple_no_error_handling_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; int create_flag = O_RDONLY | O_CLOEXEC; @@ -1456,13 +1409,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept return lseek(file, 0, SEEK_END); } -/** Gets a file size. -@param[in] filename Full path to the filename to check -@return file size if OK, else set m_total_size to ~0 and m_alloc_size to - errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept { struct stat s; os_file_size_t file_size; @@ -1583,11 +1530,7 @@ os_file_truncate_posix( return(res == 0); } -/** Truncates a file at its current position. -@return true if success */ -bool -os_file_set_eof( - FILE* file) /*!< in: file to be truncated */ +bool os_file_set_eof(FILE *file) noexcept { return(!ftruncate(fileno(file), ftell(file))); } @@ -1789,7 +1732,7 @@ function! Flushes the write buffers of a given file to the disk. @param[in] file handle to a file @return true if success */ -bool os_file_flush_func(os_file_t file) +bool os_file_flush_func(os_file_t file) noexcept { if (UNIV_UNLIKELY(my_disable_sync)) return true; @@ -1839,7 +1782,7 @@ printed of all errors to the log @return error number, or OS error number + OS_FILE_ERROR_MAX */ ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) - + noexcept { ulint err = (ulint) GetLastError(); @@ -1937,7 +1880,7 @@ os_file_create_simple_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; @@ -1996,20 +1939,8 @@ os_file_create_simple_func( return(file); } -/** This function attempts to create a directory named pathname. The new -directory gets default permissions. On Unix the permissions are -(0770 & ~umask). If the directory exists already, nothing is done and -the call succeeds, unless the fail_if_exists arguments is true. -If another error occurs, such as a permission error, this does not crash, -but reports the error and returns false. -@param[in] pathname directory name as null-terminated string -@param[in] fail_if_exists if true, pre-existing directory is treated - as an error. -@return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists) +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept { BOOL rcode; @@ -2057,7 +1988,7 @@ os_file_create_func( os_file_create_t create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; @@ -2175,7 +2106,7 @@ os_file_create_simple_no_error_handling_func( os_file_create_t create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; @@ -2392,13 +2323,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept return ((os_offset_t) -1); } -/** Gets a file size. -@param[in] filename Full path to the filename to check -@return file size if OK, else set m_total_size to ~0 and m_alloc_size to - errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept { struct __stat64 s; os_file_size_t file_size; @@ -2516,7 +2441,7 @@ Sets a sparse flag on Windows file. @return true on success, false on error */ #include -bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) +bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) noexcept { if (!is_sparse && !IsWindows8OrGreater()) { /* Cannot unset sparse flag on older Windows. @@ -2531,11 +2456,8 @@ bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) FSCTL_SET_SPARSE, &sparse_buffer, sizeof(sparse_buffer), 0, 0,&temp); } -bool -os_file_set_size( - const char* pathname, - os_file_t file, - os_offset_t size) +bool os_file_set_size(const char *pathname, os_file_t file, os_offset_t size) + noexcept { LARGE_INTEGER length; @@ -2556,12 +2478,7 @@ os_file_set_size( return(success); } -/** Truncates a file at its current position. -@param[in] file Handle to be truncated -@return true if success */ -bool -os_file_set_eof( - FILE* file) +bool os_file_set_eof(FILE *file) noexcept { HANDLE h = (HANDLE) _get_osfhandle(fileno(file)); @@ -2778,7 +2695,7 @@ os_file_read_func( void* buf, os_offset_t offset, ulint n, - ulint* o) + ulint* o) noexcept { ut_ad(!type.node || type.node->handle == file); ut_ad(n); @@ -2816,7 +2733,7 @@ os_file_handle_error_cond_exit( const char* name, const char* operation, bool should_abort, - bool on_error_silent) + bool on_error_silent) noexcept { ulint err; @@ -2901,7 +2818,7 @@ os_file_handle_error_cond_exit( /** Check if the file system supports sparse files. @param fh file handle @return true if the file system supports sparse files */ -static bool os_is_sparse_file_supported(os_file_t fh) +static bool os_is_sparse_file_supported(os_file_t fh) noexcept { #ifdef _WIN32 FILE_ATTRIBUTE_TAG_INFO info; @@ -2930,7 +2847,7 @@ os_file_truncate( const char* pathname, os_file_t file, os_offset_t size, - bool allow_shrink) + bool allow_shrink) noexcept { if (!allow_shrink) { /* Do nothing if the size preserved is larger than or @@ -2958,7 +2875,7 @@ bool os_file_status( const char* path, bool* exists, - os_file_type_t* type) + os_file_type_t* type) noexcept { #ifdef _WIN32 return(os_file_status_win32(path, exists, type)); @@ -2976,7 +2893,7 @@ dberr_t os_file_punch_hole( os_file_t fh, os_offset_t off, - os_offset_t len) + os_offset_t len) noexcept { #ifdef _WIN32 return os_file_punch_hole_win32(fh, off, len); @@ -2989,7 +2906,7 @@ os_file_punch_hole( @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ -dberr_t IORequest::punch_hole(os_offset_t off, ulint len) const +dberr_t IORequest::punch_hole(os_offset_t off, ulint len) const noexcept { ulint trim_len = bpage ? bpage->physical_size() - len : 0; @@ -3061,7 +2978,7 @@ os_file_get_status( const char* path, os_file_stat_t* stat_info, bool check_rw_perm, - bool read_only) + bool read_only) noexcept { dberr_t ret; @@ -3254,7 +3171,7 @@ static bool is_linux_native_aio_supported() } #endif -int os_aio_init() +int os_aio_init() noexcept { int max_write_events= int(srv_n_write_io_threads * OS_AIO_N_PENDING_IOS_PER_THREAD); @@ -3319,7 +3236,7 @@ more concurrent threads via thread_group setting. executing write callbacks @return 0 for success, !=0 for error. */ -int os_aio_resize(ulint n_reader_threads, ulint n_writer_threads) +int os_aio_resize(ulint n_reader_threads, ulint n_writer_threads) noexcept { /* Lock the slots, and wait until all current IOs finish.*/ auto &lk_read= read_slots->mutex(), &lk_write= write_slots->mutex(); @@ -3358,7 +3275,7 @@ int os_aio_resize(ulint n_reader_threads, ulint n_writer_threads) return ret; } -void os_aio_free() +void os_aio_free() noexcept { delete read_slots; delete write_slots; @@ -3368,7 +3285,7 @@ void os_aio_free() } /** Wait until there are no pending asynchronous writes. */ -static void os_aio_wait_until_no_pending_writes_low(bool declare) +static void os_aio_wait_until_no_pending_writes_low(bool declare) noexcept { const bool notify_wait= declare && write_slots->pending_io_count(); @@ -3383,14 +3300,14 @@ static void os_aio_wait_until_no_pending_writes_low(bool declare) /** Wait until there are no pending asynchronous writes. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_writes(bool declare) +void os_aio_wait_until_no_pending_writes(bool declare) noexcept { os_aio_wait_until_no_pending_writes_low(declare); buf_dblwr.wait_flush_buffered_writes(); } /** @return number of pending reads */ -size_t os_aio_pending_reads() +size_t os_aio_pending_reads() noexcept { mysql_mutex_lock(&read_slots->mutex()); size_t pending= read_slots->pending_io_count(); @@ -3399,13 +3316,13 @@ size_t os_aio_pending_reads() } /** @return approximate number of pending reads */ -size_t os_aio_pending_reads_approx() +size_t os_aio_pending_reads_approx() noexcept { return read_slots->pending_io_count(); } /** @return number of pending writes */ -size_t os_aio_pending_writes() +size_t os_aio_pending_writes() noexcept { mysql_mutex_lock(&write_slots->mutex()); size_t pending= write_slots->pending_io_count(); @@ -3415,7 +3332,7 @@ size_t os_aio_pending_writes() /** Wait until all pending asynchronous reads have completed. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_reads(bool declare) +void os_aio_wait_until_no_pending_reads(bool declare) noexcept { const bool notify_wait= declare && read_slots->pending_io_count(); @@ -3431,7 +3348,7 @@ void os_aio_wait_until_no_pending_reads(bool declare) /** Submit a fake read request during crash recovery. @param type fake read request @param offset additional context */ -void os_fake_read(const IORequest &type, os_offset_t offset) +void os_fake_read(const IORequest &type, os_offset_t offset) noexcept { tpool::aiocb *cb= read_slots->acquire(); @@ -3458,6 +3375,7 @@ void os_fake_read(const IORequest &type, os_offset_t offset) @retval DB_SUCCESS if request was queued successfully @retval DB_IO_ERROR on I/O error */ dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n) + noexcept { ut_ad(n > 0); ut_ad(!(n & 511)); /* payload of page_compressed tables */ @@ -3535,10 +3453,7 @@ func_exit: goto func_exit; } -/** Prints info of the aio arrays. -@param[in,out] file file where to print */ -void -os_aio_print(FILE* file) +void os_aio_print(FILE *file) noexcept { time_t current_time; double time_elapsed; @@ -3587,9 +3502,7 @@ os_aio_print(FILE* file) os_last_printout = current_time; } -/** Refreshes the statistics used to print per-second averages. */ -void -os_aio_refresh_stats() +void os_aio_refresh_stats() noexcept { os_n_fsyncs_old = os_n_fsyncs; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 7068888c716..45ea8a4110f 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -722,7 +722,7 @@ row_ins_foreign_trx_print( ut_print_timestamp(dict_foreign_err_file); fputs(" Transaction:\n", dict_foreign_err_file); - trx_print_low(dict_foreign_err_file, trx, 600, + trx_print_low(dict_foreign_err_file, trx, n_rec_locks, n_trx_locks, heap_size); mysql_mutex_assert_owner(&dict_foreign_err_mutex); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 258598f45be..dba11c37ef0 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1969,15 +1969,11 @@ skip_monitors: if (srv_print_verbose_log) { sql_print_information("InnoDB: " "log sequence number " LSN_PF -#ifdef HAVE_INNODB_MMAP "%s" -#endif "; transaction id " TRX_ID_FMT, recv_sys.lsn, -#ifdef HAVE_INNODB_MMAP log_sys.is_mmap() ? " (memory-mapped)" : "", -#endif trx_sys.get_max_trx_id()); } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 80cba1789ae..c0e7431397a 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -63,7 +63,7 @@ const byte timestamp_max_bytes[7] = { }; -static const ulint MAX_DETAILED_ERROR_LEN = 256; +static const ulint MAX_DETAILED_ERROR_LEN = 512; /*************************************************************//** Set detailed error message for the transaction. */ @@ -1764,9 +1764,6 @@ trx_print_low( /*!< in: output stream */ const trx_t* trx, /*!< in: transaction */ - ulint max_query_len, - /*!< in: max query length to print, - or 0 to use the default max length */ ulint n_rec_locks, /*!< in: trx->lock.n_rec_locks */ ulint n_trx_locks, @@ -1856,7 +1853,7 @@ state_ok: } if (thd) { - innobase_mysql_print_thd(f, thd, uint(max_query_len)); + innobase_mysql_print_thd(f, thd); } } @@ -1868,13 +1865,11 @@ void trx_print_latched( /*==============*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len) /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx) /*!< in: transaction */ { lock_sys.assert_locked(); - trx_print_low(f, trx, max_query_len, + trx_print_low(f, trx, trx->lock.n_rec_locks, UT_LIST_GET_LEN(trx->lock.trx_locks), mem_heap_get_size(trx->lock.lock_heap)); @@ -1888,9 +1883,7 @@ void trx_print( /*======*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len) /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx) /*!< in: transaction */ { ulint n_rec_locks, n_trx_locks, heap_size; { @@ -1900,7 +1893,7 @@ trx_print( heap_size= mem_heap_get_size(trx->lock.lock_heap); } - trx_print_low(f, trx, max_query_len, n_rec_locks, n_trx_locks, heap_size); + trx_print_low(f, trx, n_rec_locks, n_trx_locks, heap_size); } /** Prepare a transaction. diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 535f0a2e460..1344aaee17a 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -760,28 +760,34 @@ static bool allow_drop_table_privilege() { PFS_readonly_acl pfs_readonly_acl; ACL_internal_access_result -PFS_readonly_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_readonly_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_readonly_world_acl pfs_readonly_world_acl; ACL_internal_access_result -PFS_readonly_world_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_readonly_world_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { - ACL_internal_access_result res= PFS_readonly_acl::check(want_access, save_priv); + ACL_internal_access_result res= + PFS_readonly_acl::check(want_access, save_priv, any_combination_will_do); if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT) { - if (want_access == SELECT_ACL) + if (any_combination_will_do ? + ((want_access & SELECT_ACL) != NO_ACL) : (want_access == SELECT_ACL)) res= ACL_INTERNAL_ACCESS_GRANTED; } return res; @@ -790,9 +796,11 @@ PFS_readonly_world_acl::check(privilege_t want_access, privilege_t *save_priv) c PFS_readonly_processlist_acl pfs_readonly_processlist_acl; ACL_internal_access_result PFS_readonly_processlist_acl::check( - privilege_t want_access, privilege_t *save_priv) const { + privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const +{ ACL_internal_access_result res = - PFS_readonly_acl::check(want_access, save_priv); + PFS_readonly_acl::check(want_access, save_priv, any_combination_will_do); if ((res == ACL_INTERNAL_ACCESS_CHECK_GRANT) && (want_access == SELECT_ACL)) { THD *thd = current_thd; @@ -818,34 +826,41 @@ ACL_internal_access_result PFS_readonly_processlist_acl::check( PFS_truncatable_acl pfs_truncatable_acl; ACL_internal_access_result -PFS_truncatable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_truncatable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_truncatable_world_acl pfs_truncatable_world_acl; ACL_internal_access_result -PFS_truncatable_world_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_truncatable_world_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { - ACL_internal_access_result res= PFS_truncatable_acl::check(want_access, save_priv); + ACL_internal_access_result res= + PFS_truncatable_acl::check(want_access, save_priv, any_combination_will_do); if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT) { - if (want_access == DROP_ACL) + if (any_combination_will_do ? + ((want_access & SELECT_ACL) != NO_ACL) : (want_access == SELECT_ACL)) + res= ACL_INTERNAL_ACCESS_GRANTED; + else if (any_combination_will_do ? + ((want_access & DROP_ACL) != NO_ACL) : (want_access == DROP_ACL)) { if (allow_drop_table_privilege()) res= ACL_INTERNAL_ACCESS_GRANTED; } - else if (want_access == SELECT_ACL) - res= ACL_INTERNAL_ACCESS_GRANTED; } return res; } @@ -854,44 +869,48 @@ PFS_truncatable_world_acl::check(privilege_t want_access, privilege_t *save_priv PFS_updatable_acl pfs_updatable_acl; ACL_internal_access_result -PFS_updatable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_updatable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_editable_acl pfs_editable_acl; ACL_internal_access_result -PFS_editable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_editable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_unknown_acl pfs_unknown_acl; ACL_internal_access_result -PFS_unknown_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_unknown_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= CREATE_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - /* There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL on performance_schema.*) tables that do not exist anyway. @@ -902,7 +921,12 @@ PFS_unknown_acl::check(privilege_t want_access, privilege_t *save_priv) const The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL), for ease of use: error messages will be less surprising. */ - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } /** diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h index 50d40e9bf24..907097d384d 100644 --- a/storage/perfschema/pfs_engine_table.h +++ b/storage/perfschema/pfs_engine_table.h @@ -340,8 +340,8 @@ public: ~PFS_readonly_acl() = default; - ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_readonly_acl. */ @@ -359,7 +359,7 @@ public: ~PFS_truncatable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_truncatable_acl. */ @@ -377,7 +377,7 @@ public: ~PFS_updatable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_updatable_acl. */ @@ -395,7 +395,7 @@ public: ~PFS_editable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_editable_acl. */ @@ -412,7 +412,7 @@ public: ~PFS_unknown_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_unknown_acl. */ @@ -430,7 +430,8 @@ public: ~PFS_readonly_world_acl() {} - ACL_internal_access_result check(privilege_t want_access, privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; @@ -449,7 +450,8 @@ public: ~PFS_truncatable_world_acl() {} - ACL_internal_access_result check(privilege_t want_access, privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; @@ -469,7 +471,7 @@ class PFS_readonly_processlist_acl : public PFS_readonly_acl { {} ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_readonly_processlist_acl */ diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result index 3010e220421..56d1ce210d9 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result @@ -1543,12 +1543,12 @@ d53_10 double(53,10) NO NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -1571,7 +1571,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -1588,6 +1587,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -1603,7 +1603,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1626,6 +1625,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -1654,12 +1654,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -1688,7 +1688,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1716,6 +1715,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -1763,7 +1763,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1796,6 +1795,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result index 14170e2a1b1..a7c27140e76 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result @@ -1330,12 +1330,12 @@ d53_10 double(53,10) YES NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -1358,7 +1358,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -1375,6 +1374,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -1390,7 +1390,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1413,6 +1412,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -1441,12 +1441,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -1475,7 +1475,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1503,6 +1502,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -1550,7 +1550,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1583,6 +1582,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result index 0a8f49ebf36..d49ed255184 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result @@ -206,12 +206,12 @@ d53_10 double(53,10) unsigned YES NULL pk double unsigned NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -234,7 +234,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -251,6 +250,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -277,7 +277,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -300,6 +299,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f0 0 f0 0 @@ -328,12 +328,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -362,7 +362,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -390,6 +389,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 0 @@ -437,7 +437,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -470,6 +469,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/misc.result b/storage/rocksdb/mysql-test/rocksdb/r/misc.result index f8734da6e6b..14afc71665a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/misc.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/misc.result @@ -28,10 +28,6 @@ DROP EVENT ev1; SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME; TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' -Warnings: column_stats column_name NULL NULL column_stats db_name NULL NULL column_stats table_name NULL NULL @@ -93,3 +89,7 @@ time_zone_transition Time_zone_id NULL NULL time_zone_transition Transition_time NULL NULL time_zone_transition_type Time_zone_id NULL NULL time_zone_transition_type Transition_type_id NULL NULL +Warnings: +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_float.result b/storage/rocksdb/mysql-test/rocksdb/r/type_float.result index 0cf5c5e0496..4a99710a30c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_float.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_float.result @@ -27,12 +27,12 @@ d53_10 double(53,10) YES NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -55,7 +55,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -72,6 +71,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -87,7 +87,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -110,6 +109,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -138,12 +138,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -172,7 +172,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -200,6 +199,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -247,7 +247,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -280,6 +279,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.pm b/storage/rocksdb/mysql-test/rocksdb/suite.pm index b4feb20a451..40e424a75f9 100644 --- a/storage/rocksdb/mysql-test/rocksdb/suite.pm +++ b/storage/rocksdb/mysql-test/rocksdb/suite.pm @@ -18,6 +18,7 @@ my $sst_dump= "$::bindir/storage/rocksdb$::multiconfig/sst_dump", "$::path_client_bindir/sst_dump"); return "RocksDB is not compiled, no sst_dump" unless $sst_dump; +return "doesn't work in embedded" if $::opt_embedded_server; $ENV{MARIAROCKS_SST_DUMP}="$sst_dump"; ## Temporarily disable testing under valgrind, due to MDEV-12439 diff --git a/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc b/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc index 27adda9ba35..601d61feb1f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc +++ b/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc @@ -91,6 +91,7 @@ INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( --sorted_result --query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1 +--enable_prepare_warnings INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( 999999999999999999999999999999999999999, 999999999999999999999999999999999999999.9999999999999999, @@ -104,6 +105,7 @@ INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( 19999999999999999999999999999999999999999999.9999999999, 6 ); +--disable_prepare_warnings --sorted_result --query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1