Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
37817f60
Commit
37817f60
authored
Mar 11, 2004
by
Sinisa@sinisa.nasamreza.org
Browse files
Options
Browse Files
Download
Plain Diff
Merge sinisa@bk-internal.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/work/mysql-4.0
parents
a86753b0
2bf78563
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
268 additions
and
572 deletions
+268
-572
acinclude.m4
acinclude.m4
+0
-1
client/mysqlbinlog.cc
client/mysqlbinlog.cc
+1
-1
innobase/include/Makefile.am
innobase/include/Makefile.am
+2
-2
innobase/include/ib_odbc.h
innobase/include/ib_odbc.h
+0
-149
innobase/include/odbc0odbc.h
innobase/include/odbc0odbc.h
+0
-20
innobase/include/pars0pars.h
innobase/include/pars0pars.h
+5
-26
innobase/pars/pars0pars.c
innobase/pars/pars0pars.c
+21
-237
innobase/srv/srv0srv.c
innobase/srv/srv0srv.c
+0
-1
mysql-test/r/rpl_error_ignored_table.result
mysql-test/r/rpl_error_ignored_table.result
+25
-0
mysql-test/t/rpl_error_ignored_table-slave.opt
mysql-test/t/rpl_error_ignored_table-slave.opt
+1
-1
mysql-test/t/rpl_error_ignored_table.test
mysql-test/t/rpl_error_ignored_table.test
+30
-0
sql/item_func.cc
sql/item_func.cc
+0
-2
sql/log_event.cc
sql/log_event.cc
+87
-72
sql/mysql_priv.h
sql/mysql_priv.h
+1
-0
sql/repl_failsafe.cc
sql/repl_failsafe.cc
+4
-4
sql/set_var.cc
sql/set_var.cc
+4
-4
sql/slave.cc
sql/slave.cc
+17
-11
sql/slave.h
sql/slave.h
+16
-20
sql/sql_parse.cc
sql/sql_parse.cc
+52
-19
sql/sql_show.cc
sql/sql_show.cc
+2
-2
No files found.
acinclude.m4
View file @
37817f60
...
...
@@ -1231,7 +1231,6 @@ dnl circular references.
\$(top_builddir)/innobase/page/libpage.a\
\$(top_builddir)/innobase/rem/librem.a\
\$(top_builddir)/innobase/thr/libthr.a\
\$(top_builddir)/innobase/com/libcom.a\
\$(top_builddir)/innobase/sync/libsync.a\
\$(top_builddir)/innobase/data/libdata.a\
\$(top_builddir)/innobase/mach/libmach.a\
...
...
client/mysqlbinlog.cc
View file @
37817f60
...
...
@@ -952,7 +952,7 @@ int main(int argc, char** argv)
exit_value
=
0
;
fprintf
(
result_file
,
"/*!400
01
SET @@session.max_insert_delayed_threads=0*/;
\n
"
);
"/*!400
19
SET @@session.max_insert_delayed_threads=0*/;
\n
"
);
while
(
--
argc
>=
0
)
{
if
(
dump_log_entries
(
*
(
argv
++
)))
...
...
innobase/include/Makefile.am
View file @
37817f60
...
...
@@ -25,13 +25,13 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \
dict0mem.ic dict0types.h dyn0dyn.h dyn0dyn.ic eval0eval.h
\
eval0eval.ic eval0proc.h eval0proc.ic fil0fil.h fsp0fsp.h
\
fsp0fsp.ic fut0fut.h fut0fut.ic fut0lst.h fut0lst.ic
\
ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic
ib_odbc.h
\
ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic
\
ibuf0ibuf.h ibuf0ibuf.ic ibuf0types.h lock0lock.h
\
lock0lock.ic lock0types.h log0log.h log0log.ic log0recv.h
\
log0recv.ic mach0data.h mach0data.ic makefilewin.i
\
mem0dbg.h mem0dbg.ic mem0mem.h mem0mem.ic mem0pool.h
\
mem0pool.ic mtr0log.h mtr0log.ic mtr0mtr.h mtr0mtr.ic
\
mtr0types.h o
dbc0odbc.h o
s0file.h os0proc.h os0proc.ic
\
mtr0types.h os0file.h os0proc.h os0proc.ic
\
os0shm.h os0shm.ic os0sync.h os0sync.ic os0thread.h
\
os0thread.ic page0cur.h page0cur.ic page0page.h
\
page0page.ic page0types.h pars0grm.h pars0opt.h
\
...
...
innobase/include/ib_odbc.h
deleted
100644 → 0
View file @
a86753b0
/******************************************************
Innobase ODBC client library header; this is equivalent to
the standard sql.h ODBC header file
(c) 1998 Innobase Oy
Created 2/22/1998 Heikki Tuuri
*******************************************************/
#ifndef ib_odbc_h
#define ib_odbc_h
typedef
unsigned
char
UCHAR
;
typedef
signed
char
SCHAR
;
typedef
long
int
SDWORD
;
typedef
short
int
SWORD
;
typedef
unsigned
long
int
UDWORD
;
typedef
unsigned
short
int
UWORD
;
typedef
void
*
PTR
;
typedef
void
*
HENV
;
typedef
void
*
HDBC
;
typedef
void
*
HSTMT
;
typedef
signed
short
RETCODE
;
/* RETCODEs */
#define SQL_NO_DATA_FOUND (-3)
#define SQL_INVALID_HANDLE (-2)
#define SQL_ERROR (-1)
#define SQL_SUCCESS 0
/* Standard SQL datatypes, using ANSI type numbering */
#define SQL_CHAR 1
#define SQL_INTEGER 4
#define SQL_VARCHAR 12
/* C datatype to SQL datatype mapping */
#define SQL_C_CHAR SQL_CHAR
#define SQL_C_LONG SQL_INTEGER
/* Special length value */
#define SQL_NULL_DATA (-1)
#define SQL_PARAM_INPUT 1
#define SQL_PARAM_OUTPUT 4
/* Null handles */
#define SQL_NULL_HENV NULL
#define SQL_NULL_HDBC NULL
#define SQL_NULL_HSTM NULL
/**************************************************************************
Allocates an SQL environment. */
RETCODE
SQLAllocEnv
(
/*========*/
/* out: SQL_SUCCESS */
HENV
*
phenv
);
/* out: pointer to an environment handle */
/**************************************************************************
Allocates an SQL connection. */
RETCODE
SQLAllocConnect
(
/*============*/
/* out: SQL_SUCCESS */
HENV
henv
,
/* in: pointer to an environment handle */
HDBC
*
phdbc
);
/* out: pointer to a connection handle */
/**************************************************************************
Allocates an SQL statement. */
RETCODE
SQLAllocStmt
(
/*=========*/
HDBC
hdbc
,
/* in: SQL connection */
HSTMT
*
phstmt
);
/* out: pointer to a statement handle */
/**************************************************************************
Connects to a database server process (establishes a connection and a
session). */
RETCODE
SQLConnect
(
/*=======*/
/* out: SQL_SUCCESS */
HDBC
hdbc
,
/* in: SQL connection handle */
UCHAR
*
szDSN
,
/* in: data source name (server name) */
SWORD
cbDSN
,
/* in: data source name length */
UCHAR
*
szUID
,
/* in: user name */
SWORD
cbUID
,
/* in: user name length */
UCHAR
*
szAuthStr
,
/* in: password */
SWORD
cbAuthStr
);
/* in: password length */
/**************************************************************************
Makes the server to parse and optimize an SQL string. */
RETCODE
SQLPrepare
(
/*=======*/
/* out: SQL_SUCCESS */
HSTMT
hstmt
,
/* in: statement handle */
UCHAR
*
szSqlStr
,
/* in: SQL string */
SDWORD
cbSqlStr
);
/* in: SQL string length */
/**************************************************************************
Binds a parameter in a prepared statement. */
RETCODE
SQLBindParameter
(
/*=============*/
/* out: SQL_SUCCESS */
HSTMT
hstmt
,
/* in: statement handle */
UWORD
ipar
,
/* in: parameter index, starting from 1 */
SWORD
fParamType
,
/* in: SQL_PARAM_INPUT or SQL_PARAM_OUTPUT */
SWORD
fCType
,
/* in: SQL_C_CHAR, ... */
SWORD
fSqlType
,
/* in: SQL_CHAR, ... */
UDWORD
cbColDef
,
/* in: precision: ignored */
SWORD
ibScale
,
/* in: scale: ignored */
PTR
rgbValue
,
/* in: pointer to a buffer for the data */
SDWORD
cbValueMax
,
/* in: buffer size */
SDWORD
*
pcbValue
);
/* in: pointer to a buffer for the data
length or SQL_NULL_DATA */
/**************************************************************************
Executes a prepared statement where all parameters have been bound. */
RETCODE
SQLExecute
(
/*=======*/
/* out: SQL_SUCCESS or SQL_ERROR */
HSTMT
hstmt
);
/* in: statement handle */
/**************************************************************************
Queries an error message. */
RETCODE
SQLError
(
/*=====*/
/* out: SQL_SUCCESS or SQL_NO_DATA_FOUND */
HENV
henv
,
/* in: SQL_NULL_HENV */
HDBC
hdbc
,
/* in: SQL_NULL_HDBC */
HSTMT
hstmt
,
/* in: statement handle */
UCHAR
*
szSqlState
,
/* in/out: SQLSTATE as a null-terminated string,
(currently, always == "S1000") */
SDWORD
*
pfNativeError
,
/* out: native error code */
UCHAR
*
szErrorMsg
,
/* in/out: buffer for an error message as a
null-terminated string */
SWORD
cbErrorMsgMax
,
/* in: buffer size for szErrorMsg */
SWORD
*
pcbErrorMsg
);
/* out: error message length */
#endif
innobase/include/odbc0odbc.h
deleted
100644 → 0
View file @
a86753b0
/******************************************************
Innobase ODBC client library additional header
(c) 1998 Innobase Oy
Created 2/22/1998 Heikki Tuuri
*******************************************************/
#ifndef odbc0odbc_h
#define odbc0odbc_h
#include "ib_odbc.h"
/* Datagram size in communications */
#define ODBC_DATAGRAM_SIZE 8192
/* Communication address maximum length in bytes */
#define ODBC_ADDRESS_SIZE COM_MAX_ADDR_LEN
#endif
innobase/include/pars0pars.h
View file @
37817f60
...
...
@@ -21,7 +21,9 @@ extern int yydebug;
/* If the following is set TRUE, the lexer will print the SQL string
as it tokenizes it */
#ifdef UNIV_SQL_DEBUG
extern
ibool
pars_print_lexed
;
#endif
/* UNIV_SQL_DEBUG */
/* Global variable used while parsing a single procedure or query : the code is
NOT re-entrant */
...
...
@@ -390,41 +392,18 @@ pars_procedure_definition(
table */
sym_node_t
*
param_list
,
/* in: parameter declaration list */
que_node_t
*
stat_list
);
/* in: statement list */
/*****************************************************************
Reads stored procedure input parameter values from a buffer. */
void
pars_proc_read_input_params_from_buf
(
/*=================================*/
que_t
*
graph
,
/* in: query graph which contains a stored procedure */
byte
*
buf
);
/* in: buffer */
/*****************************************************************
Writes stored procedure output parameter values to a buffer. */
ulint
pars_proc_write_output_params_to_buf
(
/*=================================*/
byte
*
buf
,
/* in: buffer which must be big enough */
que_t
*
graph
);
/* in: query graph which contains a stored procedure */
/*****************************************************************
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly. */
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
parsed procedure tree, not via InnoDB SQL, so this function is not used. */
que_fork_t
*
pars_stored_procedure_call
(
/*=======================*/
/* out: query graph */
sym_node_t
*
sym_node
);
/* in: stored procedure name */
/*****************************************************************
Writes info about query parameter markers (denoted with '?' in ODBC) into a
buffer. */
ulint
pars_write_query_param_info
(
/*========================*/
/* out: number of bytes used for info in buf */
byte
*
buf
,
/* in: buffer which must be big enough */
que_fork_t
*
graph
);
/* in: parsed query graph */
/**********************************************************************
Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
...
...
innobase/pars/pars0pars.c
View file @
37817f60
...
...
@@ -29,13 +29,14 @@ on 1/27/1998 */
#include "trx0trx.h"
#include "trx0roll.h"
#include "lock0lock.h"
#include "odbc0odbc.h"
#include "eval0eval.h"
#ifdef UNIV_SQL_DEBUG
/* If the following is set TRUE, the lexer will print the SQL string
as it tokenizes it */
ibool
pars_print_lexed
=
FALSE
;
#endif
/* UNIV_SQL_DEBUG */
/* Global variable used while parsing a single procedure or query : the code is
NOT re-entrant */
...
...
@@ -389,7 +390,7 @@ pars_resolve_exp_variables_and_types(
}
if
(
!
node
)
{
printf
(
"PARSER ERROR: Unresolved identifier %s
\n
"
,
fprintf
(
stderr
,
"PARSER ERROR: Unresolved identifier %s
\n
"
,
sym_node
->
name
);
}
...
...
@@ -521,25 +522,6 @@ pars_resolve_exp_list_columns(
}
}
/*************************************************************************
Retrieves the stored procedure definition for a procedure name. */
static
void
pars_retrieve_procedure_def
(
/*========================*/
sym_node_t
*
sym_node
)
/* in: procedure name node */
{
ut_a
(
sym_node
);
ut_a
(
que_node_get_type
(
sym_node
)
==
QUE_NODE_SYMBOL
);
sym_node
->
resolved
=
TRUE
;
sym_node
->
token_type
=
SYM_PROCEDURE_NAME
;
sym_node
->
procedure_def
=
dict_procedure_get
((
char
*
)
sym_node
->
name
,
NULL
);
ut_a
(
sym_node
->
procedure_def
);
}
/*************************************************************************
Retrieves the table definition for a table name id. */
static
...
...
@@ -1662,216 +1644,19 @@ pars_procedure_definition(
/*****************************************************************
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly. */
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
parsed procedure tree, not via InnoDB SQL, so this function is not used. */
que_fork_t
*
pars_stored_procedure_call
(
/*=======================*/
/* out: query graph */
sym_node_t
*
sym_node
)
/* in: stored procedure name */
{
call_node_t
*
node
;
que_fork_t
*
fork
;
que_thr_t
*
thr
;
mem_heap_t
*
heap
;
heap
=
pars_sym_tab_global
->
heap
;
fork
=
que_fork_create
(
NULL
,
NULL
,
QUE_FORK_PROCEDURE_CALL
,
heap
);
fork
->
trx
=
NULL
;
thr
=
que_thr_create
(
fork
,
heap
);
node
=
mem_heap_alloc
(
heap
,
sizeof
(
call_node_t
));
thr
->
child
=
node
;
node
->
common
.
type
=
QUE_NODE_CALL
;
node
->
common
.
parent
=
thr
;
sym_node
->
token_type
=
SYM_PROCEDURE_NAME
;
pars_retrieve_procedure_def
(
sym_node
);
node
->
procedure_def
=
sym_node
->
procedure_def
;
node
->
proc_name
=
sym_node
;
node
->
sym_tab
=
pars_sym_tab_global
;
pars_sym_tab_global
->
query_graph
=
fork
;
return
(
fork
);
}
/*****************************************************************
Writes info about query parameter markers (denoted with '?' in ODBC) into a
buffer. */
ulint
pars_write_query_param_info
(
/*========================*/
/* out: number of bytes used for info in buf */
byte
*
buf
,
/* in: buffer which must be big enough */
que_fork_t
*
graph
)
/* in: parsed query graph */
sym_node_t
*
sym_node
__attribute__
((
unused
)))
/* in: stored procedure name */
{
que_thr_t
*
thr
;
call_node_t
*
call_node
;
dict_proc_t
*
procedure_def
;
que_t
*
stored_graph
;
proc_node_t
*
proc_node
;
sym_node_t
*
param
;
ulint
n_params
;
ibool
is_input
;
/* We currently support parameter markers only in stored procedure
calls, and there ALL procedure parameters must be marked with '?':
no literal values are allowed */
thr
=
UT_LIST_GET_FIRST
(
graph
->
thrs
);
n_params
=
0
;
if
(
que_node_get_type
(
thr
->
child
)
==
QUE_NODE_CALL
)
{
call_node
=
thr
->
child
;
procedure_def
=
call_node
->
procedure_def
;
stored_graph
=
dict_procedure_reserve_parsed_copy
(
procedure_def
);
proc_node
=
que_fork_get_child
(
stored_graph
);
param
=
proc_node
->
param_list
;
while
(
param
)
{
if
(
param
->
param_type
==
PARS_INPUT
)
{
is_input
=
TRUE
;
}
else
{
is_input
=
FALSE
;
}
mach_write_to_1
(
buf
+
4
+
n_params
,
is_input
);
n_params
++
;
param
=
que_node_get_next
(
param
);
}
dict_procedure_release_parsed_copy
(
stored_graph
);
}
mach_write_to_4
(
buf
,
n_params
);
return
(
4
+
n_params
);
}
/*****************************************************************
Reads stored procedure input parameter values from a buffer. */
void
pars_proc_read_input_params_from_buf
(
/*=================================*/
que_t
*
graph
,
/* in: query graph which contains a stored procedure */
byte
*
buf
)
/* in: buffer */
{
que_thr_t
*
thr
;
proc_node_t
*
proc_node
;
sym_node_t
*
param
;
byte
*
ptr
;
ulint
len
;
lint
odbc_len
;
ut_ad
(
graph
->
fork_type
==
QUE_FORK_PROCEDURE
);
thr
=
UT_LIST_GET_FIRST
(
graph
->
thrs
);
proc_node
=
thr
->
child
;
ptr
=
buf
;
param
=
proc_node
->
param_list
;
while
(
param
)
{
if
(
param
->
param_type
==
PARS_INPUT
)
{
odbc_len
=
(
lint
)
mach_read_from_4
(
ptr
);
ptr
+=
4
;
if
(
odbc_len
==
SQL_NULL_DATA
)
{
len
=
UNIV_SQL_NULL
;
}
else
{
len
=
(
ulint
)
odbc_len
;
}
eval_node_copy_and_alloc_val
(
param
,
ptr
,
len
);
if
(
len
!=
UNIV_SQL_NULL
)
{
ptr
+=
len
;
}
}
param
=
que_node_get_next
(
param
);
}
ut_ad
(
ptr
-
buf
<
ODBC_DATAGRAM_SIZE
);
}
/*****************************************************************
Writes stored procedure output parameter values to a buffer. */
ulint
pars_proc_write_output_params_to_buf
(
/*=================================*/
/* out: bytes used in buf */
byte
*
buf
,
/* in: buffer which must be big enough */
que_t
*
graph
)
/* in: query graph which contains a stored procedure */
{
que_thr_t
*
thr
;
proc_node_t
*
proc_node
;
sym_node_t
*
param
;
dfield_t
*
dfield
;
byte
*
ptr
;
ulint
len
;
lint
odbc_len
;
ut_ad
(
graph
->
fork_type
==
QUE_FORK_PROCEDURE
);
thr
=
UT_LIST_GET_FIRST
(
graph
->
thrs
);
proc_node
=
thr
->
child
;
ptr
=
buf
;
param
=
proc_node
->
param_list
;
while
(
param
)
{
if
(
param
->
param_type
==
PARS_OUTPUT
)
{
dfield
=
que_node_get_val
(
param
);
len
=
dfield_get_len
(
dfield
);
if
(
len
==
UNIV_SQL_NULL
)
{
odbc_len
=
SQL_NULL_DATA
;
}
else
{
odbc_len
=
(
lint
)
len
;
}
mach_write_to_4
(
ptr
,
(
ulint
)
odbc_len
);
ptr
+=
4
;
if
(
len
!=
UNIV_SQL_NULL
)
{
ut_memcpy
(
ptr
,
dfield_get_data
(
dfield
),
len
);
ptr
+=
len
;
}
}
param
=
que_node_get_next
(
param
);
}
ut_ad
(
ptr
-
buf
<
ODBC_DATAGRAM_SIZE
);
return
((
ulint
)(
ptr
-
buf
));
ut_error
;
return
(
NULL
);
}
/*****************************************************************
...
...
@@ -1886,13 +1671,12 @@ pars_get_lex_chars(
in the buffer */
{
int
len
;
char
print_buf
[
16
];
len
=
pars_sym_tab_global
->
string_len
-
pars_sym_tab_global
->
next_char_pos
;
if
(
len
==
0
)
{
#ifdef YYDEBUG
/*
printf("SQL string ends\n"
); */
/*
fputs("SQL string ends\n", stderr
); */
#endif
*
result
=
0
;
...
...
@@ -1903,18 +1687,18 @@ pars_get_lex_chars(
len
=
max_size
;
}
#ifdef UNIV_SQL_DEBUG
if
(
pars_print_lexed
)
{
if
(
len
>=
5
)
{
len
=
5
;
}
ut_memcpy
(
print_buf
,
pars_sym_tab_global
->
sql_string
+
pars_sym_tab_global
->
next_char_pos
,
len
);
print_buf
[
len
]
=
'\0'
;
printf
(
"%s"
,
print_buf
);
fwrite
(
pars_sym_tab_global
->
sql_string
+
pars_sym_tab_global
->
next_char_pos
,
1
,
len
,
stderr
);
}
#endif
/* UNIV_SQL_DEBUG */
ut_memcpy
(
buf
,
pars_sym_tab_global
->
sql_string
+
pars_sym_tab_global
->
next_char_pos
,
len
);
...
...
@@ -1944,7 +1728,7 @@ yyerror(
{
ut_ad
(
s
);
printf
(
"PARSER ERROR: Syntax error in SQL string
\n
"
);
fputs
(
"PARSER ERROR: Syntax error in SQL string
\n
"
,
stderr
);
ut_error
;
}
...
...
@@ -1968,10 +1752,10 @@ pars_sql(
heap
=
mem_heap_create
(
256
);
#ifdef UNIV_SYNC_DEBUG
/* Currently, the parser is not reentrant: */
ut_ad
(
mutex_own
(
&
(
dict_sys
->
mutex
)));
#endif
/* UNIV_SYNC_DEBUG */
pars_sym_tab_global
=
sym_tab_create
(
heap
);
len
=
ut_strlen
(
str
);
...
...
@@ -1996,7 +1780,7 @@ pars_sql(
graph
->
sym_tab
=
pars_sym_tab_global
;
/*
printf(
"SQL graph size %lu\n", mem_heap_get_size(heap)); */
/*
fprintf(stderr,
"SQL graph size %lu\n", mem_heap_get_size(heap)); */
return
(
graph
);
}
...
...
innobase/srv/srv0srv.c
View file @
37817f60
...
...
@@ -37,7 +37,6 @@ Created 10/8/1995 Heikki Tuuri
#include "que0que.h"
#include "srv0que.h"
#include "log0recv.h"
#include "odbc0odbc.h"
#include "pars0pars.h"
#include "usr0sess.h"
#include "lock0lock.h"
...
...
mysql-test/r/rpl_error_ignored_table.result
View file @
37817f60
...
...
@@ -13,3 +13,28 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo
show tables like 't1';
Tables_in_test (t1)
drop table t1;
select get_lock('crash_lock%20C', 10);
get_lock('crash_lock%20C', 10)
1
create table t2 (a int primary key);
insert into t2 values(1);
create table t3 (id int);
insert into t3 values(connection_id());
update t2 set a = a + 1 + get_lock('crash_lock%20C', 10);
select (@id := id) - id from t3;
(@id := id) - id
0
kill @id;
drop table t2,t3;
Server shutdown in progress
show binlog events from 79;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 79 Query 1 79 use `test`; create table t1 (a int primary key)
master-bin.001 149 Query 1 149 use `test`; insert into t1 values (1),(1)
master-bin.001 213 Query 1 213 use `test`; drop table t1
master-bin.001 261 Query 1 261 use `test`; create table t2 (a int primary key)
master-bin.001 331 Query 1 331 use `test`; insert into t2 values(1)
master-bin.001 390 Query 1 390 use `test`; create table t3 (id int)
master-bin.001 449 Query 1 449 use `test`; insert into t3 values(connection_id())
master-bin.001 522 Query 1 522 use `test`; update t2 set a = a + 1 + get_lock('crash_lock%20C', 10)
master-bin.001 613 Query 1 613 use `test`; drop table t2,t3
mysql-test/t/rpl_error_ignored_table-slave.opt
View file @
37817f60
--replicate-ignore-table=test.t1
--replicate-ignore-table=test.t1
--replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3
mysql-test/t/rpl_error_ignored_table.test
View file @
37817f60
...
...
@@ -23,3 +23,33 @@ drop table t1;
save_master_pos
;
connection
slave
;
sync_with_master
;
# Now test that even critical errors (connection killed)
# are ignored if rules allow it.
# The "kill" idea was copied from rpl000001.test.
connection
master1
;
select
get_lock
(
'crash_lock%20C'
,
10
);
connection
master
;
create
table
t2
(
a
int
primary
key
);
insert
into
t2
values
(
1
);
create
table
t3
(
id
int
);
insert
into
t3
values
(
connection_id
());
send
update
t2
set
a
=
a
+
1
+
get_lock
(
'crash_lock%20C'
,
10
);
connection
master1
;
sleep
2
;
select
(
@
id
:=
id
)
-
id
from
t3
;
kill
@
id
;
drop
table
t2
,
t3
;
connection
master
;
--
error
1053
;
reap
;
connection
master1
;
show
binlog
events
from
79
;
save_master_pos
;
connection
slave
;
# SQL slave thread should not have stopped (because table of the killed
# query is in the ignore list).
sync_with_master
;
sql/item_func.cc
View file @
37817f60
...
...
@@ -1543,13 +1543,11 @@ longlong Item_master_pos_wait::val_int()
}
longlong
pos
=
args
[
1
]
->
val_int
();
longlong
timeout
=
(
arg_count
==
3
)
?
args
[
2
]
->
val_int
()
:
0
;
LOCK_ACTIVE_MI
;
if
((
event_count
=
active_mi
->
rli
.
wait_for_pos
(
thd
,
log_name
,
pos
,
timeout
))
==
-
2
)
{
null_value
=
1
;
event_count
=
0
;
}
UNLOCK_ACTIVE_MI
;
return
event_count
;
}
...
...
sql/log_event.cc
View file @
37817f60
...
...
@@ -53,6 +53,14 @@ static void pretty_print_str(FILE* file, char* str, int len)
#ifndef MYSQL_CLIENT
static
void
clear_all_errors
(
THD
*
thd
,
struct
st_relay_log_info
*
rli
)
{
thd
->
query_error
=
0
;
thd
->
clear_error
();
*
rli
->
last_slave_error
=
0
;
rli
->
last_slave_errno
=
0
;
}
inline
int
ignored_error_code
(
int
err_code
)
{
return
((
err_code
==
ER_SLAVE_IGNORED_TABLE
)
||
...
...
@@ -1803,8 +1811,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
#else
rli
->
future_group_master_log_pos
=
log_pos
;
#endif
thd
->
query_error
=
0
;
// clear error
thd
->
clear_error
();
clear_all_errors
(
thd
,
rli
);
if
(
db_ok
(
thd
->
db
,
replicate_do_db
,
replicate_ignore_db
))
{
...
...
@@ -1817,16 +1824,36 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
thd
->
slave_proxy_id
=
thread_id
;
// for temp tables
/*
Sanity check to make sure the master did not get a really bad
error on the query.
*/
if
(
ignored_error_code
((
expected_error
=
error_code
))
||
!
check_expected_error
(
thd
,
rli
,
expected_error
))
{
mysql_log
.
write
(
thd
,
COM_QUERY
,
"%s"
,
thd
->
query
);
DBUG_PRINT
(
"query"
,(
"%s"
,
thd
->
query
));
if
(
ignored_error_code
(
expected_error
=
error_code
)
||
!
check_expected_error
(
thd
,
rli
,
expected_error
))
mysql_parse
(
thd
,
thd
->
query
,
q_len
);
else
{
/*
The query got a really bad error on the master (thread killed etc),
which could be inconsistent. Parse it to test the table names: if the
replicate-*-do|ignore-table rules say "this query must be ignored" then
we exit gracefully; otherwise we warn about the bad error and tell DBA
to check/fix it.
*/
if
(
mysql_test_parse_for_slave
(
thd
,
thd
->
query
,
q_len
))
/* Can ignore query */
clear_all_errors
(
thd
,
rli
);
else
{
slave_print_error
(
rli
,
expected_error
,
"query '%s' partially completed on the master \
(error on master: %d) \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;\
START SLAVE; ."
,
thd
->
query
,
expected_error
);
thd
->
query_error
=
1
;
}
goto
end
;
}
/*
Set a flag if we are inside an transaction so that we can restart
...
...
@@ -1867,12 +1894,7 @@ Default database: '%s'",
*/
else
if
(
expected_error
==
actual_error
||
ignored_error_code
(
actual_error
))
{
thd
->
query_error
=
0
;
thd
->
clear_error
();
*
rli
->
last_slave_error
=
0
;
rli
->
last_slave_errno
=
0
;
}
clear_all_errors
(
thd
,
rli
);
/*
Other cases: mostly we expected no error and get one.
*/
...
...
@@ -1886,15 +1908,9 @@ Default database: '%s'",
print_slave_db_safe
(
db
));
thd
->
query_error
=
1
;
}
}
/*
End of sanity check. If the test was wrong, the query got a really bad
error on the master, which could be inconsistent, abort and tell DBA to
check/fix it. check_expected_error() already printed the message to
stderr and rli, and set thd->query_error to 1.
*/
}
/* End of if (db_ok(... */
end:
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
db
=
0
;
// prevent db from being freed
thd
->
query
=
0
;
// just to be sure
...
...
@@ -1939,8 +1955,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
thd
->
db
=
(
char
*
)
rewrite_db
(
db
);
DBUG_ASSERT
(
thd
->
query
==
0
);
thd
->
query
=
0
;
// Should not be needed
thd
->
query_error
=
0
;
thd
->
clear_error
();
clear_all_errors
(
thd
,
rli
);
if
(
!
use_rli_only_for_errors
)
{
...
...
sql/mysql_priv.h
View file @
37817f60
...
...
@@ -353,6 +353,7 @@ int quick_rm_table(enum db_type base,const char *db,
bool
mysql_rename_tables
(
THD
*
thd
,
TABLE_LIST
*
table_list
);
bool
mysql_change_db
(
THD
*
thd
,
const
char
*
name
);
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
);
bool
mysql_test_parse_for_slave
(
THD
*
thd
,
char
*
inBuf
,
uint
length
);
void
mysql_init_select
(
LEX
*
lex
);
bool
mysql_new_select
(
LEX
*
lex
);
void
mysql_init_multi_delete
(
LEX
*
lex
);
...
...
sql/repl_failsafe.cc
View file @
37817f60
...
...
@@ -750,7 +750,7 @@ int load_master_data(THD* thd)
We do not want anyone messing with the slave at all for the entire
duration of the data load.
*/
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
lock_slave_threads
(
active_mi
);
init_thread_mask
(
&
restart_thread_mask
,
active_mi
,
0
/*not inverse*/
);
if
(
restart_thread_mask
&&
...
...
@@ -759,7 +759,7 @@ int load_master_data(THD* thd)
{
send_error
(
&
thd
->
net
,
error
);
unlock_slave_threads
(
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
return
1
;
}
...
...
@@ -913,7 +913,7 @@ int load_master_data(THD* thd)
{
send_error
(
&
thd
->
net
,
0
,
"Failed purging old relay logs"
);
unlock_slave_threads
(
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
return
1
;
}
pthread_mutex_lock
(
&
active_mi
->
rli
.
data_lock
);
...
...
@@ -934,7 +934,7 @@ int load_master_data(THD* thd)
err:
unlock_slave_threads
(
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
thd
->
proc_info
=
0
;
mc_mysql_close
(
&
mysql
);
// safe to call since we always do mc_mysql_init()
...
...
sql/set_var.cc
View file @
37817f60
...
...
@@ -1273,7 +1273,7 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type)
bool
sys_var_slave_skip_counter
::
check
(
THD
*
thd
,
set_var
*
var
)
{
int
result
=
0
;
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
pthread_mutex_lock
(
&
active_mi
->
rli
.
run_lock
);
if
(
active_mi
->
rli
.
slave_running
)
{
...
...
@@ -1281,14 +1281,14 @@ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
result
=
1
;
}
pthread_mutex_unlock
(
&
active_mi
->
rli
.
run_lock
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
return
result
;
}
bool
sys_var_slave_skip_counter
::
update
(
THD
*
thd
,
set_var
*
var
)
{
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
pthread_mutex_lock
(
&
active_mi
->
rli
.
run_lock
);
/*
The following test should normally never be true as we test this
...
...
@@ -1302,7 +1302,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
pthread_mutex_unlock
(
&
active_mi
->
rli
.
data_lock
);
}
pthread_mutex_unlock
(
&
active_mi
->
rli
.
run_lock
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
return
0
;
}
...
...
sql/slave.cc
View file @
37817f60
...
...
@@ -34,7 +34,6 @@ typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
volatile
bool
slave_sql_running
=
0
,
slave_io_running
=
0
;
char
*
slave_load_tmpdir
=
0
;
MASTER_INFO
*
active_mi
;
volatile
int
active_mi_in_use
=
0
;
HASH
replicate_do_table
,
replicate_ignore_table
;
DYNAMIC_ARRAY
replicate_wild_do_table
,
replicate_wild_ignore_table
;
bool
do_table_inited
=
0
,
ignore_table_inited
=
0
;
...
...
@@ -114,8 +113,12 @@ int init_slave()
{
DBUG_ENTER
(
"init_slave"
);
/* This is called when mysqld starts */
/*
This is called when mysqld starts. Before client connections are
accepted. However bootstrap may conflict with us if it does START SLAVE.
So it's safer to take the lock.
*/
pthread_mutex_lock
(
&
LOCK_active_mi
);
/*
TODO: re-write this to interate through the list of files
for multi-master
...
...
@@ -160,9 +163,11 @@ int init_slave()
goto
err
;
}
}
pthread_mutex_unlock
(
&
LOCK_active_mi
);
DBUG_RETURN
(
0
);
err:
pthread_mutex_unlock
(
&
LOCK_active_mi
);
DBUG_RETURN
(
1
);
}
...
...
@@ -806,7 +811,14 @@ static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
void
end_slave
()
{
/* This is called when the server terminates, in close_connections(). */
/*
This is called when the server terminates, in close_connections().
It terminates slave threads. However, some CHANGE MASTER etc may still be
running presently. If a START SLAVE was in progress, the mutex lock below
will make us wait until slave threads have started, and START SLAVE
returns, then we terminate them here.
*/
pthread_mutex_lock
(
&
LOCK_active_mi
);
if
(
active_mi
)
{
/*
...
...
@@ -827,6 +839,7 @@ void end_slave()
delete
active_mi
;
active_mi
=
0
;
}
pthread_mutex_unlock
(
&
LOCK_active_mi
);
}
...
...
@@ -2237,13 +2250,6 @@ int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
case
ER_NET_ERROR_ON_WRITE
:
case
ER_SERVER_SHUTDOWN
:
case
ER_NEW_ABORTING_CONNECTION
:
slave_print_error
(
rli
,
expected_error
,
"query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;\
SLAVE START; ."
,
thd
->
query
);
thd
->
query_error
=
1
;
return
1
;
default:
return
0
;
...
...
sql/slave.h
View file @
37817f60
...
...
@@ -27,12 +27,19 @@
/*
MUTEXES in replication:
LOCK_active_mi: this is meant for multimaster, when we can switch from a
master to another. It protects active_mi. We don't care of it for the moment,
as active_mi never moves (it's created at startup and deleted at shutdown, and
not changed: it always points to the same MASTER_INFO struct), because we
don't have multimaster. So for the moment, mi does not move, and mi->rli does
not either.
LOCK_active_mi: [note: this was originally meant for multimaster, to switch
from a master to another, to protect active_mi] It is used to SERIALIZE ALL
administrative commands of replication: START SLAVE, STOP SLAVE, CHANGE
MASTER, RESET SLAVE, end_slave() (when mysqld stops) [init_slave() does not
need it it's called early]. Any of these commands holds the mutex from the
start till the end. This thus protects us against a handful of deadlocks
(consider start_slave_thread() which, when starting the I/O thread, releases
mi->run_lock, keeps rli->run_lock, and tries to re-acquire mi->run_lock).
Currently active_mi never moves (it's created at startup and deleted at
shutdown, and not changed: it always points to the same MASTER_INFO struct),
because we don't have multimaster. So for the moment, mi does not move, and
mi->rli does not either.
In MASTER_INFO: run_lock, data_lock
run_lock protects all information about the run state: slave_running, and the
...
...
@@ -43,6 +50,9 @@
In RELAY_LOG_INFO: run_lock, data_lock
see MASTER_INFO
Order of acquisition: if you want to have LOCK_active_mi and a run_lock, you
must acquire LOCK_active_mi first.
In MYSQL_LOG: LOCK_log, LOCK_index of the binlog and the relay log
LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog
(so that you have to update the .index file).
...
...
@@ -64,19 +74,6 @@ enum enum_binlog_formats {
BINLOG_FORMAT_323_LESS_57
,
BINLOG_FORMAT_323_GEQ_57
};
/*
TODO: this needs to be redone, but for now it does not matter since
we do not have multi-master yet.
*/
#define LOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
++active_mi_in_use; \
pthread_mutex_unlock(&LOCK_active_mi);}
#define UNLOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
--active_mi_in_use; \
pthread_mutex_unlock(&LOCK_active_mi); }
/*
st_relay_log_info contains information on the current relay log and
relay log offset, and master log name and log sequence corresponding to the
...
...
@@ -441,7 +438,6 @@ extern "C" pthread_handler_decl(handle_slave_io,arg);
extern
"C"
pthread_handler_decl
(
handle_slave_sql
,
arg
);
extern
bool
volatile
abort_loop
;
extern
MASTER_INFO
main_mi
,
*
active_mi
;
/* active_mi for multi-master */
extern
volatile
int
active_mi_in_use
;
extern
LIST
master_list
;
extern
HASH
replicate_do_table
,
replicate_ignore_table
;
extern
DYNAMIC_ARRAY
replicate_wild_do_table
,
replicate_wild_ignore_table
;
...
...
sql/sql_parse.cc
View file @
37817f60
...
...
@@ -65,6 +65,7 @@ static bool create_total_list(THD *thd, LEX *lex,
TABLE_LIST
**
result
,
bool
skip_first
);
static
bool
check_one_table_access
(
THD
*
thd
,
ulong
want_access
,
TABLE_LIST
*
table
,
bool
no_errors
);
static
inline
bool
all_tables_not_ok
(
THD
*
thd
,
TABLE_LIST
*
tables
);
const
char
*
any_db
=
"*any*"
;
// Special symbol for check_access
...
...
@@ -1332,9 +1333,7 @@ mysql_execute_command(void)
Skip if we are in the slave thread, some table rules have been
given and the table list says the query should not be replicated
*/
if
(
table_rules_on
&&
tables
&&
!
tables_ok
(
thd
,
tables
)
&&
((
lex
->
sql_command
!=
SQLCOM_DELETE_MULTI
)
||
!
tables_ok
(
thd
,(
TABLE_LIST
*
)
thd
->
lex
.
auxilliary_table_list
.
first
)))
if
(
all_tables_not_ok
(
thd
,
tables
))
{
/* we warn the slave SQL thread */
my_error
(
ER_SLAVE_IGNORED_TABLE
,
MYF
(
0
));
...
...
@@ -1519,9 +1518,9 @@ mysql_execute_command(void)
{
if
(
check_global_access
(
thd
,
SUPER_ACL
))
goto
error
;
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
res
=
change_master
(
thd
,
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
case
SQLCOM_SHOW_SLAVE_STAT
:
...
...
@@ -1529,9 +1528,9 @@ mysql_execute_command(void)
/* Accept one of two privileges */
if
(
check_global_access
(
thd
,
SUPER_ACL
|
REPL_CLIENT_ACL
))
goto
error
;
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
res
=
show_master_info
(
thd
,
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
case
SQLCOM_SHOW_MASTER_STAT
:
...
...
@@ -1581,7 +1580,7 @@ mysql_execute_command(void)
if
(
error
)
goto
error
;
}
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
/*
fetch_master_table will send the error to the client on failure.
Give error if the table already exists.
...
...
@@ -1591,7 +1590,7 @@ mysql_execute_command(void)
{
send_ok
(
&
thd
->
net
);
}
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
#endif
/* HAVE_REPLICATION */
...
...
@@ -1702,9 +1701,9 @@ mysql_execute_command(void)
#ifdef HAVE_REPLICATION
case
SQLCOM_SLAVE_START
:
{
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
start_slave
(
thd
,
active_mi
,
1
/* net report*/
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
case
SQLCOM_SLAVE_STOP
:
...
...
@@ -1727,9 +1726,9 @@ mysql_execute_command(void)
break
;
}
{
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
stop_slave
(
thd
,
active_mi
,
1
/* net report*/
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
#endif
/* HAVE_REPLICATION */
...
...
@@ -2968,9 +2967,18 @@ void mysql_init_multi_delete(LEX *lex)
lex
->
select
->
table_list
.
save_and_clear
(
&
lex
->
auxilliary_table_list
);
}
static
inline
bool
all_tables_not_ok
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
return
(
table_rules_on
&&
tables
&&
!
tables_ok
(
thd
,
tables
)
&&
((
thd
->
lex
.
sql_command
!=
SQLCOM_DELETE_MULTI
)
||
!
tables_ok
(
thd
,(
TABLE_LIST
*
)
thd
->
lex
.
auxilliary_table_list
.
first
)));
}
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
)
/*
When you modify mysql_parse(), you may need to mofify
mysql_test_parse_for_slave() in this same file.
*/
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
)
{
DBUG_ENTER
(
"mysql_parse"
);
...
...
@@ -3005,6 +3013,31 @@ mysql_parse(THD *thd,char *inBuf,uint length)
DBUG_VOID_RETURN
;
}
/*
Usable by the replication SQL thread only: just parse a query to know if it
can be ignored because of replicate-*-table rules.
RETURN VALUES
0 cannot be ignored
1 can be ignored
*/
bool
mysql_test_parse_for_slave
(
THD
*
thd
,
char
*
inBuf
,
uint
length
)
{
LEX
*
lex
;
bool
error
=
0
;
mysql_init_query
(
thd
);
lex
=
lex_start
(
thd
,
(
uchar
*
)
inBuf
,
length
);
if
(
!
yyparse
()
&&
!
thd
->
fatal_error
&&
all_tables_not_ok
(
thd
,(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
))
error
=
1
;
/* Ignore question */
free_items
(
thd
);
/* Free strings used by items */
lex_end
(
lex
);
return
error
;
}
/*****************************************************************************
** Store field definition for create
...
...
@@ -3638,9 +3671,9 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
mysql_update_log
.
new_file
(
1
);
mysql_bin_log
.
new_file
(
1
);
mysql_slow_log
.
new_file
(
1
);
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
rotate_relay_log
(
active_mi
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
if
(
ha_flush_logs
())
result
=
1
;
...
...
@@ -3685,7 +3718,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
#endif
if
(
options
&
REFRESH_SLAVE
)
{
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
if
(
reset_slave
(
thd
,
active_mi
))
{
result
=
1
;
...
...
@@ -3697,7 +3730,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
*/
error_already_sent
=
1
;
}
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
}
if
(
options
&
REFRESH_USER_RESOURCES
)
reset_mqh
(
thd
,(
LEX_USER
*
)
NULL
);
...
...
sql/sql_show.cc
View file @
37817f60
...
...
@@ -1270,11 +1270,11 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
#ifdef HAVE_REPLICATION
case
SHOW_SLAVE_RUNNING
:
{
LOCK_ACTIVE_MI
;
pthread_mutex_lock
(
&
LOCK_active_mi
)
;
net_store_data
(
&
packet2
,
(
active_mi
->
slave_running
&&
active_mi
->
rli
.
slave_running
)
?
"ON"
:
"OFF"
);
UNLOCK_ACTIVE_MI
;
pthread_mutex_unlock
(
&
LOCK_active_mi
)
;
break
;
}
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment