Commit 8f73bddc authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Merge from mysql-5.5-bugteam to mysql-5.5-runtime

No conflicts
parents 248625d9 87b91752
......@@ -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])
])
......
......@@ -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);
}
......
/* 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
......
#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
#
# 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;
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;
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;
......
......@@ -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;
/*
......
......@@ -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
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment