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
e6f59dd6
Commit
e6f59dd6
authored
Mar 11, 2004
by
unknown
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
dc970f95
bb305494
Changes
20
Hide 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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
dc970f95
/******************************************************
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 @
dc970f95
/******************************************************
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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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,218 +1644,21 @@ 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 */
sym_node_t
*
sym_node
__attribute__
((
unused
)))
/* 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 */
{
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
);
ut_error
;
return
(
NULL
);
}
/*****************************************************************
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
));
}
/*****************************************************************
Retrieves characters to the lexical analyzer. */
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
--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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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,84 +1824,93 @@ 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
));
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
);
/*
Set a flag if we are inside an transaction so that we can restart
the transaction from the start if we are killed
This will only be done if we are supporting transactional tables
in the slave.
*/
if
(
!
strcmp
(
thd
->
query
,
"BEGIN"
))
rli
->
inside_transaction
=
opt_using_transactions
;
else
if
(
!
(
strcmp
(
thd
->
query
,
"COMMIT"
)
&&
strcmp
(
thd
->
query
,
"ROLLBACK"
)))
rli
->
inside_transaction
=
0
;
else
{
/*
If we expected a non-zero error code, and we don't get the same error
code, and none of them should be ignored.
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
(
(
expected_error
!=
(
actual_error
=
thd
->
net
.
last_errno
))
&&
expected_error
&&
!
ignored_error_code
(
actual_error
)
&&
!
ignored_error_code
(
expected_error
))
if
(
mysql_test_parse_for_slave
(
thd
,
thd
->
query
,
q_len
))
/* Can ignore query */
clear_all_errors
(
thd
,
rli
);
else
{
slave_print_error
(
rli
,
0
,
"\
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
the transaction from the start if we are killed
This will only be done if we are supporting transactional tables
in the slave.
*/
if
(
!
strcmp
(
thd
->
query
,
"BEGIN"
))
rli
->
inside_transaction
=
opt_using_transactions
;
else
if
(
!
(
strcmp
(
thd
->
query
,
"COMMIT"
)
&&
strcmp
(
thd
->
query
,
"ROLLBACK"
)))
rli
->
inside_transaction
=
0
;
/*
If we expected a non-zero error code, and we don't get the same error
code, and none of them should be ignored.
*/
if
((
expected_error
!=
(
actual_error
=
thd
->
net
.
last_errno
))
&&
expected_error
&&
!
ignored_error_code
(
actual_error
)
&&
!
ignored_error_code
(
expected_error
))
{
slave_print_error
(
rli
,
0
,
"\
Query '%s' caused different errors on master and slave. \
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
Default database: '%s'"
,
query
,
ER_SAFE
(
expected_error
),
expected_error
,
actual_error
?
thd
->
net
.
last_error
:
"no error"
,
actual_error
,
print_slave_db_safe
(
db
));
thd
->
query_error
=
1
;
}
/*
If we get the same error code as expected, or they should be ignored.
*/
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
;
}
/*
Other cases: mostly we expected no error and get one.
*/
else
if
(
thd
->
query_error
||
thd
->
fatal_error
)
{
slave_print_error
(
rli
,
actual_error
,
"Error '%s' on query '%s'. Default database: '%s'"
,
(
actual_error
?
thd
->
net
.
last_error
:
"unexpected success or fatal error"
),
query
,
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.
query
,
ER_SAFE
(
expected_error
),
expected_error
,
actual_error
?
thd
->
net
.
last_error
:
"no error"
,
actual_error
,
print_slave_db_safe
(
db
));
thd
->
query_error
=
1
;
}
/*
If we get the same error code as expected, or they should be ignored.
*/
else
if
(
expected_error
==
actual_error
||
ignored_error_code
(
actual_error
))
clear_all_errors
(
thd
,
rli
);
/*
Other cases: mostly we expected no error and get one.
*/
else
if
(
thd
->
query_error
||
thd
->
fatal_error
)
{
slave_print_error
(
rli
,
actual_error
,
"Error '%s' on query '%s'. Default database: '%s'"
,
(
actual_error
?
thd
->
net
.
last_error
:
"unexpected success or fatal error"
),
query
,
print_slave_db_safe
(
db
));
thd
->
query_error
=
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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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 @
e6f59dd6
...
...
@@ -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