From cd156e2c3e8576ee42ff470235d3af005daee274 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Nov 2019 18:30:48 +0100 Subject: MDEV-20971 ASAN heap-use-after-free in list_delete / heap_close Don't save/restore HP_INFO as it could be changed by a concurrent thread. different parts of HP_INFO are protected by different mutexes and the mutex that protect most of the HP_INFO does not protect its open_list data. As a bonus, make heap_check_heap() to take const HP_INFO* and not make any changes there whatsoever. --- include/heap.h | 2 +- storage/heap/_check.c | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/heap.h b/include/heap.h index 63d961b577a..014ec042671 100644 --- a/include/heap.h +++ b/include/heap.h @@ -245,7 +245,7 @@ int hp_panic(enum ha_panic_function flag); int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag); extern uchar * heap_find(HP_INFO *info,int inx,const uchar *key); -extern int heap_check_heap(HP_INFO *info, my_bool print_status); +extern int heap_check_heap(const HP_INFO *info, my_bool print_status); extern uchar *heap_position(HP_INFO *info); /* The following is for programs that uses the old HEAP interface where diff --git a/storage/heap/_check.c b/storage/heap/_check.c index 33aa532bd6b..fc5716782e5 100644 --- a/storage/heap/_check.c +++ b/storage/heap/_check.c @@ -18,10 +18,8 @@ #include "heapdef.h" -static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, - ulong blength, my_bool print_status); -static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, - my_bool print_status); +static int check_one_key(HP_KEYDEF *, uint, ulong, ulong, my_bool); +static int check_one_rb_key(const HP_INFO *, uint, ulong, my_bool); /* @@ -40,13 +38,13 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, 1 error */ -int heap_check_heap(HP_INFO *info, my_bool print_status) +int heap_check_heap(const HP_INFO *info, my_bool print_status) { int error; uint key; ulong records=0, deleted=0, pos, next_block; HP_SHARE *share=info->s; - HP_INFO save_info= *info; /* Needed because scan_init */ + uchar *current_ptr= info->current_ptr; DBUG_ENTER("heap_check_heap"); for (error=key= 0 ; key < share->keys ; key++) @@ -65,7 +63,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status) { if (pos < next_block) { - info->current_ptr+= share->block.recbuffer; + current_ptr+= share->block.recbuffer; } else { @@ -77,9 +75,9 @@ int heap_check_heap(HP_INFO *info, my_bool print_status) break; /* End of file */ } } - hp_find_record(info,pos); + current_ptr= hp_find_block(&share->block, pos); - if (!info->current_ptr[share->visible]) + if (!current_ptr[share->visible]) deleted++; else records++; @@ -92,7 +90,6 @@ int heap_check_heap(HP_INFO *info, my_bool print_status) deleted, (ulong) share->deleted)); error= 1; } - *info= save_info; DBUG_RETURN(error); } @@ -165,7 +162,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, return error; } -static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, +static int check_one_rb_key(const HP_INFO *info, uint keynr, ulong records, my_bool print_status) { HP_KEYDEF *keydef= info->s->keydef + keynr; @@ -174,9 +171,11 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, uchar *key, *recpos; uint key_length; uint not_used[2]; + TREE_ELEMENT **last_pos; + TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1]; - if ((key= tree_search_edge(&keydef->rb_tree, info->parents, - &info->last_pos, offsetof(TREE_ELEMENT, left)))) + if ((key= tree_search_edge(&keydef->rb_tree, parents, + &last_pos, offsetof(TREE_ELEMENT, left)))) { do { @@ -191,7 +190,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, } else found++; - key= tree_search_next(&keydef->rb_tree, &info->last_pos, + key= tree_search_next(&keydef->rb_tree, &last_pos, offsetof(TREE_ELEMENT, left), offsetof(TREE_ELEMENT, right)); } while (key); -- cgit v1.2.1 From e23cb3835e4679a51af5fe00ce411148fba72785 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Tue, 5 Nov 2019 09:53:45 -0500 Subject: bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index df06ca3b38a..127385d04a0 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=66 +MYSQL_VERSION_PATCH=67 MYSQL_VERSION_EXTRA= -- cgit v1.2.1 From d8ace23d260033fc6588599e0a03e2832d20dae9 Mon Sep 17 00:00:00 2001 From: Hashir Sarwar Date: Wed, 23 Oct 2019 17:40:24 +0500 Subject: Fixed some typos in mysql.cc Closes #1403 --- client/mysql.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 50d45696a5c..c872968b78d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3177,7 +3177,7 @@ static int com_go(String *buffer,char *line __attribute__((unused))) { char buff[200]; /* about 110 chars used so far */ - char time_buff[52+3+1]; /* time max + space&parens + NUL */ + char time_buff[52+3+1]; /* time max + space & parens + NUL */ MYSQL_RES *result; ulong timer, warnings= 0; uint error= 0; @@ -3196,7 +3196,7 @@ com_go(String *buffer,char *line __attribute__((unused))) if (buffer->is_empty()) { - if (status.batch) // Ignore empty quries + if (status.batch) // Ignore empty queries. return 0; return put_info("No query specified\n",INFO_ERROR); @@ -3261,7 +3261,7 @@ com_go(String *buffer,char *line __attribute__((unused))) else time_buff[0]= '\0'; - /* Every branch must truncate buff . */ + /* Every branch must truncate buff. */ if (result) { if (!mysql_num_rows(result) && ! quick && !column_types_flag) -- cgit v1.2.1 From 866e5c250e27e32cd295d84988ffdf7ae64503b2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 11 Feb 2018 14:42:11 +1100 Subject: MDEV-15503: mtr fix --strace $glob_mysql_test_dir was the wrong directory for strace output as it was for in-tree builds only so failed for: * out of tree builds * --parallel; and * --mem strace output wasn't saved. strace-option never replaced existing arguments (so ammended documentation). strace-client didn't accept an argument as described. Replaced specification of client with this with 'stracer' to be consistent with --debugger option. For consistency with debugger options, --client-strace was added to execute the strace on the mysqltest. Example: Running one test $ ./mtr --strace --client-strace funcs_1.is_table_constraints Logging: ./mtr --strace --client-strace funcs_1.is_table_constraints vardir: /home/anel/mariadb/5.5/mysql-test/var Checking leftover processes... Removing old var directory... - WARNING: Using the 'mysql-test/var' symlink Creating var directory '/home/anel/mariadb/5.5/mysql-test/var'... Checking supported features... MariaDB Version 5.5.67-MariaDB-debug Installing system database... - SSL connections supported - binaries are debug compiled Collecting tests... ============================================================================== TEST RESULT TIME (ms) or COMMENT -------------------------------------------------------------------------- worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019 funcs_1.is_table_constraints [ pass ] 1270 -------------------------------------------------------------------------- The servers were restarted 0 times Spent 1.270 of 3 seconds executing testcases Completed: All 1 tests were successful $ find -L . -name \*strace -ls 653 56 -rw-r--r-- 1 anel anel 57147 Nov 29 15:08 ./var/log/mysqltest.strace 646 1768 -rw-r--r-- 1 anel anel 1809855 Nov 29 15:08 ./var/log/mysqld.1.strace Example: Running test in parallel $ mysql-test/mtr --strace --client-strace --mem --parallel=3 main.select Logging: /home/dan/software_projects/mariadb-server/mysql-test/mysql-test-run.pl --strace --client-strace --mem --parallel=3 main.select vardir: /home/dan/software_projects/build-mariadb-10.3/mysql-test/var Checking leftover processes... Removing old var directory... Creating var directory '/home/dan/software_projects/build-mariadb-10.3/mysql-test/var'... - symlinking 'var' to '/dev/shm/var_auto_0v2E' Checking supported features... MariaDB Version 5.5.67-MariaDB - SSL connections supported Collecting tests... Installing system database... ============================================================================== TEST WORKER RESULT TIME (ms) or COMMENT -------------------------------------------------------------------------- worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019 worker[3] - 'localhost:16040' was not free worker[2] Using MTR_BUILD_THREAD 301, with reserved ports 16020..16039 worker[3] Using MTR_BUILD_THREAD 303, with reserved ports 16060..16079 main.select w1 [ pass ] 7310 -------------------------------------------------------------------------- The servers were restarted 0 times Spent 7.310 of 11 seconds executing testcases Completed: All 1 tests were successful. $ find mysql-test/var/ -name \*strace -ls 5213766 1212 -rw-r--r-- 1 dan dan 1237817 May 20 16:47 mysql-test/var/1/log/mysqltest.strace 5214733 13016 -rw-r--r-- 1 dan dan 13328335 May 20 16:47 mysql-test/var/1/log/mysqld.1.strace $ mysql-test/mtr --strace --client-strace --strace-option='-e' --strace-option='trace=openat' --mem --parallel=3 main.select ... $ find mysql-test/var/ -name \*strace -ls 5220790 8 -rw-r--r-- 1 dan dan 6291 May 20 17:02 mysql-test/var/3/log/mysqltest.strace 5224140 308 -rw-r--r-- 1 dan dan 314356 May 20 17:02 mysql-test/var/3/log/mysqld.1.strace $ more mysql-test/var/3/mysqltest.strace 1692 openat(AT_FDCWD, "/home/dan/software_projects/mariadb-server/libmysql/.libs/tls/x86_64/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) 1692 openat(AT_FDCWD, "/home/dan/software_projects/mariadb-server/libmysql/.libs/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOE NT (No such file or directory) Closes #600 --- mysql-test/mysql-test-run.pl | 48 +++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e3e9460f35a..8b9d91935bf 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -311,7 +311,8 @@ my $opt_valgrind_mysqltest= 0; my @default_valgrind_args= ("--show-reachable=yes"); my @valgrind_args; my $opt_strace= 0; -my $opt_strace_client; +my $opt_stracer; +my $opt_client_strace = 0; my @strace_args; my $opt_valgrind_path; my $valgrind_reports= 0; @@ -1156,9 +1157,10 @@ sub command_line_setup { 'debugger=s' => \$opt_debugger, 'boot-dbx' => \$opt_boot_dbx, 'client-debugger=s' => \$opt_client_debugger, - 'strace' => \$opt_strace, - 'strace-client' => \$opt_strace_client, - 'strace-option=s' => \@strace_args, + 'strace' => \$opt_strace, + 'strace-option=s' => \@strace_args, + 'client-strace' => \$opt_client_strace, + 'stracer=s' => \$opt_stracer, 'max-save-core=i' => \$opt_max_save_core, 'max-save-datadir=i' => \$opt_max_save_datadir, 'max-test-fail=i' => \$opt_max_test_fail, @@ -1750,7 +1752,7 @@ sub command_line_setup { join(" ", @valgrind_args), "\""); } - if (@strace_args) + if (@strace_args || $opt_stracer) { $opt_strace=1; } @@ -5840,14 +5842,6 @@ sub start_mysqltest ($) { mtr_add_arg($args, "--non-blocking-api"); } - if ( $opt_strace_client ) - { - $exe= $opt_strace_client || "strace"; - mtr_add_arg($args, "-o"); - mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir); - mtr_add_arg($args, "$exe_mysqltest"); - } - mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir); if ( $opt_compress ) @@ -5914,6 +5908,17 @@ sub start_mysqltest ($) { mtr_add_arg($args, "%s", $_) for @args_saved; } + # ---------------------------------------------------------------------- + # Prefix the strace options to the argument list. + # ---------------------------------------------------------------------- + if ( $opt_client_strace ) + { + my @args_saved = @$args; + mtr_init_args(\$args); + strace_arguments($args, \$exe, "mysqltest"); + mtr_add_arg($args, "%s", $_) for @args_saved; + } + if ($opt_force > 1) { mtr_add_arg($args, "--continue-on-error"); @@ -6252,16 +6257,17 @@ sub strace_arguments { my $args= shift; my $exe= shift; my $mysqld_name= shift; + my $output= sprintf("%s/log/%s.strace", $path_vardir_trace, $mysqld_name); mtr_add_arg($args, "-f"); - mtr_add_arg($args, "-o%s/var/log/%s.strace", $glob_mysql_test_dir, $mysqld_name); + mtr_add_arg($args, "-o%s", $output); - # Add strace options, can be overriden by user + # Add strace options mtr_add_arg($args, '%s', $_) for (@strace_args); mtr_add_arg($args, $$exe); - $$exe= "strace"; + $$exe= $opt_stracer || "strace"; if ($exe_libtool) { @@ -6520,11 +6526,11 @@ Options for valgrind Options for strace strace Run the "mysqld" executables using strace. Default - options are -f -o var/log/'mysqld-name'.strace - strace-option=ARGS Option to give strace, replaces default option(s), - strace-client=[path] Create strace output for mysqltest client, optionally - specifying name and path to the trace program to use. - Example: $0 --strace-client=ktrace + options are -f -o 'vardir'/log/'mysqld-name'.strace. + client-strace Trace the "mysqltest". + strace-option=ARGS Option to give strace, appends to existing options. + stracer= Specify name and path to the trace program to use. + Example: $0 --strace-client=ktrace. Misc options user=USER User for connecting to mysqld(default: $opt_user) -- cgit v1.2.1 From 3cb60ec2c305f0b0ab9c3680eb787f8dcd78e57b Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Fri, 29 Nov 2019 15:50:40 +0100 Subject: Update `stracer` description in `mtr`. `strace-client` is not used --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 8b9d91935bf..6d32e97d6b4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -6530,7 +6530,7 @@ Options for strace client-strace Trace the "mysqltest". strace-option=ARGS Option to give strace, appends to existing options. stracer= Specify name and path to the trace program to use. - Example: $0 --strace-client=ktrace. + Default is "strace". Example: $0 --stracer=ktrace. Misc options user=USER User for connecting to mysqld(default: $opt_user) -- cgit v1.2.1 From e3d3bbf59829e93e83ab05d831e92a742ffd7e32 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Thu, 28 Nov 2019 15:08:29 +0100 Subject: Using `variables` instead of `values` in mysqld --help documentation would be more accurate --- mysql-test/r/mysqld--help.result | 2 +- scripts/mysql_install_db.sh | 2 +- sql/mysqld.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 825c7e786a3..bececa14d7a 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1107,5 +1107,5 @@ userstat FALSE verbose TRUE wait-timeout 28800 -To see what values a running MySQL server is using, type +To see what variables a running MySQL server is using, type 'mysqladmin variables' instead of 'mysqld --verbose --help'. diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index fb1663d9d69..fe7375494fe 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -214,7 +214,7 @@ cannot_find_file() echo "If you compiled from source, you need to either run 'make install' to" echo "copy the software into the correct location ready for operation." echo "If you don't want to do a full install, you can use the --srcdir" - echo "option to only install the mysql database and privilege tables" + echo "option to only install the mysql database and privilege tables." echo echo "If you are using a binary release, you must either be at the top" echo "level of the extracted archive, or pass the --basedir option" diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 96daeab867d..2aedec595c0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7240,7 +7240,7 @@ because execution stopped before plugins were initialized."); } puts("\n\ -To see what values a running MySQL server is using, type\n\ +To see what variables a running MySQL server is using, type\n\ 'mysqladmin variables' instead of 'mysqld --verbose --help'."); } DBUG_VOID_RETURN; -- cgit v1.2.1 From 91c3d99804e4154b87440712f8c6a5fee04c3dd0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 13 Dec 2019 11:23:04 +0100 Subject: tokudb: fix to compile with gcc 9.2.0 --- storage/tokudb/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 9bff7d4729f..ed802307519 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -30,6 +30,12 @@ IF (HAVE_WVLA) SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-vla") ENDIF() +CHECK_C_COMPILER_FLAG("-Wno-address-of-packed-member" HAVE_NO_ADDRESS_PACKED) +IF(HAVE_NO_ADDRESS_PACKED) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-address-of-packed-member") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-address-of-packed-member") +ENDIF() + ############################################ SET(TOKUDB_VERSION "tokudb-7.5.7") SET(TOKUDB_DEB_FILES "usr/lib/mysql/plugin/ha_tokudb.so\netc/mysql/conf.d/tokudb.cnf\nusr/bin/tokuftdump\nusr/share/doc/mariadb-server-5.5/README-TOKUDB\nusr/share/doc/mariadb-server-5.5/README.md" PARENT_SCOPE) -- cgit v1.2.1 From 794911a27a14ea83eda054cf34d94b43191aa19e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 13 Dec 2019 11:23:29 +0100 Subject: tokudb: disable check_huge_pages_in_practice() crashes on Debian 10 --- storage/tokudb/ft-index/portability/huge_page_detection.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/tokudb/ft-index/portability/huge_page_detection.cc b/storage/tokudb/ft-index/portability/huge_page_detection.cc index ca428987486..ea0eb568e4c 100644 --- a/storage/tokudb/ft-index/portability/huge_page_detection.cc +++ b/storage/tokudb/ft-index/portability/huge_page_detection.cc @@ -120,6 +120,7 @@ static bool check_huge_pages_config_file(const char *fname) static bool check_huge_pages_in_practice(void) // Effect: Return true if huge pages appear to be defined in practice. { + return false; // disabled, doesn't seem to work on newest distros #ifdef HAVE_MINCORE #ifdef HAVE_MAP_ANONYMOUS const int map_anonymous = MAP_ANONYMOUS; -- cgit v1.2.1 From fc860d3fa3bc854fbe6aab9179d7a4aaf6eb9edf Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 16 Dec 2019 12:57:08 +0400 Subject: MDEV-21065 UNIQUE constraint causes a query with string comparison to omit a row in the result set --- mysql-test/r/type_int.result | 13 +++++++++++++ mysql-test/t/type_int.test | 12 ++++++++++++ strings/ctype-simple.c | 3 ++- strings/my_strtoll10.c | 17 ++++++++++++----- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/type_int.result b/mysql-test/r/type_int.result index aaf35690306..c8b77490102 100644 --- a/mysql-test/r/type_int.result +++ b/mysql-test/r/type_int.result @@ -20,5 +20,18 @@ COALESCE(@a) 1 DROP TABLE t1; # +# MDEV-21065 UNIQUE constraint causes a query with string comparison to omit a row in the result set +# +CREATE TABLE t1 (c0 INT UNIQUE); +INSERT INTO t1 VALUES (NULL), (NULL), (NULL), (NULL), (1), (0); +SELECT * FROM t1 WHERE c0 < '\n2'; +c0 +0 +1 +DROP TABLE t1; +SELECT CAST('\n2' AS INT); +CAST('\n2' AS INT) +2 +# # End of 5.5 tests # diff --git a/mysql-test/t/type_int.test b/mysql-test/t/type_int.test index 52be12bf494..cc8b386aebe 100644 --- a/mysql-test/t/type_int.test +++ b/mysql-test/t/type_int.test @@ -14,6 +14,18 @@ SELECT COALESCE(@a:=1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); SELECT COALESCE(@a) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); DROP TABLE t1; +--echo # +--echo # MDEV-21065 UNIQUE constraint causes a query with string comparison to omit a row in the result set +--echo # + +CREATE TABLE t1 (c0 INT UNIQUE); +INSERT INTO t1 VALUES (NULL), (NULL), (NULL), (NULL), (1), (0); +SELECT * FROM t1 WHERE c0 < '\n2'; +DROP TABLE t1; + +SELECT CAST('\n2' AS INT); + + --echo # --echo # End of 5.5 tests --echo # diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index ba446a7df54..e5a1471cf63 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1399,7 +1399,8 @@ my_strntoull10rnd_8bit(CHARSET_INFO *cs __attribute__((unused)), int shift= 0, digits= 0, negative, addon; /* Skip leading spaces and tabs */ - for ( ; str < end && (*str == ' ' || *str == '\t') ; str++); + for ( ; str < end && my_isspace(&my_charset_latin1, *str) ; ) + str++; if (str >= end) goto ret_edom; diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index 89450f15c9f..01c3697dcdf 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -98,18 +98,25 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error) if (endptr) { end= *endptr; - while (s != end && (*s == ' ' || *s == '\t')) + /* Skip leading spaces */ + for ( ; s < end && my_isspace(&my_charset_latin1, *s) ; ) s++; + if (s == end) goto no_conv; } else { endptr= &dummy; /* Easier end test */ - while (*s == ' ' || *s == '\t') - s++; - if (!*s) - goto no_conv; + /* Skip leading spaces */ + for ( ; ; s++) + { + if (!*s) + goto no_conv; + if (!my_isspace(&my_charset_latin1, *s)) + break; + } + /* This number must be big to guard against a lot of pre-zeros */ end= s+65535; /* Can't be longer than this */ } -- cgit v1.2.1 From 80c97f8c0c496a4ef9372172704b7d0d9115325f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 17 Dec 2019 22:36:26 +0100 Subject: MDEV-21343 Threadpool/Unix- wait_begin() function does not wake/create threads, when it should Fixed the condition for waking up/creating another thread. If there is some work to do (if the request queue is not empty), a thread should be woken or created. The condition was incorrect since 18c9b34 --- sql/threadpool_unix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index b505ec3dff5..3a90f24f6e9 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -1173,7 +1173,7 @@ void wait_begin(thread_group_t *thread_group) DBUG_ASSERT(thread_group->connection_count > 0); if ((thread_group->active_thread_count == 0) && - (thread_group->queue.is_empty() || !thread_group->listener)) + (!thread_group->queue.is_empty() || !thread_group->listener)) { /* Group might stall while this thread waits, thus wake -- cgit v1.2.1 From 3c94c5b8fab0c3bb0febe62d72b89bc8d51c3932 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 3 Jan 2020 10:25:46 +0100 Subject: MDEV-21416: main.events_bugs fails due to 2020-01-01 date Moved to the next problematic year (2038). --- mysql-test/r/events_bugs.result | 4 ++-- mysql-test/t/events_bugs.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 30bc4f89d8c..1729862dba8 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -643,7 +643,7 @@ SET GLOBAL READ_ONLY = 1; # Connection: u1_con (mysqltest_u1@localhost/events_test). # -CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1; +CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1; ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement ALTER EVENT e1 COMMENT 'comment'; @@ -656,7 +656,7 @@ ERROR HY000: The MariaDB server is running with the --read-only option so it can # Connection: root_con (root@localhost/events_test). # -CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1; +CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1; ALTER EVENT e1 COMMENT 'comment'; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index dc31556998a..aca1f144ec3 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -1033,7 +1033,7 @@ SET GLOBAL READ_ONLY = 1; --echo --error ER_OPTION_PREVENTS_STATEMENT -CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1; +CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1; --echo @@ -1057,7 +1057,7 @@ DROP EVENT e1; --echo -CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1; +CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1; --echo -- cgit v1.2.1 From 5683c113b817644ffa5ba13c2485ce259250a8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Thu, 5 Dec 2019 07:58:02 +0200 Subject: Use get_ident_len in heartbeat event error messages The string doesn't appear to be null-terminated when binlog checksums are enabled. This causes a corrupt binlog name in the error message when a slave is ahead of the master. --- sql/slave.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index a8946c69d18..ae1c5ca2cf8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4444,7 +4444,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) error= ER_SLAVE_HEARTBEAT_FAILURE; error_msg.append(STRING_WITH_LEN("inconsistent heartbeat event content;")); error_msg.append(STRING_WITH_LEN("the event's data: log_file_name ")); - error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident())); + error_msg.append(hb.get_log_ident(), (uint) hb.get_ident_len()); error_msg.append(STRING_WITH_LEN(" log_pos ")); llstr(hb.log_pos, llbuf); error_msg.append(llbuf, strlen(llbuf)); @@ -4471,7 +4471,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) error= ER_SLAVE_HEARTBEAT_FAILURE; error_msg.append(STRING_WITH_LEN("heartbeat is not compatible with local info;")); error_msg.append(STRING_WITH_LEN("the event's data: log_file_name ")); - error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident())); + error_msg.append(hb.get_log_ident(), (uint) hb.get_ident_len()); error_msg.append(STRING_WITH_LEN(" log_pos ")); llstr(hb.log_pos, llbuf); error_msg.append(llbuf, strlen(llbuf)); -- cgit v1.2.1 From 409aba3d997e97287bc67467ef437164c9e70b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 16 Jan 2020 12:40:45 +0200 Subject: Improve documentation of Unique class * size represents the size of an element in the Unique class * full_size is used when the Unique class counts the number of duplicates stored per element. This requires additional space per Unique element. --- sql/sql_class.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 4a390545593..2fac8d4e87f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3923,16 +3923,21 @@ class user_var_entry class Unique :public Sql_alloc { DYNAMIC_ARRAY file_ptrs; - ulong max_elements; + ulong max_elements; /* Total number of elements that will be stored in-memory */ ulonglong max_in_memory_size; IO_CACHE file; TREE tree; uchar *record_pointers; + /* Number of elements filtered out due to min_dupl_count when storing results + to table. See Unique::get */ ulong filtered_out_elems; bool flush(); - uint size; - uint full_size; - uint min_dupl_count; /* always 0 for unions, > 0 for intersections */ + uint size; /* Size of element stored in unique object. */ + uint full_size; /* Size of element + space needed to store the number of + duplicates found for the element. */ + uint min_dupl_count; /* Minimum number of occurences of element required for + it to be written to record_pointers. + always 0 for unions, > 0 for intersections */ bool merge(TABLE *table, uchar *buff, bool without_last_merge); -- cgit v1.2.1 From 1bee9efcc44d94e92a0908a3b431fc45f4490807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 16 Jan 2020 13:37:21 +0200 Subject: MDEV-21210: main.uniques_crash-7912 tries to allocate 1TB of memory Remove the offending test case. This sort of error is hard to test in all possible corner cases and thus makes the test less valuable. The overflow error will be covered by warnings generated by the compiler, which is much more reliable in the general case. --- mysql-test/r/uniques_crash-7912.result | 11 ----------- mysql-test/t/uniques_crash-7912.test | 26 -------------------------- 2 files changed, 37 deletions(-) delete mode 100644 mysql-test/r/uniques_crash-7912.result delete mode 100644 mysql-test/t/uniques_crash-7912.test diff --git a/mysql-test/r/uniques_crash-7912.result b/mysql-test/r/uniques_crash-7912.result deleted file mode 100644 index bf3aab684ae..00000000000 --- a/mysql-test/r/uniques_crash-7912.result +++ /dev/null @@ -1,11 +0,0 @@ -call mtr.add_suppression("Out of memory"); -set sql_mode=""; -drop table if exists t1,t2; -create table `t1` (`a` datetime not null) engine=InnoDB; -create table `t2` (`a` int not null) engine=innodb; -replace into t1 values (),(); -insert into t2 values(0); -set session sort_buffer_size = 1024*1024*1024*1024; -delete d2 from t2 as d1, t1 as d2 where d1.a <=> d2.a; -drop table t2; -drop table t1; diff --git a/mysql-test/t/uniques_crash-7912.test b/mysql-test/t/uniques_crash-7912.test deleted file mode 100644 index 8dc82f8f540..00000000000 --- a/mysql-test/t/uniques_crash-7912.test +++ /dev/null @@ -1,26 +0,0 @@ -# -# MDEV-7912 -# -# multitable delete with wrongly set sort_buffer_size crashes in merge_buffers - ---source include/have_innodb.inc ---source include/have_debug.inc ---source include/windows.inc - -call mtr.add_suppression("Out of memory"); - -set sql_mode=""; ---disable_warnings -drop table if exists t1,t2; -create table `t1` (`a` datetime not null) engine=InnoDB; -create table `t2` (`a` int not null) engine=innodb; -replace into t1 values (),(); -insert into t2 values(0); -set session sort_buffer_size = 1024*1024*1024*1024; -#Either fail with EE_OUTOFMEMORY, or succeed ---error 0 , 5 -delete d2 from t2 as d1, t1 as d2 where d1.a <=> d2.a; ---enable_warnings - -drop table t2; -drop table t1; -- cgit v1.2.1 From 49b9ce15ef1e27ce27b6c173ec8f82dcdffba956 Mon Sep 17 00:00:00 2001 From: Maheedhar PV Date: Wed, 20 Nov 2019 08:10:36 +0530 Subject: Bug#30194841 INSERT ON DUPLICATE KEY UPDATE UPDATES THE WRONG ROW test case only --- mysql-test/r/insert_debug.result | 25 +++++++++++++++++ mysql-test/t/insert_debug-master.opt | 1 + mysql-test/t/insert_debug.test | 54 ++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 mysql-test/r/insert_debug.result create mode 100644 mysql-test/t/insert_debug-master.opt create mode 100644 mysql-test/t/insert_debug.test diff --git a/mysql-test/r/insert_debug.result b/mysql-test/r/insert_debug.result new file mode 100644 index 00000000000..ef4f304800a --- /dev/null +++ b/mysql-test/r/insert_debug.result @@ -0,0 +1,25 @@ +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +CREATE TABLE t1(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL); +INSERT INTO t1(c1, c2, c3) VALUES('A1','B1','IT1'), ('A2','B2','IT1'), ('A3','B3','IT1'), ('A4','B4','IT1'), ('A5','B5','IT1'), ('A6','B6','IT1'), ('A7','B7','IT1'); +CREATE TABLE t2(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL); +INSERT INTO t2(c1, c2, c3) VALUES ('A3','B3','IT2'), ('A2','B2','IT2'), ('A4','B4','IT2'), ('A5','B5','II2'); +CREATE TABLE result(id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10), +c3 VARCHAR(10), update_count INT DEFAULT 0, UNIQUE KEY uniq_idx (c1,c2), PRIMARY KEY (id)) ENGINE = innodb; +SET DEBUG_SYNC = "ha_write_row_end WAIT_FOR flushed EXECUTE 1"; +INSERT INTO result(c1, c2, c3) SELECT * FROM t1 ON DUPLICATE KEY UPDATE c2=t1.c2, c3='UT1', update_count=update_count+1; +INSERT INTO result(c1, c2, c3) SELECT * FROM t2 ON DUPLICATE KEY UPDATE c2=t2.c2, c3='UT2', update_count=update_count+1; +SET DEBUG_SYNC = "now SIGNAL flushed"; +SELECT * FROM result; +id c1 c2 c3 update_count +1 A1 B1 IT1 0 +2 A3 B3 UT1 1 +3 A2 B2 UT1 1 +4 A4 B4 UT1 1 +5 A5 B5 UT1 1 +9 A6 B6 IT1 0 +10 A7 B7 IT1 0 +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE result; +SET DEBUG_SYNC = "RESET"; diff --git a/mysql-test/t/insert_debug-master.opt b/mysql-test/t/insert_debug-master.opt new file mode 100644 index 00000000000..824f656cbd5 --- /dev/null +++ b/mysql-test/t/insert_debug-master.opt @@ -0,0 +1 @@ +--innodb_autoinc_lock_mode=2 diff --git a/mysql-test/t/insert_debug.test b/mysql-test/t/insert_debug.test new file mode 100644 index 00000000000..b35d6b838da --- /dev/null +++ b/mysql-test/t/insert_debug.test @@ -0,0 +1,54 @@ +source include/have_innodb.inc; +source include/have_debug.inc; +source include/have_debug_sync.inc; + +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; + +connect (con1, localhost, root,,); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; + +connection default; + +let $conn0_id= `SELECT CONNECTION_ID()`; + +CREATE TABLE t1(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL); +INSERT INTO t1(c1, c2, c3) VALUES('A1','B1','IT1'), ('A2','B2','IT1'), ('A3','B3','IT1'), ('A4','B4','IT1'), ('A5','B5','IT1'), ('A6','B6','IT1'), ('A7','B7','IT1'); + +CREATE TABLE t2(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL); +INSERT INTO t2(c1, c2, c3) VALUES ('A3','B3','IT2'), ('A2','B2','IT2'), ('A4','B4','IT2'), ('A5','B5','II2'); + +CREATE TABLE result(id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10), +c3 VARCHAR(10), update_count INT DEFAULT 0, UNIQUE KEY uniq_idx (c1,c2), PRIMARY KEY (id)) ENGINE = innodb; + +# Insert one row from 't1' into the 'result' table and wait on a debug sync +# point. The next insert statement from an session 2 inserts values that would +# lead to unique key clash, when this insert resumes. +# The subsequent inserts of this statement(after resume) will fail because of a +# clash with the unique index, and are expected to update the row which clashes +# with the unique key. +# Without the fix for bug#30194841 a stale auto increment value, would cause a +# collision with existing auto increment column value and ends up updating that +# colliding row, instead of the row colliding with the unique index. +SET DEBUG_SYNC = "ha_write_row_end WAIT_FOR flushed EXECUTE 1"; +send INSERT INTO result(c1, c2, c3) SELECT * FROM t1 ON DUPLICATE KEY UPDATE c2=t1.c2, c3='UT1', update_count=update_count+1; + +# While session 1 is waiting (after one insert), insert rows that will cause a clash +# with the inserts of session 1 on the unique key. +connection con1; + +# Wait for the session 1 to hit the debug sync point. +let $wait_condition=SELECT 1 FROM information_schema.processlist WHERE id = $conn0_id AND state LIKE '%ha_write_row_end%'; +--source include/wait_condition.inc + +INSERT INTO result(c1, c2, c3) SELECT * FROM t2 ON DUPLICATE KEY UPDATE c2=t2.c2, c3='UT2', update_count=update_count+1; + +# Signal to resume the insert statement in session 1 +SET DEBUG_SYNC = "now SIGNAL flushed"; +connection default; +reap; +SELECT * FROM result; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE result; +SET DEBUG_SYNC = "RESET"; -- cgit v1.2.1 From 4d1c1b23e1373bbd4e72f524e855f1db076d2c73 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 17 Jan 2020 15:08:11 +0100 Subject: Bug#29630767 - USE OF UNINITIALIZED VALUE IN LIBMYSQL (CLIENT.CC FUNCTION RUN_PLUGIN_AUTH) --- mysql-test/r/connect_debug.result | 8 ++++++++ mysql-test/t/connect_debug.test | 15 +++++++++++++++ sql-common/client.c | 5 ++++- sql/sql_acl.cc | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/connect_debug.result b/mysql-test/r/connect_debug.result index 3151166a0e6..c455363eb41 100644 --- a/mysql-test/r/connect_debug.result +++ b/mysql-test/r/connect_debug.result @@ -8,3 +8,11 @@ create user 'bad' identified by 'worse'; ERROR 2059 (HY000): Authentication plugin 'foo/bar' cannot be loaded: invalid plugin name set global debug_dbug=@old_dbug; drop user bad; +set global debug_dbug='+d,increase_srv_handshake_scramble_len'; +connect(localhost,root,,test,MASTER_MYPORT,MYSQL_TMP_DIR/mysqld.1.sock); +ERROR HY000: Malformed packet +set global debug_dbug=@old_dbug; +set global debug_dbug='+d,poison_srv_handshake_scramble_len'; +connect(localhost,root,,test,MASTER_MYPORT,MYSQL_TMP_DIR/mysqld.1.sock); +ERROR HY000: Malformed packet +set global debug_dbug=@old_dbug; diff --git a/mysql-test/t/connect_debug.test b/mysql-test/t/connect_debug.test index 7a2f2872b79..de7a292ce67 100644 --- a/mysql-test/t/connect_debug.test +++ b/mysql-test/t/connect_debug.test @@ -21,3 +21,18 @@ create user 'bad' identified by 'worse'; --exec $MYSQL --default-auth=mysql_old_password --user=bad --password=worse 2>&1 set global debug_dbug=@old_dbug; drop user bad; + +# +# Bug#29630767 - USE OF UNINITIALIZED VALUE IN LIBMYSQL (CLIENT.CC FUNCTION RUN_PLUGIN_AUTH) +# +set global debug_dbug='+d,increase_srv_handshake_scramble_len'; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MASTER_MYPORT MASTER_MYPORT +--error 2027 +connect con1,localhost,root; +set global debug_dbug=@old_dbug; + +set global debug_dbug='+d,poison_srv_handshake_scramble_len'; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MASTER_MYPORT MASTER_MYPORT +--error 2027 +connect con2,localhost,root; +set global debug_dbug=@old_dbug; diff --git a/sql-common/client.c b/sql-common/client.c index f535b5119b7..c7fb70fbeef 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -3538,7 +3538,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, scramble_data_len= pkt_scramble_len; scramble_plugin= scramble_data + scramble_data_len; if (scramble_data + scramble_data_len > pkt_end) - scramble_data_len= pkt_end - scramble_data; + { + set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); + goto error; + } } else { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8670f5b390d..ac1adf9e58b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8178,6 +8178,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, int2store(end+5, thd->client_capabilities >> 16); end[7]= data_len; DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;); + DBUG_EXECUTE_IF("increase_srv_handshake_scramble_len", end[7]= 50;); bzero(end + 8, 10); end+= 18; /* write scramble tail */ -- cgit v1.2.1