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)
|
||||
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)
|
||||
ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG)
|
||||
IF(CUSTOM_C_FLAGS)
|
||||
|
@ -263,6 +263,8 @@ test-full-qa:
|
||||
#
|
||||
# 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 \
|
||||
$(top_srcdir)/include/mysql/plugin_ftparser.h \
|
||||
|
@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
ELSE()
|
||||
SET(COMPILER ${CMAKE_C_COMPILER})
|
||||
ENDIF()
|
||||
SET(API_PREPROCESSOR_HEADER
|
||||
SET(API_PREPROCESSOR_HEADER
|
||||
${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h
|
||||
${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.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/client_plugin.h
|
||||
${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(abi_check ALL
|
||||
|
@ -8,7 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [
|
||||
[AS_HELP_STRING([--enable-mysql-maintainer-mode],
|
||||
[Enable a MySQL maintainer-specific development environment])],
|
||||
[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])
|
||||
])
|
||||
|
||||
|
13
configure.in
13
configure.in
@ -27,7 +27,7 @@ dnl
|
||||
dnl When changing the major version number please also check the switch
|
||||
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
||||
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_CANONICAL_SYSTEM
|
||||
@ -118,6 +118,13 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION)
|
||||
AC_SUBST(SHARED_LIB_VERSION)
|
||||
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.
|
||||
MY_MAINTAINER_MODE
|
||||
|
||||
@ -1689,10 +1696,6 @@ then
|
||||
DEBUG_OPTIMIZE_CXX=""
|
||||
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"
|
||||
then
|
||||
AC_DEFINE([DBUG_ON], [1], [Use libdbug])
|
||||
|
@ -905,6 +905,7 @@ void _db_set_init_(const char *control)
|
||||
CODE_STATE tmp_cs;
|
||||
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
|
||||
tmp_cs.stack= &init_settings;
|
||||
tmp_cs.process= db_process ? db_process : "dbug";
|
||||
DbugParse(&tmp_cs, control);
|
||||
}
|
||||
|
||||
@ -2370,7 +2371,7 @@ static void DbugFlush(CODE_STATE *cs)
|
||||
|
||||
void _db_flush_()
|
||||
{
|
||||
CODE_STATE *cs;
|
||||
CODE_STATE *cs= NULL;
|
||||
get_code_state_or_return;
|
||||
(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
|
||||
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
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef _dbug_h
|
||||
#define _dbug_h
|
||||
#ifndef MY_DBUG_INCLUDED
|
||||
#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
|
||||
extern "C" {
|
||||
@ -111,6 +121,20 @@ extern const char* _db_get_func_(void);
|
||||
#define DBUG_CRASH_VOID_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 */
|
||||
|
||||
#define DBUG_ENTER(a1)
|
||||
@ -139,10 +163,11 @@ extern const char* _db_get_func_(void);
|
||||
#define DBUG_EXPLAIN_INITIAL(buf,len)
|
||||
#define DEBUGGER_OFF 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_RETURN(val) do { return(val); } while(0)
|
||||
#define DBUG_CRASH_VOID_RETURN do { return; } while(0)
|
||||
#define DBUG_SUICIDE() do { } while(0)
|
||||
|
||||
#endif
|
||||
|
||||
@ -164,4 +189,5 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* MY_DBUG_INCLUDED */
|
||||
|
@ -23,8 +23,10 @@
|
||||
*/
|
||||
#define MYSQL_CLIENT_PLUGIN_INCLUDED
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* known plugin types */
|
||||
#define MYSQL_CLIENT_reserved1 0
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
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 *);
|
||||
|
@ -122,4 +122,60 @@ drop table t1i, t2m;
|
||||
|
||||
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
|
||||
|
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
|
||||
-- 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
|
||||
CREATE DEFINER=root@localhost TRIGGER ts_insert
|
||||
BEFORE INSERT ON test_suppressions
|
||||
@ -24,6 +30,9 @@ FOR EACH ROW BEGIN
|
||||
SELECT "" REGEXP NEW.pattern INTO dummy;
|
||||
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
|
||||
-- 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
|
||||
CREATE DEFINER=root@localhost TRIGGER gs_insert
|
||||
BEFORE INSERT ON global_suppressions
|
||||
@ -46,6 +61,9 @@ FOR EACH ROW BEGIN
|
||||
SELECT "" REGEXP NEW.pattern INTO dummy;
|
||||
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 DATABASE db1;
|
||||
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.
|
||||
|
@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOST;
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
CUser LOCALHOST
|
||||
CUser localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||
user host db select_priv
|
||||
CUser LOCALHOST test Y
|
||||
CUser localhost test Y
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
CUser LOCALHOST
|
||||
CUser localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||
user host db select_priv
|
||||
CUser localhost test Y
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
CUser LOCALHOST
|
||||
CUser localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
|
||||
user host db select_priv
|
||||
DROP USER CUser@localhost;
|
||||
DROP USER CUser@LOCALHOST;
|
||||
ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
|
||||
create table t1 (a int);
|
||||
grant select on test.t1 to CUser@localhost;
|
||||
grant select on test.t1 to CUser@LOCALHOST;
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
CUser LOCALHOST test t1 Select
|
||||
CUser localhost test t1 Select
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
CUser localhost test t1 Select
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
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;
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
CUser LOCALHOST test t1 Select
|
||||
CUser localhost test t1 Select
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
CUser localhost test t1 Select
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
|
||||
user host
|
||||
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;
|
||||
user host db Table_name Table_priv Column_priv
|
||||
DROP USER CUser@localhost;
|
||||
DROP USER CUser@LOCALHOST;
|
||||
ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
|
||||
drop table t1;
|
||||
grant select on test.* to CUser2@localhost;
|
||||
grant select on test.* to CUser2@LOCALHOST;
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||
user host
|
||||
CUser2 LOCALHOST
|
||||
CUser2 localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||
user host db select_priv
|
||||
CUser2 LOCALHOST test Y
|
||||
CUser2 localhost test Y
|
||||
REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||
user host
|
||||
CUser2 LOCALHOST
|
||||
CUser2 localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||
user host db select_priv
|
||||
CUser2 localhost test Y
|
||||
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
||||
ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost'
|
||||
flush privileges;
|
||||
SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
|
||||
user host
|
||||
CUser2 LOCALHOST
|
||||
CUser2 localhost
|
||||
SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||
user host db select_priv
|
||||
DROP USER CUser2@localhost;
|
||||
DROP USER CUser2@LOCALHOST;
|
||||
ERROR HY000: Operation DROP USER failed for 'CUser2'@'localhost'
|
||||
CREATE DATABASE mysqltest_1;
|
||||
CREATE TABLE mysqltest_1.t1 (a INT);
|
||||
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';
|
||||
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';
|
||||
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 ALL PRIVILEGES ON `test`.* TO '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 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');
|
||||
SELECT @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';
|
||||
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';
|
||||
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 ALL PRIVILEGES ON `test`.* TO '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 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');
|
||||
SELECT @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';
|
||||
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';
|
||||
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 ALL PRIVILEGES ON `test`.* TO '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 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');
|
||||
SELECT @nip;
|
||||
@nip
|
||||
@ -119,9 +119,9 @@ mysqld is alive
|
||||
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';
|
||||
SHOW 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 ALL PRIVILEGES ON `test`.* TO '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 ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:ffff:127.0.0.1'
|
||||
SET @nip= inet_aton('0::0000:FFFF:127.0.0.1');
|
||||
SELECT @nip;
|
||||
@nip
|
||||
@ -149,9 +149,9 @@ mysqld is alive
|
||||
CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234';
|
||||
GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1';
|
||||
SHOW 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 ALL PRIVILEGES ON `test`.* TO '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 ALL PRIVILEGES ON `test`.* TO 'testuser'@'::ffff:127.0.0.1'
|
||||
SET @nip= inet_aton('::FFFF:127.0.0.1');
|
||||
SELECT @nip;
|
||||
@nip
|
||||
|
@ -43,3 +43,25 @@ one
|
||||
1
|
||||
include/start_slave.inc
|
||||
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 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
|
||||
--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;
|
||||
|
||||
DROP USER CUser@localhost;
|
||||
--error ER_CANNOT_USER
|
||||
DROP USER CUser@LOCALHOST;
|
||||
|
||||
#### 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;
|
||||
|
||||
DROP USER CUser@localhost;
|
||||
--error ER_CANNOT_USER
|
||||
DROP USER CUser@LOCALHOST;
|
||||
|
||||
### 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;
|
||||
|
||||
DROP USER CUser@localhost;
|
||||
--error ER_CANNOT_USER
|
||||
DROP USER CUser@LOCALHOST;
|
||||
|
||||
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, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
|
||||
|
||||
--error ER_NONEXISTING_GRANT
|
||||
REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
|
||||
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;
|
||||
|
||||
DROP USER CUser2@localhost;
|
||||
--error ER_CANNOT_USER
|
||||
DROP USER CUser2@LOCALHOST;
|
||||
|
||||
|
||||
|
@ -1156,7 +1156,7 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
uint rw_ha_count;
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT(););
|
||||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
|
||||
if (error || (is_real_trans && xid &&
|
||||
(error= !(cookie= tc_log->log_xid(thd, xid)))))
|
||||
{
|
||||
@ -1216,13 +1216,13 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
error= 1;
|
||||
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;
|
||||
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_ABORT(););
|
||||
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
|
||||
if (cookie)
|
||||
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));
|
||||
end:
|
||||
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 lock the associated mutex
|
||||
@param abstime the amount of time in seconds to wait
|
||||
@param cond The condition variable to wait on.
|
||||
@param mutex The associated mutex.
|
||||
|
||||
@remark The absolute timeout is preserved across calls.
|
||||
|
||||
@retval return value from mysql_cond_timedwait
|
||||
*/
|
||||
|
||||
#define INTERRUPT_INTERVAL (5 * ULL(1000000000))
|
||||
|
||||
static int interruptible_wait(THD *thd, mysql_cond_t *cond,
|
||||
mysql_mutex_t *lock, double time)
|
||||
int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
|
||||
{
|
||||
int error;
|
||||
struct timespec abstime;
|
||||
ulonglong slice, timeout= (ulonglong) (time * 1000000000.0);
|
||||
struct timespec timeout;
|
||||
|
||||
do
|
||||
while (1)
|
||||
{
|
||||
/* Wait for a fixed interval. */
|
||||
if (timeout > INTERRUPT_INTERVAL)
|
||||
slice= INTERRUPT_INTERVAL;
|
||||
else
|
||||
slice= timeout;
|
||||
set_timespec_nsec(timeout, m_interrupt_interval);
|
||||
|
||||
timeout-= slice;
|
||||
set_timespec_nsec(abstime, slice);
|
||||
error= mysql_cond_timedwait(cond, lock, &abstime);
|
||||
/* But only if not past the absolute timeout. */
|
||||
if (cmp_timespec(timeout, m_abs_timeout) > 0)
|
||||
timeout= m_abs_timeout;
|
||||
|
||||
error= mysql_cond_timedwait(cond, mutex, &timeout);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
} while (error && timeout);
|
||||
/* Otherwise, propagate status to the caller. */
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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);
|
||||
String *res=args[0]->val_str(&value);
|
||||
double timeout= args[1]->val_real();
|
||||
ulonglong timeout= args[1]->val_int();
|
||||
THD *thd=current_thd;
|
||||
User_level_lock *ull;
|
||||
int error;
|
||||
Interruptible_wait timed_cond(thd);
|
||||
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_cond= &ull->cond;
|
||||
|
||||
timed_cond.set_timeout(timeout * ULL(1000000000));
|
||||
|
||||
error= 0;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
Interruptible_wait timed_cond(thd);
|
||||
mysql_cond_t cond;
|
||||
double timeout;
|
||||
int error;
|
||||
@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int()
|
||||
if (timeout < 0.00001)
|
||||
return 0;
|
||||
|
||||
timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0));
|
||||
|
||||
mysql_cond_init(key_item_func_sleep_cond, &cond, NULL);
|
||||
mysql_mutex_lock(&LOCK_user_locks);
|
||||
|
||||
@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int()
|
||||
error= 0;
|
||||
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)
|
||||
break;
|
||||
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.");
|
||||
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
|
||||
|
||||
write_error= 0;
|
||||
@ -2946,7 +2946,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
||||
if (write_file_name_to_index_file)
|
||||
{
|
||||
#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
|
||||
|
||||
DBUG_ASSERT(my_b_inited(&index_file) != 0);
|
||||
@ -2965,7 +2965,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
||||
goto err;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_ABORT(););
|
||||
DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE(););
|
||||
#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 */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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()))
|
||||
{
|
||||
@ -3571,7 +3571,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
|
||||
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:
|
||||
/* Read each entry from purge_index_file and delete the file. */
|
||||
@ -3581,7 +3581,7 @@ err:
|
||||
" that would be purged.");
|
||||
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)
|
||||
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",
|
||||
write_error));
|
||||
DBUG_PRINT("info", ("crashing before writing xid"));
|
||||
DBUG_ABORT();
|
||||
DBUG_SUICIDE();
|
||||
});
|
||||
|
||||
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;
|
||||
if (flush_and_sync(&synced))
|
||||
goto err;
|
||||
DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_ABORT(););
|
||||
DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
|
||||
if (cache->error) // Error on read
|
||||
{
|
||||
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;
|
||||
#ifdef HAVE_REPLICATION
|
||||
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;
|
||||
#endif /* HAVE_REPLICATION */
|
||||
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
|
||||
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'.
|
||||
|
||||
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"));
|
||||
|
||||
@ -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. */
|
||||
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
||||
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
||||
/* We are using description_event so that slave does not crash on Log_event
|
||||
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)
|
||||
return;
|
||||
|
@ -1846,7 +1846,9 @@ public:
|
||||
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
|
||||
#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();
|
||||
int get_data_size();
|
||||
bool is_valid() const { return master_host != 0; }
|
||||
|
@ -97,6 +97,16 @@ public:
|
||||
*/
|
||||
MYSQL_BIN_LOG relay_log;
|
||||
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;
|
||||
|
||||
/*
|
||||
|
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
|
||||
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[]=
|
||||
"... 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);
|
||||
|
||||
/*
|
||||
Read pointer has to be at the start since we are the only
|
||||
reader.
|
||||
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).
|
||||
When the SQL thread is [stopped and] (re)started the
|
||||
following may happen:
|
||||
|
||||
1. Log was hot at stop time and remains hot at restart
|
||||
|
||||
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 (!hot_log)
|
||||
|
@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd)
|
||||
The same with db_load_routine() required circa 7k bytes and
|
||||
14k bytes accordingly. Hence, here we book the stack with some
|
||||
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);
|
||||
|
||||
/* 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_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;
|
||||
}
|
||||
case SQLCOM_REPLACE_SELECT:
|
||||
|
@ -12334,6 +12334,12 @@ user:
|
||||
system_charset_info, 0) ||
|
||||
check_host_name(&$$->host))
|
||||
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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user