Merge from mysql-5.5-bugteam to mysql-5.5-runtime
No conflicts
This commit is contained in:
commit
1bb2c68bfa
@ -61,6 +61,8 @@ SET(BUILDTYPE_DOCSTRING
|
|||||||
|
|
||||||
IF(WITH_DEBUG)
|
IF(WITH_DEBUG)
|
||||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE)
|
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE)
|
||||||
|
SET(MYSQL_MAINTAINER_MODE ON CACHE BOOL
|
||||||
|
"MySQL maintainer-specific development environment")
|
||||||
SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE)
|
SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE)
|
||||||
ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG)
|
ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG)
|
||||||
IF(CUSTOM_C_FLAGS)
|
IF(CUSTOM_C_FLAGS)
|
||||||
|
@ -263,6 +263,8 @@ test-full-qa:
|
|||||||
#
|
#
|
||||||
# Headers which need to be checked for abi/api compatibility.
|
# Headers which need to be checked for abi/api compatibility.
|
||||||
#
|
#
|
||||||
|
# Attention: do not forget to also add to cmake/abi_check.cmake
|
||||||
|
#
|
||||||
|
|
||||||
API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin_audit.h \
|
API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin_audit.h \
|
||||||
$(top_srcdir)/include/mysql/plugin_ftparser.h \
|
$(top_srcdir)/include/mysql/plugin_ftparser.h \
|
||||||
|
@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
ELSE()
|
ELSE()
|
||||||
SET(COMPILER ${CMAKE_C_COMPILER})
|
SET(COMPILER ${CMAKE_C_COMPILER})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(API_PREPROCESSOR_HEADER
|
SET(API_PREPROCESSOR_HEADER
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h
|
${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h
|
${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql.h
|
${CMAKE_SOURCE_DIR}/include/mysql.h
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h
|
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h
|
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h
|
||||||
|
${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h
|
||||||
|
${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(abi_check ALL
|
ADD_CUSTOM_TARGET(abi_check ALL
|
||||||
|
@ -8,7 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [
|
|||||||
[AS_HELP_STRING([--enable-mysql-maintainer-mode],
|
[AS_HELP_STRING([--enable-mysql-maintainer-mode],
|
||||||
[Enable a MySQL maintainer-specific development environment])],
|
[Enable a MySQL maintainer-specific development environment])],
|
||||||
[USE_MYSQL_MAINTAINER_MODE=$enableval],
|
[USE_MYSQL_MAINTAINER_MODE=$enableval],
|
||||||
[USE_MYSQL_MAINTAINER_MODE=no])
|
[AS_IF([test "$with_debug" != "no"],
|
||||||
|
[USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])])
|
||||||
AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE])
|
AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
13
configure.in
13
configure.in
@ -27,7 +27,7 @@ dnl
|
|||||||
dnl When changing the major version number please also check the switch
|
dnl When changing the major version number please also check the switch
|
||||||
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
||||||
dnl to update version.c in ndb.
|
dnl to update version.c in ndb.
|
||||||
AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql])
|
AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
@ -118,6 +118,13 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION)
|
|||||||
AC_SUBST(SHARED_LIB_VERSION)
|
AC_SUBST(SHARED_LIB_VERSION)
|
||||||
AC_SUBST(AVAILABLE_LANGUAGES)
|
AC_SUBST(AVAILABLE_LANGUAGES)
|
||||||
|
|
||||||
|
# Check whether a debug mode should be enabled.
|
||||||
|
AC_ARG_WITH([debug],
|
||||||
|
AS_HELP_STRING([--with-debug@<:@=full@:>@],
|
||||||
|
[Enable various amounts of debugging support (full adds a slow memory checker).]),
|
||||||
|
[with_debug=$withval],
|
||||||
|
[with_debug=no])
|
||||||
|
|
||||||
# Whether the maintainer mode should be enabled.
|
# Whether the maintainer mode should be enabled.
|
||||||
MY_MAINTAINER_MODE
|
MY_MAINTAINER_MODE
|
||||||
|
|
||||||
@ -1689,10 +1696,6 @@ then
|
|||||||
DEBUG_OPTIMIZE_CXX=""
|
DEBUG_OPTIMIZE_CXX=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH(debug,
|
|
||||||
[AS_HELP_STRING([--with-debug], [Add debug code @<:@default=no@:>@])],
|
|
||||||
[with_debug=$withval],
|
|
||||||
[with_debug=no])
|
|
||||||
if test "$with_debug" = "yes"
|
if test "$with_debug" = "yes"
|
||||||
then
|
then
|
||||||
AC_DEFINE([DBUG_ON], [1], [Use libdbug])
|
AC_DEFINE([DBUG_ON], [1], [Use libdbug])
|
||||||
|
@ -905,6 +905,7 @@ void _db_set_init_(const char *control)
|
|||||||
CODE_STATE tmp_cs;
|
CODE_STATE tmp_cs;
|
||||||
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
|
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
|
||||||
tmp_cs.stack= &init_settings;
|
tmp_cs.stack= &init_settings;
|
||||||
|
tmp_cs.process= db_process ? db_process : "dbug";
|
||||||
DbugParse(&tmp_cs, control);
|
DbugParse(&tmp_cs, control);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2370,7 +2371,7 @@ static void DbugFlush(CODE_STATE *cs)
|
|||||||
|
|
||||||
void _db_flush_()
|
void _db_flush_()
|
||||||
{
|
{
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs= NULL;
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
(void) fflush(cs->stack->out_file);
|
(void) fflush(cs->stack->out_file);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB
|
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,8 +13,18 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
#ifndef _dbug_h
|
#ifndef MY_DBUG_INCLUDED
|
||||||
#define _dbug_h
|
#define MY_DBUG_INCLUDED
|
||||||
|
|
||||||
|
#ifndef __WIN__
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
|
#endif /* not __WIN__ */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -111,6 +121,20 @@ extern const char* _db_get_func_(void);
|
|||||||
#define DBUG_CRASH_VOID_RETURN \
|
#define DBUG_CRASH_VOID_RETURN \
|
||||||
DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return")
|
DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return")
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make the program fail, without creating a core file.
|
||||||
|
abort() will send SIGABRT which (most likely) generates core.
|
||||||
|
Use SIGKILL instead, which cannot be caught.
|
||||||
|
We also pause the current thread, until the signal is actually delivered.
|
||||||
|
An alternative would be to use _exit(EXIT_FAILURE),
|
||||||
|
but then valgrind would report lots of memory leaks.
|
||||||
|
*/
|
||||||
|
#ifdef __WIN__
|
||||||
|
#define DBUG_SUICIDE() DBUG_ABORT()
|
||||||
|
#else
|
||||||
|
#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause())
|
||||||
|
#endif
|
||||||
|
|
||||||
#else /* No debugger */
|
#else /* No debugger */
|
||||||
|
|
||||||
#define DBUG_ENTER(a1)
|
#define DBUG_ENTER(a1)
|
||||||
@ -139,10 +163,11 @@ extern const char* _db_get_func_(void);
|
|||||||
#define DBUG_EXPLAIN_INITIAL(buf,len)
|
#define DBUG_EXPLAIN_INITIAL(buf,len)
|
||||||
#define DEBUGGER_OFF do { } while(0)
|
#define DEBUGGER_OFF do { } while(0)
|
||||||
#define DEBUGGER_ON do { } while(0)
|
#define DEBUGGER_ON do { } while(0)
|
||||||
#define DBUG_ABORT() abort()
|
#define DBUG_ABORT() do { } while(0)
|
||||||
#define DBUG_CRASH_ENTER(func)
|
#define DBUG_CRASH_ENTER(func)
|
||||||
#define DBUG_CRASH_RETURN(val) do { return(val); } while(0)
|
#define DBUG_CRASH_RETURN(val) do { return(val); } while(0)
|
||||||
#define DBUG_CRASH_VOID_RETURN do { return; } while(0)
|
#define DBUG_CRASH_VOID_RETURN do { return; } while(0)
|
||||||
|
#define DBUG_SUICIDE() do { } while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -164,4 +189,5 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* MY_DBUG_INCLUDED */
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
#define MYSQL_CLIENT_PLUGIN_INCLUDED
|
#define MYSQL_CLIENT_PLUGIN_INCLUDED
|
||||||
|
|
||||||
|
#ifndef MYSQL_ABI_CHECK
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* known plugin types */
|
/* known plugin types */
|
||||||
#define MYSQL_CLIENT_reserved1 0
|
#define MYSQL_CLIENT_reserved1 0
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
struct st_mysql_client_plugin
|
struct st_mysql_client_plugin
|
||||||
{
|
{
|
||||||
int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *);
|
int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *);
|
||||||
|
@ -122,4 +122,60 @@ drop table t1i, t2m;
|
|||||||
|
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT );
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--connection slave1
|
||||||
|
--echo # Slave1: lock table for synchronization
|
||||||
|
LOCK TABLES t1 WRITE;
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
--echo # Master: insert into the table
|
||||||
|
INSERT INTO t1 SELECT SLEEP(4);
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--echo # Slave: wait for the insert
|
||||||
|
let $wait_condition=
|
||||||
|
SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||||
|
WHERE STATE = "Waiting for table metadata lock"
|
||||||
|
AND INFO = "INSERT INTO t1 SELECT SLEEP(4)";
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--echo # Slave: send slave stop
|
||||||
|
--send STOP SLAVE
|
||||||
|
|
||||||
|
--connection slave1
|
||||||
|
--echo # Slave1: wait for stop slave
|
||||||
|
let $wait_condition=
|
||||||
|
SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||||
|
WHERE INFO = "STOP SLAVE";
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--echo # Slave1: unlock the table
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--echo # Slave: wait for the slave to stop
|
||||||
|
--reap
|
||||||
|
--source include/wait_for_slave_to_stop.inc
|
||||||
|
|
||||||
|
--echo # Start slave again
|
||||||
|
--source include/start_slave.inc
|
||||||
|
|
||||||
|
--echo # Clean up
|
||||||
|
--connection master
|
||||||
|
DROP TABLE t1;
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
# End of tests
|
# End of tests
|
||||||
|
61
mysql-test/extra/rpl_tests/rpl_stop_slave.test
Normal file
61
mysql-test/extra/rpl_tests/rpl_stop_slave.test
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#
|
||||||
|
# Auxiliary file which is used to test BUG#56118
|
||||||
|
#
|
||||||
|
# Slave should apply all statements in the transaction before stop if any
|
||||||
|
# temporary table is created or dropped.
|
||||||
|
#
|
||||||
|
# USEAGE:
|
||||||
|
# --let $tmp_table_stm= a SQL statement
|
||||||
|
# --source extra/rpl_tests/rpl_stop_slave.test
|
||||||
|
#
|
||||||
|
|
||||||
|
if (`SELECT "$tmp_table_stm" = ''`)
|
||||||
|
{
|
||||||
|
--echo \$tmp_table_stm is NULL
|
||||||
|
--die $tmp_table_stm is NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo [ On Master ]
|
||||||
|
connection master;
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM t1;
|
||||||
|
eval $tmp_table_stm;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
DROP TEMPORARY TABLE tt1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo [ On Slave ]
|
||||||
|
connection slave;
|
||||||
|
|
||||||
|
# To check if slave SQL thread is applying INSERT statement
|
||||||
|
let $show_statement= SHOW PROCESSLIST;
|
||||||
|
let $field= Info;
|
||||||
|
let $condition= LIKE 'INSERT%';
|
||||||
|
source include/wait_show_condition.inc;
|
||||||
|
|
||||||
|
send STOP SLAVE SQL_THREAD;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo [ On Slave1 ]
|
||||||
|
connection slave1;
|
||||||
|
--echo # To resume slave SQL thread
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||||
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo [ On Slave ]
|
||||||
|
connection slave;
|
||||||
|
reap;
|
||||||
|
source include/wait_for_slave_sql_to_stop.inc;
|
||||||
|
|
||||||
|
--echo # Slave should stop after the transaction has committed.
|
||||||
|
--echo # So t1 on master is same to t1 on slave.
|
||||||
|
let diff_table_1=master:test.t1;
|
||||||
|
let diff_table_2=slave:test.t1;
|
||||||
|
source include/diff_tables.inc;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
START SLAVE SQL_THREAD;
|
||||||
|
source include/wait_for_slave_sql_to_start.inc;
|
@ -16,6 +16,12 @@ CREATE TABLE test_suppressions (
|
|||||||
-- no invalid patterns can be inserted
|
-- no invalid patterns can be inserted
|
||||||
-- into test_suppressions
|
-- into test_suppressions
|
||||||
--
|
--
|
||||||
|
SET @character_set_client_saved = @@character_set_client||
|
||||||
|
SET @character_set_results_saved = @@character_set_results||
|
||||||
|
SET @collation_connection_saved = @@collation_connection||
|
||||||
|
SET @@character_set_client = latin1||
|
||||||
|
SET @@character_set_results = latin1||
|
||||||
|
SET @@collation_connection = latin1_swedish_ci||
|
||||||
/*!50002
|
/*!50002
|
||||||
CREATE DEFINER=root@localhost TRIGGER ts_insert
|
CREATE DEFINER=root@localhost TRIGGER ts_insert
|
||||||
BEFORE INSERT ON test_suppressions
|
BEFORE INSERT ON test_suppressions
|
||||||
@ -24,6 +30,9 @@ FOR EACH ROW BEGIN
|
|||||||
SELECT "" REGEXP NEW.pattern INTO dummy;
|
SELECT "" REGEXP NEW.pattern INTO dummy;
|
||||||
END
|
END
|
||||||
*/||
|
*/||
|
||||||
|
SET @@character_set_client = @character_set_client_saved||
|
||||||
|
SET @@character_set_results = @character_set_results_saved||
|
||||||
|
SET @@collation_connection = @collation_connection_saved||
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -38,6 +47,12 @@ CREATE TABLE global_suppressions (
|
|||||||
-- no invalid patterns can be inserted
|
-- no invalid patterns can be inserted
|
||||||
-- into global_suppressions
|
-- into global_suppressions
|
||||||
--
|
--
|
||||||
|
SET @character_set_client_saved = @@character_set_client||
|
||||||
|
SET @character_set_results_saved = @@character_set_results||
|
||||||
|
SET @collation_connection_saved = @@collation_connection||
|
||||||
|
SET @@character_set_client = latin1||
|
||||||
|
SET @@character_set_results = latin1||
|
||||||
|
SET @@collation_connection = latin1_swedish_ci||
|
||||||
/*!50002
|
/*!50002
|
||||||
CREATE DEFINER=root@localhost TRIGGER gs_insert
|
CREATE DEFINER=root@localhost TRIGGER gs_insert
|
||||||
BEFORE INSERT ON global_suppressions
|
BEFORE INSERT ON global_suppressions
|
||||||
@ -46,6 +61,9 @@ FOR EACH ROW BEGIN
|
|||||||
SELECT "" REGEXP NEW.pattern INTO dummy;
|
SELECT "" REGEXP NEW.pattern INTO dummy;
|
||||||
END
|
END
|
||||||
*/||
|
*/||
|
||||||
|
SET @@character_set_client = @character_set_client_saved||
|
||||||
|
SET @@character_set_results = @character_set_results_saved||
|
||||||
|
SET @@collation_connection = @collation_connection_saved||
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1575,6 +1575,17 @@ DROP USER 'testbug'@localhost;
|
|||||||
DROP TABLE db2.t1;
|
DROP TABLE db2.t1;
|
||||||
DROP DATABASE db1;
|
DROP DATABASE db1;
|
||||||
DROP DATABASE db2;
|
DROP DATABASE db2;
|
||||||
|
#
|
||||||
|
# Bug #36742
|
||||||
|
#
|
||||||
|
grant usage on Foo.* to myuser@Localhost identified by 'foo';
|
||||||
|
grant select on Foo.* to myuser@localhost;
|
||||||
|
select host,user from mysql.user where User='myuser';
|
||||||
|
host user
|
||||||
|
localhost myuser
|
||||||
|
revoke select on Foo.* from myuser@localhost;
|
||||||
|
delete from mysql.user where User='myuser';
|
||||||
|
flush privileges;
|
||||||
#########################################################################
|
#########################################################################
|
||||||
#
|
#
|
||||||
# Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
|
# Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
|
||||||
|
@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOST;
|
|||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
CUser LOCALHOST test Y
|
|
||||||
CUser localhost test Y
|
CUser localhost test Y
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
CUser localhost test Y
|
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
grant select on test.t1 to CUser@localhost;
|
grant select on test.t1 to CUser@localhost;
|
||||||
grant select on test.t1 to CUser@LOCALHOST;
|
grant select on test.t1 to CUser@LOCALHOST;
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
CUser LOCALHOST test t1 Select
|
|
||||||
CUser localhost test t1 Select
|
CUser localhost test t1 Select
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
CUser localhost test t1 Select
|
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
|
||||||
grant select(a) on test.t1 to CUser@localhost;
|
grant select(a) on test.t1 to CUser@localhost;
|
||||||
grant select(a) on test.t1 to CUser@LOCALHOST;
|
grant select(a) on test.t1 to CUser@LOCALHOST;
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
CUser LOCALHOST test t1 Select
|
|
||||||
CUser localhost test t1 Select
|
CUser localhost test t1 Select
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
CUser localhost test t1 Select
|
|
||||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser LOCALHOST
|
|
||||||
CUser localhost
|
CUser localhost
|
||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
user host db Table_name Table_priv Column_priv
|
user host db Table_name Table_priv Column_priv
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
grant select on test.* to CUser2@localhost;
|
grant select on test.* to CUser2@localhost;
|
||||||
grant select on test.* to CUser2@LOCALHOST;
|
grant select on test.* to CUser2@LOCALHOST;
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser2 LOCALHOST
|
|
||||||
CUser2 localhost
|
CUser2 localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
CUser2 LOCALHOST test Y
|
|
||||||
CUser2 localhost test Y
|
CUser2 localhost test Y
|
||||||
REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
|
REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser2 LOCALHOST
|
|
||||||
CUser2 localhost
|
CUser2 localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
CUser2 localhost test Y
|
|
||||||
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
||||||
|
ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost'
|
||||||
flush privileges;
|
flush privileges;
|
||||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||||
user host
|
user host
|
||||||
CUser2 LOCALHOST
|
|
||||||
CUser2 localhost
|
CUser2 localhost
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||||
user host db select_priv
|
user host db select_priv
|
||||||
DROP USER CUser2@localhost;
|
DROP USER CUser2@localhost;
|
||||||
DROP USER CUser2@LOCALHOST;
|
DROP USER CUser2@LOCALHOST;
|
||||||
|
ERROR HY000: Operation DROP USER failed for 'CUser2'@'localhost'
|
||||||
CREATE DATABASE mysqltest_1;
|
CREATE DATABASE mysqltest_1;
|
||||||
CREATE TABLE mysqltest_1.t1 (a INT);
|
CREATE TABLE mysqltest_1.t1 (a INT);
|
||||||
CREATE USER 'mysqltest1'@'%';
|
CREATE USER 'mysqltest1'@'%';
|
||||||
|
@ -32,9 +32,9 @@ mysqld is alive
|
|||||||
CREATE USER testuser@'0:0:0:0:0:FFFF:127.0.0.1' identified by '1234';
|
CREATE USER testuser@'0:0:0:0:0:FFFF:127.0.0.1' identified by '1234';
|
||||||
GRANT ALL ON test.* TO testuser@'0:0:0:0:0:FFFF:127.0.0.1';
|
GRANT ALL ON test.* TO testuser@'0:0:0:0:0:FFFF:127.0.0.1';
|
||||||
SHOW GRANTS FOR testuser@'0:0:0:0:0:FFFF:127.0.0.1';
|
SHOW GRANTS FOR testuser@'0:0:0:0:0:FFFF:127.0.0.1';
|
||||||
Grants for testuser@0:0:0:0:0:FFFF:127.0.0.1
|
Grants for testuser@0:0:0:0:0:ffff:127.0.0.1
|
||||||
GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
||||||
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1'
|
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1'
|
||||||
SET @nip= inet_aton('0:0:0:0:0:FFFF:127.0.0.1');
|
SET @nip= inet_aton('0:0:0:0:0:FFFF:127.0.0.1');
|
||||||
SELECT @nip;
|
SELECT @nip;
|
||||||
@nip
|
@nip
|
||||||
@ -61,9 +61,9 @@ mysqld is alive
|
|||||||
CREATE USER testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' identified by '1234';
|
CREATE USER testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' identified by '1234';
|
||||||
GRANT ALL ON test.* TO testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
|
GRANT ALL ON test.* TO testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
|
||||||
SHOW GRANTS FOR testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
|
SHOW GRANTS FOR testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
|
||||||
Grants for testuser@0000:0000:0000:0000:0000:FFFF:127.0.0.1
|
Grants for testuser@0000:0000:0000:0000:0000:ffff:127.0.0.1
|
||||||
GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
||||||
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'
|
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1'
|
||||||
SET @nip= inet_aton('0000:0000:0000:0000:0000:FFFF:127.0.0.1');
|
SET @nip= inet_aton('0000:0000:0000:0000:0000:FFFF:127.0.0.1');
|
||||||
SELECT @nip;
|
SELECT @nip;
|
||||||
@nip
|
@nip
|
||||||
@ -90,9 +90,9 @@ mysqld is alive
|
|||||||
CREATE USER testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1' identified by '1234';
|
CREATE USER testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1' identified by '1234';
|
||||||
GRANT ALL ON test.* TO testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
|
GRANT ALL ON test.* TO testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
|
||||||
SHOW GRANTS FOR testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
|
SHOW GRANTS FOR testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
|
||||||
Grants for testuser@0:0000:0000:0:0000:FFFF:127.0.0.1
|
Grants for testuser@0:0000:0000:0:0000:ffff:127.0.0.1
|
||||||
GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
||||||
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1'
|
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1'
|
||||||
SET @nip= inet_aton('0:0000:0000:0:0000:FFFF:127.0.0.1');
|
SET @nip= inet_aton('0:0000:0000:0:0000:FFFF:127.0.0.1');
|
||||||
SELECT @nip;
|
SELECT @nip;
|
||||||
@nip
|
@nip
|
||||||
@ -119,9 +119,9 @@ mysqld is alive
|
|||||||
CREATE USER testuser@'0::0000:FFFF:127.0.0.1' identified by '1234';
|
CREATE USER testuser@'0::0000:FFFF:127.0.0.1' identified by '1234';
|
||||||
GRANT ALL ON test.* TO testuser@'0::0000:FFFF:127.0.0.1';
|
GRANT ALL ON test.* TO testuser@'0::0000:FFFF:127.0.0.1';
|
||||||
SHOW GRANTS FOR testuser@'0::0000:FFFF:127.0.0.1';
|
SHOW GRANTS FOR testuser@'0::0000:FFFF:127.0.0.1';
|
||||||
Grants for testuser@0::0000:FFFF:127.0.0.1
|
Grants for testuser@0::0000:ffff:127.0.0.1
|
||||||
GRANT USAGE ON *.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
GRANT USAGE ON *.* TO 'testuser'@'0::0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
||||||
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:FFFF:127.0.0.1'
|
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:ffff:127.0.0.1'
|
||||||
SET @nip= inet_aton('0::0000:FFFF:127.0.0.1');
|
SET @nip= inet_aton('0::0000:FFFF:127.0.0.1');
|
||||||
SELECT @nip;
|
SELECT @nip;
|
||||||
@nip
|
@nip
|
||||||
@ -149,9 +149,9 @@ mysqld is alive
|
|||||||
CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234';
|
CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234';
|
||||||
GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1';
|
GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1';
|
||||||
SHOW GRANTS FOR testuser@'::FFFF:127.0.0.1';
|
SHOW GRANTS FOR testuser@'::FFFF:127.0.0.1';
|
||||||
Grants for testuser@::FFFF:127.0.0.1
|
Grants for testuser@::ffff:127.0.0.1
|
||||||
GRANT USAGE ON *.* TO 'testuser'@'::FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
GRANT USAGE ON *.* TO 'testuser'@'::ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
|
||||||
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::FFFF:127.0.0.1'
|
GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::ffff:127.0.0.1'
|
||||||
SET @nip= inet_aton('::FFFF:127.0.0.1');
|
SET @nip= inet_aton('::FFFF:127.0.0.1');
|
||||||
SELECT @nip;
|
SELECT @nip;
|
||||||
@nip
|
@nip
|
||||||
|
@ -43,3 +43,25 @@ one
|
|||||||
1
|
1
|
||||||
include/start_slave.inc
|
include/start_slave.inc
|
||||||
drop table t1i, t2m;
|
drop table t1i, t2m;
|
||||||
|
#
|
||||||
|
# Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep
|
||||||
|
#
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a INT );
|
||||||
|
# Slave1: lock table for synchronization
|
||||||
|
LOCK TABLES t1 WRITE;
|
||||||
|
# Master: insert into the table
|
||||||
|
INSERT INTO t1 SELECT SLEEP(4);
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave.
|
||||||
|
# Slave: wait for the insert
|
||||||
|
# Slave: send slave stop
|
||||||
|
STOP SLAVE;
|
||||||
|
# Slave1: wait for stop slave
|
||||||
|
# Slave1: unlock the table
|
||||||
|
UNLOCK TABLES;
|
||||||
|
# Slave: wait for the slave to stop
|
||||||
|
# Start slave again
|
||||||
|
include/start_slave.inc
|
||||||
|
# Clean up
|
||||||
|
DROP TABLE t1;
|
||||||
|
77
mysql-test/suite/rpl/r/rpl_stop_slave.result
Normal file
77
mysql-test/suite/rpl/r/rpl_stop_slave.result
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
stop slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
start slave;
|
||||||
|
|
||||||
|
# BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
|
||||||
|
#
|
||||||
|
# If a temporary table is created or dropped, the transaction should be
|
||||||
|
# regarded similarly that a non-transactional table is modified. So
|
||||||
|
# STOP SLAVE should wait until the transaction has finished.
|
||||||
|
CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
|
||||||
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
include/stop_slave.inc
|
||||||
|
|
||||||
|
# Suspend the INSERT statement in current transaction on SQL thread.
|
||||||
|
# It guarantees that SQL thread is applying the transaction when
|
||||||
|
# STOP SLAVE command launchs.
|
||||||
|
SET GLOBAL debug= 'd,after_mysql_insert';
|
||||||
|
include/start_slave.inc
|
||||||
|
|
||||||
|
# CREATE TEMPORARY TABLE with InnoDB engine
|
||||||
|
# -----------------------------------------
|
||||||
|
|
||||||
|
[ On Master ]
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM t1;
|
||||||
|
CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
DROP TEMPORARY TABLE tt1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
[ On Slave ]
|
||||||
|
STOP SLAVE SQL_THREAD;
|
||||||
|
|
||||||
|
[ On Slave1 ]
|
||||||
|
# To resume slave SQL thread
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||||
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
|
||||||
|
[ On Slave ]
|
||||||
|
# Slave should stop after the transaction has committed.
|
||||||
|
# So t1 on master is same to t1 on slave.
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
START SLAVE SQL_THREAD;
|
||||||
|
|
||||||
|
# CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
[ On Master ]
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM t1;
|
||||||
|
CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
|
||||||
|
SELECT c1 FROM t2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
DROP TEMPORARY TABLE tt1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
[ On Slave ]
|
||||||
|
STOP SLAVE SQL_THREAD;
|
||||||
|
|
||||||
|
[ On Slave1 ]
|
||||||
|
# To resume slave SQL thread
|
||||||
|
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||||
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
|
||||||
|
[ On Slave ]
|
||||||
|
# Slave should stop after the transaction has committed.
|
||||||
|
# So t1 on master is same to t1 on slave.
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
START SLAVE SQL_THREAD;
|
||||||
|
|
||||||
|
# Test end
|
||||||
|
SET GLOBAL debug= '$debug_save';
|
||||||
|
DROP TABLE t1, t2;
|
51
mysql-test/suite/rpl/t/rpl_stop_slave.test
Normal file
51
mysql-test/suite/rpl/t/rpl_stop_slave.test
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
source include/master-slave.inc;
|
||||||
|
source include/have_innodb.inc;
|
||||||
|
source include/have_debug.inc;
|
||||||
|
source include/have_debug_sync.inc;
|
||||||
|
source include/have_binlog_format_mixed_or_statement.inc;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
|
||||||
|
--echo #
|
||||||
|
--echo # If a temporary table is created or dropped, the transaction should be
|
||||||
|
--echo # regarded similarly that a non-transactional table is modified. So
|
||||||
|
--echo # STOP SLAVE should wait until the transaction has finished.
|
||||||
|
|
||||||
|
CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
SET DEBUG_SYNC= 'RESET';
|
||||||
|
source include/stop_slave.inc;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Suspend the INSERT statement in current transaction on SQL thread.
|
||||||
|
--echo # It guarantees that SQL thread is applying the transaction when
|
||||||
|
--echo # STOP SLAVE command launchs.
|
||||||
|
let $debug_save= `SELECT @@GLOBAL.debug`;
|
||||||
|
SET GLOBAL debug= 'd,after_mysql_insert';
|
||||||
|
source include/start_slave.inc;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # CREATE TEMPORARY TABLE with InnoDB engine
|
||||||
|
--echo # -----------------------------------------
|
||||||
|
let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
|
||||||
|
source extra/rpl_tests/rpl_stop_slave.test;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
|
||||||
|
--echo # ----------------------------------------------------
|
||||||
|
let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
|
||||||
|
SELECT c1 FROM t2;
|
||||||
|
source extra/rpl_tests/rpl_stop_slave.test;
|
||||||
|
|
||||||
|
# Don't need to verify 'CREATE TEMPORARY TABLE' with MyIASM engine, as it
|
||||||
|
# never is binlogged into a transaction since 5.5.
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Test end
|
||||||
|
SET GLOBAL debug= '$debug_save';
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
source include/master-slave-end.inc;
|
@ -1573,6 +1573,16 @@ DROP TABLE db2.t1;
|
|||||||
DROP DATABASE db1;
|
DROP DATABASE db1;
|
||||||
DROP DATABASE db2;
|
DROP DATABASE db2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #36742
|
||||||
|
--echo #
|
||||||
|
grant usage on Foo.* to myuser@Localhost identified by 'foo';
|
||||||
|
grant select on Foo.* to myuser@localhost;
|
||||||
|
select host,user from mysql.user where User='myuser';
|
||||||
|
revoke select on Foo.* from myuser@localhost;
|
||||||
|
delete from mysql.user where User='myuser';
|
||||||
|
flush privileges;
|
||||||
|
|
||||||
# Wait till we reached the initial number of concurrent sessions
|
# Wait till we reached the initial number of concurrent sessions
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
|||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||||
|
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
|
--error ER_CANNOT_USER
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
|
||||||
#### table grants
|
#### table grants
|
||||||
@ -88,6 +89,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
|||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
|
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
|
--error ER_CANNOT_USER
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
|
||||||
### column grants
|
### column grants
|
||||||
@ -112,6 +114,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
|||||||
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
|
||||||
|
|
||||||
DROP USER CUser@localhost;
|
DROP USER CUser@localhost;
|
||||||
|
--error ER_CANNOT_USER
|
||||||
DROP USER CUser@LOCALHOST;
|
DROP USER CUser@LOCALHOST;
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -131,6 +134,7 @@ flush privileges;
|
|||||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||||
|
|
||||||
|
--error ER_NONEXISTING_GRANT
|
||||||
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
|
||||||
@ -138,6 +142,7 @@ SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
|||||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||||
|
|
||||||
DROP USER CUser2@localhost;
|
DROP USER CUser2@localhost;
|
||||||
|
--error ER_CANNOT_USER
|
||||||
DROP USER CUser2@LOCALHOST;
|
DROP USER CUser2@LOCALHOST;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1156,7 +1156,7 @@ int ha_commit_trans(THD *thd, bool all)
|
|||||||
uint rw_ha_count;
|
uint rw_ha_count;
|
||||||
bool rw_trans;
|
bool rw_trans;
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("crash_commit_before", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE(););
|
||||||
|
|
||||||
/* Close all cursors that can not survive COMMIT */
|
/* Close all cursors that can not survive COMMIT */
|
||||||
if (is_real_trans) /* not a statement commit */
|
if (is_real_trans) /* not a statement commit */
|
||||||
@ -1208,7 +1208,7 @@ int ha_commit_trans(THD *thd, bool all)
|
|||||||
}
|
}
|
||||||
status_var_increment(thd->status_var.ha_prepare_count);
|
status_var_increment(thd->status_var.ha_prepare_count);
|
||||||
}
|
}
|
||||||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
|
||||||
if (error || (is_real_trans && xid &&
|
if (error || (is_real_trans && xid &&
|
||||||
(error= !(cookie= tc_log->log_xid(thd, xid)))))
|
(error= !(cookie= tc_log->log_xid(thd, xid)))))
|
||||||
{
|
{
|
||||||
@ -1216,13 +1216,13 @@ int ha_commit_trans(THD *thd, bool all)
|
|||||||
error= 1;
|
error= 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
|
||||||
}
|
}
|
||||||
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
|
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
|
||||||
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
|
||||||
if (cookie)
|
if (cookie)
|
||||||
tc_log->unlog(cookie, xid);
|
tc_log->unlog(cookie, xid);
|
||||||
DBUG_EXECUTE_IF("crash_commit_after", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
|
||||||
RUN_HOOK(transaction, after_commit, (thd, FALSE));
|
RUN_HOOK(transaction, after_commit, (thd, FALSE));
|
||||||
end:
|
end:
|
||||||
if (rw_trans)
|
if (rw_trans)
|
||||||
|
@ -3691,48 +3691,92 @@ longlong Item_master_pos_wait::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables a session to wait on a condition until a timeout or a network
|
||||||
|
disconnect occurs.
|
||||||
|
|
||||||
|
@remark The connection is polled every m_interrupt_interval nanoseconds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Interruptible_wait
|
||||||
|
{
|
||||||
|
THD *m_thd;
|
||||||
|
struct timespec m_abs_timeout;
|
||||||
|
static const ulonglong m_interrupt_interval;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Interruptible_wait(THD *thd)
|
||||||
|
: m_thd(thd) {}
|
||||||
|
|
||||||
|
~Interruptible_wait() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Set the absolute timeout.
|
||||||
|
|
||||||
|
@param timeout The amount of time in nanoseconds to wait
|
||||||
|
*/
|
||||||
|
void set_timeout(ulonglong timeout)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Calculate the absolute system time at the start so it can
|
||||||
|
be controlled in slices. It relies on the fact that once
|
||||||
|
the absolute time passes, the timed wait call will fail
|
||||||
|
automatically with a timeout error.
|
||||||
|
*/
|
||||||
|
set_timespec_nsec(m_abs_timeout, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The timed wait. */
|
||||||
|
int wait(mysql_cond_t *, mysql_mutex_t *);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Time to wait before polling the connection status. */
|
||||||
|
const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Wait for a given condition to be signaled within the specified timeout.
|
Wait for a given condition to be signaled.
|
||||||
|
|
||||||
@param cond the condition variable to wait on
|
@param cond The condition variable to wait on.
|
||||||
@param lock the associated mutex
|
@param mutex The associated mutex.
|
||||||
@param abstime the amount of time in seconds to wait
|
|
||||||
|
@remark The absolute timeout is preserved across calls.
|
||||||
|
|
||||||
@retval return value from mysql_cond_timedwait
|
@retval return value from mysql_cond_timedwait
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INTERRUPT_INTERVAL (5 * ULL(1000000000))
|
int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
|
||||||
|
|
||||||
static int interruptible_wait(THD *thd, mysql_cond_t *cond,
|
|
||||||
mysql_mutex_t *lock, double time)
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct timespec abstime;
|
struct timespec timeout;
|
||||||
ulonglong slice, timeout= (ulonglong) (time * 1000000000.0);
|
|
||||||
|
|
||||||
do
|
while (1)
|
||||||
{
|
{
|
||||||
/* Wait for a fixed interval. */
|
/* Wait for a fixed interval. */
|
||||||
if (timeout > INTERRUPT_INTERVAL)
|
set_timespec_nsec(timeout, m_interrupt_interval);
|
||||||
slice= INTERRUPT_INTERVAL;
|
|
||||||
else
|
|
||||||
slice= timeout;
|
|
||||||
|
|
||||||
timeout-= slice;
|
/* But only if not past the absolute timeout. */
|
||||||
set_timespec_nsec(abstime, slice);
|
if (cmp_timespec(timeout, m_abs_timeout) > 0)
|
||||||
error= mysql_cond_timedwait(cond, lock, &abstime);
|
timeout= m_abs_timeout;
|
||||||
|
|
||||||
|
error= mysql_cond_timedwait(cond, mutex, &timeout);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
{
|
{
|
||||||
/* Return error if timed out or connection is broken. */
|
/* Return error if timed out or connection is broken. */
|
||||||
if (!timeout || !thd->is_connected())
|
if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (error && timeout);
|
/* Otherwise, propagate status to the caller. */
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a user level lock. If the thread has an old lock this is first released.
|
Get a user level lock. If the thread has an old lock this is first released.
|
||||||
|
|
||||||
@ -3748,10 +3792,11 @@ longlong Item_func_get_lock::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
String *res=args[0]->val_str(&value);
|
String *res=args[0]->val_str(&value);
|
||||||
double timeout= args[1]->val_real();
|
ulonglong timeout= args[1]->val_int();
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
User_level_lock *ull;
|
User_level_lock *ull;
|
||||||
int error;
|
int error;
|
||||||
|
Interruptible_wait timed_cond(thd);
|
||||||
DBUG_ENTER("Item_func_get_lock::val_int");
|
DBUG_ENTER("Item_func_get_lock::val_int");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3812,11 +3857,13 @@ longlong Item_func_get_lock::val_int()
|
|||||||
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
||||||
thd->mysys_var->current_cond= &ull->cond;
|
thd->mysys_var->current_cond= &ull->cond;
|
||||||
|
|
||||||
|
timed_cond.set_timeout(timeout * ULL(1000000000));
|
||||||
|
|
||||||
error= 0;
|
error= 0;
|
||||||
while (ull->locked && !thd->killed)
|
while (ull->locked && !thd->killed)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("waiting on lock"));
|
DBUG_PRINT("info", ("waiting on lock"));
|
||||||
error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout);
|
error= timed_cond.wait(&ull->cond, &LOCK_user_locks);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("lock wait timeout"));
|
DBUG_PRINT("info", ("lock wait timeout"));
|
||||||
@ -4011,6 +4058,7 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type)
|
|||||||
longlong Item_func_sleep::val_int()
|
longlong Item_func_sleep::val_int()
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
|
Interruptible_wait timed_cond(thd);
|
||||||
mysql_cond_t cond;
|
mysql_cond_t cond;
|
||||||
double timeout;
|
double timeout;
|
||||||
int error;
|
int error;
|
||||||
@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int()
|
|||||||
if (timeout < 0.00001)
|
if (timeout < 0.00001)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0));
|
||||||
|
|
||||||
mysql_cond_init(key_item_func_sleep_cond, &cond, NULL);
|
mysql_cond_init(key_item_func_sleep_cond, &cond, NULL);
|
||||||
mysql_mutex_lock(&LOCK_user_locks);
|
mysql_mutex_lock(&LOCK_user_locks);
|
||||||
|
|
||||||
@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int()
|
|||||||
error= 0;
|
error= 0;
|
||||||
while (!thd->killed)
|
while (!thd->killed)
|
||||||
{
|
{
|
||||||
error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout);
|
error= timed_cond.wait(&cond, &LOCK_user_locks);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
break;
|
break;
|
||||||
error= 0;
|
error= 0;
|
||||||
|
18
sql/log.cc
18
sql/log.cc
@ -2849,7 +2849,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
|||||||
sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
|
sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE(););
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
write_error= 0;
|
write_error= 0;
|
||||||
@ -2946,7 +2946,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
|||||||
if (write_file_name_to_index_file)
|
if (write_file_name_to_index_file)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE(););
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBUG_ASSERT(my_b_inited(&index_file) != 0);
|
DBUG_ASSERT(my_b_inited(&index_file) != 0);
|
||||||
@ -2965,7 +2965,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE(););
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3428,7 +3428,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
|
|||||||
/* Store where we are in the new file for the execution thread */
|
/* Store where we are in the new file for the execution thread */
|
||||||
flush_relay_log_info(rli);
|
flush_relay_log_info(rli);
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
|
||||||
|
|
||||||
mysql_mutex_lock(&rli->log_space_lock);
|
mysql_mutex_lock(&rli->log_space_lock);
|
||||||
rli->relay_log.purge_logs(to_purge_if_included, included,
|
rli->relay_log.purge_logs(to_purge_if_included, included,
|
||||||
@ -3556,7 +3556,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE(););
|
||||||
|
|
||||||
if ((error= sync_purge_index_file()))
|
if ((error= sync_purge_index_file()))
|
||||||
{
|
{
|
||||||
@ -3571,7 +3571,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE(););
|
||||||
|
|
||||||
err:
|
err:
|
||||||
/* Read each entry from purge_index_file and delete the file. */
|
/* Read each entry from purge_index_file and delete the file. */
|
||||||
@ -3581,7 +3581,7 @@ err:
|
|||||||
" that would be purged.");
|
" that would be purged.");
|
||||||
close_purge_index_file();
|
close_purge_index_file();
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE(););
|
||||||
|
|
||||||
if (need_mutex)
|
if (need_mutex)
|
||||||
mysql_mutex_unlock(&LOCK_index);
|
mysql_mutex_unlock(&LOCK_index);
|
||||||
@ -5177,7 +5177,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
|
|||||||
DBUG_PRINT("info", ("error writing binlog cache: %d",
|
DBUG_PRINT("info", ("error writing binlog cache: %d",
|
||||||
write_error));
|
write_error));
|
||||||
DBUG_PRINT("info", ("crashing before writing xid"));
|
DBUG_PRINT("info", ("crashing before writing xid"));
|
||||||
DBUG_ABORT();
|
DBUG_SUICIDE();
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((write_error= write_cache(cache, false, false)))
|
if ((write_error= write_cache(cache, false, false)))
|
||||||
@ -5192,7 +5192,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
|
|||||||
bool synced= 0;
|
bool synced= 0;
|
||||||
if (flush_and_sync(&synced))
|
if (flush_and_sync(&synced))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_ABORT(););
|
DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
|
||||||
if (cache->error) // Error on read
|
if (cache->error) // Error on read
|
||||||
{
|
{
|
||||||
sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
|
sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
|
||||||
|
@ -1244,7 +1244,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||||||
break;
|
break;
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
case SLAVE_EVENT: /* can never happen (unused event) */
|
case SLAVE_EVENT: /* can never happen (unused event) */
|
||||||
ev = new Slave_log_event(buf, event_len);
|
ev = new Slave_log_event(buf, event_len, description_event);
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
case CREATE_FILE_EVENT:
|
case CREATE_FILE_EVENT:
|
||||||
@ -1332,8 +1332,10 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||||||
(because constructor is "void") ; so instead we leave the pointer we
|
(because constructor is "void") ; so instead we leave the pointer we
|
||||||
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
|
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
|
||||||
Same for Format_description_log_event, member 'post_header_len'.
|
Same for Format_description_log_event, member 'post_header_len'.
|
||||||
|
|
||||||
|
SLAVE_EVENT is never used, so it should not be read ever.
|
||||||
*/
|
*/
|
||||||
if (!ev || !ev->is_valid())
|
if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Found invalid event in binary log"));
|
DBUG_PRINT("error",("Found invalid event in binary log"));
|
||||||
|
|
||||||
@ -6117,8 +6119,12 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
|||||||
|
|
||||||
|
|
||||||
/** This code is not used, so has not been updated to be format-tolerant. */
|
/** This code is not used, so has not been updated to be format-tolerant. */
|
||||||
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
/* We are using description_event so that slave does not crash on Log_event
|
||||||
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
constructor */
|
||||||
|
Slave_log_event::Slave_log_event(const char* buf,
|
||||||
|
uint event_len,
|
||||||
|
const Format_description_log_event* description_event)
|
||||||
|
:Log_event(buf,description_event),mem_pool(0),master_host(0)
|
||||||
{
|
{
|
||||||
if (event_len < LOG_EVENT_HEADER_LEN)
|
if (event_len < LOG_EVENT_HEADER_LEN)
|
||||||
return;
|
return;
|
||||||
|
@ -1846,7 +1846,9 @@ public:
|
|||||||
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
|
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Slave_log_event(const char* buf, uint event_len);
|
Slave_log_event(const char* buf,
|
||||||
|
uint event_len,
|
||||||
|
const Format_description_log_event *description_event);
|
||||||
~Slave_log_event();
|
~Slave_log_event();
|
||||||
int get_data_size();
|
int get_data_size();
|
||||||
bool is_valid() const { return master_host != 0; }
|
bool is_valid() const { return master_host != 0; }
|
||||||
|
@ -97,6 +97,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
MYSQL_BIN_LOG relay_log;
|
MYSQL_BIN_LOG relay_log;
|
||||||
LOG_INFO linfo;
|
LOG_INFO linfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
cur_log
|
||||||
|
Pointer that either points at relay_log.get_log_file() or
|
||||||
|
&rli->cache_buf, depending on whether the log is hot or there was
|
||||||
|
the need to open a cold relay_log.
|
||||||
|
|
||||||
|
cache_buf
|
||||||
|
IO_CACHE used when opening cold relay logs.
|
||||||
|
*/
|
||||||
IO_CACHE cache_buf,*cur_log;
|
IO_CACHE cache_buf,*cur_log;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
76
sql/slave.cc
76
sql/slave.cc
@ -881,7 +881,17 @@ static bool sql_slave_killed(THD* thd, Relay_log_info* rli)
|
|||||||
DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
|
DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
|
||||||
if (abort_loop || thd->killed || rli->abort_slave)
|
if (abort_loop || thd->killed || rli->abort_slave)
|
||||||
{
|
{
|
||||||
if (thd->transaction.all.modified_non_trans_table && rli->is_in_group())
|
/*
|
||||||
|
The transaction should always be binlogged if OPTION_KEEP_LOG is set
|
||||||
|
(it implies that something can not be rolled back). And such case
|
||||||
|
should be regarded similarly as modifing a non-transactional table
|
||||||
|
because retrying of the transaction will lead to an error or inconsistency
|
||||||
|
as well.
|
||||||
|
Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped.
|
||||||
|
*/
|
||||||
|
if ((thd->transaction.all.modified_non_trans_table ||
|
||||||
|
(thd->variables.option_bits & OPTION_KEEP_LOG))
|
||||||
|
&& rli->is_in_group())
|
||||||
{
|
{
|
||||||
char msg_stopped[]=
|
char msg_stopped[]=
|
||||||
"... The slave SQL is stopped, leaving the current group "
|
"... The slave SQL is stopped, leaving the current group "
|
||||||
@ -4726,12 +4736,66 @@ static Log_event* next_event(Relay_log_info* rli)
|
|||||||
DBUG_ASSERT(rli->cur_log_fd == -1);
|
DBUG_ASSERT(rli->cur_log_fd == -1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read pointer has to be at the start since we are the only
|
When the SQL thread is [stopped and] (re)started the
|
||||||
reader.
|
following may happen:
|
||||||
We must keep the LOCK_log to read the 4 first bytes, as this is a hot
|
|
||||||
log (same as when we call read_log_event() above: for a hot log we
|
1. Log was hot at stop time and remains hot at restart
|
||||||
take the mutex).
|
|
||||||
|
SQL thread reads again from hot_log (SQL thread was
|
||||||
|
reading from the active log when it was stopped and the
|
||||||
|
very same log is still active on SQL thread restart).
|
||||||
|
|
||||||
|
In this case, my_b_seek is performed on cur_log, while
|
||||||
|
cur_log points to relay_log.get_log_file();
|
||||||
|
|
||||||
|
2. Log was hot at stop time but got cold before restart
|
||||||
|
|
||||||
|
The log was hot when SQL thread stopped, but it is not
|
||||||
|
anymore when the SQL thread restarts.
|
||||||
|
|
||||||
|
In this case, the SQL thread reopens the log, using
|
||||||
|
cache_buf, ie, cur_log points to &cache_buf, and thence
|
||||||
|
its coordinates are reset.
|
||||||
|
|
||||||
|
3. Log was already cold at stop time
|
||||||
|
|
||||||
|
The log was not hot when the SQL thread stopped, and, of
|
||||||
|
course, it will not be hot when it restarts.
|
||||||
|
|
||||||
|
In this case, the SQL thread opens the cold log again,
|
||||||
|
using cache_buf, ie, cur_log points to &cache_buf, and
|
||||||
|
thence its coordinates are reset.
|
||||||
|
|
||||||
|
4. Log was hot at stop time, DBA changes to previous cold
|
||||||
|
log and restarts SQL thread
|
||||||
|
|
||||||
|
The log was hot when the SQL thread was stopped, but the
|
||||||
|
user changed the coordinates of the SQL thread to
|
||||||
|
restart from a previous cold log.
|
||||||
|
|
||||||
|
In this case, at start time, cur_log points to a cold
|
||||||
|
log, opened using &cache_buf as cache, and coordinates
|
||||||
|
are reset. However, as it moves on to the next logs, it
|
||||||
|
will eventually reach the hot log. If the hot log is the
|
||||||
|
same at the time the SQL thread was stopped, then
|
||||||
|
coordinates were not reset - the cur_log will point to
|
||||||
|
relay_log.get_log_file(), and not a freshly opened
|
||||||
|
IO_CACHE through cache_buf. For this reason we need to
|
||||||
|
deploy a my_b_seek before calling check_binlog_magic at
|
||||||
|
this point of the code (see: BUG#55263 for more
|
||||||
|
details).
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
- We must keep the LOCK_log to read the 4 first bytes, as
|
||||||
|
this is a hot log (same as when we call read_log_event()
|
||||||
|
above: for a hot log we take the mutex).
|
||||||
|
|
||||||
|
- Because of scenario #4 above, we need to have a
|
||||||
|
my_b_seek here. Otherwise, we might hit the assertion
|
||||||
|
inside check_binlog_magic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
my_b_seek(cur_log, (my_off_t) 0);
|
||||||
if (check_binlog_magic(cur_log,&errmsg))
|
if (check_binlog_magic(cur_log,&errmsg))
|
||||||
{
|
{
|
||||||
if (!hot_log)
|
if (!hot_log)
|
||||||
|
@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd)
|
|||||||
The same with db_load_routine() required circa 7k bytes and
|
The same with db_load_routine() required circa 7k bytes and
|
||||||
14k bytes accordingly. Hence, here we book the stack with some
|
14k bytes accordingly. Hence, here we book the stack with some
|
||||||
reasonable margin.
|
reasonable margin.
|
||||||
|
|
||||||
|
Reverting back to 8 * STACK_MIN_SIZE until further fix.
|
||||||
|
8 * STACK_MIN_SIZE is required on some exotic platforms.
|
||||||
*/
|
*/
|
||||||
if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet))
|
if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* init per-instruction memroot */
|
/* init per-instruction memroot */
|
||||||
|
@ -2832,6 +2832,15 @@ end_with_restore_list:
|
|||||||
thd->first_successful_insert_id_in_cur_stmt=
|
thd->first_successful_insert_id_in_cur_stmt=
|
||||||
thd->first_successful_insert_id_in_prev_stmt;
|
thd->first_successful_insert_id_in_prev_stmt;
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("after_mysql_insert",
|
||||||
|
{
|
||||||
|
const char act[]=
|
||||||
|
"now "
|
||||||
|
"wait_for signal.continue";
|
||||||
|
DBUG_ASSERT(opt_debug_sync_timeout > 0);
|
||||||
|
DBUG_ASSERT(!debug_sync_set_action(current_thd,
|
||||||
|
STRING_WITH_LEN(act)));
|
||||||
|
};);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_REPLACE_SELECT:
|
case SQLCOM_REPLACE_SELECT:
|
||||||
|
@ -12334,6 +12334,12 @@ user:
|
|||||||
system_charset_info, 0) ||
|
system_charset_info, 0) ||
|
||||||
check_host_name(&$$->host))
|
check_host_name(&$$->host))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
/*
|
||||||
|
Convert hostname part of username to lowercase.
|
||||||
|
It's OK to use in-place lowercase as long as
|
||||||
|
the character set is utf8.
|
||||||
|
*/
|
||||||
|
my_casedn_str(system_charset_info, $$->host.str);
|
||||||
}
|
}
|
||||||
| CURRENT_USER optional_braces
|
| CURRENT_USER optional_braces
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user