mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Additional merge to lp:maria/10.0
This commit is contained in:
@@ -153,6 +153,7 @@ INCLUDE(readline)
|
|||||||
INCLUDE(libutils)
|
INCLUDE(libutils)
|
||||||
INCLUDE(dtrace)
|
INCLUDE(dtrace)
|
||||||
INCLUDE(jemalloc)
|
INCLUDE(jemalloc)
|
||||||
|
INCLUDE(pcre)
|
||||||
INCLUDE(ctest)
|
INCLUDE(ctest)
|
||||||
INCLUDE(plugin)
|
INCLUDE(plugin)
|
||||||
INCLUDE(install_macros)
|
INCLUDE(install_macros)
|
||||||
@@ -362,6 +363,8 @@ MYSQL_CHECK_READLINE()
|
|||||||
SET(MALLOC_LIBRARY "system")
|
SET(MALLOC_LIBRARY "system")
|
||||||
CHECK_JEMALLOC()
|
CHECK_JEMALLOC()
|
||||||
|
|
||||||
|
CHECK_PCRE()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Setup maintainer mode options. Platform checks are
|
# Setup maintainer mode options. Platform checks are
|
||||||
# not run with the warning options as to not perturb fragile checks
|
# not run with the warning options as to not perturb fragile checks
|
||||||
@@ -397,7 +400,6 @@ ADD_SUBDIRECTORY(include)
|
|||||||
ADD_SUBDIRECTORY(dbug)
|
ADD_SUBDIRECTORY(dbug)
|
||||||
ADD_SUBDIRECTORY(strings)
|
ADD_SUBDIRECTORY(strings)
|
||||||
ADD_SUBDIRECTORY(vio)
|
ADD_SUBDIRECTORY(vio)
|
||||||
ADD_SUBDIRECTORY(pcre)
|
|
||||||
ADD_SUBDIRECTORY(mysys)
|
ADD_SUBDIRECTORY(mysys)
|
||||||
ADD_SUBDIRECTORY(mysys_ssl)
|
ADD_SUBDIRECTORY(mysys_ssl)
|
||||||
ADD_SUBDIRECTORY(libmysql)
|
ADD_SUBDIRECTORY(libmysql)
|
||||||
|
@@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/mysys_ssl
|
${CMAKE_SOURCE_DIR}/mysys_ssl
|
||||||
${ZLIB_INCLUDE_DIR}
|
${ZLIB_INCLUDE_DIR}
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
|
@@ -46,7 +46,7 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(WITH_JEMALLOC ${WITH_JEMALLOC_DEFAULT} CACHE STRING
|
SET(WITH_JEMALLOC ${WITH_JEMALLOC_DEFAULT} CACHE STRING
|
||||||
"Which jemalloc to use (possible values are 'no', 'bundled', 'system', 'yes' (system if possible, otherwise bundled)")
|
"Which jemalloc to use. Possible values are 'no', 'bundled', 'system', 'yes' (system if possible, otherwise bundled)")
|
||||||
|
|
||||||
MACRO (CHECK_JEMALLOC)
|
MACRO (CHECK_JEMALLOC)
|
||||||
IF(WITH_JEMALLOC STREQUAL "system" OR WITH_JEMALLOC STREQUAL "yes")
|
IF(WITH_JEMALLOC STREQUAL "system" OR WITH_JEMALLOC STREQUAL "yes")
|
||||||
|
16
cmake/pcre.cmake
Normal file
16
cmake/pcre.cmake
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
SET(WITH_PCRE "auto" CACHE STRING
|
||||||
|
"Which pcre to use (possible values are 'bundled', 'system', or 'auto')")
|
||||||
|
|
||||||
|
MACRO (CHECK_PCRE)
|
||||||
|
IF(WITH_PCRE STREQUAL "system" OR WITH_PCRE STREQUAL "auto")
|
||||||
|
CHECK_LIBRARY_EXISTS(pcre pcre_stack_guard "" HAVE_PCRE)
|
||||||
|
ENDIF()
|
||||||
|
IF(NOT HAVE_PCRE)
|
||||||
|
IF (WITH_PCRE STREQUAL "system")
|
||||||
|
MESSAGE(FATAL_ERROR "system pcre is not found or unusable")
|
||||||
|
ENDIF()
|
||||||
|
SET(PCRE_INCLUDES ${CMAKE_BINARY_DIR}/pcre ${CMAKE_SOURCE_DIR}/pcre)
|
||||||
|
ADD_SUBDIRECTORY(pcre)
|
||||||
|
ENDIF()
|
||||||
|
ENDMACRO()
|
||||||
|
|
@@ -37,8 +37,7 @@ MACRO(MYSQL_ADD_PLUGIN)
|
|||||||
# Add common include directories
|
# Add common include directories
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
${ZLIB_INCLUDE_DIR})
|
${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
|
@@ -17,8 +17,7 @@
|
|||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/libmysql
|
${CMAKE_SOURCE_DIR}/libmysql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/strings
|
${CMAKE_SOURCE_DIR}/strings
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
${SSL_INTERNAL_INCLUDE_DIRS}
|
${SSL_INTERNAL_INCLUDE_DIRS}
|
||||||
|
@@ -22,8 +22,7 @@ ${CMAKE_SOURCE_DIR}/libmysql
|
|||||||
${CMAKE_SOURCE_DIR}/libmysqld
|
${CMAKE_SOURCE_DIR}/libmysqld
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/sql
|
${CMAKE_BINARY_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${ZLIB_INCLUDE_DIR}
|
${ZLIB_INCLUDE_DIR}
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
${SSL_INTERNAL_INCLUDE_DIRS}
|
${SSL_INTERNAL_INCLUDE_DIRS}
|
||||||
|
@@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/libmysqld/include
|
${CMAKE_SOURCE_DIR}/libmysqld/include
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${MY_READLINE_INCLUDE_DIR}
|
${MY_READLINE_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
@@ -127,7 +127,7 @@ drop table t1;
|
|||||||
SET @OLD_SQL_MODE=@@SQL_MODE;
|
SET @OLD_SQL_MODE=@@SQL_MODE;
|
||||||
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
|
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
|
||||||
#illegal value fixed
|
#illegal value fixed
|
||||||
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
|
CREATE TABLE t1 (a int, b int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1912 Incorrect value '10000000000000000000' for option 'ULL'
|
Warning 1912 Incorrect value '10000000000000000000' for option 'ULL'
|
||||||
Warning 1912 Incorrect value 'ttt' for option 'one_or_two'
|
Warning 1912 Incorrect value 'ttt' for option 'one_or_two'
|
||||||
@@ -135,7 +135,8 @@ Warning 1912 Incorrect value 'SSS' for option 'YESNO'
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5'
|
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5'
|
||||||
#alter table
|
#alter table
|
||||||
alter table t1 ULL=10000000;
|
alter table t1 ULL=10000000;
|
||||||
@@ -144,7 +145,8 @@ Note 1105 EXAMPLE DEBUG: ULL 4294967290 -> 10000000
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000
|
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000
|
||||||
alter table t1 change a a int complex='c,c,c';
|
alter table t1 change a a int complex='c,c,c';
|
||||||
Warnings:
|
Warnings:
|
||||||
@@ -152,15 +154,15 @@ Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> 'c,c,c'
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL `complex`='c,c,c'
|
`a` int(11) DEFAULT NULL `complex`='c,c,c',
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000
|
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000
|
||||||
alter table t1 one_or_two=two;
|
alter table t1 one_or_two=two;
|
||||||
Warnings:
|
|
||||||
Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX 'c,c,c' -> 'c,c,c'
|
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL `complex`='c,c,c'
|
`a` int(11) DEFAULT NULL `complex`='c,c,c',
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 `one_or_two`=two
|
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 `one_or_two`=two
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#illegal value error
|
#illegal value error
|
||||||
@@ -204,8 +206,6 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL
|
||||||
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15
|
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15
|
||||||
alter table t1 varopt=default;
|
alter table t1 varopt=default;
|
||||||
Warnings:
|
|
||||||
Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> '(null)'
|
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
|
BIN
mysql-test/std_data/mariadb-5.5-binlog.000001
Normal file
BIN
mysql-test/std_data/mariadb-5.5-binlog.000001
Normal file
Binary file not shown.
@@ -1,3 +1,5 @@
|
|||||||
|
grant '' to foo@localhost;
|
||||||
|
ERROR OP000: Invalid role specification ``.
|
||||||
create user ''@localhost;
|
create user ''@localhost;
|
||||||
create role r1;
|
create role r1;
|
||||||
grant r1 to ''@localhost;
|
grant r1 to ''@localhost;
|
@@ -1,3 +1,9 @@
|
|||||||
|
#
|
||||||
|
# MDEV-5668 Assertion `granted_role->is_role()' fails on granting role with empty name
|
||||||
|
#
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
grant '' to foo@localhost;
|
||||||
|
|
||||||
#
|
#
|
||||||
# MDEV-5238 Server crashes in find_role_grant_pair on SHOW GRANTS for an anonymous user
|
# MDEV-5238 Server crashes in find_role_grant_pair on SHOW GRANTS for an anonymous user
|
||||||
#
|
#
|
@@ -62,6 +62,32 @@ slave-relay-bin.000007 # Query # # # Dummy ev
|
|||||||
slave-relay-bin.000007 # Table_map # # table_id: # (test.t1)
|
slave-relay-bin.000007 # Table_map # # table_id: # (test.t1)
|
||||||
slave-relay-bin.000007 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
slave-relay-bin.000007 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
slave-relay-bin.000007 # Query # # COMMIT
|
slave-relay-bin.000007 # Query # # COMMIT
|
||||||
|
*** MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 ***
|
||||||
|
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
SET debug_sync='now WAIT_FOR master_queued1';
|
||||||
|
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
|
||||||
|
INSERT INTO t2 VALUES (2);
|
||||||
|
SET debug_sync='now WAIT_FOR master_queued2';
|
||||||
|
SET debug_sync='now SIGNAL master_cont1';
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=#
|
||||||
|
master-bin.000003 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000003 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000003 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=#
|
||||||
|
master-bin.000003 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000003 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000003 # Xid # # COMMIT /* XID */
|
||||||
|
SELECT * FROM t2 ORDER BY a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
# Test that slave which cannot tolerate holes in binlog stream but
|
# Test that slave which cannot tolerate holes in binlog stream but
|
||||||
# knows the event does not get dummy event
|
# knows the event does not get dummy event
|
||||||
include/stop_slave.inc
|
include/stop_slave.inc
|
||||||
@@ -95,5 +121,5 @@ select @@global.replicate_annotate_row_events;
|
|||||||
set @@global.debug_dbug= @old_slave_dbug;
|
set @@global.debug_dbug= @old_slave_dbug;
|
||||||
Clean up.
|
Clean up.
|
||||||
set @@global.binlog_checksum = @old_master_binlog_checksum;
|
set @@global.binlog_checksum = @old_master_binlog_checksum;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1, t2;
|
||||||
include/rpl_end.inc
|
include/rpl_end.inc
|
||||||
|
27
mysql-test/suite/rpl/r/rpl_old_master.result
Normal file
27
mysql-test/suite/rpl/r/rpl_old_master.result
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
include/stop_slave.inc
|
||||||
|
include/rpl_stop_server.inc [server_number=1]
|
||||||
|
include/rpl_start_server.inc [server_number=1]
|
||||||
|
SET @old_parallel= @@GLOBAL.slave_parallel_threads;
|
||||||
|
SET GLOBAL slave_parallel_threads=10;
|
||||||
|
CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4;
|
||||||
|
include/start_slave.inc
|
||||||
|
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 4
|
||||||
|
4 8
|
||||||
|
5 16
|
||||||
|
SELECT * FROM t2;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
include/stop_slave.inc
|
||||||
|
SET GLOBAL slave_parallel_threads=@old_parallel;
|
||||||
|
DROP TABLE t1;
|
||||||
|
include/start_slave.inc
|
||||||
|
DROP TABLE t2;
|
||||||
|
include/rpl_end.inc
|
@@ -1,6 +1,8 @@
|
|||||||
--source include/master-slave.inc
|
--source include/master-slave.inc
|
||||||
--source include/have_debug.inc
|
--source include/have_debug.inc
|
||||||
|
--source include/have_debug_sync.inc
|
||||||
--source include/have_binlog_format_row.inc
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
|
|
||||||
@@ -71,6 +73,52 @@ let $binlog_start= 0;
|
|||||||
let $binlog_limit=7,5;
|
let $binlog_limit=7,5;
|
||||||
--source include/show_relaylog_events.inc
|
--source include/show_relaylog_events.inc
|
||||||
|
|
||||||
|
|
||||||
|
--echo *** MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 ***
|
||||||
|
|
||||||
|
# The problem was that for a group commit, we get commit id into the
|
||||||
|
# GTID event, and there was a bug in the code that replaces GTID with
|
||||||
|
# dummy that failed when commit id was present.
|
||||||
|
#
|
||||||
|
# So setup a group commit in InnoDB.
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
||||||
|
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||||
|
|
||||||
|
--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,)
|
||||||
|
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
|
||||||
|
send INSERT INTO t2 VALUES (1);
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
SET debug_sync='now WAIT_FOR master_queued1';
|
||||||
|
|
||||||
|
--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,)
|
||||||
|
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
|
||||||
|
send INSERT INTO t2 VALUES (2);
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
SET debug_sync='now WAIT_FOR master_queued2';
|
||||||
|
SET debug_sync='now SIGNAL master_cont1';
|
||||||
|
|
||||||
|
--connection con1
|
||||||
|
REAP;
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
--connection con2
|
||||||
|
REAP;
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
--connection master
|
||||||
|
SET debug_sync='RESET';
|
||||||
|
let $binlog_limit= 0, 8;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--sync_with_master
|
||||||
|
SELECT * FROM t2 ORDER BY a;
|
||||||
|
|
||||||
|
|
||||||
--echo # Test that slave which cannot tolerate holes in binlog stream but
|
--echo # Test that slave which cannot tolerate holes in binlog stream but
|
||||||
--echo # knows the event does not get dummy event
|
--echo # knows the event does not get dummy event
|
||||||
|
|
||||||
@@ -106,6 +154,6 @@ set @@global.debug_dbug= @old_slave_dbug;
|
|||||||
--echo Clean up.
|
--echo Clean up.
|
||||||
connection master;
|
connection master;
|
||||||
set @@global.binlog_checksum = @old_master_binlog_checksum;
|
set @@global.binlog_checksum = @old_master_binlog_checksum;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1, t2;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
--source include/rpl_end.inc
|
--source include/rpl_end.inc
|
||||||
|
49
mysql-test/suite/rpl/t/rpl_old_master.test
Normal file
49
mysql-test/suite/rpl/t/rpl_old_master.test
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Test replicating off old master.
|
||||||
|
# We simulate old master by copying in pre-generated binlog files from earlier
|
||||||
|
# server versions.
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--source include/stop_slave.inc
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
--let $datadir= `SELECT @@datadir`
|
||||||
|
|
||||||
|
--let $rpl_server_number= 1
|
||||||
|
--source include/rpl_stop_server.inc
|
||||||
|
|
||||||
|
--remove_file $datadir/master-bin.000001
|
||||||
|
--copy_file $MYSQL_TEST_DIR/std_data/mariadb-5.5-binlog.000001 $datadir/master-bin.000001
|
||||||
|
|
||||||
|
--let $rpl_server_number= 1
|
||||||
|
--source include/rpl_start_server.inc
|
||||||
|
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
SET @old_parallel= @@GLOBAL.slave_parallel_threads;
|
||||||
|
SET GLOBAL slave_parallel_threads=10;
|
||||||
|
--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
|
||||||
|
eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4;
|
||||||
|
--source include/start_slave.inc
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--sync_with_master
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
--source include/stop_slave.inc
|
||||||
|
SET GLOBAL slave_parallel_threads=@old_parallel;
|
||||||
|
DROP TABLE t1;
|
||||||
|
--source include/start_slave.inc
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
DROP TABLE t2;
|
||||||
|
--source include/rpl_end.inc
|
@@ -121,7 +121,7 @@ SET @OLD_SQL_MODE=@@SQL_MODE;
|
|||||||
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
|
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
|
||||||
|
|
||||||
--echo #illegal value fixed
|
--echo #illegal value fixed
|
||||||
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
|
CREATE TABLE t1 (a int, b int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
|
|
||||||
--echo #alter table
|
--echo #alter table
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${SSL_INCLUDE_DIRS})
|
${SSL_INCLUDE_DIRS})
|
||||||
|
|
||||||
SET(FEEDBACK_SOURCES feedback.cc sender_thread.cc
|
SET(FEEDBACK_SOURCES feedback.cc sender_thread.cc
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
||||||
|
|
||||||
MYSQL_ADD_PLUGIN(QUERY_CACHE_INFO qc_info.cc)
|
MYSQL_ADD_PLUGIN(QUERY_CACHE_INFO qc_info.cc)
|
||||||
|
@@ -16,8 +16,7 @@
|
|||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${ZLIB_INCLUDE_DIR}
|
${ZLIB_INCLUDE_DIR}
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
${CMAKE_BINARY_DIR}/sql
|
${CMAKE_BINARY_DIR}/sql
|
||||||
|
@@ -188,6 +188,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
|||||||
my_b_clear(&buffpek_pointers);
|
my_b_clear(&buffpek_pointers);
|
||||||
buffpek=0;
|
buffpek=0;
|
||||||
error= 1;
|
error= 1;
|
||||||
|
*found_rows= HA_POS_ERROR;
|
||||||
|
|
||||||
param.init_for_filesort(sortlength(thd, sortorder, s_length,
|
param.init_for_filesort(sortlength(thd, sortorder, s_length,
|
||||||
&multi_byte_charset),
|
&multi_byte_charset),
|
||||||
|
@@ -4123,6 +4123,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table,
|
|||||||
Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH |
|
Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH |
|
||||||
Alter_inplace_info::ALTER_COLUMN_NAME |
|
Alter_inplace_info::ALTER_COLUMN_NAME |
|
||||||
Alter_inplace_info::ALTER_COLUMN_DEFAULT |
|
Alter_inplace_info::ALTER_COLUMN_DEFAULT |
|
||||||
|
Alter_inplace_info::ALTER_COLUMN_OPTION |
|
||||||
Alter_inplace_info::CHANGE_CREATE_OPTION |
|
Alter_inplace_info::CHANGE_CREATE_OPTION |
|
||||||
Alter_inplace_info::ALTER_RENAME;
|
Alter_inplace_info::ALTER_RENAME;
|
||||||
|
|
||||||
|
@@ -1740,8 +1740,11 @@ public:
|
|||||||
// Table is renamed
|
// Table is renamed
|
||||||
static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18;
|
static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18;
|
||||||
|
|
||||||
// Change the storage type of column
|
// column's engine options changed, something in field->option_struct
|
||||||
static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19;
|
static const HA_ALTER_FLAGS ALTER_COLUMN_OPTION = 1L << 19;
|
||||||
|
|
||||||
|
// MySQL alias for the same thing:
|
||||||
|
static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19;
|
||||||
|
|
||||||
// Change the column format of column
|
// Change the column format of column
|
||||||
static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1L << 20;
|
static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1L << 20;
|
||||||
@@ -1770,7 +1773,7 @@ public:
|
|||||||
// Partition operation with ALL keyword
|
// Partition operation with ALL keyword
|
||||||
static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28;
|
static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28;
|
||||||
|
|
||||||
// Partition operation with ALL keyword
|
// Virtual columns changed
|
||||||
static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1L << 29;
|
static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1L << 29;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -3736,9 +3736,14 @@ Query_log_event::begin_event(String *packet, ulong ev_offset,
|
|||||||
DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
|
DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
|
||||||
checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
|
checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
|
||||||
|
|
||||||
/* Currently we only need to replace GTID event. */
|
/*
|
||||||
DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN);
|
Currently we only need to replace GTID event.
|
||||||
if (data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
|
The length of GTID differs depending on whether it contains commit id.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN ||
|
||||||
|
data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
|
||||||
|
if (data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN &&
|
||||||
|
data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
flags= uint2korr(p + FLAGS_OFFSET);
|
flags= uint2korr(p + FLAGS_OFFSET);
|
||||||
@@ -3751,9 +3756,22 @@ Query_log_event::begin_event(String *packet, ulong ev_offset,
|
|||||||
int4store(q + Q_EXEC_TIME_OFFSET, 0);
|
int4store(q + Q_EXEC_TIME_OFFSET, 0);
|
||||||
q[Q_DB_LEN_OFFSET]= 0;
|
q[Q_DB_LEN_OFFSET]= 0;
|
||||||
int2store(q + Q_ERR_CODE_OFFSET, 0);
|
int2store(q + Q_ERR_CODE_OFFSET, 0);
|
||||||
int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
|
if (data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
|
||||||
q[Q_DATA_OFFSET]= 0; /* Zero terminator for empty db */
|
{
|
||||||
q+= Q_DATA_OFFSET + 1;
|
int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
|
||||||
|
q[Q_DATA_OFFSET]= 0; /* Zero terminator for empty db */
|
||||||
|
q+= Q_DATA_OFFSET + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
|
||||||
|
/* Put in an empty time_zone_str to take up the extra 2 bytes. */
|
||||||
|
int2store(q + Q_STATUS_VARS_LEN_OFFSET, 2);
|
||||||
|
q[Q_DATA_OFFSET]= Q_TIME_ZONE_CODE;
|
||||||
|
q[Q_DATA_OFFSET+1]= 0; /* Zero length for empty time_zone_str */
|
||||||
|
q[Q_DATA_OFFSET+2]= 0; /* Zero terminator for empty db */
|
||||||
|
q+= Q_DATA_OFFSET + 3;
|
||||||
|
}
|
||||||
memcpy(q, "BEGIN", 5);
|
memcpy(q, "BEGIN", 5);
|
||||||
|
|
||||||
if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
|
if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
|
||||||
@@ -6779,7 +6797,7 @@ Gtid_list_log_event::write(IO_CACHE *file)
|
|||||||
int
|
int
|
||||||
Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
|
Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
|
||||||
{
|
{
|
||||||
Relay_log_info const *rli= rgi->rli;
|
Relay_log_info *rli= const_cast<Relay_log_info*>(rgi->rli);
|
||||||
int ret;
|
int ret;
|
||||||
if (gl_flags & FLAG_IGN_GTIDS)
|
if (gl_flags & FLAG_IGN_GTIDS)
|
||||||
{
|
{
|
||||||
@@ -6799,10 +6817,11 @@ Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
|
|||||||
{
|
{
|
||||||
char str_buf[128];
|
char str_buf[128];
|
||||||
String str(str_buf, sizeof(str_buf), system_charset_info);
|
String str(str_buf, sizeof(str_buf), system_charset_info);
|
||||||
const_cast<Relay_log_info*>(rli)->until_gtid_pos.to_string(&str);
|
rli->until_gtid_pos.to_string(&str);
|
||||||
sql_print_information("Slave SQL thread stops because it reached its"
|
sql_print_information("Slave SQL thread stops because it reached its"
|
||||||
" UNTIL master_gtid_pos %s", str.c_ptr_safe());
|
" UNTIL master_gtid_pos %s", str.c_ptr_safe());
|
||||||
const_cast<Relay_log_info*>(rli)->abort_slave= true;
|
rli->abort_slave= true;
|
||||||
|
rli->stop_for_until= true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -3123,12 +3123,15 @@ public:
|
|||||||
<td>flags</td>
|
<td>flags</td>
|
||||||
<td>1 byte bitfield</td>
|
<td>1 byte bitfield</td>
|
||||||
<td>Bit 0 set indicates stand-alone event (no terminating COMMIT)</td>
|
<td>Bit 0 set indicates stand-alone event (no terminating COMMIT)</td>
|
||||||
|
<td>Bit 1 set indicates group commit, and that commit id exists</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Reserved</td>
|
<td>Reserved (no group commit) / commit id (group commit) (see flags bit 1)</td>
|
||||||
<td>6 bytes</td>
|
<td>6 bytes / 8 bytes</td>
|
||||||
<td>Reserved bytes, set to 0. Maybe be used for future expansion.</td>
|
<td>Reserved bytes, set to 0. Maybe be used for future expansion (no
|
||||||
|
group commit). OR commit id, same for all GTIDs in the same group
|
||||||
|
commit (see flags bit 1).</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@@ -173,6 +173,7 @@ signal_error_to_sql_driver_thread(THD *thd, rpl_group_info *rgi)
|
|||||||
rgi->is_error= true;
|
rgi->is_error= true;
|
||||||
rgi->cleanup_context(thd, true);
|
rgi->cleanup_context(thd, true);
|
||||||
rgi->rli->abort_slave= true;
|
rgi->rli->abort_slave= true;
|
||||||
|
rgi->rli->stop_for_until= false;
|
||||||
mysql_mutex_lock(rgi->rli->relay_log.get_log_lock());
|
mysql_mutex_lock(rgi->rli->relay_log.get_log_lock());
|
||||||
mysql_mutex_unlock(rgi->rli->relay_log.get_log_lock());
|
mysql_mutex_unlock(rgi->rli->relay_log.get_log_lock());
|
||||||
rgi->rli->relay_log.signal_update();
|
rgi->rli->relay_log.signal_update();
|
||||||
@@ -1122,7 +1123,7 @@ rpl_parallel::find(uint32 domain_id)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rpl_parallel::wait_for_done(THD *thd)
|
rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
struct rpl_parallel_entry *e;
|
struct rpl_parallel_entry *e;
|
||||||
rpl_parallel_thread *rpt;
|
rpl_parallel_thread *rpt;
|
||||||
@@ -1152,9 +1153,13 @@ rpl_parallel::wait_for_done(THD *thd)
|
|||||||
started executing yet. So we set e->stop_count here and use it to
|
started executing yet. So we set e->stop_count here and use it to
|
||||||
decide in the worker threads whether to continue executing an event
|
decide in the worker threads whether to continue executing an event
|
||||||
group or whether to skip it, when force_abort is set.
|
group or whether to skip it, when force_abort is set.
|
||||||
|
|
||||||
|
If we stop due to reaching the START SLAVE UNTIL condition, then we
|
||||||
|
need to continue executing any queued events up to that point.
|
||||||
*/
|
*/
|
||||||
e->force_abort= true;
|
e->force_abort= true;
|
||||||
e->stop_count= e->count_committing_event_groups;
|
e->stop_count= rli->stop_for_until ?
|
||||||
|
e->count_queued_event_groups : e->count_committing_event_groups;
|
||||||
mysql_mutex_unlock(&e->LOCK_parallel_entry);
|
mysql_mutex_unlock(&e->LOCK_parallel_entry);
|
||||||
for (j= 0; j < e->rpl_thread_max; ++j)
|
for (j= 0; j < e->rpl_thread_max; ++j)
|
||||||
{
|
{
|
||||||
@@ -1190,6 +1195,30 @@ rpl_parallel::wait_for_done(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function handles the case where the SQL driver thread reached the
|
||||||
|
START SLAVE UNTIL position; we stop queueing more events but continue
|
||||||
|
processing remaining, already queued events; then use executes manual
|
||||||
|
STOP SLAVE; then this function signals to worker threads that they
|
||||||
|
should stop the processing of any remaining queued events.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rpl_parallel::stop_during_until()
|
||||||
|
{
|
||||||
|
struct rpl_parallel_entry *e;
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
for (i= 0; i < domain_hash.records; ++i)
|
||||||
|
{
|
||||||
|
e= (struct rpl_parallel_entry *)my_hash_element(&domain_hash, i);
|
||||||
|
mysql_mutex_lock(&e->LOCK_parallel_entry);
|
||||||
|
if (e->force_abort)
|
||||||
|
e->stop_count= e->count_committing_event_groups;
|
||||||
|
mysql_mutex_unlock(&e->LOCK_parallel_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rpl_parallel::workers_idle()
|
rpl_parallel::workers_idle()
|
||||||
{
|
{
|
||||||
@@ -1230,11 +1259,12 @@ abandon_worker_thread(THD *thd, rpl_parallel_thread *cur_thread,
|
|||||||
do_event() is executed by the sql_driver_thd thread.
|
do_event() is executed by the sql_driver_thd thread.
|
||||||
It's main purpose is to find a thread that can execute the query.
|
It's main purpose is to find a thread that can execute the query.
|
||||||
|
|
||||||
@retval false ok, event was accepted
|
@retval 0 ok, event was accepted
|
||||||
@retval true error
|
@retval 1 error
|
||||||
|
@retval -1 event should be executed serially, in the sql driver thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
int
|
||||||
rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
||||||
ulonglong event_size)
|
ulonglong event_size)
|
||||||
{
|
{
|
||||||
@@ -1248,6 +1278,32 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
bool did_enter_cond= false;
|
bool did_enter_cond= false;
|
||||||
PSI_stage_info old_stage;
|
PSI_stage_info old_stage;
|
||||||
|
|
||||||
|
/* Handle master log name change, seen in Rotate_log_event. */
|
||||||
|
typ= ev->get_type_code();
|
||||||
|
if (unlikely(typ == ROTATE_EVENT))
|
||||||
|
{
|
||||||
|
Rotate_log_event *rev= static_cast<Rotate_log_event *>(ev);
|
||||||
|
if ((rev->server_id != global_system_variables.server_id ||
|
||||||
|
rli->replicate_same_server_id) &&
|
||||||
|
!rev->is_relay_log_event() &&
|
||||||
|
!rli->is_in_group())
|
||||||
|
{
|
||||||
|
memcpy(rli->future_event_master_log_name,
|
||||||
|
rev->new_log_ident, rev->ident_len+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Execute queries non-parallel if slave_skip_counter is set, as it's is
|
||||||
|
easier to skip queries in single threaded mode.
|
||||||
|
*/
|
||||||
|
if (rli->slave_skip_counter)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Execute pre-10.0 event, which have no GTID, in single-threaded mode. */
|
||||||
|
if (unlikely(!current) && typ != GTID_EVENT)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* ToDo: what to do with this lock?!? */
|
/* ToDo: what to do with this lock?!? */
|
||||||
mysql_mutex_unlock(&rli->data_lock);
|
mysql_mutex_unlock(&rli->data_lock);
|
||||||
|
|
||||||
@@ -1259,21 +1315,20 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
been partially queued, but after that we will just ignore any further
|
been partially queued, but after that we will just ignore any further
|
||||||
events the SQL driver thread may try to queue, and eventually it will stop.
|
events the SQL driver thread may try to queue, and eventually it will stop.
|
||||||
*/
|
*/
|
||||||
if (((typ= ev->get_type_code()) == GTID_EVENT ||
|
is_group_event= Log_event::is_group_event(typ);
|
||||||
!(is_group_event= Log_event::is_group_event(typ))) &&
|
if ((typ == GTID_EVENT || !is_group_event) && rli->abort_slave)
|
||||||
rli->abort_slave)
|
|
||||||
sql_thread_stopping= true;
|
sql_thread_stopping= true;
|
||||||
if (sql_thread_stopping)
|
if (sql_thread_stopping)
|
||||||
{
|
{
|
||||||
delete ev;
|
delete ev;
|
||||||
/*
|
/*
|
||||||
Return false ("no error"); normal stop is not an error, and otherwise the
|
Return "no error"; normal stop is not an error, and otherwise the error
|
||||||
error has already been recorded.
|
has already been recorded.
|
||||||
*/
|
*/
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typ == GTID_EVENT || unlikely(!current))
|
if (typ == GTID_EVENT)
|
||||||
{
|
{
|
||||||
uint32 domain_id;
|
uint32 domain_id;
|
||||||
if (likely(typ == GTID_EVENT))
|
if (likely(typ == GTID_EVENT))
|
||||||
@@ -1288,7 +1343,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
{
|
{
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(MY_WME));
|
my_error(ER_OUT_OF_RESOURCES, MYF(MY_WME));
|
||||||
delete ev;
|
delete ev;
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
current= e;
|
current= e;
|
||||||
}
|
}
|
||||||
@@ -1307,7 +1362,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
{
|
{
|
||||||
/* This means we were killed. The error is already signalled. */
|
/* This means we were killed. The error is already signalled. */
|
||||||
delete ev;
|
delete ev;
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(qev= cur_thread->get_qev(ev, event_size, rli)))
|
if (!(qev= cur_thread->get_qev(ev, event_size, rli)))
|
||||||
@@ -1315,7 +1370,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
||||||
&did_enter_cond, &old_stage);
|
&did_enter_cond, &old_stage);
|
||||||
delete ev;
|
delete ev;
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typ == GTID_EVENT)
|
if (typ == GTID_EVENT)
|
||||||
@@ -1328,7 +1383,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
||||||
&did_enter_cond, &old_stage);
|
&did_enter_cond, &old_stage);
|
||||||
delete ev;
|
delete ev;
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1366,7 +1421,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
||||||
&did_enter_cond, &old_stage);
|
&did_enter_cond, &old_stage);
|
||||||
delete ev;
|
delete ev;
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
e->current_gco= rgi->gco= gco;
|
e->current_gco= rgi->gco= gco;
|
||||||
}
|
}
|
||||||
@@ -1380,7 +1435,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
e->current_sub_id= rgi->gtid_sub_id;
|
e->current_sub_id= rgi->gtid_sub_id;
|
||||||
++e->count_queued_event_groups;
|
++e->count_queued_event_groups;
|
||||||
}
|
}
|
||||||
else if (!is_group_event || !e)
|
else if (!is_group_event)
|
||||||
{
|
{
|
||||||
my_off_t log_pos;
|
my_off_t log_pos;
|
||||||
int err;
|
int err;
|
||||||
@@ -1389,38 +1444,22 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
Events like ROTATE and FORMAT_DESCRIPTION. Do not run in worker thread.
|
Events like ROTATE and FORMAT_DESCRIPTION. Do not run in worker thread.
|
||||||
Same for events not preceeded by GTID (we should not see those normally,
|
Same for events not preceeded by GTID (we should not see those normally,
|
||||||
but they might be from an old master).
|
but they might be from an old master).
|
||||||
|
|
||||||
The variable `e' is NULL for the case where the master did not
|
|
||||||
have GTID, like a MariaDB 5.5 or MySQL master.
|
|
||||||
*/
|
*/
|
||||||
qev->rgi= serial_rgi;
|
qev->rgi= serial_rgi;
|
||||||
/* Handle master log name change, seen in Rotate_log_event. */
|
|
||||||
if (typ == ROTATE_EVENT)
|
|
||||||
{
|
|
||||||
Rotate_log_event *rev= static_cast<Rotate_log_event *>(qev->ev);
|
|
||||||
if ((rev->server_id != global_system_variables.server_id ||
|
|
||||||
rli->replicate_same_server_id) &&
|
|
||||||
!rev->is_relay_log_event() &&
|
|
||||||
!rli->is_in_group())
|
|
||||||
{
|
|
||||||
memcpy(rli->future_event_master_log_name,
|
|
||||||
rev->new_log_ident, rev->ident_len+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp= serial_rgi->is_parallel_exec;
|
tmp= serial_rgi->is_parallel_exec;
|
||||||
serial_rgi->is_parallel_exec= true;
|
serial_rgi->is_parallel_exec= true;
|
||||||
err= rpt_handle_event(qev, NULL);
|
err= rpt_handle_event(qev, NULL);
|
||||||
serial_rgi->is_parallel_exec= tmp;
|
serial_rgi->is_parallel_exec= tmp;
|
||||||
log_pos= qev->ev->log_pos;
|
log_pos= ev->log_pos;
|
||||||
delete_or_keep_event_post_apply(serial_rgi, typ, qev->ev);
|
delete_or_keep_event_post_apply(serial_rgi, typ, ev);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
cur_thread->free_qev(qev);
|
cur_thread->free_qev(qev);
|
||||||
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
abandon_worker_thread(rli->sql_driver_thd, cur_thread,
|
||||||
&did_enter_cond, &old_stage);
|
&did_enter_cond, &old_stage);
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Queue an empty event, so that the position will be updated in a
|
Queue an empty event, so that the position will be updated in a
|
||||||
@@ -1451,5 +1490,5 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
|||||||
&did_enter_cond, &old_stage);
|
&did_enter_cond, &old_stage);
|
||||||
mysql_cond_signal(&cur_thread->COND_rpl_thread);
|
mysql_cond_signal(&cur_thread->COND_rpl_thread);
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -222,10 +222,10 @@ struct rpl_parallel {
|
|||||||
~rpl_parallel();
|
~rpl_parallel();
|
||||||
void reset();
|
void reset();
|
||||||
rpl_parallel_entry *find(uint32 domain_id);
|
rpl_parallel_entry *find(uint32 domain_id);
|
||||||
void wait_for_done(THD *thd);
|
void wait_for_done(THD *thd, Relay_log_info *rli);
|
||||||
|
void stop_during_until();
|
||||||
bool workers_idle();
|
bool workers_idle();
|
||||||
bool do_event(rpl_group_info *serial_rgi, Log_event *ev,
|
int do_event(rpl_group_info *serial_rgi, Log_event *ev, ulonglong event_size);
|
||||||
ulonglong event_size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -60,7 +60,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
|
|||||||
group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0),
|
group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0),
|
||||||
last_master_timestamp(0), sql_thread_caught_up(true), slave_skip_counter(0),
|
last_master_timestamp(0), sql_thread_caught_up(true), slave_skip_counter(0),
|
||||||
abort_pos_wait(0), slave_run_id(0), sql_driver_thd(),
|
abort_pos_wait(0), slave_run_id(0), sql_driver_thd(),
|
||||||
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
|
inited(0), abort_slave(0), stop_for_until(0),
|
||||||
|
slave_running(0), until_condition(UNTIL_NONE),
|
||||||
until_log_pos(0), retried_trans(0), executed_entries(0),
|
until_log_pos(0), retried_trans(0), executed_entries(0),
|
||||||
m_flags(0)
|
m_flags(0)
|
||||||
{
|
{
|
||||||
|
@@ -262,6 +262,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
volatile bool inited;
|
volatile bool inited;
|
||||||
volatile bool abort_slave;
|
volatile bool abort_slave;
|
||||||
|
volatile bool stop_for_until;
|
||||||
volatile uint slave_running;
|
volatile uint slave_running;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
33
sql/slave.cc
33
sql/slave.cc
@@ -615,7 +615,14 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
|
|||||||
if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
|
if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("Terminating SQL thread"));
|
DBUG_PRINT("info",("Terminating SQL thread"));
|
||||||
mi->rli.abort_slave=1;
|
if (opt_slave_parallel_threads > 0 &&
|
||||||
|
mi->rli.abort_slave && mi->rli.stop_for_until)
|
||||||
|
{
|
||||||
|
mi->rli.stop_for_until= false;
|
||||||
|
mi->rli.parallel.stop_during_until();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mi->rli.abort_slave=1;
|
||||||
if ((error=terminate_slave_thread(mi->rli.sql_driver_thd, sql_lock,
|
if ((error=terminate_slave_thread(mi->rli.sql_driver_thd, sql_lock,
|
||||||
&mi->rli.stop_cond,
|
&mi->rli.stop_cond,
|
||||||
&mi->rli.slave_running,
|
&mi->rli.slave_running,
|
||||||
@@ -3427,6 +3434,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
|
|||||||
message about error in query execution to be printed.
|
message about error in query execution to be printed.
|
||||||
*/
|
*/
|
||||||
rli->abort_slave= 1;
|
rli->abort_slave= 1;
|
||||||
|
rli->stop_for_until= true;
|
||||||
mysql_mutex_unlock(&rli->data_lock);
|
mysql_mutex_unlock(&rli->data_lock);
|
||||||
delete ev;
|
delete ev;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@@ -3454,13 +3462,17 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
|
|||||||
|
|
||||||
update_state_of_relay_log(rli, ev);
|
update_state_of_relay_log(rli, ev);
|
||||||
|
|
||||||
/*
|
if (opt_slave_parallel_threads > 0)
|
||||||
Execute queries in parallel, except if slave_skip_counter is set,
|
{
|
||||||
as it's is easier to skip queries in single threaded mode.
|
int res= rli->parallel.do_event(serial_rgi, ev, event_size);
|
||||||
*/
|
if (res >= 0)
|
||||||
|
DBUG_RETURN(res);
|
||||||
if (opt_slave_parallel_threads > 0 && rli->slave_skip_counter == 0)
|
/*
|
||||||
DBUG_RETURN(rli->parallel.do_event(serial_rgi, ev, event_size));
|
Else we proceed to execute the event non-parallel.
|
||||||
|
This is the case for pre-10.0 events without GTID, and for handling
|
||||||
|
slave_skip_counter.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For GTID, allocate a new sub_id for the given domain_id.
|
For GTID, allocate a new sub_id for the given domain_id.
|
||||||
@@ -4371,6 +4383,7 @@ pthread_handler_t handle_slave_sql(void *arg)
|
|||||||
Seconds_Behind_Master grows. No big deal.
|
Seconds_Behind_Master grows. No big deal.
|
||||||
*/
|
*/
|
||||||
rli->abort_slave = 0;
|
rli->abort_slave = 0;
|
||||||
|
rli->stop_for_until= false;
|
||||||
mysql_mutex_unlock(&rli->run_lock);
|
mysql_mutex_unlock(&rli->run_lock);
|
||||||
mysql_cond_broadcast(&rli->start_cond);
|
mysql_cond_broadcast(&rli->start_cond);
|
||||||
|
|
||||||
@@ -4542,7 +4555,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt_slave_parallel_threads > 0)
|
if (opt_slave_parallel_threads > 0)
|
||||||
rli->parallel.wait_for_done(thd);
|
rli->parallel.wait_for_done(thd, rli);
|
||||||
|
|
||||||
/* Thread stopped. Print the current replication position to the log */
|
/* Thread stopped. Print the current replication position to the log */
|
||||||
{
|
{
|
||||||
@@ -4568,7 +4581,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME,
|
|||||||
get the correct position printed.)
|
get the correct position printed.)
|
||||||
*/
|
*/
|
||||||
if (opt_slave_parallel_threads > 0)
|
if (opt_slave_parallel_threads > 0)
|
||||||
rli->parallel.wait_for_done(thd);
|
rli->parallel.wait_for_done(thd, rli);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some events set some playgrounds, which won't be cleared because thread
|
Some events set some playgrounds, which won't be cleared because thread
|
||||||
|
@@ -5894,9 +5894,6 @@ static bool fill_alter_inplace_info(THD *thd,
|
|||||||
|
|
||||||
if (new_field)
|
if (new_field)
|
||||||
{
|
{
|
||||||
ha_alter_info->create_info->fields_option_struct[f_ptr - table->field]=
|
|
||||||
new_field->option_struct;
|
|
||||||
|
|
||||||
/* Field is not dropped. Evaluate changes bitmap for it. */
|
/* Field is not dropped. Evaluate changes bitmap for it. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6008,6 +6005,15 @@ static bool fill_alter_inplace_info(THD *thd,
|
|||||||
if (new_field->column_format() != field->column_format())
|
if (new_field->column_format() != field->column_format())
|
||||||
ha_alter_info->handler_flags|=
|
ha_alter_info->handler_flags|=
|
||||||
Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT;
|
Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT;
|
||||||
|
|
||||||
|
if (engine_options_differ(field->option_struct, new_field->option_struct,
|
||||||
|
table->file->ht->field_options))
|
||||||
|
{
|
||||||
|
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_OPTION;
|
||||||
|
ha_alter_info->create_info->fields_option_struct[f_ptr - table->field]=
|
||||||
|
new_field->option_struct;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -15192,6 +15192,11 @@ current_role:
|
|||||||
grant_role:
|
grant_role:
|
||||||
ident_or_text
|
ident_or_text
|
||||||
{
|
{
|
||||||
|
if ($1.length == 0)
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_ROLE, MYF(0), "");
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$$->user = $1;
|
$$->user = $1;
|
||||||
|
@@ -906,84 +906,84 @@ int ha_example::create(const char *name, TABLE *table_arg,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
|
check_if_supported_inplace_alter() is used to ask the engine whether
|
||||||
if new and old definition are compatible
|
it can execute this ALTER TABLE statement in place or the server needs to
|
||||||
|
create a new table and copy th data over.
|
||||||
|
|
||||||
@details If there are no other explicit signs like changed number of
|
The engine may answer that the inplace alter is not supported or,
|
||||||
fields this function will be called by compare_tables()
|
if supported, whether the server should protect the table from concurrent
|
||||||
(sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
|
accesses. Return values are
|
||||||
file.
|
|
||||||
|
|
||||||
|
HA_ALTER_INPLACE_NOT_SUPPORTED
|
||||||
|
HA_ALTER_INPLACE_EXCLUSIVE_LOCK
|
||||||
|
HA_ALTER_INPLACE_SHARED_LOCK
|
||||||
|
etc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
|
enum_alter_inplace_result
|
||||||
uint table_changes)
|
ha_example::check_if_supported_inplace_alter(TABLE* altered_table,
|
||||||
|
Alter_inplace_info* ha_alter_info)
|
||||||
{
|
{
|
||||||
ha_table_option_struct *param_old, *param_new;
|
HA_CREATE_INFO *info= ha_alter_info->create_info;
|
||||||
DBUG_ENTER("ha_example::check_if_incompatible_data");
|
DBUG_ENTER("ha_example::check_if_supported_inplace_alter");
|
||||||
/*
|
|
||||||
This example shows how custom engine specific table and field
|
|
||||||
options can be accessed from this function to be compared.
|
|
||||||
*/
|
|
||||||
param_new= info->option_struct;
|
|
||||||
DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u "
|
|
||||||
"boolparam: %u",
|
|
||||||
(param_new->strparam ? param_new->strparam : "<NULL>"),
|
|
||||||
param_new->ullparam, param_new->enumparam,
|
|
||||||
param_new->boolparam));
|
|
||||||
|
|
||||||
param_old= table->s->option_struct;
|
if (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION)
|
||||||
DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u "
|
|
||||||
"boolparam: %u",
|
|
||||||
(param_old->strparam ? param_old->strparam : "<NULL>"),
|
|
||||||
param_old->ullparam, param_old->enumparam,
|
|
||||||
param_old->boolparam));
|
|
||||||
|
|
||||||
/*
|
|
||||||
check important parameters:
|
|
||||||
for this example engine, we'll assume that changing ullparam or
|
|
||||||
boolparam requires a table to be rebuilt, while changing strparam
|
|
||||||
or enumparam - does not.
|
|
||||||
|
|
||||||
For debugging purposes we'll announce this to the user
|
|
||||||
(don't do it in production!)
|
|
||||||
|
|
||||||
*/
|
|
||||||
if (param_new->ullparam != param_old->ullparam)
|
|
||||||
{
|
{
|
||||||
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
/*
|
||||||
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu",
|
This example shows how custom engine specific table and field
|
||||||
param_old->ullparam, param_new->ullparam);
|
options can be accessed from this function to be compared.
|
||||||
DBUG_RETURN(COMPATIBLE_DATA_NO);
|
*/
|
||||||
}
|
ha_table_option_struct *param_new= info->option_struct;
|
||||||
|
ha_table_option_struct *param_old= table->s->option_struct;
|
||||||
|
|
||||||
if (param_new->boolparam != param_old->boolparam)
|
/*
|
||||||
{
|
check important parameters:
|
||||||
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
for this example engine, we'll assume that changing ullparam or
|
||||||
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u",
|
boolparam requires a table to be rebuilt, while changing strparam
|
||||||
param_old->boolparam, param_new->boolparam);
|
or enumparam - does not.
|
||||||
DBUG_RETURN(COMPATIBLE_DATA_NO);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint i= 0; i < table->s->fields; i++)
|
For debugging purposes we'll announce this to the user
|
||||||
{
|
(don't do it in production!)
|
||||||
ha_field_option_struct *f_old, *f_new;
|
|
||||||
f_old= table->s->field[i]->option_struct;
|
*/
|
||||||
DBUG_ASSERT(f_old);
|
if (param_new->ullparam != param_old->ullparam)
|
||||||
if (info->fields_option_struct[i])
|
|
||||||
{
|
{
|
||||||
f_new= info->fields_option_struct[i];
|
|
||||||
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
||||||
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'",
|
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu",
|
||||||
table->s->field[i]->field_name,
|
param_old->ullparam, param_new->ullparam);
|
||||||
f_old->complex_param_to_parse_it_in_engine,
|
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||||
f_new->complex_param_to_parse_it_in_engine);
|
}
|
||||||
|
|
||||||
|
if (param_new->boolparam != param_old->boolparam)
|
||||||
|
{
|
||||||
|
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
||||||
|
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u",
|
||||||
|
param_old->boolparam, param_new->boolparam);
|
||||||
|
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
DBUG_PRINT("info", ("old field %i did not changed", i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(COMPATIBLE_DATA_YES);
|
if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_OPTION)
|
||||||
|
{
|
||||||
|
for (uint i= 0; i < table->s->fields; i++)
|
||||||
|
{
|
||||||
|
ha_field_option_struct *f_old= table->s->field[i]->option_struct;
|
||||||
|
ha_field_option_struct *f_new= info->fields_option_struct[i];
|
||||||
|
DBUG_ASSERT(f_old);
|
||||||
|
if (f_new)
|
||||||
|
{
|
||||||
|
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
|
||||||
|
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'",
|
||||||
|
table->s->field[i]->field_name,
|
||||||
|
f_old->complex_param_to_parse_it_in_engine,
|
||||||
|
f_new->complex_param_to_parse_it_in_engine);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DBUG_PRINT("info", ("old field %i did not changed", i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -247,8 +247,9 @@ public:
|
|||||||
int delete_table(const char *from);
|
int delete_table(const char *from);
|
||||||
int create(const char *name, TABLE *form,
|
int create(const char *name, TABLE *form,
|
||||||
HA_CREATE_INFO *create_info); ///< required
|
HA_CREATE_INFO *create_info); ///< required
|
||||||
bool check_if_incompatible_data(HA_CREATE_INFO *info,
|
enum_alter_inplace_result
|
||||||
uint table_changes);
|
check_if_supported_inplace_alter(TABLE* altered_table,
|
||||||
|
Alter_inplace_info* ha_alter_info);
|
||||||
|
|
||||||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||||
enum thr_lock_type lock_type); ///< required
|
enum thr_lock_type lock_type); ///< required
|
||||||
|
@@ -44,7 +44,7 @@ Created 1/20/1994 Heikki Tuuri
|
|||||||
|
|
||||||
#define INNODB_VERSION_MAJOR 5
|
#define INNODB_VERSION_MAJOR 5
|
||||||
#define INNODB_VERSION_MINOR 6
|
#define INNODB_VERSION_MINOR 6
|
||||||
#define INNODB_VERSION_BUGFIX 14
|
#define INNODB_VERSION_BUGFIX 15
|
||||||
|
|
||||||
/* The following is the InnoDB version as shown in
|
/* The following is the InnoDB version as shown in
|
||||||
SELECT plugin_version FROM information_schema.plugins;
|
SELECT plugin_version FROM information_schema.plugins;
|
||||||
|
@@ -538,7 +538,11 @@ int ha_oqgraph::open(const char *name, int mode, uint test_if_locked)
|
|||||||
|
|
||||||
origid= destid= weight= 0;
|
origid= destid= weight= 0;
|
||||||
|
|
||||||
|
// Here we're abusing init_tmp_table_share() which is normally only works for thread-local shares.
|
||||||
init_tmp_table_share( thd, share, table->s->db.str, table->s->db.length, options->table_name, "");
|
init_tmp_table_share( thd, share, table->s->db.str, table->s->db.length, options->table_name, "");
|
||||||
|
// because of that, we need to reinitialize the memroot (to reset MY_THREAD_SPECIFIC flag)
|
||||||
|
DBUG_ASSERT(share->mem_root.used == NULL); // it's still empty
|
||||||
|
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
|
||||||
|
|
||||||
// What I think this code is doing:
|
// What I think this code is doing:
|
||||||
// * Our OQGRAPH table is `database_blah/name`
|
// * Our OQGRAPH table is `database_blah/name`
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
CREATE TABLE oq_backing (
|
||||||
|
origid INT UNSIGNED NOT NULL,
|
||||||
|
destid INT UNSIGNED NOT NULL,
|
||||||
|
weight DOUBLE NOT NULL,
|
||||||
|
PRIMARY KEY (origid, destid),
|
||||||
|
KEY (destid)
|
||||||
|
);
|
||||||
|
CREATE TABLE oq_table (
|
||||||
|
latch VARCHAR(32) NULL,
|
||||||
|
origid BIGINT UNSIGNED NULL,
|
||||||
|
destid BIGINT UNSIGNED NULL,
|
||||||
|
weight DOUBLE NULL,
|
||||||
|
seq BIGINT UNSIGNED NULL,
|
||||||
|
linkid BIGINT UNSIGNED NULL,
|
||||||
|
KEY (latch, origid, destid) USING HASH,
|
||||||
|
KEY (latch, destid, origid) USING HASH
|
||||||
|
) ENGINE=OQGRAPH
|
||||||
|
data_table='oq_backing' origid='origid' destid='destid' weight='weight';
|
||||||
|
flush tables;
|
||||||
|
show fields in oq_table;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
latch varchar(32) YES MUL NULL
|
||||||
|
origid bigint(20) unsigned YES NULL
|
||||||
|
destid bigint(20) unsigned YES NULL
|
||||||
|
weight double YES NULL
|
||||||
|
seq bigint(20) unsigned YES NULL
|
||||||
|
linkid bigint(20) unsigned YES NULL
|
||||||
|
show tables;
|
||||||
|
Tables_in_test
|
||||||
|
oq_backing
|
||||||
|
oq_table
|
||||||
|
drop table oq_table, oq_backing;
|
37
storage/oqgraph/mysql-test/oqgraph/connections_mdev5748.test
Normal file
37
storage/oqgraph/mysql-test/oqgraph/connections_mdev5748.test
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
# MDEV-5748 Assertion `status_var.memory_used == 0' fails on disconnect after opening an OQGRAPH table
|
||||||
|
#
|
||||||
|
|
||||||
|
# try to open oqgraph table in one connection and use in another:
|
||||||
|
|
||||||
|
--connect (con1,localhost,root,,)
|
||||||
|
|
||||||
|
CREATE TABLE oq_backing (
|
||||||
|
origid INT UNSIGNED NOT NULL,
|
||||||
|
destid INT UNSIGNED NOT NULL,
|
||||||
|
weight DOUBLE NOT NULL,
|
||||||
|
PRIMARY KEY (origid, destid),
|
||||||
|
KEY (destid)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE oq_table (
|
||||||
|
latch VARCHAR(32) NULL,
|
||||||
|
origid BIGINT UNSIGNED NULL,
|
||||||
|
destid BIGINT UNSIGNED NULL,
|
||||||
|
weight DOUBLE NULL,
|
||||||
|
seq BIGINT UNSIGNED NULL,
|
||||||
|
linkid BIGINT UNSIGNED NULL,
|
||||||
|
KEY (latch, origid, destid) USING HASH,
|
||||||
|
KEY (latch, destid, origid) USING HASH
|
||||||
|
) ENGINE=OQGRAPH
|
||||||
|
data_table='oq_backing' origid='origid' destid='destid' weight='weight';
|
||||||
|
|
||||||
|
flush tables;
|
||||||
|
show fields in oq_table;
|
||||||
|
--disconnect con1
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
show tables;
|
||||||
|
|
||||||
|
drop table oq_table, oq_backing;
|
||||||
|
|
@@ -16,8 +16,7 @@
|
|||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DMYSQL_SERVER)
|
ADD_DEFINITIONS(-DMYSQL_SERVER)
|
||||||
|
@@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/include/mysql
|
${CMAKE_SOURCE_DIR}/include/mysql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/sql
|
${CMAKE_SOURCE_DIR}/sql
|
||||||
${SSL_INCLUDE_DIRS}
|
${SSL_INCLUDE_DIRS}
|
||||||
${CMAKE_SOURCE_DIR}/unittest/mytap
|
${CMAKE_SOURCE_DIR}/unittest/mytap
|
||||||
|
@@ -40,6 +40,10 @@ show create table se;
|
|||||||
ERROR 42S02: Table 'test.se' doesn't exist
|
ERROR 42S02: Table 'test.se' doesn't exist
|
||||||
show create table seq_1_to_15_step_0;
|
show create table seq_1_to_15_step_0;
|
||||||
ERROR HY000: Got error 140 "Wrong create options" from storage engine SEQUENCE
|
ERROR HY000: Got error 140 "Wrong create options" from storage engine SEQUENCE
|
||||||
|
show create table `seq_-1_to_15`;
|
||||||
|
ERROR 42S02: Table 'test.seq_-1_to_15' doesn't exist
|
||||||
|
show create table `seq_1_to_+2`;
|
||||||
|
ERROR 42S02: Table 'test.seq_1_to_+2' doesn't exist
|
||||||
select * from seq_1_to_15_step_2;
|
select * from seq_1_to_15_step_2;
|
||||||
seq
|
seq
|
||||||
1
|
1
|
||||||
|
@@ -26,6 +26,14 @@ show create table se;
|
|||||||
--error ER_GET_ERRNO
|
--error ER_GET_ERRNO
|
||||||
show create table seq_1_to_15_step_0;
|
show create table seq_1_to_15_step_0;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-5735 Selecting from SEQUENCE table with negative number hangs server
|
||||||
|
#
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
show create table `seq_-1_to_15`;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
show create table `seq_1_to_+2`;
|
||||||
|
|
||||||
# simple select
|
# simple select
|
||||||
select * from seq_1_to_15_step_2;
|
select * from seq_1_to_15_step_2;
|
||||||
select * from seq_1_to_15;
|
select * from seq_1_to_15;
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
a engine that auto-creates tables with rows filled with sequential values
|
a engine that auto-creates tables with rows filled with sequential values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <mysql_version.h>
|
#include <mysql_version.h>
|
||||||
#include <handler.h>
|
#include <handler.h>
|
||||||
#include <table.h>
|
#include <table.h>
|
||||||
@@ -265,14 +266,19 @@ static handler *create_handler(handlerton *hton, TABLE_SHARE *table,
|
|||||||
static bool parse_table_name(const char *name, size_t name_length,
|
static bool parse_table_name(const char *name, size_t name_length,
|
||||||
ulonglong *from, ulonglong *to, ulonglong *step)
|
ulonglong *from, ulonglong *to, ulonglong *step)
|
||||||
{
|
{
|
||||||
uint n1= 0, n2= 0;
|
uint n0=0, n1= 0, n2= 0;
|
||||||
*step= 1;
|
*step= 1;
|
||||||
|
|
||||||
// the table is discovered if its name matches the pattern of seq_1_to_10 or
|
// the table is discovered if its name matches the pattern of seq_1_to_10 or
|
||||||
// seq_1_to_10_step_3
|
// seq_1_to_10_step_3
|
||||||
sscanf(name, "seq_%llu_to_%llu%n_step_%llu%n",
|
sscanf(name, "seq_%llu_to_%n%llu%n_step_%llu%n",
|
||||||
from, to, &n1, step, &n2);
|
from, &n0, to, &n1, step, &n2);
|
||||||
return n1 != name_length && n2 != name_length;
|
// I consider this a bug in sscanf() - when an unsigned number
|
||||||
|
// is requested, -5 should *not* be accepted. But is is :(
|
||||||
|
// hence the additional check below:
|
||||||
|
return
|
||||||
|
n0 == 0 || !isdigit(name[4]) || !isdigit(name[n0]) || // reject negative numbers
|
||||||
|
(n1 != name_length && n2 != name_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -276,18 +276,17 @@ void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
const uchar *key, size_t len,
|
const uchar *key, size_t len,
|
||||||
ulong *nr1, ulong *nr2)
|
ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
const uchar *pos = key;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove trailing spaces. We have to do this to be able to compare
|
Remove trailing spaces. We have to do this to be able to compare
|
||||||
'A ' and 'A' as identical
|
'A ' and 'A' as identical
|
||||||
*/
|
*/
|
||||||
key= skip_trailing_space(key, len);
|
const uchar *end = skip_trailing_space(key, len);
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
for (; key < end ; key++)
|
||||||
{
|
{
|
||||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
((uint)*pos)) + (nr1[0] << 8);
|
((uint)*key)) + (nr1[0] << 8);
|
||||||
nr2[0]+=3;
|
nr2[0]+=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,14 +295,12 @@ void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
|
void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
const uchar *pos = key;
|
const uchar *end = key + len;
|
||||||
|
|
||||||
key+= len;
|
for (; key < end ; key++)
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
|
||||||
{
|
{
|
||||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
((uint)*pos)) + (nr1[0] << 8);
|
((uint)*key)) + (nr1[0] << 8);
|
||||||
nr2[0]+=3;
|
nr2[0]+=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -680,18 +680,16 @@ void
|
|||||||
my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
const uchar *pos = key;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove trailing spaces. We have to do this to be able to compare
|
Remove trailing spaces. We have to do this to be able to compare
|
||||||
'A ' and 'A' as identical
|
'A ' and 'A' as identical
|
||||||
*/
|
*/
|
||||||
key= skip_trailing_space(key, len);
|
const uchar *end = skip_trailing_space(key, len);
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
for (; key < end ; key++)
|
||||||
{
|
{
|
||||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
((uint)*pos)) + (nr1[0] << 8);
|
((uint)*key)) + (nr1[0] << 8);
|
||||||
nr2[0]+=3;
|
nr2[0]+=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3311,17 +3311,15 @@ static
|
|||||||
void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)),
|
void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
const uchar *pos = key;
|
const uchar *end = key + len;
|
||||||
|
|
||||||
key+= len;
|
|
||||||
|
|
||||||
while (key > pos+1 && key[-1] == ' ' && key[-2] == '\0')
|
while (end > key+1 && end[-1] == ' ' && end[-2] == '\0')
|
||||||
key-= 2;
|
end-= 2;
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
for (; key < (uchar*) end ; key++)
|
||||||
{
|
{
|
||||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
((uint)*pos)) + (nr1[0] << 8);
|
((uint)*key)) + (nr1[0] << 8);
|
||||||
nr2[0]+=3;
|
nr2[0]+=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,8 +14,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
|
||||||
${CMAKE_BINARY_DIR}/pcre
|
${PCRE_INCLUDES}
|
||||||
${CMAKE_SOURCE_DIR}/pcre
|
|
||||||
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
||||||
|
|
||||||
MY_ADD_TESTS(bitmap base64 my_vsnprintf my_atomic my_rdtsc lf my_malloc
|
MY_ADD_TESTS(bitmap base64 my_vsnprintf my_atomic my_rdtsc lf my_malloc
|
||||||
|
Reference in New Issue
Block a user