#At file:///export/home/x/mysql-5.5-runtime-test/ based on revid:kostja@stripped
3167 Jon Olav Hauglid 2010-10-19 [merge]
Merge from mysql-5.5-bugteam to mysql-5.5-runtime
No conflicts
added:
mysql-test/extra/rpl_tests/rpl_stop_slave.test
mysql-test/suite/rpl/r/rpl_stop_slave.result
mysql-test/suite/rpl/t/rpl_stop_slave.test
modified:
CMakeLists.txt
Makefile.am
cmake/abi_check.cmake
config/ac-macros/maintainer.m4
configure.in
dbug/dbug.c
include/my_dbug.h
include/mysql/client_plugin.h
include/mysql/client_plugin.h.pp
mysql-test/extra/rpl_tests/rpl_start_stop_slave.test
mysql-test/include/mtr_warnings.sql
mysql-test/r/grant.result
mysql-test/r/grant3.result
mysql-test/r/ipv4_as_ipv6.result
mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result
mysql-test/t/grant.test
mysql-test/t/grant3.test
sql/handler.cc
sql/item_func.cc
sql/log.cc
sql/log_event.cc
sql/log_event.h
sql/rpl_rli.h
sql/slave.cc
sql/sp_head.cc
sql/sql_parse.cc
sql/sql_yacc.yy
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-09-24 13:03:17 +0000
+++ b/CMakeLists.txt 2010-10-18 17:38:32 +0000
@@ -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)
=== modified file 'Makefile.am'
--- a/Makefile.am 2010-10-04 12:42:16 +0000
+++ b/Makefile.am 2010-10-13 15:11:29 +0000
@@ -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 \
=== modified file 'cmake/abi_check.cmake'
--- a/cmake/abi_check.cmake 2010-08-27 06:45:35 +0000
+++ b/cmake/abi_check.cmake 2010-10-13 15:11:29 +0000
@@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYS
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
=== modified file 'config/ac-macros/maintainer.m4'
--- a/config/ac-macros/maintainer.m4 2010-09-24 12:36:31 +0000
+++ b/config/ac-macros/maintainer.m4 2010-10-18 16:27:10 +0000
@@ -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])
])
=== modified file 'configure.in'
--- a/configure.in 2010-10-07 14:34:42 +0000
+++ b/configure.in 2010-10-18 17:38:32 +0000
@@ -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])
=== modified file 'dbug/dbug.c'
--- a/dbug/dbug.c 2010-10-01 20:12:27 +0000
+++ b/dbug/dbug.c 2010-10-19 08:30:26 +0000
@@ -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);
}
=== modified file 'include/my_dbug.h'
--- a/include/my_dbug.h 2010-07-15 11:16:06 +0000
+++ b/include/my_dbug.h 2010-10-18 11:27:52 +0000
@@ -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_n
#ifdef __cplusplus
}
#endif
-#endif
+
+#endif /* MY_DBUG_INCLUDED */
=== modified file 'include/mysql/client_plugin.h'
--- a/include/mysql/client_plugin.h 2010-10-04 12:54:41 +0000
+++ b/include/mysql/client_plugin.h 2010-10-13 15:11:29 +0000
@@ -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
=== modified file 'include/mysql/client_plugin.h.pp'
--- a/include/mysql/client_plugin.h.pp 2010-10-05 12:26:49 +0000
+++ b/include/mysql/client_plugin.h.pp 2010-10-13 15:11:29 +0000
@@ -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 *);
=== modified file 'mysql-test/extra/rpl_tests/rpl_start_stop_slave.test'
--- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test 2010-04-28 12:47:49 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test 2010-10-14 01:54:07 +0000
@@ -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
=== added file 'mysql-test/extra/rpl_tests/rpl_stop_slave.test'
--- a/mysql-test/extra/rpl_tests/rpl_stop_slave.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test 2010-10-16 12:03:44 +0000
@@ -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;
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql 2010-06-02 16:08:06 +0000
+++ b/mysql-test/include/mtr_warnings.sql 2010-10-14 10:05:59 +0000
@@ -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||
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2010-10-07 16:01:17 +0000
+++ b/mysql-test/r/grant.result 2010-10-19 09:26:45 +0000
@@ -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.
=== modified file 'mysql-test/r/grant3.result'
--- a/mysql-test/r/grant3.result 2009-10-20 06:17:57 +0000
+++ b/mysql-test/r/grant3.result 2010-10-18 14:03:53 +0000
@@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOS
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'@'%';
=== modified file 'mysql-test/r/ipv4_as_ipv6.result'
--- a/mysql-test/r/ipv4_as_ipv6.result 2009-11-26 08:03:04 +0000
+++ b/mysql-test/r/ipv4_as_ipv6.result 2010-10-18 16:20:26 +0000
@@ -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
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result 2010-04-28 12:47:49 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result 2010-10-14 01:54:07 +0000
@@ -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;
=== added file 'mysql-test/suite/rpl/r/rpl_stop_slave.result'
--- a/mysql-test/suite/rpl/r/rpl_stop_slave.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result 2010-10-16 14:20:35 +0000
@@ -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;
=== added file 'mysql-test/suite/rpl/t/rpl_stop_slave.test'
--- a/mysql-test/suite/rpl/t/rpl_stop_slave.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test 2010-10-16 14:20:35 +0000
@@ -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;
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2010-10-07 16:01:17 +0000
+++ b/mysql-test/t/grant.test 2010-10-19 09:26:45 +0000
@@ -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
=== modified file 'mysql-test/t/grant3.test'
--- a/mysql-test/t/grant3.test 2009-10-20 06:17:57 +0000
+++ b/mysql-test/t/grant3.test 2010-10-18 14:03:53 +0000
@@ -64,6 +64,7 @@ SELECT user, host FROM mysql.user where
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
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
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
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;
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-10-06 14:34:28 +0000
+++ b/sql/handler.cc 2010-10-18 11:27:52 +0000
@@ -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)
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2010-10-05 11:33:54 +0000
+++ b/sql/item_func.cc 2010-10-14 01:54:07 +0000
@@ -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 mutex The associated mutex.
- @param cond the condition variable to wait on
- @param lock 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
*/
-#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);
+
+ /* But only if not past the absolute timeout. */
+ if (cmp_timespec(timeout, m_abs_timeout) > 0)
+ timeout= m_abs_timeout;
- timeout-= slice;
- set_timespec_nsec(abstime, slice);
- error= mysql_cond_timedwait(cond, lock, &abstime);
+ 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 *
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;
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-09-29 14:26:32 +0000
+++ b/sql/log.cc 2010-10-18 11:27:52 +0000
@@ -2849,7 +2849,7 @@ bool MYSQL_BIN_LOG::open(const char *log
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
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
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
/* 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
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
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_C
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_C
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);
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-10-09 10:18:16 +0000
+++ b/sql/log_event.cc 2010-10-13 10:08:39 +0000
@@ -1244,7 +1244,7 @@ Log_event* Log_event::read_log_event(con
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(con
(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
/** 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;
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2010-07-15 13:47:50 +0000
+++ b/sql/log_event.h 2010-10-13 10:08:39 +0000
@@ -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; }
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2010-03-31 14:05:33 +0000
+++ b/sql/rpl_rli.h 2010-10-13 10:08:39 +0000
@@ -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;
/*
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2010-10-09 10:18:16 +0000
+++ b/sql/slave.cc 2010-10-16 14:20:35 +0000
@@ -881,7 +881,17 @@ static bool sql_slave_killed(THD* thd, R
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_i
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)
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-10-12 12:19:33 +0000
+++ b/sql/sp_head.cc 2010-10-13 09:34:02 +0000
@@ -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 */
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-10-07 16:01:17 +0000
+++ b/sql/sql_parse.cc 2010-10-19 09:26:45 +0000
@@ -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:
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-10-07 23:34:59 +0000
+++ b/sql/sql_yacc.yy 2010-10-13 06:27:03 +0000
@@ -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
{
No bundle (reason: revision is a merge).
| Thread |
|---|
| • bzr commit into mysql-5.5-runtime branch (jon.hauglid:3167) | Jon Olav Hauglid | 19 Oct |