mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge branch '10.6.12' into 10.6
This commit is contained in:
commit
70a515df43
17 changed files with 325 additions and 102 deletions
2
VERSION
2
VERSION
|
@ -1,4 +1,4 @@
|
||||||
MYSQL_VERSION_MAJOR=10
|
MYSQL_VERSION_MAJOR=10
|
||||||
MYSQL_VERSION_MINOR=6
|
MYSQL_VERSION_MINOR=6
|
||||||
MYSQL_VERSION_PATCH=12
|
MYSQL_VERSION_PATCH=13
|
||||||
SERVER_MATURITY=stable
|
SERVER_MATURITY=stable
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifdef HAVE_gcov
|
#ifdef HAVE_gcov
|
||||||
extern void __gcov_flush();
|
#include <gcov.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -2212,7 +2212,7 @@ void _db_suicide_()
|
||||||
fprintf(stderr, "SIGKILL myself\n");
|
fprintf(stderr, "SIGKILL myself\n");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#ifdef HAVE_gcov
|
#ifdef HAVE_gcov
|
||||||
__gcov_flush();
|
__gcov_dump();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
retval= kill(getpid(), SIGKILL);
|
retval= kill(getpid(), SIGKILL);
|
||||||
|
@ -2262,7 +2262,7 @@ my_bool _db_my_assert(const char *file, int line, const char *msg)
|
||||||
fprintf(stderr, "%s:%d: assert: %s\n", file, line, msg);
|
fprintf(stderr, "%s:%d: assert: %s\n", file, line, msg);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#ifdef HAVE_gcov
|
#ifdef HAVE_gcov
|
||||||
__gcov_flush();
|
__gcov_dump();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
|
|
|
@ -2,7 +2,7 @@ SET DEBUG_SYNC= 'RESET';
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1;
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: ''
|
debug_sync ON - current signals: ''
|
||||||
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
|
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
|
||||||
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
|
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
|
||||||
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
|
SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
|
||||||
|
@ -150,34 +150,34 @@ SET @myvar= 'now SIGNAL from_myvar';
|
||||||
SET DEBUG_SYNC= @myvar;
|
SET DEBUG_SYNC= @myvar;
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 'from_myvar'
|
debug_sync ON - current signals: 'from_myvar'
|
||||||
SET DEBUG_SYNC= LEFT('now SIGNAL from_function_cut_here', 24);
|
SET DEBUG_SYNC= LEFT('now SIGNAL from_function_cut_here', 24);
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 'from_function'
|
debug_sync ON - current signals: 'from_myvar,from_function'
|
||||||
SET DEBUG_SYNC= 'now SIGNAL something';
|
SET DEBUG_SYNC= 'now SIGNAL something';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 'something'
|
debug_sync ON - current signals: 'something,from_function,from_myvar'
|
||||||
SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
|
SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning #### debug sync point wait timed out
|
Warning #### debug sync point wait timed out
|
||||||
SET DEBUG_SYNC= 'now SIGNAL nothing';
|
SET DEBUG_SYNC= 'now SIGNAL nothing';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 'nothing'
|
debug_sync ON - current signals: 'something,from_function,nothing,from_myvar'
|
||||||
SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
|
SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
|
||||||
SET DEBUG_SYNC= 'now SIGNAL something EXECUTE 0';
|
SET DEBUG_SYNC= 'now SIGNAL something EXECUTE 0';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 'nothing'
|
debug_sync ON - current signals: 'something,from_function,from_myvar'
|
||||||
SET DEBUG_SYNC= 'now WAIT_FOR anotherthing TIMEOUT 0 EXECUTE 0';
|
SET DEBUG_SYNC= 'now WAIT_FOR anotherthing TIMEOUT 0 EXECUTE 0';
|
||||||
SET DEBUG_SYNC= 'now HIT_LIMIT 1';
|
SET DEBUG_SYNC= 'now HIT_LIMIT 1';
|
||||||
ERROR HY000: debug sync point hit limit reached
|
ERROR HY000: debug sync point hit limit reached
|
||||||
SET DEBUG_SYNC= 'RESET';
|
SET DEBUG_SYNC= 'RESET';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: ''
|
debug_sync ON - current signals: ''
|
||||||
SET DEBUG_SYNC= 'p1abcd SIGNAL s1 EXECUTE 2';
|
SET DEBUG_SYNC= 'p1abcd SIGNAL s1 EXECUTE 2';
|
||||||
SET DEBUG_SYNC= 'p2abc SIGNAL s2 EXECUTE 2';
|
SET DEBUG_SYNC= 'p2abc SIGNAL s2 EXECUTE 2';
|
||||||
SET DEBUG_SYNC= 'p9abcdef SIGNAL s9 EXECUTE 2';
|
SET DEBUG_SYNC= 'p9abcdef SIGNAL s9 EXECUTE 2';
|
||||||
|
@ -190,23 +190,30 @@ SET DEBUG_SYNC= 'p3abcdef SIGNAL s3 EXECUTE 2';
|
||||||
SET DEBUG_SYNC= 'p4a TEST';
|
SET DEBUG_SYNC= 'p4a TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's4'
|
debug_sync ON - current signals: 's4'
|
||||||
SET DEBUG_SYNC= 'p1abcd TEST';
|
SET DEBUG_SYNC= 'p1abcd TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's1'
|
debug_sync ON - current signals: 's4,s1'
|
||||||
SET DEBUG_SYNC= 'p7 TEST';
|
SET DEBUG_SYNC= 'p7 TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's7'
|
debug_sync ON - current signals: 's1,s7,s4'
|
||||||
SET DEBUG_SYNC= 'p9abcdef TEST';
|
SET DEBUG_SYNC= 'p9abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's9'
|
debug_sync ON - current signals: 's1,s7,s4,s9'
|
||||||
SET DEBUG_SYNC= 'p3abcdef TEST';
|
SET DEBUG_SYNC= 'p3abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's3'
|
debug_sync ON - current signals: 's1,s3,s4,s9,s7'
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s9';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s4';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s7';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
Variable_name Value
|
||||||
|
debug_sync ON - current signals: 's3'
|
||||||
SET DEBUG_SYNC= 'p1abcd CLEAR';
|
SET DEBUG_SYNC= 'p1abcd CLEAR';
|
||||||
SET DEBUG_SYNC= 'p2abc CLEAR';
|
SET DEBUG_SYNC= 'p2abc CLEAR';
|
||||||
SET DEBUG_SYNC= 'p5abcde CLEAR';
|
SET DEBUG_SYNC= 'p5abcde CLEAR';
|
||||||
|
@ -219,19 +226,19 @@ SET DEBUG_SYNC= 'p7 CLEAR';
|
||||||
SET DEBUG_SYNC= 'p1abcd TEST';
|
SET DEBUG_SYNC= 'p1abcd TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's3'
|
debug_sync ON - current signals: 's3'
|
||||||
SET DEBUG_SYNC= 'p7 TEST';
|
SET DEBUG_SYNC= 'p7 TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's3'
|
debug_sync ON - current signals: 's3'
|
||||||
SET DEBUG_SYNC= 'p9abcdef TEST';
|
SET DEBUG_SYNC= 'p9abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: 's3'
|
debug_sync ON - current signals: 's3'
|
||||||
SET DEBUG_SYNC= 'RESET';
|
SET DEBUG_SYNC= 'RESET';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: ''
|
debug_sync ON - current signals: ''
|
||||||
CREATE USER mysqltest_1@localhost;
|
CREATE USER mysqltest_1@localhost;
|
||||||
GRANT SUPER ON *.* TO mysqltest_1@localhost;
|
GRANT SUPER ON *.* TO mysqltest_1@localhost;
|
||||||
connect con1,localhost,mysqltest_1,,;
|
connect con1,localhost,mysqltest_1,,;
|
||||||
|
@ -292,4 +299,24 @@ disconnect con1;
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
connection default;
|
connection default;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Test NO_CLEAR_EVENT flag. The signal should still be visible after
|
||||||
|
# the wait has completed succesfully.
|
||||||
|
#
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL s1';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
Variable_name Value
|
||||||
|
debug_sync ON - current signals: 's1'
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1 NO_CLEAR_EVENT';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
Variable_name Value
|
||||||
|
debug_sync ON - current signals: 's1'
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
Variable_name Value
|
||||||
|
debug_sync ON - current signals: ''
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL s1,s2,s5,s7';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
Variable_name Value
|
||||||
|
debug_sync ON - current signals: 's2,s7,s1,s5'
|
||||||
SET DEBUG_SYNC= 'RESET';
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
|
|
@ -298,6 +298,16 @@ SET DEBUG_SYNC= 'p9abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
SET DEBUG_SYNC= 'p3abcdef TEST';
|
SET DEBUG_SYNC= 'p3abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wait for all signals currently active except s3.
|
||||||
|
#
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s9';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s4';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s7';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clear the actions.
|
# Clear the actions.
|
||||||
#
|
#
|
||||||
|
@ -320,7 +330,7 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
SET DEBUG_SYNC= 'p9abcdef TEST';
|
SET DEBUG_SYNC= 'p9abcdef TEST';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
#
|
#
|
||||||
# Now cleanup. Actions are clear already, but signal needs to be cleared.
|
# Now cleanup. Actions are clear already, but s3 signal needs to be cleared.
|
||||||
#
|
#
|
||||||
SET DEBUG_SYNC= 'RESET';
|
SET DEBUG_SYNC= 'RESET';
|
||||||
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
@ -418,10 +428,24 @@ disconnect con2;
|
||||||
connection default;
|
connection default;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test NO_CLEAR_EVENT flag. The signal should still be visible after
|
||||||
|
--echo # the wait has completed succesfully.
|
||||||
|
--echo #
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL s1';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1 NO_CLEAR_EVENT';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
SET DEBUG_SYNC= 'now WAIT_FOR s1';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL s1,s2,s5,s7';
|
||||||
|
SHOW VARIABLES LIKE 'DEBUG_SYNC';
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cleanup after test case.
|
# Cleanup after test case.
|
||||||
# Otherwise signal would contain 'flushed' here,
|
# Otherwise signal would confuse the next test.
|
||||||
# which could confuse the next test.
|
|
||||||
#
|
#
|
||||||
SET DEBUG_SYNC= 'RESET';
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,7 @@ my $opt_start_exit;
|
||||||
my $start_only;
|
my $start_only;
|
||||||
my $file_wsrep_provider;
|
my $file_wsrep_provider;
|
||||||
my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far.
|
my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far.
|
||||||
|
my $test_name_for_report;
|
||||||
|
|
||||||
our @global_suppressions;
|
our @global_suppressions;
|
||||||
|
|
||||||
|
@ -515,13 +516,13 @@ sub main {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( not @$completed ) {
|
if ( not @$completed ) {
|
||||||
my $test_name= mtr_grab_file($path_testlog);
|
if ($test_name_for_report)
|
||||||
$test_name =~ s/^CURRENT_TEST:\s//;
|
{
|
||||||
chomp($test_name);
|
my $tinfo = My::Test->new(name => $test_name_for_report);
|
||||||
my $tinfo = My::Test->new(name => $test_name);
|
|
||||||
$tinfo->{result}= 'MTR_RES_FAILED';
|
$tinfo->{result}= 'MTR_RES_FAILED';
|
||||||
$tinfo->{comment}=' ';
|
$tinfo->{comment}=' ';
|
||||||
mtr_report_test($tinfo);
|
mtr_report_test($tinfo);
|
||||||
|
}
|
||||||
mtr_error("Test suite aborted");
|
mtr_error("Test suite aborted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3740,8 +3741,8 @@ sub resfile_report_test ($) {
|
||||||
sub run_testcase ($$) {
|
sub run_testcase ($$) {
|
||||||
my ($tinfo, $server_socket)= @_;
|
my ($tinfo, $server_socket)= @_;
|
||||||
my $print_freq=20;
|
my $print_freq=20;
|
||||||
|
$test_name_for_report= $tinfo->{name};
|
||||||
mtr_verbose("Running test:", $tinfo->{name});
|
mtr_verbose("Running test:", $test_name_for_report);
|
||||||
$ENV{'MTR_TEST_NAME'} = $tinfo->{name};
|
$ENV{'MTR_TEST_NAME'} = $tinfo->{name};
|
||||||
resfile_report_test($tinfo) if $opt_resfile;
|
resfile_report_test($tinfo) if $opt_resfile;
|
||||||
|
|
||||||
|
@ -5130,12 +5131,10 @@ sub mysqld_start ($$) {
|
||||||
if (!$rc)
|
if (!$rc)
|
||||||
{
|
{
|
||||||
# Report failure about the last test case before exit
|
# Report failure about the last test case before exit
|
||||||
my $test_name= mtr_grab_file($path_current_testlog);
|
my $tinfo = My::Test->new(name => $test_name_for_report);
|
||||||
$test_name =~ s/^CURRENT_TEST:\s//;
|
|
||||||
my $tinfo = My::Test->new(name => $test_name);
|
|
||||||
$tinfo->{result}= 'MTR_RES_FAILED';
|
$tinfo->{result}= 'MTR_RES_FAILED';
|
||||||
$tinfo->{failures}= 1;
|
$tinfo->{failures}= 1;
|
||||||
$tinfo->{logfile}=get_log_from_proc($mysqld->{'proc'}, $tinfo->{name});
|
$tinfo->{logfile}=get_log_from_proc($mysqld->{'proc'}, $test_name_for_report);
|
||||||
report_option('verbose', 1);
|
report_option('verbose', 1);
|
||||||
mtr_report_test($tinfo);
|
mtr_report_test($tinfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,11 +31,12 @@ pk f1 f2 f3
|
||||||
3 t q 1
|
3 t q 1
|
||||||
5 z t NULL
|
5 z t NULL
|
||||||
SET DEBUG_SYNC='now SIGNAL default_dml';
|
SET DEBUG_SYNC='now SIGNAL default_dml';
|
||||||
|
SET DEBUG_SYNC='now SIGNAL con2_dml';
|
||||||
connection default;
|
connection default;
|
||||||
SET DEBUG_SYNC='now WAIT_FOR default_dml';
|
SET DEBUG_SYNC='now WAIT_FOR default_dml';
|
||||||
UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h';
|
UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h';
|
||||||
connect con2,localhost,root,,test;
|
connect con2,localhost,root,,test;
|
||||||
set debug_sync='now WAIT_FOR default_dml';
|
set debug_sync='now WAIT_FOR con2_dml';
|
||||||
SET DEBUG_SYNC='now SIGNAL con1_dml2';
|
SET DEBUG_SYNC='now SIGNAL con1_dml2';
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
connection con1;
|
connection con1;
|
||||||
|
|
|
@ -35,6 +35,7 @@ SET DEBUG_SYNC='now WAIT_FOR con1_dml';
|
||||||
begin;
|
begin;
|
||||||
SELECT * FROM t1 for update; # Holds x lock of all records in the table t1
|
SELECT * FROM t1 for update; # Holds x lock of all records in the table t1
|
||||||
SET DEBUG_SYNC='now SIGNAL default_dml';
|
SET DEBUG_SYNC='now SIGNAL default_dml';
|
||||||
|
SET DEBUG_SYNC='now SIGNAL con2_dml';
|
||||||
|
|
||||||
--connection default
|
--connection default
|
||||||
SET DEBUG_SYNC='now WAIT_FOR default_dml';
|
SET DEBUG_SYNC='now WAIT_FOR default_dml';
|
||||||
|
@ -42,7 +43,7 @@ SET DEBUG_SYNC='now WAIT_FOR default_dml';
|
||||||
# It holds the lock of all record in t3 and tries to acquire record lock for the table t1.
|
# It holds the lock of all record in t3 and tries to acquire record lock for the table t1.
|
||||||
|
|
||||||
--connect (con2,localhost,root,,test)
|
--connect (con2,localhost,root,,test)
|
||||||
set debug_sync='now WAIT_FOR default_dml';
|
set debug_sync='now WAIT_FOR con2_dml';
|
||||||
let $wait_condition=
|
let $wait_condition=
|
||||||
select count(*) > 0 from information_schema.innodb_lock_waits;
|
select count(*) > 0 from information_schema.innodb_lock_waits;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
|
|
|
@ -19,11 +19,12 @@ a b c
|
||||||
1 NULL NULL
|
1 NULL NULL
|
||||||
set debug_sync='now SIGNAL go';
|
set debug_sync='now SIGNAL go';
|
||||||
set debug_sync='now WAIT_FOR parked2';
|
set debug_sync='now WAIT_FOR parked2';
|
||||||
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go2';
|
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go3';
|
||||||
drop table t1;;
|
drop table t1;;
|
||||||
connection con2;
|
connection con2;
|
||||||
set debug_sync='now WAIT_FOR waiting';
|
set debug_sync='now WAIT_FOR waiting';
|
||||||
set debug_sync='now SIGNAL go2';
|
set debug_sync='now SIGNAL go2';
|
||||||
|
set debug_sync='now SIGNAL go3';
|
||||||
connection default;
|
connection default;
|
||||||
connection con1;
|
connection con1;
|
||||||
connection default;
|
connection default;
|
||||||
|
|
|
@ -20,15 +20,12 @@ set debug_sync='now WAIT_FOR parked';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
set debug_sync='now SIGNAL go';
|
set debug_sync='now SIGNAL go';
|
||||||
set debug_sync='now WAIT_FOR parked2';
|
set debug_sync='now WAIT_FOR parked2';
|
||||||
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go2';
|
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go3';
|
||||||
--send drop table t1;
|
--send drop table t1;
|
||||||
--connection con2
|
--connection con2
|
||||||
set debug_sync='now WAIT_FOR waiting';
|
set debug_sync='now WAIT_FOR waiting';
|
||||||
set debug_sync='now SIGNAL go2';
|
set debug_sync='now SIGNAL go2';
|
||||||
|
set debug_sync='now SIGNAL go3';
|
||||||
# Write out show processlist if the debug sync point times out
|
|
||||||
let $wait_condition= select count(*)=0 from information_schema.processlist where state like "%debug%";
|
|
||||||
source include/wait_condition.inc;
|
|
||||||
|
|
||||||
--connection default
|
--connection default
|
||||||
--reap
|
--reap
|
||||||
|
|
|
@ -2,17 +2,17 @@ select @@global.debug_sync;
|
||||||
ERROR HY000: Variable 'debug_sync' is a SESSION variable
|
ERROR HY000: Variable 'debug_sync' is a SESSION variable
|
||||||
select @@session.debug_sync;
|
select @@session.debug_sync;
|
||||||
@@session.debug_sync
|
@@session.debug_sync
|
||||||
ON - current signal: ''
|
ON - current signals: ''
|
||||||
show global variables like "debug_sync";
|
show global variables like "debug_sync";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
show session variables like "debug_sync";
|
show session variables like "debug_sync";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
debug_sync ON - current signal: ''
|
debug_sync ON - current signals: ''
|
||||||
select * from information_schema.global_variables where variable_name="debug_sync";
|
select * from information_schema.global_variables where variable_name="debug_sync";
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
select * from information_schema.session_variables where variable_name="debug_sync";
|
select * from information_schema.session_variables where variable_name="debug_sync";
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
DEBUG_SYNC ON - current signal: ''
|
DEBUG_SYNC ON - current signals: ''
|
||||||
set @@session.debug_sync=1;
|
set @@session.debug_sync=1;
|
||||||
ERROR 42000: Incorrect argument type to variable 'debug_sync'
|
ERROR 42000: Incorrect argument type to variable 'debug_sync'
|
||||||
set @@session.debug_sync=1.1;
|
set @@session.debug_sync=1.1;
|
||||||
|
|
|
@ -77,7 +77,7 @@ READ_ONLY YES
|
||||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||||
GLOBAL_VALUE_PATH NULL
|
GLOBAL_VALUE_PATH NULL
|
||||||
VARIABLE_NAME DEBUG_SYNC
|
VARIABLE_NAME DEBUG_SYNC
|
||||||
SESSION_VALUE ON - current signal: ''
|
SESSION_VALUE ON - current signals: ''
|
||||||
GLOBAL_VALUE NULL
|
GLOBAL_VALUE NULL
|
||||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||||
DEFAULT_VALUE
|
DEFAULT_VALUE
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_gcov
|
||||||
|
#include <gcov.h>
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
Default handler for printing stacktrace
|
Default handler for printing stacktrace
|
||||||
*/
|
*/
|
||||||
|
@ -409,9 +412,6 @@ end:
|
||||||
/* Produce a core for the thread */
|
/* Produce a core for the thread */
|
||||||
void my_write_core(int sig)
|
void my_write_core(int sig)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_gcov
|
|
||||||
extern void __gcov_flush(void);
|
|
||||||
#endif
|
|
||||||
signal(sig, SIG_DFL);
|
signal(sig, SIG_DFL);
|
||||||
#ifdef HAVE_gcov
|
#ifdef HAVE_gcov
|
||||||
/*
|
/*
|
||||||
|
@ -419,7 +419,7 @@ void my_write_core(int sig)
|
||||||
information from this process, causing gcov output to be incomplete.
|
information from this process, causing gcov output to be incomplete.
|
||||||
So we force the writing of coverage information here before terminating.
|
So we force the writing of coverage information here before terminating.
|
||||||
*/
|
*/
|
||||||
__gcov_flush();
|
__gcov_dump();
|
||||||
#endif
|
#endif
|
||||||
pthread_kill(pthread_self(), sig);
|
pthread_kill(pthread_self(), sig);
|
||||||
#if defined(P_MYID) && !defined(SCO)
|
#if defined(P_MYID) && !defined(SCO)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "mariadb.h"
|
#include "mariadb.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#if defined(ENABLED_DEBUG_SYNC)
|
#if defined(ENABLED_DEBUG_SYNC)
|
||||||
|
|
||||||
|
@ -48,6 +49,8 @@ struct st_debug_sync_action
|
||||||
String wait_for; /* signal to wait for */
|
String wait_for; /* signal to wait for */
|
||||||
String sync_point; /* sync point name */
|
String sync_point; /* sync point name */
|
||||||
bool need_sort; /* if new action, array needs sort */
|
bool need_sort; /* if new action, array needs sort */
|
||||||
|
bool clear_event; /* do not clear signal when waited
|
||||||
|
for if false. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Debug sync control. Referenced by THD. */
|
/* Debug sync control. Referenced by THD. */
|
||||||
|
@ -67,21 +70,99 @@ struct st_debug_sync_control
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Definitions for the debug sync facility.
|
Definitions for the debug sync facility.
|
||||||
1. Global string variable to hold a "signal" ("signal post", "flag mast").
|
1. Global string variable to hold a set of of "signals".
|
||||||
2. Global condition variable for signaling and waiting.
|
2. Global condition variable for signaling and waiting.
|
||||||
3. Global mutex to synchronize access to the above.
|
3. Global mutex to synchronize access to the above.
|
||||||
*/
|
*/
|
||||||
struct st_debug_sync_globals
|
struct st_debug_sync_globals
|
||||||
{
|
{
|
||||||
String ds_signal; /* signal variable */
|
Hash_set<LEX_CSTRING> ds_signal_set; /* A set of active signals */
|
||||||
mysql_cond_t ds_cond; /* condition variable */
|
mysql_cond_t ds_cond; /* condition variable */
|
||||||
mysql_mutex_t ds_mutex; /* mutex variable */
|
mysql_mutex_t ds_mutex; /* mutex variable */
|
||||||
ulonglong dsp_hits; /* statistics */
|
ulonglong dsp_hits; /* statistics */
|
||||||
ulonglong dsp_executed; /* statistics */
|
ulonglong dsp_executed; /* statistics */
|
||||||
ulonglong dsp_max_active; /* statistics */
|
ulonglong dsp_max_active; /* statistics */
|
||||||
|
|
||||||
|
st_debug_sync_globals() : ds_signal_set(PSI_NOT_INSTRUMENTED, signal_key) {};
|
||||||
|
~st_debug_sync_globals()
|
||||||
|
{
|
||||||
|
clear_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_set()
|
||||||
|
{
|
||||||
|
Hash_set<LEX_CSTRING>::Iterator it{ds_signal_set};
|
||||||
|
LEX_CSTRING *s;
|
||||||
|
while ((s= it++))
|
||||||
|
my_free(s);
|
||||||
|
ds_signal_set.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hash key function for ds_signal_set. */
|
||||||
|
static uchar *signal_key(const LEX_CSTRING *str, size_t *klen, my_bool)
|
||||||
|
{
|
||||||
|
*klen= str->length;
|
||||||
|
return (uchar*) str->str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return true if the signal is found in global signal list.
|
||||||
|
|
||||||
|
@param signal_name Signal name identifying the signal.
|
||||||
|
|
||||||
|
@note
|
||||||
|
If signal is found in the global signal set, it means that the
|
||||||
|
signal thread has signalled to the waiting thread. This method
|
||||||
|
must be called with the debug_sync_global.ds_mutex held.
|
||||||
|
|
||||||
|
@retval true if signal is found in the global signal list.
|
||||||
|
@retval false otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline bool is_signalled(const char *signal_name, size_t length)
|
||||||
|
{
|
||||||
|
return ds_signal_set.find(signal_name, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_signal(const String &signal_name)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("clear_signal");
|
||||||
|
LEX_CSTRING *record= ds_signal_set.find(signal_name.ptr(),
|
||||||
|
signal_name.length());
|
||||||
|
if (record)
|
||||||
|
{
|
||||||
|
ds_signal_set.remove(record);
|
||||||
|
my_free(record);
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_signal(const char *signal_name, size_t length)
|
||||||
|
{
|
||||||
|
/* Need to check if the signal is already in the hash set, because
|
||||||
|
Hash_set doesn't differentiate between OOM and key already in. */
|
||||||
|
if (is_signalled(signal_name, length))
|
||||||
|
return FALSE;
|
||||||
|
/* LEX_CSTRING and the string allocated with only one malloc. */
|
||||||
|
LEX_CSTRING *s= (LEX_CSTRING *) my_malloc(PSI_NOT_INSTRUMENTED,
|
||||||
|
sizeof(LEX_CSTRING) + length + 1,
|
||||||
|
MYF(0));
|
||||||
|
char *str= (char *)(s + 1);
|
||||||
|
memcpy(str, signal_name, length);
|
||||||
|
str[length]= '\0';
|
||||||
|
|
||||||
|
s->length= length;
|
||||||
|
s->str= str;
|
||||||
|
if (ds_signal_set.insert(s))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static st_debug_sync_globals debug_sync_global; /* All globals in one object */
|
static st_debug_sync_globals debug_sync_global; /* All globals in one object */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -161,7 +242,7 @@ int debug_sync_init(void)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Initialize the global variables. */
|
/* Initialize the global variables. */
|
||||||
debug_sync_global.ds_signal.length(0);
|
debug_sync_global.clear_set();
|
||||||
if ((rc= mysql_cond_init(key_debug_sync_globals_ds_cond,
|
if ((rc= mysql_cond_init(key_debug_sync_globals_ds_cond,
|
||||||
&debug_sync_global.ds_cond, NULL)) ||
|
&debug_sync_global.ds_cond, NULL)) ||
|
||||||
(rc= mysql_mutex_init(key_debug_sync_globals_ds_mutex,
|
(rc= mysql_mutex_init(key_debug_sync_globals_ds_mutex,
|
||||||
|
@ -195,7 +276,7 @@ void debug_sync_end(void)
|
||||||
debug_sync_C_callback_ptr= NULL;
|
debug_sync_C_callback_ptr= NULL;
|
||||||
|
|
||||||
/* Destroy the global variables. */
|
/* Destroy the global variables. */
|
||||||
debug_sync_global.ds_signal.free();
|
debug_sync_global.clear_set();
|
||||||
mysql_cond_destroy(&debug_sync_global.ds_cond);
|
mysql_cond_destroy(&debug_sync_global.ds_cond);
|
||||||
mysql_mutex_destroy(&debug_sync_global.ds_mutex);
|
mysql_mutex_destroy(&debug_sync_global.ds_mutex);
|
||||||
|
|
||||||
|
@ -271,6 +352,40 @@ void debug_sync_init_thread(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns an allocated buffer containing a comma-separated C string of all
|
||||||
|
active signals.
|
||||||
|
|
||||||
|
Buffer must be freed by the caller.
|
||||||
|
*/
|
||||||
|
static const char *get_signal_set_as_string()
|
||||||
|
{
|
||||||
|
mysql_mutex_assert_owner(&debug_sync_global.ds_mutex);
|
||||||
|
size_t req_size= 1; // In case of empty set for the end '\0' char.
|
||||||
|
|
||||||
|
for (size_t i= 0; i < debug_sync_global.ds_signal_set.size(); i++)
|
||||||
|
req_size+= debug_sync_global.ds_signal_set.at(i)->length + 1;
|
||||||
|
|
||||||
|
char *buf= (char *) my_malloc(PSI_NOT_INSTRUMENTED, req_size, MYF(0));
|
||||||
|
if (!buf)
|
||||||
|
return nullptr;
|
||||||
|
memset(buf, '\0', req_size);
|
||||||
|
|
||||||
|
char *cur_pos= buf;
|
||||||
|
for (size_t i= 0; i < debug_sync_global.ds_signal_set.size(); i++)
|
||||||
|
{
|
||||||
|
const LEX_CSTRING *signal= debug_sync_global.ds_signal_set.at(i);
|
||||||
|
memcpy(cur_pos, signal->str, signal->length);
|
||||||
|
if (i != debug_sync_global.ds_signal_set.size() - 1)
|
||||||
|
cur_pos[signal->length]= ',';
|
||||||
|
else
|
||||||
|
cur_pos[signal->length] = '\0';
|
||||||
|
cur_pos+= signal->length + 1;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
End the debug sync facility at thread end.
|
End the debug sync facility at thread end.
|
||||||
|
|
||||||
|
@ -554,7 +669,7 @@ static void debug_sync_reset(THD *thd)
|
||||||
|
|
||||||
/* Clear the global signal. */
|
/* Clear the global signal. */
|
||||||
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
||||||
debug_sync_global.ds_signal.length(0);
|
debug_sync_global.clear_set();
|
||||||
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
|
mysql_mutex_unlock(&debug_sync_global.ds_mutex);
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -1175,6 +1290,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end)
|
||||||
/* Set default for EXECUTE and TIMEOUT options. */
|
/* Set default for EXECUTE and TIMEOUT options. */
|
||||||
action->execute= 1;
|
action->execute= 1;
|
||||||
action->timeout= opt_debug_sync_timeout;
|
action->timeout= opt_debug_sync_timeout;
|
||||||
|
action->clear_event= true;
|
||||||
|
|
||||||
/* Get next token. If none follows, set action. */
|
/* Get next token. If none follows, set action. */
|
||||||
if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end)))
|
if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end)))
|
||||||
|
@ -1225,6 +1341,15 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end)
|
||||||
goto set_action;
|
goto set_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Try NO_CLEAR_EVENT.
|
||||||
|
*/
|
||||||
|
if (!my_strcasecmp(system_charset_info, token, "NO_CLEAR_EVENT")) {
|
||||||
|
action->clear_event= false;
|
||||||
|
/* Get next token. If none follows, set action. */
|
||||||
|
if (!(ptr = debug_sync_token(&token, &token_length, ptr, action_end))) goto set_action;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try HIT_LIMIT.
|
Try HIT_LIMIT.
|
||||||
*/
|
*/
|
||||||
|
@ -1325,13 +1450,19 @@ uchar *debug_sync_value_ptr(THD *thd)
|
||||||
|
|
||||||
if (opt_debug_sync_timeout)
|
if (opt_debug_sync_timeout)
|
||||||
{
|
{
|
||||||
static char on[]= "ON - current signal: '";
|
static char on[]= "ON - current signals: '";
|
||||||
|
|
||||||
// Ensure exclusive access to debug_sync_global.ds_signal
|
// Ensure exclusive access to debug_sync_global.ds_signal
|
||||||
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
||||||
|
|
||||||
size_t lgt= (sizeof(on) /* includes '\0' */ +
|
size_t lgt= sizeof(on) + 1; /* +1 as we'll have to append ' at the end. */
|
||||||
debug_sync_global.ds_signal.length() + 1 /* for '\'' */);
|
|
||||||
|
for (size_t i= 0; i < debug_sync_global.ds_signal_set.size(); i++)
|
||||||
|
{
|
||||||
|
/* Assume each signal is separated by a comma, hence +1. */
|
||||||
|
lgt+= debug_sync_global.ds_signal_set.at(i)->length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
char *vend;
|
char *vend;
|
||||||
char *vptr;
|
char *vptr;
|
||||||
|
|
||||||
|
@ -1339,9 +1470,14 @@ uchar *debug_sync_value_ptr(THD *thd)
|
||||||
{
|
{
|
||||||
vend= value + lgt - 1; /* reserve space for '\0'. */
|
vend= value + lgt - 1; /* reserve space for '\0'. */
|
||||||
vptr= debug_sync_bmove_len(value, vend, STRING_WITH_LEN(on));
|
vptr= debug_sync_bmove_len(value, vend, STRING_WITH_LEN(on));
|
||||||
vptr= debug_sync_bmove_len(vptr, vend, debug_sync_global.ds_signal.ptr(),
|
for (size_t i= 0; i < debug_sync_global.ds_signal_set.size(); i++)
|
||||||
debug_sync_global.ds_signal.length());
|
{
|
||||||
if (vptr < vend)
|
const LEX_CSTRING *s= debug_sync_global.ds_signal_set.at(i);
|
||||||
|
vptr= debug_sync_bmove_len(vptr, vend, s->str, s->length);
|
||||||
|
if (i != debug_sync_global.ds_signal_set.size() - 1)
|
||||||
|
*(vptr++)= ',';
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(vptr < vend);
|
||||||
*(vptr++)= '\'';
|
*(vptr++)= '\'';
|
||||||
*vptr= '\0'; /* We have one byte reserved for the worst case. */
|
*vptr= '\0'; /* We have one byte reserved for the worst case. */
|
||||||
}
|
}
|
||||||
|
@ -1358,6 +1494,9 @@ uchar *debug_sync_value_ptr(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Execute requested action at a synchronization point.
|
Execute requested action at a synchronization point.
|
||||||
|
|
||||||
|
@ -1413,12 +1552,28 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
|
||||||
read access too, to create a memory barrier in order to avoid that
|
read access too, to create a memory barrier in order to avoid that
|
||||||
threads just reads an old cached version of the signal.
|
threads just reads an old cached version of the signal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
mysql_mutex_lock(&debug_sync_global.ds_mutex);
|
||||||
|
|
||||||
if (action->signal.length())
|
if (action->signal.length())
|
||||||
{
|
{
|
||||||
/* Copy the signal to the global variable. */
|
int offset= 0, pos;
|
||||||
if (debug_sync_global.ds_signal.copy(action->signal))
|
bool error= false;
|
||||||
|
|
||||||
|
/* This loop covers all signals in the list except for the last one.
|
||||||
|
Split the signal string by commas and set a signal in the global
|
||||||
|
variable for each one. */
|
||||||
|
while (!error && (pos= action->signal.strstr(",", 1, offset)) > 0)
|
||||||
|
{
|
||||||
|
error= debug_sync_global.set_signal(action->signal.ptr() + offset,
|
||||||
|
pos - offset);
|
||||||
|
offset= pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error ||
|
||||||
|
/* The last signal in the list. */
|
||||||
|
debug_sync_global.set_signal(action->signal.ptr() + offset,
|
||||||
|
action->signal.length() - offset))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Error is reported by my_malloc().
|
Error is reported by my_malloc().
|
||||||
|
@ -1461,12 +1616,22 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
|
||||||
restore_current_mutex = false;
|
restore_current_mutex = false;
|
||||||
|
|
||||||
set_timespec(abstime, action->timeout);
|
set_timespec(abstime, action->timeout);
|
||||||
DBUG_EXECUTE("debug_sync_exec",
|
DBUG_EXECUTE("debug_sync_exec", {
|
||||||
|
const char *signal_set= get_signal_set_as_string();
|
||||||
|
if (!signal_set)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("debug_sync_exec",
|
||||||
|
("Out of memory when fetching signal set"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Functions as DBUG_PRINT args can change keyword and line nr. */
|
/* Functions as DBUG_PRINT args can change keyword and line nr. */
|
||||||
DBUG_PRINT("debug_sync_exec",
|
DBUG_PRINT("debug_sync_exec",
|
||||||
("wait for '%s' at: '%s' curr: '%s'",
|
("wait for '%s' at: '%s', curr: '%s'",
|
||||||
sig_wait, dsp_name,
|
sig_wait, dsp_name, signal_set));
|
||||||
debug_sync_global.ds_signal.c_ptr())););
|
my_free((void *)signal_set);
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Wait until global signal string matches the wait_for string.
|
Wait until global signal string matches the wait_for string.
|
||||||
|
@ -1474,18 +1639,20 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
|
||||||
The facility can become disabled when some thread cannot get
|
The facility can become disabled when some thread cannot get
|
||||||
the required dynamic memory allocated.
|
the required dynamic memory allocated.
|
||||||
*/
|
*/
|
||||||
while (stringcmp(&debug_sync_global.ds_signal, &action->wait_for) &&
|
while (!debug_sync_global.is_signalled(action->wait_for.ptr(),
|
||||||
!(thd->killed & KILL_HARD_BIT) && opt_debug_sync_timeout)
|
action->wait_for.length()) &&
|
||||||
|
!(thd->killed & KILL_HARD_BIT) &&
|
||||||
|
opt_debug_sync_timeout)
|
||||||
{
|
{
|
||||||
error= mysql_cond_timedwait(&debug_sync_global.ds_cond,
|
error= mysql_cond_timedwait(&debug_sync_global.ds_cond,
|
||||||
&debug_sync_global.ds_mutex,
|
&debug_sync_global.ds_mutex,
|
||||||
&abstime);
|
&abstime);
|
||||||
DBUG_EXECUTE("debug_sync",
|
// TODO turn this into a for loop printing.
|
||||||
|
DBUG_EXECUTE("debug_sync", {
|
||||||
/* Functions as DBUG_PRINT args can change keyword and line nr. */
|
/* Functions as DBUG_PRINT args can change keyword and line nr. */
|
||||||
DBUG_PRINT("debug_sync",
|
DBUG_PRINT("debug_sync",
|
||||||
("awoke from %s global: %s error: %d",
|
("awoke from %s error: %d",
|
||||||
sig_wait, debug_sync_global.ds_signal.c_ptr(),
|
sig_wait, error));});
|
||||||
error)););
|
|
||||||
if (unlikely(error == ETIMEDOUT || error == ETIME))
|
if (unlikely(error == ETIMEDOUT || error == ETIME))
|
||||||
{
|
{
|
||||||
// We should not make the statement fail, even if in strict mode.
|
// We should not make the statement fail, even if in strict mode.
|
||||||
|
@ -1498,6 +1665,10 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
|
||||||
}
|
}
|
||||||
error= 0;
|
error= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action->clear_event)
|
||||||
|
debug_sync_global.clear_signal(action->wait_for);
|
||||||
|
|
||||||
DBUG_EXECUTE("debug_sync_exec",
|
DBUG_EXECUTE("debug_sync_exec",
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
DBUG_PRINT("debug_sync_exec",
|
DBUG_PRINT("debug_sync_exec",
|
||||||
|
@ -1571,10 +1742,10 @@ static void debug_sync(THD *thd, const char *sync_point_name, size_t name_len)
|
||||||
st_debug_sync_control *ds_control= thd->debug_sync_control;
|
st_debug_sync_control *ds_control= thd->debug_sync_control;
|
||||||
st_debug_sync_action *action;
|
st_debug_sync_action *action;
|
||||||
DBUG_ENTER("debug_sync");
|
DBUG_ENTER("debug_sync");
|
||||||
|
DBUG_PRINT("debug_sync_point", ("hit: '%s'", sync_point_name));
|
||||||
DBUG_ASSERT(sync_point_name);
|
DBUG_ASSERT(sync_point_name);
|
||||||
DBUG_ASSERT(name_len);
|
DBUG_ASSERT(name_len);
|
||||||
DBUG_ASSERT(ds_control);
|
DBUG_ASSERT(ds_control);
|
||||||
DBUG_PRINT("debug_sync_point", ("hit: '%s'", sync_point_name));
|
|
||||||
|
|
||||||
/* Statistics. */
|
/* Statistics. */
|
||||||
ds_control->dsp_hits++;
|
ds_control->dsp_hits++;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||||
|
|
||||||
|
#include "my_global.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,20 +29,18 @@ class Hash_set
|
||||||
public:
|
public:
|
||||||
enum { START_SIZE= 8 };
|
enum { START_SIZE= 8 };
|
||||||
/**
|
/**
|
||||||
Constructs an empty hash. Does not allocate memory, it is done upon
|
Constructs an empty unique hash.
|
||||||
the first insert. Thus does not cause or return errors.
|
|
||||||
*/
|
*/
|
||||||
Hash_set(PSI_memory_key psi_key, uchar *(*K)(const T *, size_t *, my_bool),
|
Hash_set(PSI_memory_key psi_key, uchar *(*K)(const T *, size_t *, my_bool),
|
||||||
CHARSET_INFO *cs= &my_charset_bin)
|
CHARSET_INFO *cs= &my_charset_bin)
|
||||||
{
|
{
|
||||||
my_hash_clear(&m_hash);
|
my_hash_init(psi_key, &m_hash, cs, START_SIZE, 0, 0, (my_hash_get_key)K, 0,
|
||||||
m_hash.get_key= (my_hash_get_key)K;
|
HASH_UNIQUE);
|
||||||
m_hash.charset= cs;
|
|
||||||
m_hash.array.m_psi_key= psi_key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash_set(PSI_memory_key psi_key, CHARSET_INFO *charset, ulong default_array_elements,
|
Hash_set(PSI_memory_key psi_key, CHARSET_INFO *charset, ulong default_array_elements,
|
||||||
size_t key_offset, size_t key_length, my_hash_get_key get_key,
|
size_t key_offset, size_t key_length, my_hash_get_key get_key,
|
||||||
void (*free_element)(void*), uint flags)
|
void (*free_element)(void*),uint flags)
|
||||||
{
|
{
|
||||||
my_hash_init(psi_key, &m_hash, charset, default_array_elements, key_offset,
|
my_hash_init(psi_key, &m_hash, charset, default_array_elements, key_offset,
|
||||||
key_length, get_key, free_element, flags);
|
key_length, get_key, free_element, flags);
|
||||||
|
@ -65,8 +64,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool insert(T *value)
|
bool insert(T *value)
|
||||||
{
|
{
|
||||||
my_hash_init_opt(m_hash.array.m_psi_key, &m_hash, m_hash.charset,
|
|
||||||
START_SIZE, 0, 0, m_hash.get_key, 0, HASH_UNIQUE);
|
|
||||||
return my_hash_insert(&m_hash, reinterpret_cast<const uchar*>(value));
|
return my_hash_insert(&m_hash, reinterpret_cast<const uchar*>(value));
|
||||||
}
|
}
|
||||||
bool remove(T *value)
|
bool remove(T *value)
|
||||||
|
|
|
@ -677,24 +677,23 @@ bool String::append_with_prefill(const char *s,uint32 arg_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Binary_string::strstr(const Binary_string &s, uint32 offset)
|
int Binary_string::strstr(const char *search, uint32 search_length, uint32 offset)
|
||||||
{
|
{
|
||||||
if (s.length()+offset <= str_length)
|
if (search_length + offset <= str_length)
|
||||||
{
|
{
|
||||||
if (!s.length())
|
if (!search_length)
|
||||||
return ((int) offset); // Empty string is always found
|
return ((int) offset); // Empty string is always found
|
||||||
|
|
||||||
const char *str = Ptr+offset;
|
const char *str= Ptr + offset;
|
||||||
const char *search=s.ptr();
|
const char *end= Ptr + str_length - search_length + 1;
|
||||||
const char *end=Ptr+str_length-s.length()+1;
|
const char *search_end= search + search_length;
|
||||||
const char *search_end=s.ptr()+s.length();
|
|
||||||
skip:
|
skip:
|
||||||
while (str != end)
|
while (str != end)
|
||||||
{
|
{
|
||||||
if (*str++ == *search)
|
if (*str++ == *search)
|
||||||
{
|
{
|
||||||
char *i,*j;
|
char *i= (char*) str;
|
||||||
i=(char*) str; j=(char*) search+1;
|
char *j= (char*) search + 1 ;
|
||||||
while (j != search_end)
|
while (j != search_end)
|
||||||
if (*i++ != *j++) goto skip;
|
if (*i++ != *j++) goto skip;
|
||||||
return (int) (str-Ptr) -1;
|
return (int) (str-Ptr) -1;
|
||||||
|
@ -704,6 +703,11 @@ skip:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Binary_string::strstr(const Binary_string &s, uint32 offset)
|
||||||
|
{
|
||||||
|
return strstr(s.ptr(), s.length(), offset);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Search string from end. Offset is offset to the end of string
|
** Search string from end. Offset is offset to the end of string
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -330,6 +330,7 @@ public:
|
||||||
|
|
||||||
// Returns offset to substring or -1
|
// Returns offset to substring or -1
|
||||||
int strstr(const Binary_string &search, uint32 offset=0);
|
int strstr(const Binary_string &search, uint32 offset=0);
|
||||||
|
int strstr(const char *search, uint32 search_length, uint32 offset=0);
|
||||||
// Returns offset to substring or -1
|
// Returns offset to substring or -1
|
||||||
int strrstr(const Binary_string &search, uint32 offset=0);
|
int strrstr(const Binary_string &search, uint32 offset=0);
|
||||||
|
|
||||||
|
|
|
@ -3571,7 +3571,7 @@ char *bson_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||||
} // endif Xchk
|
} // endif Xchk
|
||||||
|
|
||||||
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
|
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
|
||||||
JTYP type;
|
JTYP type= TYPE_JAR;
|
||||||
BJNX bnx(g);
|
BJNX bnx(g);
|
||||||
PBVAL jvp = NULL, top = NULL;
|
PBVAL jvp = NULL, top = NULL;
|
||||||
PBVAL jsp[2] = {NULL, NULL};
|
PBVAL jsp[2] = {NULL, NULL};
|
||||||
|
@ -5724,7 +5724,7 @@ char *bbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||||
} // endif Xchk
|
} // endif Xchk
|
||||||
|
|
||||||
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
|
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
|
||||||
JTYP type;
|
JTYP type = TYPE_JAR;
|
||||||
BJNX bnx(g);
|
BJNX bnx(g);
|
||||||
PBVAL jvp = NULL, top = NULL;
|
PBVAL jvp = NULL, top = NULL;
|
||||||
PBVAL jsp[2] = {NULL, NULL};
|
PBVAL jsp[2] = {NULL, NULL};
|
||||||
|
|
Loading…
Reference in a new issue