Merge branch '10.1' into 10.2
This commit is contained in:
commit
f8b5e147da
@ -3213,7 +3213,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;
|
||||
@ -3232,7 +3232,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);
|
||||
|
||||
@ -3297,7 +3297,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)
|
||||
|
146
dbug/dbug.c
146
dbug/dbug.c
@ -320,8 +320,36 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args);
|
||||
*/
|
||||
|
||||
#include <my_pthread.h>
|
||||
/*
|
||||
** Protects writing to all file descriptors, init_settings.keywords
|
||||
** pointer and it's pointee - a linked list with keywords.
|
||||
*/
|
||||
static pthread_mutex_t THR_LOCK_dbug;
|
||||
|
||||
static void LockMutex(CODE_STATE *cs)
|
||||
{
|
||||
if (!cs->locked)
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked++;
|
||||
}
|
||||
static void UnlockMutex(CODE_STATE *cs)
|
||||
{
|
||||
--cs->locked;
|
||||
assert(cs->locked >= 0);
|
||||
if (cs->locked == 0)
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
static void LockIfInitSettings(CODE_STATE *cs)
|
||||
{
|
||||
if (cs->stack == &init_settings)
|
||||
LockMutex(cs);
|
||||
}
|
||||
static void UnlockIfInitSettings(CODE_STATE *cs)
|
||||
{
|
||||
if (cs->stack == &init_settings)
|
||||
UnlockMutex(cs);
|
||||
}
|
||||
|
||||
static CODE_STATE *code_state(void)
|
||||
{
|
||||
CODE_STATE *cs, **cs_ptr;
|
||||
@ -449,16 +477,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
|
||||
const char *end;
|
||||
int rel, f_used=0;
|
||||
struct settings *stack;
|
||||
int org_cs_locked;
|
||||
|
||||
stack= cs->stack;
|
||||
|
||||
if (!(org_cs_locked= cs->locked))
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked= 1;
|
||||
}
|
||||
|
||||
if (control[0] == '-' && control[1] == '#')
|
||||
control+=2;
|
||||
|
||||
@ -472,7 +493,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
|
||||
stack->sub_level= 0;
|
||||
stack->out_file= sstderr;
|
||||
stack->functions= NULL;
|
||||
LockIfInitSettings(cs);
|
||||
stack->keywords= NULL;
|
||||
UnlockIfInitSettings(cs);
|
||||
stack->processes= NULL;
|
||||
}
|
||||
else if (!stack->out_file)
|
||||
@ -488,7 +511,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
|
||||
{
|
||||
/* never share with the global parent - it can change under your feet */
|
||||
stack->functions= ListCopy(init_settings.functions);
|
||||
LockIfInitSettings(cs);
|
||||
stack->keywords= ListCopy(init_settings.keywords);
|
||||
UnlockIfInitSettings(cs);
|
||||
stack->processes= ListCopy(init_settings.processes);
|
||||
}
|
||||
else
|
||||
@ -512,21 +537,31 @@ static int DbugParse(CODE_STATE *cs, const char *control)
|
||||
case 'd':
|
||||
if (sign < 0 && control == end)
|
||||
{
|
||||
LockIfInitSettings(cs);
|
||||
if (!is_shared(stack, keywords))
|
||||
FreeList(stack->keywords);
|
||||
stack->keywords=NULL;
|
||||
UnlockIfInitSettings(cs);
|
||||
stack->flags &= ~DEBUG_ON;
|
||||
break;
|
||||
}
|
||||
LockIfInitSettings(cs);
|
||||
if (rel && is_shared(stack, keywords))
|
||||
stack->keywords= ListCopy(stack->keywords);
|
||||
UnlockIfInitSettings(cs);
|
||||
if (sign < 0)
|
||||
{
|
||||
if (DEBUGGING)
|
||||
{
|
||||
LockIfInitSettings(cs);
|
||||
stack->keywords= ListDel(stack->keywords, control, end);
|
||||
UnlockIfInitSettings(cs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
LockIfInitSettings(cs);
|
||||
stack->keywords= ListAdd(stack->keywords, control, end);
|
||||
UnlockIfInitSettings(cs);
|
||||
stack->flags |= DEBUG_ON;
|
||||
break;
|
||||
case 'D':
|
||||
@ -661,11 +696,6 @@ static int DbugParse(CODE_STATE *cs, const char *control)
|
||||
control=end+1;
|
||||
end= DbugStrTok(control);
|
||||
}
|
||||
if (!org_cs_locked)
|
||||
{
|
||||
cs->locked= 0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
return !rel || f_used;
|
||||
}
|
||||
|
||||
@ -998,7 +1028,9 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
|
||||
|
||||
get_code_state_if_not_set_or_return *buf=0;
|
||||
|
||||
LockIfInitSettings(cs);
|
||||
op_list_to_buf('d', cs->stack->keywords, DEBUGGING);
|
||||
UnlockIfInitSettings(cs);
|
||||
op_int_to_buf ('D', cs->stack->delay, 0);
|
||||
op_list_to_buf('f', cs->stack->functions, cs->stack->functions);
|
||||
op_bool_to_buf('F', cs->stack->flags & FILE_ON);
|
||||
@ -1093,7 +1125,6 @@ int _db_explain_init_(char *buf, size_t len)
|
||||
void _db_enter_(const char *_func_, const char *_file_,
|
||||
uint _line_, struct _db_stack_frame_ *_stack_frame_)
|
||||
{
|
||||
int save_errno, org_cs_locked;
|
||||
CODE_STATE *cs;
|
||||
if (!((cs=code_state())))
|
||||
{
|
||||
@ -1101,7 +1132,6 @@ void _db_enter_(const char *_func_, const char *_file_,
|
||||
_stack_frame_->prev= 0;
|
||||
return;
|
||||
}
|
||||
save_errno= errno;
|
||||
|
||||
_stack_frame_->line= -1;
|
||||
_stack_frame_->func= cs->func;
|
||||
@ -1122,20 +1152,14 @@ void _db_enter_(const char *_func_, const char *_file_,
|
||||
cs->stack->flags &= ~SANITY_CHECK_ON;
|
||||
if (TRACING)
|
||||
{
|
||||
if (!(org_cs_locked= cs->locked))
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked= 1;
|
||||
}
|
||||
int save_errno= errno;
|
||||
LockMutex(cs);
|
||||
DoPrefix(cs, _line_);
|
||||
Indent(cs, cs->level);
|
||||
(void) fprintf(cs->stack->out_file->file, ">%s\n", cs->func);
|
||||
DbugFlush(cs); /* This does a unlock */
|
||||
if (!org_cs_locked)
|
||||
{
|
||||
cs->locked= 0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
UnlockMutex(cs);
|
||||
DbugFlush(cs);
|
||||
errno=save_errno;
|
||||
}
|
||||
break;
|
||||
case DISABLE_TRACE:
|
||||
@ -1144,7 +1168,6 @@ void _db_enter_(const char *_func_, const char *_file_,
|
||||
case DONT_TRACE:
|
||||
break;
|
||||
}
|
||||
errno=save_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1169,7 +1192,6 @@ void _db_enter_(const char *_func_, const char *_file_,
|
||||
|
||||
void _db_return_(struct _db_stack_frame_ *_stack_frame_)
|
||||
{
|
||||
int save_errno=errno;
|
||||
uint _slevel_= _stack_frame_->level & ~TRACE_ON;
|
||||
CODE_STATE *cs;
|
||||
get_code_state_or_return;
|
||||
@ -1186,25 +1208,18 @@ void _db_return_(struct _db_stack_frame_ *_stack_frame_)
|
||||
|
||||
if (DoTrace(cs) & DO_TRACE)
|
||||
{
|
||||
int org_cs_locked;
|
||||
if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
|
||||
cs->stack->flags &= ~SANITY_CHECK_ON;
|
||||
if (TRACING)
|
||||
{
|
||||
if (!(org_cs_locked= cs->locked))
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked= 1;
|
||||
}
|
||||
int save_errno=errno;
|
||||
LockMutex(cs);
|
||||
DoPrefix(cs, _stack_frame_->line);
|
||||
Indent(cs, cs->level);
|
||||
(void) fprintf(cs->stack->out_file->file, "<%s\n", cs->func);
|
||||
UnlockMutex(cs);
|
||||
DbugFlush(cs);
|
||||
if (!org_cs_locked)
|
||||
{
|
||||
cs->locked= 0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
errno=save_errno;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -1216,7 +1231,6 @@ void _db_return_(struct _db_stack_frame_ *_stack_frame_)
|
||||
cs->file= _stack_frame_->file;
|
||||
if (cs->framep != NULL)
|
||||
cs->framep= cs->framep->prev;
|
||||
errno=save_errno;
|
||||
}
|
||||
|
||||
|
||||
@ -1281,18 +1295,14 @@ void _db_doprnt_(const char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
CODE_STATE *cs;
|
||||
int save_errno, org_cs_locked;
|
||||
int save_errno;
|
||||
|
||||
get_code_state_or_return;
|
||||
|
||||
va_start(args,format);
|
||||
|
||||
if (!(org_cs_locked= cs->locked))
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked= 1;
|
||||
}
|
||||
save_errno=errno;
|
||||
LockMutex(cs);
|
||||
DoPrefix(cs, cs->u_line);
|
||||
if (TRACING)
|
||||
Indent(cs, cs->level + 1);
|
||||
@ -1300,12 +1310,8 @@ void _db_doprnt_(const char *format,...)
|
||||
(void) fprintf(cs->stack->out_file->file, "%s: ", cs->func);
|
||||
(void) fprintf(cs->stack->out_file->file, "%s: ", cs->u_keyword);
|
||||
DbugVfprintf(cs->stack->out_file->file, format, args);
|
||||
UnlockMutex(cs);
|
||||
DbugFlush(cs);
|
||||
if (!org_cs_locked)
|
||||
{
|
||||
cs->locked= 0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
errno=save_errno;
|
||||
|
||||
va_end(args);
|
||||
@ -1345,17 +1351,13 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args)
|
||||
void _db_dump_(uint _line_, const char *keyword,
|
||||
const unsigned char *memory, size_t length)
|
||||
{
|
||||
int pos, org_cs_locked;
|
||||
int pos;
|
||||
CODE_STATE *cs;
|
||||
get_code_state_or_return;
|
||||
|
||||
if (!(org_cs_locked= cs->locked))
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked= 1;
|
||||
}
|
||||
if (_db_keyword_(cs, keyword, 0))
|
||||
{
|
||||
LockMutex(cs);
|
||||
DoPrefix(cs, _line_);
|
||||
if (TRACING)
|
||||
{
|
||||
@ -1383,13 +1385,9 @@ void _db_dump_(uint _line_, const char *keyword,
|
||||
fputc(' ',cs->stack->out_file->file);
|
||||
}
|
||||
(void) fputc('\n',cs->stack->out_file->file);
|
||||
UnlockMutex(cs);
|
||||
DbugFlush(cs);
|
||||
}
|
||||
if (!org_cs_locked)
|
||||
{
|
||||
cs->locked= 0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1617,8 +1615,10 @@ static void PushState(CODE_STATE *cs)
|
||||
static void FreeState(CODE_STATE *cs, int free_state)
|
||||
{
|
||||
struct settings *state= cs->stack;
|
||||
LockIfInitSettings(cs);
|
||||
if (!is_shared(state, keywords))
|
||||
FreeList(state->keywords);
|
||||
UnlockIfInitSettings(cs);
|
||||
if (!is_shared(state, functions))
|
||||
FreeList(state->functions);
|
||||
if (!is_shared(state, processes))
|
||||
@ -1697,8 +1697,6 @@ void _db_end_()
|
||||
static int DoTrace(CODE_STATE *cs)
|
||||
{
|
||||
int res= DONT_TRACE;
|
||||
if (!cs->locked)
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) &&
|
||||
InList(cs->stack->processes, cs->process, 0) & (MATCHED|INCLUDE))
|
||||
{
|
||||
@ -1723,8 +1721,6 @@ static int DoTrace(CODE_STATE *cs)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cs->locked)
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1764,11 +1760,9 @@ BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
|
||||
|
||||
if (!(DEBUGGING && (DoTrace(cs) & DO_TRACE)))
|
||||
return 0;
|
||||
if (!cs->locked)
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
LockIfInitSettings(cs);
|
||||
res= (InList(cs->stack->keywords, keyword, strict) & match);
|
||||
if (!cs->locked)
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
UnlockIfInitSettings(cs);
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
@ -1995,16 +1989,16 @@ static void DBUGCloseFile(CODE_STATE *cs, sFILE *new_value)
|
||||
sFILE *fp;
|
||||
if (!cs || !cs->stack || !cs->stack->out_file)
|
||||
return;
|
||||
if (!cs->locked)
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
|
||||
fp= cs->stack->out_file;
|
||||
if (--fp->used == 0)
|
||||
{
|
||||
if (fclose(fp->file) == EOF)
|
||||
{
|
||||
LockMutex(cs);
|
||||
(void) fprintf(stderr, ERR_CLOSE, cs->process);
|
||||
perror("");
|
||||
UnlockMutex(cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2012,8 +2006,6 @@ static void DBUGCloseFile(CODE_STATE *cs, sFILE *new_value)
|
||||
}
|
||||
}
|
||||
cs->stack->out_file= new_value;
|
||||
if (!cs->locked)
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
|
||||
|
||||
@ -2196,9 +2188,7 @@ void _db_flush_()
|
||||
get_code_state_or_return;
|
||||
if (DEBUGGING)
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
(void) fflush(cs->stack->out_file->file);
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2226,16 +2216,14 @@ void _db_lock_file_()
|
||||
{
|
||||
CODE_STATE *cs;
|
||||
get_code_state_or_return;
|
||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||
cs->locked=1;
|
||||
LockMutex(cs);
|
||||
}
|
||||
|
||||
void _db_unlock_file_()
|
||||
{
|
||||
CODE_STATE *cs;
|
||||
get_code_state_or_return;
|
||||
cs->locked=0;
|
||||
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||
UnlockMutex(cs);
|
||||
}
|
||||
|
||||
const char* _db_get_func_(void)
|
||||
|
@ -1937,8 +1937,10 @@ Run stress test, providing options to mysql\-stress\-test\&.pl\&. Options are se
|
||||
.\" suite option: mysql-test-run.pl
|
||||
\fB\-\-suite[s]=\fR\fB\fIsuite_name...\fR\fR
|
||||
.sp
|
||||
Comma separated list of suite names to run. The default is: "main-,archive-,binlog-,csv-,federated-,funcs_1-,funcs_2-,handler-,heap-,innodb-,innodb_fts-,
|
||||
innodb_zip-,maria-,multi_source-,optimizer_unfixed_bugs-,parts-,percona-,perfschema-,
|
||||
Comma separated list of suite names to run. The default is:
|
||||
"main-,archive-,binlog-,csv-,federated-,funcs_1-,funcs_2-,
|
||||
handler-,heap-,innodb-,innodb_fts-,innodb_zip-,maria-,
|
||||
multi_source-,optimizer_unfixed_bugs-,parts-,perfschema-,
|
||||
plugins-,roles-,rpl-,sys_vars-,unit-,vcol-"\&.
|
||||
.RE
|
||||
.sp
|
||||
|
@ -321,7 +321,8 @@ my $opt_valgrind_mysqld= 0;
|
||||
my $opt_valgrind_mysqltest= 0;
|
||||
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;
|
||||
@ -1324,9 +1325,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,
|
||||
@ -1921,7 +1923,7 @@ sub command_line_setup {
|
||||
join(" ", @valgrind_args), "\"");
|
||||
}
|
||||
|
||||
if (@strace_args)
|
||||
if (@strace_args || $opt_stracer)
|
||||
{
|
||||
$opt_strace=1;
|
||||
}
|
||||
@ -5845,14 +5847,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 )
|
||||
@ -5918,6 +5912,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");
|
||||
@ -6242,16 +6247,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 overridden 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)
|
||||
{
|
||||
@ -6527,11 +6533,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=<EXE> Specify name and path to the trace program to use.
|
||||
Default is "strace". Example: $0 --stracer=ktrace.
|
||||
|
||||
Misc options
|
||||
user=USER User for connecting to mysqld(default: $opt_user)
|
||||
|
@ -1544,5 +1544,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'.
|
||||
|
@ -3206,6 +3206,36 @@ pk
|
||||
3
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-21044: Wrong result when using a smaller size for sort buffer
|
||||
#
|
||||
create table t1(a varchar(765),b int);
|
||||
insert into t1 values ("a",1),("b",2),("c",3),("e",4);
|
||||
insert into t1 values ("d",5),("f",6),("g",7),("h",8);
|
||||
insert into t1 values ("k",11),("l",12),("i",9),("j",10);
|
||||
insert into t1 values ("m",13),("n",14),("o",15),("p",16);
|
||||
set @save_sort_buffer_size= @@sort_buffer_size;
|
||||
set sort_buffer_size=1024;
|
||||
select * from t1 order by b;
|
||||
a b
|
||||
a 1
|
||||
b 2
|
||||
c 3
|
||||
e 4
|
||||
d 5
|
||||
f 6
|
||||
g 7
|
||||
h 8
|
||||
i 9
|
||||
j 10
|
||||
k 11
|
||||
l 12
|
||||
m 13
|
||||
n 14
|
||||
o 15
|
||||
p 16
|
||||
set @@sort_buffer_size= @save_sort_buffer_size;
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-13994: Bad join results with orderby_uses_equalities=on
|
||||
#
|
||||
CREATE TABLE books (
|
||||
|
14
mysql-test/suite/galera/r/galera_as_slave_ctas.result
Normal file
14
mysql-test/suite/galera/r/galera_as_slave_ctas.result
Normal file
@ -0,0 +1,14 @@
|
||||
START SLAVE;
|
||||
SHOW VARIABLES LIKE 'binlog_format';
|
||||
Variable_name Value
|
||||
binlog_format ROW
|
||||
CREATE TABLE source (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE target AS SELECT * FROM source;
|
||||
DROP TABLE target;
|
||||
INSERT INTO source VALUES(1);
|
||||
CREATE TABLE target AS SELECT * FROM source;
|
||||
DROP TABLE source;
|
||||
DROP TABLE target;
|
||||
STOP SLAVE;
|
||||
RESET SLAVE ALL;
|
||||
RESET MASTER;
|
21
mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result
Normal file
21
mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result
Normal file
@ -0,0 +1,21 @@
|
||||
ALTER TABLE mysql.gtid_slave_pos engine = InnoDB;
|
||||
START SLAVE;
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
SELECT LENGTH(@@global.gtid_binlog_state) > 1;
|
||||
LENGTH(@@global.gtid_binlog_state) > 1
|
||||
1
|
||||
gtid_binlog_state_equal
|
||||
0
|
||||
SELECT COUNT(*) = 0 FROM t1;
|
||||
COUNT(*) = 0
|
||||
1
|
||||
gtid_binlog_state_equal
|
||||
0
|
||||
#cleanup
|
||||
DROP TABLE t1;
|
||||
reset master;
|
||||
STOP SLAVE;
|
||||
RESET SLAVE ALL;
|
||||
reset master;
|
||||
reset master;
|
5
mysql-test/suite/galera/t/galera_as_slave_ctas.cnf
Normal file
5
mysql-test/suite/galera/t/galera_as_slave_ctas.cnf
Normal file
@ -0,0 +1,5 @@
|
||||
!include ../galera_2nodes_as_slave.cnf
|
||||
|
||||
# make sure master server uses ROW format for replication
|
||||
[mysqld]
|
||||
binlog-format=row
|
75
mysql-test/suite/galera/t/galera_as_slave_ctas.test
Normal file
75
mysql-test/suite/galera/t/galera_as_slave_ctas.test
Normal file
@ -0,0 +1,75 @@
|
||||
#
|
||||
# Test Galera as a slave to a MySQL master
|
||||
#
|
||||
# The galera/galera_2node_slave.cnf describes the setup of the nodes
|
||||
# also, for this test, master server must have binlog_format=ROW
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
|
||||
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
|
||||
--source include/galera_cluster.inc
|
||||
|
||||
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
|
||||
|
||||
--connection node_2
|
||||
--disable_query_log
|
||||
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1;
|
||||
--enable_query_log
|
||||
START SLAVE;
|
||||
|
||||
|
||||
# make sure master server has binlog_format=ROW
|
||||
--connection node_1
|
||||
SHOW VARIABLES LIKE 'binlog_format';
|
||||
|
||||
#
|
||||
# test phase one, issue CTAS with empty source table
|
||||
#
|
||||
--connection node_1
|
||||
CREATE TABLE source (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE target AS SELECT * FROM source;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection node_3
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
#
|
||||
# test phase two, issue CTAS with populated source table
|
||||
#
|
||||
--connection node_1
|
||||
DROP TABLE target;
|
||||
INSERT INTO source VALUES(1);
|
||||
|
||||
CREATE TABLE target AS SELECT * FROM source;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM target;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection node_3
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM target;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection node_1
|
||||
DROP TABLE source;
|
||||
DROP TABLE target;
|
||||
|
||||
--connection node_3
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
|
||||
--connection node_2
|
||||
STOP SLAVE;
|
||||
RESET SLAVE ALL;
|
||||
|
||||
--connection node_1
|
||||
RESET MASTER;
|
||||
|
@ -0,0 +1,6 @@
|
||||
!include ../galera_2nodes_as_slave.cnf
|
||||
|
||||
[mysqld]
|
||||
log-bin=mysqld-bin
|
||||
log-slave-updates
|
||||
binlog-format=ROW
|
65
mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test
Normal file
65
mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test
Normal file
@ -0,0 +1,65 @@
|
||||
#
|
||||
# Test Galera as a slave to a MariaDB master using GTIDs
|
||||
#
|
||||
# suite/galera/galera_2nodes_as_slave.cnf describes the setup of the nodes
|
||||
# suite/galera/t/galera_as_slave_gtid.cnf has the GTID options
|
||||
#
|
||||
# This test will replicate writes to MyISAM table and check that slave node is able
|
||||
# to apply them.
|
||||
# mysql.gtid_slave_pos table should be defined as innodb engine, original problem
|
||||
# by writes to mysql.gtid_slave_pos, whereas the replicated transaction contained
|
||||
# no innodb writes
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
|
||||
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
|
||||
--source include/galera_cluster.inc
|
||||
|
||||
--connection node_2
|
||||
# make sure gtid_slave_pos is of innodb engine, mtr does not currently provide that
|
||||
ALTER TABLE mysql.gtid_slave_pos engine = InnoDB;
|
||||
|
||||
--disable_query_log
|
||||
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1;
|
||||
--enable_query_log
|
||||
START SLAVE;
|
||||
|
||||
--connection node_1
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
SELECT LENGTH(@@global.gtid_binlog_state) > 1;
|
||||
--let $gtid_binlog_state_node1 = `SELECT @@global.gtid_binlog_state;`
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--disable_query_log
|
||||
--eval SELECT '$gtid_binlog_state_node1' = @@global.gtid_binlog_state AS gtid_binlog_state_equal;
|
||||
--enable_query_log
|
||||
|
||||
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
|
||||
SELECT COUNT(*) = 0 FROM t1;
|
||||
|
||||
--disable_query_log
|
||||
--eval SELECT '$gtid_binlog_state_node1' = @@global.gtid_binlog_state AS gtid_binlog_state_equal;
|
||||
--enable_query_log
|
||||
|
||||
--echo #cleanup
|
||||
--connection node_1
|
||||
DROP TABLE t1;
|
||||
reset master;
|
||||
|
||||
--connection node_2
|
||||
STOP SLAVE;
|
||||
RESET SLAVE ALL;
|
||||
reset master;
|
||||
|
||||
--connection node_3
|
||||
reset master;
|
@ -2145,6 +2145,22 @@ SELECT DISTINCT pk FROM t1 GROUP BY 'foo';
|
||||
SELECT DISTINCT pk FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-21044: Wrong result when using a smaller size for sort buffer
|
||||
--echo #
|
||||
|
||||
create table t1(a varchar(765),b int);
|
||||
insert into t1 values ("a",1),("b",2),("c",3),("e",4);
|
||||
insert into t1 values ("d",5),("f",6),("g",7),("h",8);
|
||||
insert into t1 values ("k",11),("l",12),("i",9),("j",10);
|
||||
insert into t1 values ("m",13),("n",14),("o",15),("p",16);
|
||||
set @save_sort_buffer_size= @@sort_buffer_size;
|
||||
set sort_buffer_size=1024;
|
||||
select * from t1 order by b;
|
||||
set @@sort_buffer_size= @save_sort_buffer_size;
|
||||
drop table t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-13994: Bad join results with orderby_uses_equalities=on
|
||||
--echo #
|
||||
|
@ -245,7 +245,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"
|
||||
|
@ -321,6 +321,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
||||
param.max_keys_per_buffer=((param.max_keys_per_buffer *
|
||||
(param.rec_length + sizeof(char*))) /
|
||||
param.rec_length - 1);
|
||||
set_if_bigger(param.max_keys_per_buffer, 1);
|
||||
maxbuffer--; // Offset from 0
|
||||
if (merge_many_buff(¶m,
|
||||
(uchar*) sort->get_sort_keys(),
|
||||
|
@ -5191,6 +5191,9 @@ bool event_that_should_be_ignored(const char *buf);
|
||||
bool event_checksum_test(uchar *buf, ulong event_len, enum_binlog_checksum_alg alg);
|
||||
enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len);
|
||||
extern TYPELIB binlog_checksum_typelib;
|
||||
#ifdef WITH_WSREP
|
||||
enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/**
|
||||
@} (end of group Replication)
|
||||
|
@ -8754,8 +8754,8 @@ static void usage(void)
|
||||
"\nbecause execution stopped before plugins were initialized.");
|
||||
}
|
||||
|
||||
puts("\nTo see what values a running MySQL server is using, type"
|
||||
"\n'mysqladmin variables' instead of 'mysqld --verbose --help'.");
|
||||
puts("\nTo see what variables a running MySQL server is using, type"
|
||||
"\n'mysqladmin variables' instead of 'mysqld --verbose --help'.");
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
33
sql/slave.cc
33
sql/slave.cc
@ -304,6 +304,9 @@ handle_slave_background(void *arg __attribute__((unused)))
|
||||
thd->store_globals();
|
||||
thd->security_ctx->skip_grants();
|
||||
thd->set_command(COM_DAEMON);
|
||||
#ifdef WITH_WSREP
|
||||
thd->variables.wsrep_on= 0;
|
||||
#endif
|
||||
|
||||
thd_proc_info(thd, "Loading slave GTID position from table");
|
||||
if (rpl_load_gtid_slave_state(thd))
|
||||
@ -4309,7 +4312,9 @@ pthread_handler_t handle_slave_io(void *arg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
thd->variables.wsrep_on= 0;
|
||||
#endif
|
||||
if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
|
||||
{
|
||||
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
|
||||
@ -7389,7 +7394,33 @@ err:
|
||||
sql_print_error("Error reading relay log event: %s", errmsg);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size)
|
||||
{
|
||||
mysql_mutex_lock(&rgi->rli->data_lock);
|
||||
|
||||
unsigned long long event_pos= rgi->event_relay_log_pos;
|
||||
unsigned long long future_pos= rgi->future_event_relay_log_pos;
|
||||
|
||||
/* scan the log to read next event */
|
||||
my_b_seek(rgi->rli->cur_log, future_pos);
|
||||
rgi->rli->event_relay_log_pos= future_pos;
|
||||
rgi->event_relay_log_pos= future_pos;
|
||||
|
||||
Log_event* ev = next_event(rgi, event_size);
|
||||
enum Log_event_type ev_type= (ev) ? ev->get_type_code() : UNKNOWN_EVENT;
|
||||
delete ev;
|
||||
|
||||
/* scan the log back and re-set the positions to original values */
|
||||
rgi->rli->event_relay_log_pos= event_pos;
|
||||
rgi->event_relay_log_pos= event_pos;
|
||||
my_b_seek(rgi->rli->cur_log, future_pos);
|
||||
|
||||
mysql_mutex_unlock(&rgi->rli->data_lock);
|
||||
|
||||
return ev_type;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/*
|
||||
Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
|
||||
because of size is simpler because when we do it we already have all relevant
|
||||
|
@ -19865,7 +19865,7 @@ join_read_last(JOIN_TAB *tab)
|
||||
{
|
||||
TABLE *table=tab->table;
|
||||
int error= 0;
|
||||
DBUG_ENTER("join_read_first");
|
||||
DBUG_ENTER("join_read_last");
|
||||
|
||||
DBUG_ASSERT(table->no_keyread ||
|
||||
!table->covering_keys.is_set(tab->index) ||
|
||||
|
@ -479,12 +479,29 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
|
||||
|
||||
if (WSREP_UNDEFINED_TRX_ID == thd->wsrep_ws_handle.trx_id)
|
||||
{
|
||||
WSREP_WARN("SQL statement was ineffective thd: %lld buf: %zu\n"
|
||||
/*
|
||||
Async replication slave may have applied some non-innodb workload,
|
||||
and then has written replication "meta data" into gtid_slave_pos
|
||||
innodb table. Writes to gtid_slave_pos must not be replicated,
|
||||
but this activity has caused that innodb hton is registered for this
|
||||
transaction, but no wsrep keys have been appended.
|
||||
We enter in this code path, because IO cache has events for non-innodb
|
||||
tables.
|
||||
=> we should not treat it an error if trx is not introduced for provider
|
||||
*/
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL)
|
||||
{
|
||||
WSREP_DEBUG("skipping wsrep replication for async slave, error not raised");
|
||||
DBUG_RETURN(WSREP_TRX_OK);
|
||||
}
|
||||
|
||||
WSREP_WARN("SQL statement was ineffective thd: %llu buf: %zu\n"
|
||||
"schema: %s \n"
|
||||
"QUERY: %s\n"
|
||||
" => Skipping replication",
|
||||
(longlong) thd->thread_id, data_len,
|
||||
(ulonglong) thd->thread_id, data_len,
|
||||
(thd->db ? thd->db : "(null)"), thd->query());
|
||||
|
||||
rcode = WSREP_TRX_FAIL;
|
||||
}
|
||||
else if (!rcode)
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "log_event.h"
|
||||
#include <slave.h>
|
||||
#include "sql_plugin.h" /* wsrep_plugins_pre_init() */
|
||||
#include <vector>
|
||||
|
||||
@ -1544,6 +1543,39 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
If mariadb master has replicated a CTAS, we should not replicate the create table
|
||||
part separately as TOI, but to replicate both create table and following inserts
|
||||
as one write set.
|
||||
Howver, if CTAS creates empty table, we should replicate the create table alone
|
||||
as TOI. We have to do relay log event lookup to see if row events follow the
|
||||
create table event.
|
||||
*/
|
||||
if (thd->slave_thread && !(thd->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_STANDALONE))
|
||||
{
|
||||
/* this is CTAS, either empty or populated table */
|
||||
ulonglong event_size = 0;
|
||||
enum Log_event_type ev_type= wsrep_peak_event(thd->rgi_slave, &event_size);
|
||||
switch (ev_type)
|
||||
{
|
||||
case QUERY_EVENT:
|
||||
/* CTAS with empty table, we replicate create table as TOI */
|
||||
break;
|
||||
|
||||
case TABLE_MAP_EVENT:
|
||||
WSREP_DEBUG("replicating CTAS of empty table as TOI");
|
||||
// fall through
|
||||
case WRITE_ROWS_EVENT:
|
||||
/* CTAS with populated table, we replicate later at commit time */
|
||||
WSREP_DEBUG("skipping create table of CTAS replication");
|
||||
return false;
|
||||
|
||||
default:
|
||||
WSREP_WARN("unexpected async replication event: %d", ev_type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* no next async replication event */
|
||||
return true;
|
||||
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
|
@ -194,7 +194,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
|
||||
}
|
||||
|
||||
for (key = section->key; key; key = key->next)
|
||||
if (key->name && key->name[0]) {
|
||||
if (key->name[0]) {
|
||||
fprintf(file, "%s", SVP(key->name));
|
||||
|
||||
if (key->value)
|
||||
|
@ -125,11 +125,17 @@ os_thread_create_func(
|
||||
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
int ret = pthread_attr_init(&attr);
|
||||
if (UNIV_UNLIKELY(ret)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: pthread_attr_init() returned %d\n",
|
||||
ret);
|
||||
abort();
|
||||
}
|
||||
|
||||
my_atomic_addlint(&os_thread_count, 1);
|
||||
|
||||
int ret = pthread_create(&new_thread_id, &attr, func, arg);
|
||||
ret = pthread_create(&new_thread_id, &attr, func, arg);
|
||||
|
||||
ut_a(ret == 0);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user