Merge from mysql-trunk-merge.
This commit is contained in:
commit
3fd2f50b6c
@ -221,12 +221,16 @@ ENDIF(WITHOUT_DYNAMIC_PLUGINS)
|
|||||||
FILE(GLOB STORAGE_SUBDIRS storage/*)
|
FILE(GLOB STORAGE_SUBDIRS storage/*)
|
||||||
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
|
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
|
||||||
FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
|
FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
|
||||||
STRING(TOUPPER ${DIRNAME} ENGINE)
|
|
||||||
STRING(TOLOWER ${DIRNAME} ENGINE_LOWER)
|
|
||||||
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
|
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
|
||||||
# Check MYSQL_STORAGE_ENGINE macro is present
|
# Check MYSQL_STORAGE_ENGINE macro is present
|
||||||
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
|
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
|
||||||
IF(HAVE_STORAGE_ENGINE)
|
IF(HAVE_STORAGE_ENGINE)
|
||||||
|
# Extract name of engine from HAVE_STORAGE_ENGINE
|
||||||
|
STRING(REGEX REPLACE ".*MYSQL_STORAGE_ENGINE\\((.*\)\\).*"
|
||||||
|
"\\1" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
|
||||||
|
STRING(TOUPPER ${ENGINE_NAME} ENGINE)
|
||||||
|
STRING(TOLOWER ${ENGINE_NAME} ENGINE_LOWER)
|
||||||
|
|
||||||
SET(ENGINE_BUILD_TYPE "DYNAMIC")
|
SET(ENGINE_BUILD_TYPE "DYNAMIC")
|
||||||
# Read plug.in to find out if a plugin is mandatory and whether it supports
|
# Read plug.in to find out if a plugin is mandatory and whether it supports
|
||||||
# build as shared library (dynamic).
|
# build as shared library (dynamic).
|
||||||
@ -252,6 +256,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
|
|||||||
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${ENGINE_LOWER})
|
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${ENGINE_LOWER})
|
||||||
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
|
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
|
||||||
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
|
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
|
||||||
|
SET (${ENGINE}_DIR ${DIRNAME})
|
||||||
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
|
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
|
||||||
ENDIF(EXISTS ${SUBDIR}/plug.in)
|
ENDIF(EXISTS ${SUBDIR}/plug.in)
|
||||||
|
|
||||||
|
@ -2863,7 +2863,7 @@ com_help(String *buffer __attribute__((unused)),
|
|||||||
"For developer information, including the MySQL Reference Manual, "
|
"For developer information, including the MySQL Reference Manual, "
|
||||||
"visit:\n"
|
"visit:\n"
|
||||||
" http://dev.mysql.com/\n"
|
" http://dev.mysql.com/\n"
|
||||||
"To buy MySQL Network Support, training, or other products, visit:\n"
|
"To buy MySQL Enterprise support, training, or other products, visit:\n"
|
||||||
" https://shop.mysql.com/\n", INFO_INFO);
|
" https://shop.mysql.com/\n", INFO_INFO);
|
||||||
put_info("List of all MySQL commands:", INFO_INFO);
|
put_info("List of all MySQL commands:", INFO_INFO);
|
||||||
if (!named_cmds)
|
if (!named_cmds)
|
||||||
|
@ -6775,8 +6775,10 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
|
|||||||
MYSQL_STMT *stmt;
|
MYSQL_STMT *stmt;
|
||||||
DYNAMIC_STRING ds_prepare_warnings;
|
DYNAMIC_STRING ds_prepare_warnings;
|
||||||
DYNAMIC_STRING ds_execute_warnings;
|
DYNAMIC_STRING ds_execute_warnings;
|
||||||
|
ulonglong affected_rows;
|
||||||
DBUG_ENTER("run_query_stmt");
|
DBUG_ENTER("run_query_stmt");
|
||||||
DBUG_PRINT("query", ("'%-.60s'", query));
|
DBUG_PRINT("query", ("'%-.60s'", query));
|
||||||
|
LINT_INIT(affected_rows);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Init a new stmt if it's not already one created for this connection
|
Init a new stmt if it's not already one created for this connection
|
||||||
@ -6911,9 +6913,6 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
|
|||||||
Need to grab affected rows information before getting
|
Need to grab affected rows information before getting
|
||||||
warnings here
|
warnings here
|
||||||
*/
|
*/
|
||||||
ulonglong affected_rows;
|
|
||||||
LINT_INIT(affected_rows);
|
|
||||||
|
|
||||||
if (!disable_info)
|
if (!disable_info)
|
||||||
affected_rows= mysql_affected_rows(mysql);
|
affected_rows= mysql_affected_rows(mysql);
|
||||||
|
|
||||||
|
@ -2835,7 +2835,7 @@ server_scripts=
|
|||||||
|
|
||||||
dnl This probably should be cleaned up more - for now the threaded
|
dnl This probably should be cleaned up more - for now the threaded
|
||||||
dnl client is just using plain-old libs.
|
dnl client is just using plain-old libs.
|
||||||
sql_client_dirs="strings regex mysys dbug libmysql"
|
sql_client_dirs="strings mysys dbug extra regex libmysql"
|
||||||
|
|
||||||
AM_CONDITIONAL(THREAD_SAFE_CLIENT, test "$THREAD_SAFE_CLIENT" != "no")
|
AM_CONDITIONAL(THREAD_SAFE_CLIENT, test "$THREAD_SAFE_CLIENT" != "no")
|
||||||
|
|
||||||
@ -2901,9 +2901,10 @@ AC_SUBST(mysql_plugin_defs)
|
|||||||
|
|
||||||
|
|
||||||
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
|
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
|
||||||
# Start with the (longer) server list, add each client item not yet present.
|
# We support client-only builds by "--without-server", but not vice versa,
|
||||||
sql_union_dirs=" $sql_server_dirs "
|
# so we start with the client list, then add each server item not yet present.
|
||||||
for DIR in $sql_client_dirs
|
sql_union_dirs=" $sql_client_dirs "
|
||||||
|
for DIR in $sql_server_dirs
|
||||||
do
|
do
|
||||||
if echo " $sql_union_dirs " | grep " $DIR " >/dev/null
|
if echo " $sql_union_dirs " | grep " $DIR " >/dev/null
|
||||||
then
|
then
|
||||||
|
@ -741,7 +741,6 @@ extern int wild_compare(const char *str,const char *wildstr,
|
|||||||
extern WF_PACK *wf_comp(char * str);
|
extern WF_PACK *wf_comp(char * str);
|
||||||
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
|
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
|
||||||
extern void wf_end(struct wild_file_pack *buffer);
|
extern void wf_end(struct wild_file_pack *buffer);
|
||||||
extern size_t strip_sp(char * str);
|
|
||||||
extern my_bool array_append_string_unique(const char *str,
|
extern my_bool array_append_string_unique(const char *str,
|
||||||
const char **array, size_t size);
|
const char **array, size_t size);
|
||||||
extern void get_date(char * to,int timeflag,time_t use_time);
|
extern void get_date(char * to,int timeflag,time_t use_time);
|
||||||
|
@ -81,10 +81,11 @@ ENDFOREACH(rpath)
|
|||||||
|
|
||||||
|
|
||||||
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
|
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
|
||||||
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_LIB}/CMakeLists.txt)
|
|
||||||
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
|
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
|
||||||
|
SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR})
|
||||||
|
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt)
|
||||||
FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
|
FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
|
||||||
SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_LIB}/${rpath})
|
SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath})
|
||||||
ENDFOREACH(rpath)
|
ENDFOREACH(rpath)
|
||||||
ENDFOREACH(ENGINE_LIB)
|
ENDFOREACH(ENGINE_LIB)
|
||||||
|
|
||||||
@ -147,6 +148,14 @@ ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES})
|
|||||||
ADD_DEPENDENCIES(mysqlserver GenServerSource GenError)
|
ADD_DEPENDENCIES(mysqlserver GenServerSource GenError)
|
||||||
TARGET_LINK_LIBRARIES(mysqlserver)
|
TARGET_LINK_LIBRARIES(mysqlserver)
|
||||||
|
|
||||||
|
# Add any additional libraries requested by engine(s)
|
||||||
|
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
|
||||||
|
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
|
||||||
|
IF(${ENGINE_LIB_UPPER}_LIBS)
|
||||||
|
TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS})
|
||||||
|
ENDIF(${ENGINE_LIB_UPPER}_LIBS)
|
||||||
|
ENDFOREACH(ENGINE_LIB)
|
||||||
|
|
||||||
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
|
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
|
||||||
ADD_DEPENDENCIES(libmysqld mysqlserver)
|
ADD_DEPENDENCIES(libmysqld mysqlserver)
|
||||||
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)
|
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# in alphabetical order. This also helps with merge conflict resolution.
|
# in alphabetical order. This also helps with merge conflict resolution.
|
||||||
|
|
||||||
binlog.binlog_tmp_table* # Bug#45578:2009-07-10 alik Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
|
binlog.binlog_tmp_table* # Bug#45578:2009-07-10 alik Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
|
||||||
|
binlog.binlog_multi_engine # joro : NDB tests marked as experimental as agreed with bochklin
|
||||||
|
|
||||||
funcs_1.charset_collation_1 # depends on compile-time decisions
|
funcs_1.charset_collation_1 # depends on compile-time decisions
|
||||||
|
|
||||||
|
@ -270,3 +270,42 @@ INSERT INTO test.t1 VALUES (1), (2);
|
|||||||
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
||||||
USE test;
|
USE test;
|
||||||
DROP TABLES t1, t2;
|
DROP TABLES t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#46640
|
||||||
|
# This test verifies if the server_id stored in the "format
|
||||||
|
# description BINLOG statement" will override the server_id
|
||||||
|
# of the server executing the statements.
|
||||||
|
#
|
||||||
|
|
||||||
|
connect (fresh,localhost,root,,test);
|
||||||
|
connection fresh;
|
||||||
|
|
||||||
|
RESET MASTER;
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||||
|
|
||||||
|
# Format description event, with server_id = 10;
|
||||||
|
BINLOG '
|
||||||
|
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
||||||
|
';
|
||||||
|
|
||||||
|
# What server_id is logged for a statement? Should be our own, not the
|
||||||
|
# one from the format description event.
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
# INSERT INTO t1 VALUES (2), with server_id=20. Check that this is logged
|
||||||
|
# with our own server id, not the 20 from the BINLOG statement.
|
||||||
|
BINLOG '
|
||||||
|
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
|
||||||
|
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
|
||||||
|
';
|
||||||
|
|
||||||
|
# Show binlog events to check that server ids are correct.
|
||||||
|
--replace_column 1 # 2 # 5 #
|
||||||
|
--replace_regex /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
|
||||||
|
SHOW BINLOG EVENTS;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
disconnect fresh;
|
||||||
|
|
||||||
|
300
mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
Normal file
300
mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
################################################################################
|
||||||
|
# Let
|
||||||
|
# - B be begin, C commit and R rollback.
|
||||||
|
# - T a statement that accesses and changes only transactional tables, i.e.
|
||||||
|
# T-tables
|
||||||
|
# - N a statement that accesses and changes only non-transactional tables,
|
||||||
|
# i.e, N-tables.
|
||||||
|
# - M be a mixed statement, i.e. a statement that updates both T- and
|
||||||
|
# N-tables.
|
||||||
|
# - M* be a mixed statement that fails while updating either a T
|
||||||
|
# or N-table.
|
||||||
|
# - N* be a statement that fails while updating a N-table.
|
||||||
|
#
|
||||||
|
# In this test case, when changes are logged as rows either in the RBR or MIXED
|
||||||
|
# modes, we check if a M* statement that happens early in a transaction is
|
||||||
|
# written to the binary log outside the boundaries of the transaction and
|
||||||
|
# wrapped up in a BEGIN/ROLLBACK. This is done to keep the slave consistent with
|
||||||
|
# the master as the rollback will keep the changes on N-tables and undo them on
|
||||||
|
# T-tables. In particular, we expect the following behavior:
|
||||||
|
#
|
||||||
|
# 1. B M* T C would generate in the binlog B M* R B T C.
|
||||||
|
# 2. B M M* C would generate in the binlog B M M* C.
|
||||||
|
# 3. B M* M* T C would generate in the binlog B M* R B M* R B T C.
|
||||||
|
#
|
||||||
|
# SBR is not considered in this test because a failing statement is written to
|
||||||
|
# the binary along with the error code such that a slave executes and rolls it
|
||||||
|
# back, thus undoing the effects on T-tables.
|
||||||
|
#
|
||||||
|
# Note that, in the first case, we are not preserving history from the master as
|
||||||
|
# we are introducing a rollback that never happened. However, this seems to be
|
||||||
|
# more acceptable than making the slave diverge. In the second case, the slave
|
||||||
|
# will diverge as the changes on T-tables that originated from the M statement
|
||||||
|
# are rolled back on the master but not on the slave. Unfortunately, we cannot
|
||||||
|
# simply roll the transaction back as this would undo any uncommitted changes
|
||||||
|
# on T-tables.
|
||||||
|
#
|
||||||
|
# We check two more cases. First, INSERT...SELECT* which produces the following
|
||||||
|
# results:
|
||||||
|
#
|
||||||
|
# 1. B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
|
||||||
|
# the binlog the following entries: "Nothing".
|
||||||
|
# 2. B INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
|
||||||
|
# the binlog the following entries: B INSERT M...SELECT* R.
|
||||||
|
#
|
||||||
|
# Finally, we also check if any N statement that happens early in a transaction
|
||||||
|
# (i.e. before any T or M statement) is written to the binary log outside the
|
||||||
|
# boundaries of the transaction. In particular, we expect the following
|
||||||
|
# behavior:
|
||||||
|
#
|
||||||
|
# 1. B N N T C would generate in the binlog B N C B N C B T C.
|
||||||
|
# 2. B N N T R would generate in the binlog B N C B N C B T R.
|
||||||
|
# 3. B N* N* T C would generate in the binlog B N R B N R B T C.
|
||||||
|
# 4. B N* N* T R would generate in the binlog B N R B N R B T R.
|
||||||
|
# 5. B N N T N T C would generate in the binlog B N C B N C B T N T C.
|
||||||
|
# 6. B N N T N T R would generate in the binlog the B N C B N C B T N T R.
|
||||||
|
#
|
||||||
|
# Such issues do not happen in SBR. In RBR and MBR, a full-fledged fix will be
|
||||||
|
# pushed after the WL#2687.
|
||||||
|
#
|
||||||
|
# Please, remove this test case after pushing WL#2687.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
--echo ###################################################################################
|
||||||
|
--echo # CONFIGURATION
|
||||||
|
--echo ###################################################################################
|
||||||
|
CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
|
||||||
|
CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
--echo ###################################################################################
|
||||||
|
--echo # CHECK HISTORY IN BINLOG
|
||||||
|
--echo ###################################################################################
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 1", 1);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 3", 3);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 4", 4);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 6", 6);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 10", 10);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 11", 11);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 15", 15);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 16", 16);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 18", 18);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 20", 20);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 21", 21);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 23", 23);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 25", 25);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 26", 26);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
--echo *** in the binlog the following entries: "Nothing".
|
||||||
|
--echo *** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 27", 27);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 28", 28);
|
||||||
|
ROLLBACK;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
--echo *** in the binlog the following entries: "B INSERT M..SELECT* R".
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
TRUNCATE TABLE nt_1;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 1);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 2);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 3);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 4);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 5);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 6);
|
||||||
|
ROLLBACK;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 9);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
BEGIN;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 12);
|
||||||
|
ROLLBACK;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 13);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 14);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 15);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 16);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 17);
|
||||||
|
COMMIT;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo
|
||||||
|
--echo *** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
|
||||||
|
--echo
|
||||||
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 18);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 19);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 20);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 21);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 22);
|
||||||
|
ROLLBACK;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--echo ###################################################################################
|
||||||
|
--echo # CLEAN
|
||||||
|
--echo ###################################################################################
|
||||||
|
|
||||||
|
DROP TABLE tt_1;
|
||||||
|
DROP TABLE tt_2;
|
||||||
|
DROP TABLE nt_1;
|
||||||
|
DROP TABLE nt_2;
|
@ -22,3 +22,4 @@ connection master;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
commit;
|
commit;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
-- sync_slave_with_master
|
||||||
|
@ -321,3 +321,11 @@ Vv
|
|||||||
Xx
|
Xx
|
||||||
YyÝýỲỳỴỵỶỷỸỹ
|
YyÝýỲỳỴỵỶỷỸỹ
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
|
||||||
|
set names latin1;
|
||||||
|
show collation like 'latin1_test';
|
||||||
|
Collation Charset Id Default Compiled Sortlen
|
||||||
|
latin1_test latin1 99 Yes 1
|
||||||
|
select "foo" = "foo " collate latin1_test;
|
||||||
|
"foo" = "foo " collate latin1_test
|
||||||
|
1
|
||||||
|
@ -1477,3 +1477,47 @@ COUNT(*)
|
|||||||
SET SQL_MODE=default;
|
SET SQL_MODE=default;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
#
|
||||||
|
# BUG#47280 - strange results from count(*) with order by multiple
|
||||||
|
# columns without where/group
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Initialize test
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
pk INT NOT NULL,
|
||||||
|
i INT,
|
||||||
|
PRIMARY KEY (pk)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
|
||||||
|
#
|
||||||
|
# Start test
|
||||||
|
# All the following queries shall return 1 record
|
||||||
|
#
|
||||||
|
|
||||||
|
# Masking all correct values {11...13} for column i in this result.
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
ORDER BY max;
|
||||||
|
max i
|
||||||
|
3 #
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
ORDER BY max;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
|
||||||
|
|
||||||
|
# Only 11 is correct for collumn i in this result
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
WHERE pk<2
|
||||||
|
ORDER BY max;
|
||||||
|
max i
|
||||||
|
1 11
|
||||||
|
#
|
||||||
|
# Cleanup
|
||||||
|
#
|
||||||
|
DROP TABLE t1;
|
||||||
|
End of 5.1 tests
|
||||||
|
@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
||||||
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
||||||
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
||||||
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
|
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
|
||||||
@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
|
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
|
||||||
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
|
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
|
||||||
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
|
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
|
||||||
|
35
mysql-test/r/innodb-consistent.result
Normal file
35
mysql-test/r/innodb-consistent.result
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
drop table if exists t1;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t2 like t1;
|
||||||
|
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
|
||||||
|
set autocommit=0;
|
||||||
|
begin;
|
||||||
|
replace into t1 select * from t2;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
set autocommit=0;
|
||||||
|
delete from t2 where a=5;
|
||||||
|
commit;
|
||||||
|
delete from t2;
|
||||||
|
commit;
|
||||||
|
commit;
|
||||||
|
begin;
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
set autocommit=0;
|
||||||
|
delete from t2 where a=5;
|
||||||
|
commit;
|
||||||
|
delete from t2;
|
||||||
|
commit;
|
||||||
|
commit;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
@ -6,4 +6,5 @@ SELECT f4, f8 FROM bug34300;
|
|||||||
f4 f8
|
f4 f8
|
||||||
xxx zzz
|
xxx zzz
|
||||||
DROP TABLE bug34300;
|
DROP TABLE bug34300;
|
||||||
|
SET @@global.max_allowed_packet=1048576;
|
||||||
SET @@global.max_allowed_packet=default;
|
SET @@global.max_allowed_packet=default;
|
||||||
|
14
mysql-test/r/innodb_bug44369.result
Normal file
14
mysql-test/r/innodb_bug44369.result
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
create table bug44369 (DB_ROW_ID int) engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||||
|
create table bug44369 (db_row_id int) engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||||
|
show errors;
|
||||||
|
Level Code Message
|
||||||
|
Error 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
|
||||||
|
Error 1005 Can't create table 'test.bug44369' (errno: -1)
|
||||||
|
create table bug44369 (db_TRX_Id int) engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||||
|
show errors;
|
||||||
|
Level Code Message
|
||||||
|
Error 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
|
||||||
|
Error 1005 Can't create table 'test.bug44369' (errno: -1)
|
9
mysql-test/r/innodb_bug44571.result
Normal file
9
mysql-test/r/innodb_bug44571.result
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE bug44571 CHANGE foo bar INT;
|
||||||
|
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
|
||||||
|
ERROR 42000: Key column 'foo' doesn't exist in table
|
||||||
|
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
|
||||||
|
ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
|
||||||
|
CREATE INDEX bug44571b ON bug44571 (bar);
|
||||||
|
ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
|
||||||
|
DROP TABLE bug44571;
|
17
mysql-test/r/innodb_bug46000.result
Normal file
17
mysql-test/r/innodb_bug46000.result
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
|
||||||
|
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
|
||||||
|
show errors;
|
||||||
|
Level Code Message
|
||||||
|
Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
|
||||||
|
Error 1005 Can't create table 'test.bug46000' (errno: -1)
|
||||||
|
create table bug46000(id int) engine=innodb;
|
||||||
|
create index GEN_CLUST_INDEX on bug46000(id);
|
||||||
|
ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
|
||||||
|
show errors;
|
||||||
|
Level Code Message
|
||||||
|
Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
|
||||||
|
Error 1005 Can't create table '#sql-temporary' (errno: -1)
|
||||||
|
create index idx on bug46000(id);
|
||||||
|
drop table bug46000;
|
@ -2271,4 +2271,25 @@ checksum table t3;
|
|||||||
Table Checksum
|
Table Checksum
|
||||||
test.t3 326284887
|
test.t3 326284887
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
|
||||||
|
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
|
||||||
|
(6,'0'),(7,'0');
|
||||||
|
INSERT INTO t1 SELECT a+10,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+20,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+40,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+80,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+160,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+320,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+640,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+1280,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+2560,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+5120,b FROM t1;
|
||||||
|
SET myisam_sort_buffer_size=4;
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair error myisam_sort_buffer_size is too small
|
||||||
|
test.t1 repair warning Number of rows changed from 0 to 7168
|
||||||
|
test.t1 repair status OK
|
||||||
|
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -1557,3 +1557,34 @@ a
|
|||||||
2001
|
2001
|
||||||
1991
|
1991
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
|
||||||
|
# is used
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
|
||||||
|
INSERT INTO t1 SELECT a+4, b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+8, b FROM t1;
|
||||||
|
CREATE TABLE t2 (a INT, b INT);
|
||||||
|
INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
|
||||||
|
INSERT INTO t2 SELECT a+4, b FROM t2;
|
||||||
|
# shouldn't have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 2 Using where
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 10
|
||||||
|
# should have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
|
||||||
|
# should have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
End of 5.1 tests
|
||||||
|
@ -50,6 +50,21 @@ t1 CREATE TABLE `t1` (
|
|||||||
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
|
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
|
||||||
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
|
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (a int, b int, key(a))
|
||||||
|
partition by list (a)
|
||||||
|
( partition p0 values in (1),
|
||||||
|
partition p1 values in (2));
|
||||||
|
insert into t1 values (1,1),(2,1),(2,2),(2,3);
|
||||||
|
show indexes from t1;
|
||||||
|
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||||
|
t1 1 a 1 a A NULL NULL NULL YES BTREE
|
||||||
|
analyze table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status OK
|
||||||
|
show indexes from t1;
|
||||||
|
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||||
|
t1 1 a 1 a A 1 NULL NULL YES BTREE
|
||||||
|
drop table t1;
|
||||||
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
|
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
|
||||||
ENGINE=MyISAM
|
ENGINE=MyISAM
|
||||||
PARTITION BY HASH (a);
|
PARTITION BY HASH (a);
|
||||||
|
22
mysql-test/r/partition_open_files_limit.result
Normal file
22
mysql-test/r/partition_open_files_limit.result
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
DROP TABLE IF EXISTS `t1`;
|
||||||
|
# Bug#46922: crash when adding partitions and open_files_limit is reached
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY)
|
||||||
|
ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
|
||||||
|
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
|
||||||
|
# if the bug exists, then crash will happen here
|
||||||
|
ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
|
||||||
|
ERROR HY000: Out of resources when opening file '<partition file>' (Errcode: 24)
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
10
|
||||||
|
11
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
DROP TABLE t1;
|
@ -1219,3 +1219,182 @@ explain select * from t2 where a=1000 and b<11;
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t2 ref a a 5 const 502 Using where
|
1 SIMPLE t2 ref a a 5 const 502 Using where
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
|
||||||
|
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
|
||||||
|
CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
|
||||||
|
INSERT INTO t1( a, b )
|
||||||
|
VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
|
||||||
|
INSERT INTO t2( a, b )
|
||||||
|
VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
|
||||||
|
( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
|
||||||
|
(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
|
||||||
|
(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
|
||||||
|
INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
|
||||||
|
INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
INSERT INTO t3
|
||||||
|
VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
|
||||||
|
(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
|
||||||
|
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
|
||||||
|
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 < a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
a b
|
||||||
|
5 0
|
||||||
|
9 7
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 < a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
a b
|
||||||
|
5 0
|
||||||
|
9 7
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
a b
|
||||||
|
5 0
|
||||||
|
9 7
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
3 <= a;
|
||||||
|
a b
|
||||||
|
5 0
|
||||||
|
9 7
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
3 <= a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 1 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
3 1
|
||||||
|
4 1
|
||||||
|
5 1
|
||||||
|
6 1
|
||||||
|
7 1
|
||||||
|
8 1
|
||||||
|
9 1
|
||||||
|
10 1
|
||||||
|
11 1
|
||||||
|
12 1
|
||||||
|
13 1
|
||||||
|
14 1
|
||||||
|
15 1
|
||||||
|
15 3
|
||||||
|
16 1
|
||||||
|
16 3
|
||||||
|
17 1
|
||||||
|
17 3
|
||||||
|
18 1
|
||||||
|
18 3
|
||||||
|
19 1
|
||||||
|
19 3
|
||||||
|
20 1
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 1 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 2 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
3 1
|
||||||
|
4 1
|
||||||
|
5 1
|
||||||
|
5 2
|
||||||
|
6 1
|
||||||
|
6 2
|
||||||
|
7 1
|
||||||
|
7 2
|
||||||
|
8 1
|
||||||
|
8 2
|
||||||
|
9 1
|
||||||
|
9 2
|
||||||
|
10 1
|
||||||
|
11 1
|
||||||
|
12 1
|
||||||
|
13 1
|
||||||
|
14 1
|
||||||
|
15 1
|
||||||
|
15 3
|
||||||
|
16 1
|
||||||
|
16 3
|
||||||
|
17 1
|
||||||
|
17 3
|
||||||
|
18 1
|
||||||
|
18 3
|
||||||
|
19 1
|
||||||
|
19 3
|
||||||
|
20 1
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 2 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
|
||||||
|
SELECT * FROM t3 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 3 OR
|
||||||
|
a < 5 OR
|
||||||
|
a < 10;
|
||||||
|
a b
|
||||||
|
1 0
|
||||||
|
2 0
|
||||||
|
3 0
|
||||||
|
4 0
|
||||||
|
5 0
|
||||||
|
6 0
|
||||||
|
7 0
|
||||||
|
8 0
|
||||||
|
9 0
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t3 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 3 OR
|
||||||
|
a < 5 OR
|
||||||
|
a < 10;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
@ -749,6 +749,16 @@ bin(a1)
|
|||||||
110000111111111
|
110000111111111
|
||||||
110001011111111
|
110001011111111
|
||||||
drop table t1bit7, t2bit7;
|
drop table t1bit7, t2bit7;
|
||||||
|
#
|
||||||
|
# Bug42803: Field_bit does not have unsigned_flag field,
|
||||||
|
# can lead to bad memory access
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
|
||||||
|
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
|
||||||
|
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 2 NULL 4 Using where; Using index; Using filesort
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
create table t1(a bit(7));
|
create table t1(a bit(7));
|
||||||
insert into t1 values(0x40);
|
insert into t1 values(0x40);
|
||||||
|
@ -68,4 +68,17 @@
|
|||||||
|
|
||||||
</charset>
|
</charset>
|
||||||
|
|
||||||
|
<charset name="latin1">
|
||||||
|
<family>Western</family>
|
||||||
|
<description>cp1252 West European</description>
|
||||||
|
<alias>csisolatin1</alias>
|
||||||
|
<alias>iso-8859-1</alias>
|
||||||
|
<alias>iso-ir-100</alias>
|
||||||
|
<alias>iso_8859-1</alias>
|
||||||
|
<alias>iso_8859-1:1987</alias>
|
||||||
|
<alias>l1</alias>
|
||||||
|
<alias>latin1</alias>
|
||||||
|
<collation name="latin1_test" id="99" order="test"/>
|
||||||
|
</charset>
|
||||||
|
|
||||||
</charsets>
|
</charsets>
|
||||||
|
135
mysql-test/std_data/latin1.xml
Normal file
135
mysql-test/std_data/latin1.xml
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?xml version='1.0' encoding="utf-8"?>
|
||||||
|
|
||||||
|
<charsets>
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
Copyright (C) 2009 Sun Microsystems, Inc
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<charset name="latin1">
|
||||||
|
|
||||||
|
<ctype>
|
||||||
|
<map>
|
||||||
|
00
|
||||||
|
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
|
||||||
|
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
|
||||||
|
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
|
||||||
|
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
|
||||||
|
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
|
||||||
|
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
|
||||||
|
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
|
||||||
|
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
|
||||||
|
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
|
||||||
|
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
|
||||||
|
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
|
||||||
|
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
|
||||||
|
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
|
||||||
|
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
|
||||||
|
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
|
||||||
|
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
|
||||||
|
</map>
|
||||||
|
</ctype>
|
||||||
|
|
||||||
|
|
||||||
|
<lower>
|
||||||
|
<map>
|
||||||
|
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||||
|
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
|
||||||
|
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
|
||||||
|
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
|
||||||
|
40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
|
||||||
|
70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F
|
||||||
|
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
|
||||||
|
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
|
||||||
|
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
|
||||||
|
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
|
||||||
|
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
|
||||||
|
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
|
||||||
|
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
|
||||||
|
F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF
|
||||||
|
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
|
||||||
|
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
|
||||||
|
</map>
|
||||||
|
</lower>
|
||||||
|
|
||||||
|
|
||||||
|
<upper>
|
||||||
|
<map>
|
||||||
|
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||||
|
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
|
||||||
|
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
|
||||||
|
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
|
||||||
|
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
|
||||||
|
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
|
||||||
|
60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
|
||||||
|
50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
|
||||||
|
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
|
||||||
|
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
|
||||||
|
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
|
||||||
|
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
|
||||||
|
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
|
||||||
|
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
|
||||||
|
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
|
||||||
|
D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF
|
||||||
|
</map>
|
||||||
|
</upper>
|
||||||
|
|
||||||
|
|
||||||
|
<unicode>
|
||||||
|
<map>
|
||||||
|
0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
|
||||||
|
0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F
|
||||||
|
0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F
|
||||||
|
0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F
|
||||||
|
0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
|
||||||
|
0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F
|
||||||
|
0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F
|
||||||
|
0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F
|
||||||
|
20AC 0081 201A 0192 201E 2026 2020 2021 02C6 2030 0160 2039 0152 008D 017D 008F
|
||||||
|
0090 2018 2019 201C 201D 2022 2013 2014 02DC 2122 0161 203A 0153 009D 017E 0178
|
||||||
|
00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF
|
||||||
|
00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF
|
||||||
|
00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF
|
||||||
|
00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF
|
||||||
|
00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF
|
||||||
|
00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF
|
||||||
|
</map>
|
||||||
|
</unicode>
|
||||||
|
|
||||||
|
<collation name="latin1_test">
|
||||||
|
<map>
|
||||||
|
00 01 02 03 37 2D 2E 2F 16 05 25 0B 0C 0D 0E 0F
|
||||||
|
10 11 12 13 3C 3D 32 26 18 19 3F 27 1C 1D 1E 1F
|
||||||
|
40 4F 7F 7B 5B 6C 50 7D 4D 5D 5C 4E 6B 60 4B 61
|
||||||
|
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 7A 5E 4C 7E 6E 6F
|
||||||
|
7C C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6
|
||||||
|
D7 D8 D9 E2 E3 E4 E5 E6 E7 E8 E9 4A E0 5A 5F 6D
|
||||||
|
79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96
|
||||||
|
97 98 99 A2 A3 A4 A5 A6 A7 A8 A9 C0 6A D0 A1 07
|
||||||
|
20 21 22 23 24 15 06 17 28 29 2A 2B 2C 09 0A 1B
|
||||||
|
30 31 1A 33 34 35 36 08 38 39 3A 3B 04 14 3E E1
|
||||||
|
41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57
|
||||||
|
58 59 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
||||||
|
76 77 78 80 8A 8B 8C 8D 8E 8F 90 9A 9B 9C 9D 9E
|
||||||
|
9F A0 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7
|
||||||
|
B8 B9 BA BB BC BD BE BF CA CB CC CD CE CF DA DB
|
||||||
|
DC DD DE DF EA EB EC ED EE EF FA FB FC FD FE FF
|
||||||
|
</map>
|
||||||
|
</collation>
|
||||||
|
|
||||||
|
</charset>
|
||||||
|
|
||||||
|
</charsets>
|
@ -0,0 +1,406 @@
|
|||||||
|
###################################################################################
|
||||||
|
# CONFIGURATION
|
||||||
|
###################################################################################
|
||||||
|
CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
###################################################################################
|
||||||
|
# CHECK HISTORY IN BINLOG
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 1", 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 3", 3);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 1", 1)
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 3", 3)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 4", 4);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
|
||||||
|
ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 6", 6);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 4", 4)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 6", 6)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 10", 10);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
|
||||||
|
ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 11", 11);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 10", 10)
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 11", 11)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 15", 15);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
|
||||||
|
ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 16", 16);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 15", 15)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 16", 16)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 18", 18);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 20", 20);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
|
||||||
|
ERROR 23000: Duplicate entry '18' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
|
||||||
|
ERROR 23000: Duplicate entry '20' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 21", 21);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 18", 18)
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 20", 20)
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 21", 21)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 23", 23);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 25", 25);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
|
||||||
|
ERROR 23000: Duplicate entry '23' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
|
||||||
|
ERROR 23000: Duplicate entry '25' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 26", 26);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 23", 23)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 25", 25)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 26", 26)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
*** in the binlog the following entries: "Nothing".
|
||||||
|
*** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 27", 27);
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 28", 28);
|
||||||
|
ROLLBACK;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
*** in the binlog the following entries: "B INSERT M..SELECT* R".
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7)
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_1;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 1);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 2);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 3);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 4);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 5);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 6);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 9);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 12);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 13);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 14);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 15);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 16);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 17);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 18);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 19);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 20);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 21);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 22);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
###################################################################################
|
||||||
|
# CLEAN
|
||||||
|
###################################################################################
|
||||||
|
DROP TABLE tt_1;
|
||||||
|
DROP TABLE tt_2;
|
||||||
|
DROP TABLE nt_1;
|
||||||
|
DROP TABLE nt_2;
|
@ -1309,3 +1309,27 @@ INSERT INTO test.t1 VALUES (1), (2);
|
|||||||
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
||||||
USE test;
|
USE test;
|
||||||
DROP TABLES t1, t2;
|
DROP TABLES t1, t2;
|
||||||
|
RESET MASTER;
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||||
|
BINLOG '
|
||||||
|
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
||||||
|
';
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
BINLOG '
|
||||||
|
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
|
||||||
|
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
|
||||||
|
';
|
||||||
|
SHOW BINLOG EVENTS;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
# # Format_desc 1 # Server ver: #, Binlog ver: #
|
||||||
|
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
|
||||||
|
# # Query 1 # BEGIN
|
||||||
|
# # Table_map 1 # table_id: # (test.t1)
|
||||||
|
# # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||||
|
# # Query 1 # COMMIT
|
||||||
|
# # Query 1 # BEGIN
|
||||||
|
# # Table_map 1 # table_id: # (test.t1)
|
||||||
|
# # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||||
|
# # Query 1 # COMMIT
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -0,0 +1,440 @@
|
|||||||
|
###################################################################################
|
||||||
|
# CONFIGURATION
|
||||||
|
###################################################################################
|
||||||
|
CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
|
||||||
|
CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
|
||||||
|
CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
|
||||||
|
END|
|
||||||
|
###################################################################################
|
||||||
|
# CHECK HISTORY IN BINLOG
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 1", 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 3", 3);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 4", 4);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
|
||||||
|
ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 6", 6);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 10", 10);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
|
||||||
|
ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 11", 11);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 15", 15);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
|
||||||
|
ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 16", 16);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
|
||||||
|
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 18", 18);
|
||||||
|
INSERT INTO nt_1 VALUES ("new text 20", 20);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
|
||||||
|
ERROR 23000: Duplicate entry '18' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
|
||||||
|
ERROR 23000: Duplicate entry '20' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 21", 21);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 23", 23);
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 25", 25);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
|
||||||
|
ERROR 23000: Duplicate entry '23' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
|
||||||
|
ERROR 23000: Duplicate entry '25' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 26", 26);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
*** in the binlog the following entries: "Nothing".
|
||||||
|
*** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 27", 27);
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 28", 28);
|
||||||
|
ROLLBACK;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
|
||||||
|
*** in the binlog the following entries: "B INSERT M..SELECT* R".
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_2;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
INSERT INTO tt_2 VALUES ("new text 7", 7);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
|
||||||
|
ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
|
||||||
|
|
||||||
|
TRUNCATE TABLE nt_1;
|
||||||
|
TRUNCATE TABLE tt_2;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 1);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 2);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 3);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 4);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 5);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 6);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 9);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 12);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 13);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 14);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 15);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 16);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 17);
|
||||||
|
COMMIT;
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 18);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 19);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 20);
|
||||||
|
INSERT INTO nt_1 VALUES (USER(), 21);
|
||||||
|
INSERT INTO tt_2 VALUES (USER(), 22);
|
||||||
|
ROLLBACK;
|
||||||
|
Warnings:
|
||||||
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.nt_1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.tt_2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # ROLLBACK
|
||||||
|
###################################################################################
|
||||||
|
# CLEAN
|
||||||
|
###################################################################################
|
||||||
|
DROP TABLE tt_1;
|
||||||
|
DROP TABLE tt_2;
|
||||||
|
DROP TABLE nt_1;
|
||||||
|
DROP TABLE nt_2;
|
@ -133,6 +133,10 @@ master-bin.000001 # Query # # BEGIN
|
|||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
insert into t1 values(11);
|
insert into t1 values(11);
|
||||||
commit;
|
commit;
|
||||||
show binlog events from <binlog_start>;
|
show binlog events from <binlog_start>;
|
||||||
@ -144,6 +148,8 @@ master-bin.000001 # Xid # # COMMIT /* XID */
|
|||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
@ -272,6 +278,10 @@ master-bin.000001 # Query # # BEGIN
|
|||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
master-bin.000001 # Query # # use `test`; drop table t1,t2
|
master-bin.000001 # Query # # use `test`; drop table t1,t2
|
||||||
master-bin.000001 # Query # # use `test`; create table t0 (n int)
|
master-bin.000001 # Query # # use `test`; create table t0 (n int)
|
||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
@ -372,7 +382,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE if exists t2
|
|||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Query # # ROLLBACK
|
master-bin.000001 # Query # # COMMIT
|
||||||
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2
|
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2
|
||||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb
|
||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
@ -390,9 +400,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE t2
|
|||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Query # # COMMIT
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
||||||
master-bin.000001 # Query # # ROLLBACK
|
|
||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
@ -400,7 +408,11 @@ master-bin.000001 # Query # # COMMIT
|
|||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
master-bin.000001 # Query # # ROLLBACK
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
|
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
|
||||||
master-bin.000001 # Query # # BEGIN
|
master-bin.000001 # Query # # BEGIN
|
||||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
161
mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
Normal file
161
mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
Verbose statements from : write-partial-row.binlog
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
stmt
|
||||||
|
### INSERT INTO mysql.ndb_apply_status
|
||||||
|
### SET
|
||||||
|
### @1=1
|
||||||
|
### @2=25769803786
|
||||||
|
### @3=''
|
||||||
|
### @4=0
|
||||||
|
### @5=0
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=3
|
||||||
|
### @2=3
|
||||||
|
### @3=3
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=1
|
||||||
|
### @2=1
|
||||||
|
### @3=1
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=2
|
||||||
|
### @2=2
|
||||||
|
### @3=2
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=4
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @3=40
|
||||||
|
### DELETE FROM test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=2
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
Verbose statements from : write-full-row.binlog
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
stmt
|
||||||
|
### INSERT INTO mysql.ndb_apply_status
|
||||||
|
### SET
|
||||||
|
### @1=2
|
||||||
|
### @2=25769803786
|
||||||
|
### @3=''
|
||||||
|
### @4=0
|
||||||
|
### @5=0
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=3
|
||||||
|
### @2=3
|
||||||
|
### @3=3
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=1
|
||||||
|
### @2=1
|
||||||
|
### @3=1
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=2
|
||||||
|
### @2=2
|
||||||
|
### @3=2
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=4
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=40
|
||||||
|
### DELETE FROM test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=2
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
Verbose statements from : update-partial-row.binlog
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
stmt
|
||||||
|
### INSERT INTO mysql.ndb_apply_status
|
||||||
|
### SET
|
||||||
|
### @1=3
|
||||||
|
### @2=25769803786
|
||||||
|
### @3=''
|
||||||
|
### @4=0
|
||||||
|
### @5=0
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=3
|
||||||
|
### @2=3
|
||||||
|
### @3=3
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=1
|
||||||
|
### @2=1
|
||||||
|
### @3=1
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=2
|
||||||
|
### @2=2
|
||||||
|
### @3=2
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=4
|
||||||
|
### UPDATE test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=4
|
||||||
|
### @3=4
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @3=40
|
||||||
|
### DELETE FROM test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=2
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
Verbose statements from : update-full-row.binlog
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
stmt
|
||||||
|
### INSERT INTO mysql.ndb_apply_status
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=25769803786
|
||||||
|
### @3=''
|
||||||
|
### @4=0
|
||||||
|
### @5=0
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=3
|
||||||
|
### @2=3
|
||||||
|
### @3=3
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=1
|
||||||
|
### @2=1
|
||||||
|
### @3=1
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=2
|
||||||
|
### @2=2
|
||||||
|
### @3=2
|
||||||
|
### INSERT INTO test.ba
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=4
|
||||||
|
### UPDATE test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=4
|
||||||
|
### SET
|
||||||
|
### @1=4
|
||||||
|
### @2=4
|
||||||
|
### @3=40
|
||||||
|
### DELETE FROM test.ba
|
||||||
|
### WHERE
|
||||||
|
### @1=2
|
||||||
|
drop table raw_binlog_rows;
|
@ -784,3 +784,24 @@ INSERT INTO test.t1 VALUES (1), (2);
|
|||||||
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
CREATE TABLE test.t2 SELECT * FROM test.t1;
|
||||||
USE test;
|
USE test;
|
||||||
DROP TABLES t1, t2;
|
DROP TABLES t1, t2;
|
||||||
|
RESET MASTER;
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||||
|
BINLOG '
|
||||||
|
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
||||||
|
';
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
BINLOG '
|
||||||
|
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
|
||||||
|
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
|
||||||
|
';
|
||||||
|
SHOW BINLOG EVENTS;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
# # Format_desc 1 # Server ver: #, Binlog ver: #
|
||||||
|
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
|
||||||
|
# # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
|
||||||
|
# # Query 1 # BEGIN
|
||||||
|
# # Table_map 1 # table_id: # (test.t1)
|
||||||
|
# # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||||
|
# # Query 1 # COMMIT
|
||||||
|
DROP TABLE t1;
|
||||||
|
BIN
mysql-test/suite/binlog/std_data/update-full-row.binlog
Normal file
BIN
mysql-test/suite/binlog/std_data/update-full-row.binlog
Normal file
Binary file not shown.
BIN
mysql-test/suite/binlog/std_data/update-partial-row.binlog
Normal file
BIN
mysql-test/suite/binlog/std_data/update-partial-row.binlog
Normal file
Binary file not shown.
BIN
mysql-test/suite/binlog/std_data/write-full-row.binlog
Normal file
BIN
mysql-test/suite/binlog/std_data/write-full-row.binlog
Normal file
Binary file not shown.
BIN
mysql-test/suite/binlog/std_data/write-partial-row.binlog
Normal file
BIN
mysql-test/suite/binlog/std_data/write-partial-row.binlog
Normal file
Binary file not shown.
@ -0,0 +1,4 @@
|
|||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--source extra/binlog_tests/binlog_failure_mixing_engines.test
|
@ -0,0 +1,4 @@
|
|||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--source extra/binlog_tests/binlog_failure_mixing_engines.test
|
@ -0,0 +1,86 @@
|
|||||||
|
########################################################
|
||||||
|
# Test mysqlbinlog command with Ndb produced Binlog
|
||||||
|
# variants
|
||||||
|
#
|
||||||
|
# WHAT
|
||||||
|
# ====
|
||||||
|
# This test aims to check that the mysqlbinlog --verbose
|
||||||
|
# command can output binlogs in 4 format variants, currently
|
||||||
|
# used by Ndb
|
||||||
|
#
|
||||||
|
# 1) Updates logged as write_row events
|
||||||
|
# Only primary key and updated columns included in the
|
||||||
|
# event
|
||||||
|
# 2) Updates logged as write_row_events
|
||||||
|
# All columns included in the event
|
||||||
|
# 3) Updates logged as update_row events
|
||||||
|
# Only primary key and updated columns included in the
|
||||||
|
# event
|
||||||
|
# 4) Updates logged as update_row events
|
||||||
|
# All columns included in the event
|
||||||
|
#
|
||||||
|
# Format variant (1) is the Ndb default.
|
||||||
|
# Bug#47323 resulted in binlogs generated in format (1)
|
||||||
|
# being incorrectly parsed by the mysqlbinlog --verbose
|
||||||
|
# option
|
||||||
|
#
|
||||||
|
# HOW
|
||||||
|
# ===
|
||||||
|
# Row-based binlog files in each format have been
|
||||||
|
# captured from an Ndb cluster
|
||||||
|
# These are output using the mysqlbinlog --verbose
|
||||||
|
# tool and the output is checked.
|
||||||
|
#
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
# We require binlog_format_row as we're independent of binlog format
|
||||||
|
# and there's no point running the same test 3 times
|
||||||
|
-- source include/have_binlog_format_row.inc
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--let $binlog_file=write-partial-row.binlog
|
||||||
|
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
create table raw_binlog_rows (txt varchar(1000));
|
||||||
|
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
--enable_query_log
|
||||||
|
--echo Verbose statements from : $binlog_file
|
||||||
|
# Output --verbose lines, with extra Windows CR's trimmed
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--let $binlog_file=write-full-row.binlog
|
||||||
|
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
create table raw_binlog_rows (txt varchar(1000));
|
||||||
|
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
--enable_query_log
|
||||||
|
--echo Verbose statements from : $binlog_file
|
||||||
|
# Output --verbose lines, with extra Windows CR's trimmed
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--let $binlog_file=update-partial-row.binlog
|
||||||
|
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
create table raw_binlog_rows (txt varchar(1000));
|
||||||
|
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
--enable_query_log
|
||||||
|
--echo Verbose statements from : $binlog_file
|
||||||
|
# Output --verbose lines, with extra Windows CR's trimmed
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
drop table raw_binlog_rows;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--let $binlog_file=update-full-row.binlog
|
||||||
|
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
create table raw_binlog_rows (txt varchar(1000));
|
||||||
|
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
|
||||||
|
--enable_query_log
|
||||||
|
--echo Verbose statements from : $binlog_file
|
||||||
|
# Output --verbose lines, with extra Windows CR's trimmed
|
||||||
|
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
|
||||||
|
drop table raw_binlog_rows;
|
@ -94,15 +94,24 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
SET GLOBAL log_warnings = @old_log_warnings;
|
SET GLOBAL log_warnings = @old_log_warnings;
|
||||||
|
|
||||||
let LOG_ERROR= `SELECT @@GLOBAL.log_error`;
|
let $log_error_= `SELECT @@GLOBAL.log_error`;
|
||||||
|
if(!`select LENGTH('$log_error_')`)
|
||||||
|
{
|
||||||
|
# MySQL Server on windows is started with --console and thus
|
||||||
|
# does not know the location of its .err log, use default location
|
||||||
|
let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||||
|
}
|
||||||
|
# Assign env variable LOG_ERROR
|
||||||
|
let LOG_ERROR=$log_error_;
|
||||||
|
|
||||||
--echo # Count the number of times the "Unsafe" message was printed
|
--echo # Count the number of times the "Unsafe" message was printed
|
||||||
--echo # to the error log.
|
--echo # to the error log.
|
||||||
|
|
||||||
perl;
|
perl;
|
||||||
$log_error= $ENV{'LOG_ERROR'};
|
use strict;
|
||||||
|
my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set";
|
||||||
open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
|
open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
|
||||||
$count = () = grep(/Bug#46265/g,<FILE>);
|
my $count = () = grep(/Bug#46265/g,<FILE>);
|
||||||
print "Occurrences: $count\n";
|
print "Occurrences: $count\n";
|
||||||
close(FILE);
|
close(FILE);
|
||||||
EOF
|
EOF
|
||||||
|
@ -105,12 +105,6 @@ drop table t1;
|
|||||||
--error ER_TOO_BIG_ROWSIZE
|
--error ER_TOO_BIG_ROWSIZE
|
||||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
|
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
|
||||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||||
# 439 throws error with certain system zlib (ubuntu "intrepid")
|
|
||||||
# but not with zlib bundled with MySQL, because zlib's compressBound()
|
|
||||||
# are different (and used by InnoDB's page_zip_empty_size()); see
|
|
||||||
# http://www.linux-archive.org/archlinux-development/119356-zlib-1-2-3-3-1-a.html
|
|
||||||
# "Fix compressBound(), was low for some pathological cases [Fearnley]".
|
|
||||||
# 438 works with both zlib-s.
|
|
||||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
|
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
|
||||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||||
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
|
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
|
||||||
|
@ -176,7 +176,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
|||||||
# 106 Query # 174 BEGIN
|
# 106 Query # 174 BEGIN
|
||||||
# 174 Table_map # 216 table_id: # (test.t7)
|
# 174 Table_map # 216 table_id: # (test.t7)
|
||||||
# 216 Write_rows # 272 table_id: # flags: STMT_END_F
|
# 216 Write_rows # 272 table_id: # flags: STMT_END_F
|
||||||
# 272 Query # 343 ROLLBACK
|
# 272 Query # 341 COMMIT
|
||||||
SELECT * FROM t7 ORDER BY a,b;
|
SELECT * FROM t7 ORDER BY a,b;
|
||||||
a b
|
a b
|
||||||
1 2
|
1 2
|
||||||
@ -327,7 +327,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
|||||||
# 1329 Query # 1397 BEGIN
|
# 1329 Query # 1397 BEGIN
|
||||||
# 1397 Table_map # 1438 table_id: # (test.t1)
|
# 1397 Table_map # 1438 table_id: # (test.t1)
|
||||||
# 1438 Write_rows # 1482 table_id: # flags: STMT_END_F
|
# 1438 Write_rows # 1482 table_id: # flags: STMT_END_F
|
||||||
# 1482 Query # 1553 ROLLBACK
|
# 1482 Query # 1551 COMMIT
|
||||||
SHOW TABLES;
|
SHOW TABLES;
|
||||||
Tables_in_test
|
Tables_in_test
|
||||||
t1
|
t1
|
||||||
|
@ -102,3 +102,4 @@ Last_IO_Errno #
|
|||||||
Last_IO_Error #
|
Last_IO_Error #
|
||||||
Last_SQL_Errno 0
|
Last_SQL_Errno 0
|
||||||
Last_SQL_Error
|
Last_SQL_Error
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -58,3 +58,4 @@ STOP SLAVE;
|
|||||||
# cleanup
|
# cleanup
|
||||||
--connection master
|
--connection master
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
-- sync_slave_with_master
|
||||||
|
@ -78,3 +78,7 @@ SELECT * FROM t1 ORDER BY a;
|
|||||||
--replace_result $MASTER_MYPORT MASTER_PORT
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
||||||
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
|
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
|
||||||
query_vertical SHOW SLAVE STATUS;
|
query_vertical SHOW SLAVE STATUS;
|
||||||
|
|
||||||
|
-- connection master
|
||||||
|
DROP TABLE t1;
|
||||||
|
-- sync_slave_with_master
|
||||||
|
@ -86,3 +86,8 @@ select hex(c1) as h, c1 from t1 order by c1, h;
|
|||||||
select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
|
select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
|
||||||
select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
|
select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
|
||||||
|
set names latin1;
|
||||||
|
show collation like 'latin1_test';
|
||||||
|
select "foo" = "foo " collate latin1_test;
|
||||||
|
@ -14,3 +14,4 @@ innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded
|
|||||||
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
|
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
|
||||||
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
||||||
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
||||||
|
innodb_bug46000 : Bug#47860 2009-10-16 satyab Test fails for innodb plugin 1.0.5
|
||||||
|
@ -1006,3 +1006,51 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
###
|
###
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#47280 - strange results from count(*) with order by multiple
|
||||||
|
--echo # columns without where/group
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Initialize test
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
pk INT NOT NULL,
|
||||||
|
i INT,
|
||||||
|
PRIMARY KEY (pk)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start test
|
||||||
|
--echo # All the following queries shall return 1 record
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Masking all correct values {11...13} for column i in this result.
|
||||||
|
--replace_column 2 #
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
ORDER BY max;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
EXPLAIN
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
ORDER BY max;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Only 11 is correct for collumn i in this result
|
||||||
|
SELECT MAX(pk) as max, i
|
||||||
|
FROM t1
|
||||||
|
WHERE pk<2
|
||||||
|
ORDER BY max;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Cleanup
|
||||||
|
--echo #
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
1
mysql-test/t/innodb-consistent-master.opt
Normal file
1
mysql-test/t/innodb-consistent-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--innodb_lock_wait_timeout=2
|
58
mysql-test/t/innodb-consistent.test
Normal file
58
mysql-test/t/innodb-consistent.test
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
-- source include/not_embedded.inc
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
|
||||||
|
# a consistent read of the source table.
|
||||||
|
|
||||||
|
connect (a,localhost,root,,);
|
||||||
|
connect (b,localhost,root,,);
|
||||||
|
connection a;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t2 like t1;
|
||||||
|
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
|
||||||
|
set autocommit=0;
|
||||||
|
|
||||||
|
# REPLACE INTO ... SELECT case
|
||||||
|
begin;
|
||||||
|
# this should not result in any locks on t2.
|
||||||
|
replace into t1 select * from t2;
|
||||||
|
|
||||||
|
connection b;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
set autocommit=0;
|
||||||
|
# should not cuase a lock wait.
|
||||||
|
delete from t2 where a=5;
|
||||||
|
commit;
|
||||||
|
delete from t2;
|
||||||
|
commit;
|
||||||
|
connection a;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
# INSERT INTO ... SELECT case
|
||||||
|
begin;
|
||||||
|
# this should not result in any locks on t2.
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
|
||||||
|
connection b;
|
||||||
|
set session transaction isolation level read committed;
|
||||||
|
set autocommit=0;
|
||||||
|
# should not cuase a lock wait.
|
||||||
|
delete from t2 where a=5;
|
||||||
|
commit;
|
||||||
|
delete from t2;
|
||||||
|
commit;
|
||||||
|
connection a;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
disconnect a;
|
||||||
|
disconnect b;
|
@ -9,6 +9,7 @@
|
|||||||
-- disable_result_log
|
-- disable_result_log
|
||||||
|
|
||||||
# set packet size and reconnect
|
# set packet size and reconnect
|
||||||
|
let $max_packet=`select @@global.max_allowed_packet`;
|
||||||
SET @@global.max_allowed_packet=16777216;
|
SET @@global.max_allowed_packet=16777216;
|
||||||
--connect (newconn, localhost, root,,)
|
--connect (newconn, localhost, root,,)
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ SELECT f4, f8 FROM bug34300;
|
|||||||
|
|
||||||
DROP TABLE bug34300;
|
DROP TABLE bug34300;
|
||||||
|
|
||||||
|
EVAL SET @@global.max_allowed_packet=$max_packet;
|
||||||
disconnect newconn;
|
disconnect newconn;
|
||||||
connection default;
|
connection default;
|
||||||
SET @@global.max_allowed_packet=default;
|
SET @@global.max_allowed_packet=default;
|
||||||
|
21
mysql-test/t/innodb_bug44369.test
Normal file
21
mysql-test/t/innodb_bug44369.test
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# This is the test for bug 44369. We should
|
||||||
|
# block table creation with columns match
|
||||||
|
# some innodb internal reserved key words,
|
||||||
|
# both case sensitively and insensitely.
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
# This create table operation should fail.
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create table bug44369 (DB_ROW_ID int) engine=innodb;
|
||||||
|
|
||||||
|
# This create should fail as well
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create table bug44369 (db_row_id int) engine=innodb;
|
||||||
|
|
||||||
|
show errors;
|
||||||
|
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create table bug44369 (db_TRX_Id int) engine=innodb;
|
||||||
|
|
||||||
|
show errors;
|
17
mysql-test/t/innodb_bug44571.test
Normal file
17
mysql-test/t/innodb_bug44571.test
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# Bug#44571 InnoDB Plugin crashes on ADD INDEX
|
||||||
|
# http://bugs.mysql.com/44571
|
||||||
|
#
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
|
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE bug44571 CHANGE foo bar INT;
|
||||||
|
-- error ER_KEY_COLUMN_DOES_NOT_EXITS
|
||||||
|
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
|
||||||
|
# The following will fail, because the CHANGE foo bar was
|
||||||
|
# not communicated to InnoDB.
|
||||||
|
--error ER_NOT_KEYFILE
|
||||||
|
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
|
||||||
|
--error ER_NOT_KEYFILE
|
||||||
|
CREATE INDEX bug44571b ON bug44571 (bar);
|
||||||
|
DROP TABLE bug44571;
|
34
mysql-test/t/innodb_bug46000.test
Normal file
34
mysql-test/t/innodb_bug46000.test
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# This is the test for bug 46000. We shall
|
||||||
|
# block any index creation with the name of
|
||||||
|
# "GEN_CLUST_INDEX", which is the reserved
|
||||||
|
# name for innodb default primary index.
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
# This 'create table' operation should fail because of
|
||||||
|
# using the reserve name as its index name.
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
|
||||||
|
|
||||||
|
# Mixed upper/lower case of the reserved key words
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
|
||||||
|
|
||||||
|
show errors;
|
||||||
|
|
||||||
|
create table bug46000(id int) engine=innodb;
|
||||||
|
|
||||||
|
# This 'create index' operation should fail.
|
||||||
|
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
create index GEN_CLUST_INDEX on bug46000(id);
|
||||||
|
|
||||||
|
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||||
|
show errors;
|
||||||
|
|
||||||
|
# This 'create index' operation should succeed, no
|
||||||
|
# temp table left from last failed create index
|
||||||
|
# operation.
|
||||||
|
create index idx on bug46000(id);
|
||||||
|
|
||||||
|
drop table bug46000;
|
@ -1518,5 +1518,36 @@ CREATE TABLE t3 select * from t1;
|
|||||||
checksum table t3;
|
checksum table t3;
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#47073 - valgrind errs, corruption,failed repair of partition,
|
||||||
|
# low myisam_sort_buffer_size
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
|
||||||
|
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
|
||||||
|
(6,'0'),(7,'0');
|
||||||
|
INSERT INTO t1 SELECT a+10,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+20,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+40,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+80,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+160,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+320,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+640,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+1280,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+2560,b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+5120,b FROM t1;
|
||||||
|
SET myisam_sort_buffer_size=4;
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
|
||||||
|
# !!! Disabled until additional fix for BUG#47073 is pushed.
|
||||||
|
#SET myisam_repair_threads=2;
|
||||||
|
# May report different values depending on threads activity.
|
||||||
|
#--replace_regex /changed from [0-9]+/changed from #/
|
||||||
|
#REPAIR TABLE t1;
|
||||||
|
#SET myisam_repair_threads=@@global.myisam_repair_threads;
|
||||||
|
|
||||||
|
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
|
@ -1402,3 +1402,35 @@ SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
|
|||||||
SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
|
SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
|
||||||
|
--echo # is used
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY (a));
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
|
||||||
|
INSERT INTO t1 SELECT a+4, b FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a+8, b FROM t1;
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a INT, b INT);
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
|
||||||
|
INSERT INTO t2 SELECT a+4, b FROM t2;
|
||||||
|
|
||||||
|
--echo # shouldn't have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
|
||||||
|
--echo # should have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
|
||||||
|
--echo # should have "using filesort"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
@ -61,6 +61,19 @@ SELECT * FROM t1;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#44059: rec_per_key on empty partition gives weird optimiser results
|
||||||
|
#
|
||||||
|
create table t1 (a int, b int, key(a))
|
||||||
|
partition by list (a)
|
||||||
|
( partition p0 values in (1),
|
||||||
|
partition p1 values in (2));
|
||||||
|
insert into t1 values (1,1),(2,1),(2,2),(2,3);
|
||||||
|
show indexes from t1;
|
||||||
|
analyze table t1;
|
||||||
|
show indexes from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#36001: Partitions: spelling and using some error messages
|
# Bug#36001: Partitions: spelling and using some error messages
|
||||||
#
|
#
|
||||||
|
1
mysql-test/t/partition_open_files_limit-master.opt
Normal file
1
mysql-test/t/partition_open_files_limit-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--open-files-limit=5 --max_connections=2 --table_open_cache=1
|
26
mysql-test/t/partition_open_files_limit.test
Normal file
26
mysql-test/t/partition_open_files_limit.test
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS `t1`;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
# On some platforms the lowest possible open_files_limit is too high...
|
||||||
|
let $max_open_files_limit= `SELECT @@open_files_limit > 511`;
|
||||||
|
if ($max_open_files_limit)
|
||||||
|
{
|
||||||
|
skip Need open_files_limit to be lower than 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
--echo # Bug#46922: crash when adding partitions and open_files_limit is reached
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY)
|
||||||
|
ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
|
||||||
|
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
|
||||||
|
--echo # if the bug exists, then crash will happen here
|
||||||
|
--replace_regex /file '.*'/file '<partition file>'/
|
||||||
|
--error 23
|
||||||
|
ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
@ -1046,3 +1046,128 @@ explain select * from t2 where a=1000 and b<11;
|
|||||||
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#42846: wrong result returned for range scan when using covering index
|
||||||
|
#
|
||||||
|
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
|
||||||
|
|
||||||
|
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
|
||||||
|
|
||||||
|
CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
|
||||||
|
|
||||||
|
INSERT INTO t1( a, b )
|
||||||
|
VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
|
||||||
|
|
||||||
|
INSERT INTO t2( a, b )
|
||||||
|
VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
|
||||||
|
( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
|
||||||
|
(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
|
||||||
|
(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
|
||||||
|
|
||||||
|
INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
|
||||||
|
INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
|
||||||
|
|
||||||
|
# To make range scan compelling to the optimizer
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT -1, -1 FROM t2;
|
||||||
|
|
||||||
|
INSERT INTO t3
|
||||||
|
VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
|
||||||
|
(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
|
||||||
|
|
||||||
|
# To make range scan compelling to the optimizer
|
||||||
|
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
|
||||||
|
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem#1 Test queries. Will give missing results unless Problem#1 is fixed.
|
||||||
|
# With one exception, they are independent of Problem#2.
|
||||||
|
#
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 < a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 < a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
# Query below: Tests both Problem#1 and Problem#2 (EXPLAIN differs as well)
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a < 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
5 <= a AND b = 3 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
3 <= a AND a <= 5 OR
|
||||||
|
3 <= a;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem#2 Test queries.
|
||||||
|
# These queries will give missing results if Problem#1 is fixed.
|
||||||
|
# But Problem#1 also hides this bug.
|
||||||
|
#
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 1 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 1 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 2 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 2 OR
|
||||||
|
15 <= a AND a < 20 AND b = 3
|
||||||
|
OR
|
||||||
|
1 <= a AND b = 1;
|
||||||
|
|
||||||
|
SELECT * FROM t3 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 3 OR
|
||||||
|
a < 5 OR
|
||||||
|
a < 10;
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t3 WHERE
|
||||||
|
5 <= a AND a < 10 AND b = 3 OR
|
||||||
|
a < 5 OR
|
||||||
|
a < 10;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
@ -397,6 +397,17 @@ insert into t2bit7 values (b'110011011111111');
|
|||||||
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
||||||
drop table t1bit7, t2bit7;
|
drop table t1bit7, t2bit7;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug42803: Field_bit does not have unsigned_flag field,
|
||||||
|
--echo # can lead to bad memory access
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
|
||||||
|
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
|
||||||
|
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -27,7 +27,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
|
|||||||
errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
|
errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
|
||||||
mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c
|
mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c
|
||||||
mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
|
mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
|
||||||
mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_arr_appstr.c mf_tempdir.c
|
mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_arr_appstr.c mf_tempdir.c
|
||||||
mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
|
mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
|
||||||
my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c
|
my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c
|
||||||
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
|
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
|
||||||
|
@ -35,7 +35,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
|
|||||||
my_error.c errors.c my_div.c my_messnc.c \
|
my_error.c errors.c my_div.c my_messnc.c \
|
||||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
||||||
my_symlink.c my_symlink2.c \
|
my_symlink.c my_symlink2.c \
|
||||||
mf_pack.c mf_unixpath.c mf_strip.c mf_arr_appstr.c \
|
mf_pack.c mf_unixpath.c mf_arr_appstr.c \
|
||||||
mf_wcomp.c mf_wfile.c my_gethwaddr.c \
|
mf_wcomp.c mf_wfile.c my_gethwaddr.c \
|
||||||
mf_qsort.c mf_qsort2.c mf_sort.c \
|
mf_qsort.c mf_qsort2.c mf_sort.c \
|
||||||
ptr_cmp.c mf_radix.c queues.c my_getncpus.c \
|
ptr_cmp.c mf_radix.c queues.c my_getncpus.c \
|
||||||
|
@ -1730,6 +1730,7 @@ restart:
|
|||||||
- block assigned but not yet read from file (invalid data).
|
- block assigned but not yet read from file (invalid data).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef THREAD
|
||||||
if (keycache->in_resize)
|
if (keycache->in_resize)
|
||||||
{
|
{
|
||||||
/* This is a request during a resize operation */
|
/* This is a request during a resize operation */
|
||||||
@ -1971,6 +1972,9 @@ restart:
|
|||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
#else /* THREAD */
|
||||||
|
DBUG_ASSERT(!keycache->in_resize);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (page_status == PAGE_READ &&
|
if (page_status == PAGE_READ &&
|
||||||
(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
|
(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB
|
|
||||||
|
|
||||||
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
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
||||||
|
|
||||||
/* T|mmer en str{ng p{ slut_space */
|
|
||||||
|
|
||||||
#include "mysys_priv.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
strip_sp(char * str)
|
|
||||||
Strips end-space from string and returns new length.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t strip_sp(register char * str)
|
|
||||||
{
|
|
||||||
reg2 char * found;
|
|
||||||
reg3 char * start;
|
|
||||||
|
|
||||||
start=found=str;
|
|
||||||
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
if (*str != ' ')
|
|
||||||
{
|
|
||||||
while (*++str && *str != ' ') {};
|
|
||||||
if (!*str)
|
|
||||||
return (size_t) (str-start); /* Return stringlength */
|
|
||||||
}
|
|
||||||
found=str;
|
|
||||||
while (*++str == ' ') {};
|
|
||||||
}
|
|
||||||
*found= '\0'; /* Stripp at first space */
|
|
||||||
return (size_t) (found-start);
|
|
||||||
} /* strip_sp */
|
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
SET(REGEX_SOURCES debug.c regcomp.c regerror.c regexec.c regfree.c reginit.c split.c)
|
SET(REGEX_SOURCES regcomp.c regerror.c regexec.c regfree.c reginit.c)
|
||||||
|
|
||||||
IF(NOT SOURCE_SUBLIBS)
|
IF(NOT SOURCE_SUBLIBS)
|
||||||
ADD_LIBRARY(regex ${REGEX_SOURCES})
|
ADD_LIBRARY(regex ${REGEX_SOURCES})
|
||||||
|
@ -1337,10 +1337,10 @@ void ha_partition::cleanup_new_partition(uint part_count)
|
|||||||
m_file= m_added_file;
|
m_file= m_added_file;
|
||||||
m_added_file= NULL;
|
m_added_file= NULL;
|
||||||
|
|
||||||
|
external_lock(ha_thd(), F_UNLCK);
|
||||||
/* delete_table also needed, a bit more complex */
|
/* delete_table also needed, a bit more complex */
|
||||||
close();
|
close();
|
||||||
|
|
||||||
m_added_file= m_file;
|
|
||||||
m_file= save_m_file;
|
m_file= save_m_file;
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -5144,8 +5144,9 @@ int ha_partition::info(uint flag)
|
|||||||
If the handler doesn't support statistics, it should set all of the
|
If the handler doesn't support statistics, it should set all of the
|
||||||
above to 0.
|
above to 0.
|
||||||
|
|
||||||
We will allow the first handler to set the rec_per_key and use
|
We first scans through all partitions to get the one holding most rows.
|
||||||
this as an estimate on the total table.
|
We will then allow the handler with the most rows to set
|
||||||
|
the rec_per_key and use this as an estimate on the total table.
|
||||||
|
|
||||||
max_data_file_length: Maximum data file length
|
max_data_file_length: Maximum data file length
|
||||||
We ignore it, is only used in
|
We ignore it, is only used in
|
||||||
@ -5157,14 +5158,33 @@ int ha_partition::info(uint flag)
|
|||||||
ref_length: We set this to the value calculated
|
ref_length: We set this to the value calculated
|
||||||
and stored in local object
|
and stored in local object
|
||||||
create_time: Creation time of table
|
create_time: Creation time of table
|
||||||
Set by first handler
|
|
||||||
|
|
||||||
So we calculate these constants by using the variables on the first
|
So we calculate these constants by using the variables from the
|
||||||
handler.
|
handler with most rows.
|
||||||
*/
|
*/
|
||||||
handler *file;
|
handler *file, **file_array;
|
||||||
|
ulonglong max_records= 0;
|
||||||
|
uint32 i= 0;
|
||||||
|
uint32 handler_instance= 0;
|
||||||
|
|
||||||
file= m_file[0];
|
file_array= m_file;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
file= *file_array;
|
||||||
|
/* Get variables if not already done */
|
||||||
|
if (!(flag & HA_STATUS_VARIABLE) ||
|
||||||
|
!bitmap_is_set(&(m_part_info->used_partitions),
|
||||||
|
(file_array - m_file)))
|
||||||
|
file->info(HA_STATUS_VARIABLE);
|
||||||
|
if (file->stats.records > max_records)
|
||||||
|
{
|
||||||
|
max_records= file->stats.records;
|
||||||
|
handler_instance= i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (*(++file_array));
|
||||||
|
|
||||||
|
file= m_file[handler_instance];
|
||||||
file->info(HA_STATUS_CONST);
|
file->info(HA_STATUS_CONST);
|
||||||
stats.create_time= file->stats.create_time;
|
stats.create_time= file->stats.create_time;
|
||||||
ref_length= m_ref_length;
|
ref_length= m_ref_length;
|
||||||
|
32
sql/log.cc
32
sql/log.cc
@ -158,7 +158,7 @@ private:
|
|||||||
class binlog_trx_data {
|
class binlog_trx_data {
|
||||||
public:
|
public:
|
||||||
binlog_trx_data()
|
binlog_trx_data()
|
||||||
: at_least_one_stmt(0), incident(FALSE), m_pending(0),
|
: at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
|
||||||
before_stmt_pos(MY_OFF_T_UNDEF)
|
before_stmt_pos(MY_OFF_T_UNDEF)
|
||||||
{
|
{
|
||||||
trans_log.end_of_file= max_binlog_cache_size;
|
trans_log.end_of_file= max_binlog_cache_size;
|
||||||
@ -187,7 +187,10 @@ public:
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
|
DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
|
||||||
DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
|
DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
|
||||||
delete pending();
|
if (pending())
|
||||||
|
{
|
||||||
|
delete pending();
|
||||||
|
}
|
||||||
set_pending(0);
|
set_pending(0);
|
||||||
reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
|
reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
|
||||||
trans_log.end_of_file= max_binlog_cache_size;
|
trans_log.end_of_file= max_binlog_cache_size;
|
||||||
@ -197,12 +200,12 @@ public:
|
|||||||
/*
|
/*
|
||||||
The only valid positions that can be truncated to are at the
|
The only valid positions that can be truncated to are at the
|
||||||
beginning of a statement. We are relying on this fact to be able
|
beginning of a statement. We are relying on this fact to be able
|
||||||
to set the at_least_one_stmt flag correctly. In other word, if
|
to set the at_least_one_stmt_committed flag correctly. In other word, if
|
||||||
we are truncating to the beginning of the transaction cache,
|
we are truncating to the beginning of the transaction cache,
|
||||||
there will be no statements in the cache, otherwhise, we will
|
there will be no statements in the cache, otherwhise, we will
|
||||||
have at least one statement in the transaction cache.
|
have at least one statement in the transaction cache.
|
||||||
*/
|
*/
|
||||||
at_least_one_stmt= (pos > 0);
|
at_least_one_stmt_committed= (pos > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -244,7 +247,7 @@ public:
|
|||||||
Boolean that is true if there is at least one statement in the
|
Boolean that is true if there is at least one statement in the
|
||||||
transaction cache.
|
transaction cache.
|
||||||
*/
|
*/
|
||||||
bool at_least_one_stmt;
|
bool at_least_one_stmt_committed;
|
||||||
bool incident;
|
bool incident;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1277,7 +1280,7 @@ static bool stmt_has_updated_trans_table(THD *thd)
|
|||||||
{
|
{
|
||||||
Ha_trx_info *ha_info;
|
Ha_trx_info *ha_info;
|
||||||
|
|
||||||
for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next())
|
for (ha_info= thd->transaction.stmt.ha_list; ha_info && ha_info->is_started(); ha_info= ha_info->next())
|
||||||
{
|
{
|
||||||
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
|
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
@ -1540,13 +1543,17 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
|
|||||||
YESNO(in_transaction),
|
YESNO(in_transaction),
|
||||||
YESNO(thd->transaction.all.modified_non_trans_table),
|
YESNO(thd->transaction.all.modified_non_trans_table),
|
||||||
YESNO(thd->transaction.stmt.modified_non_trans_table)));
|
YESNO(thd->transaction.stmt.modified_non_trans_table)));
|
||||||
if (!in_transaction || all)
|
if (!in_transaction || all ||
|
||||||
|
(!all && !trx_data->at_least_one_stmt_committed &&
|
||||||
|
!stmt_has_updated_trans_table(thd) &&
|
||||||
|
thd->transaction.stmt.modified_non_trans_table))
|
||||||
{
|
{
|
||||||
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
|
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
|
||||||
error= binlog_end_trans(thd, trx_data, &qev, all);
|
error= binlog_end_trans(thd, trx_data, &qev, all);
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (!all)
|
if (!all)
|
||||||
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
|
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
|
||||||
@ -1613,15 +1620,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We flush the cache with a rollback, wrapped in a beging/rollback if:
|
We flush the cache with a rollback, wrapped in a beging/rollback if:
|
||||||
. aborting a transcation that modified a non-transactional table or;
|
. aborting a transaction that modified a non-transactional table;
|
||||||
. aborting a statement that modified both transactional and
|
. aborting a statement that modified both transactional and
|
||||||
non-transctional tables but which is not in the boundaries of any
|
non-transactional tables but which is not in the boundaries of any
|
||||||
transaction;
|
transaction or there was no early change;
|
||||||
. the OPTION_KEEP_LOG is activate.
|
. the OPTION_KEEP_LOG is activate.
|
||||||
*/
|
*/
|
||||||
if ((all && thd->transaction.all.modified_non_trans_table) ||
|
if ((all && thd->transaction.all.modified_non_trans_table) ||
|
||||||
(!all && thd->transaction.stmt.modified_non_trans_table &&
|
(!all && thd->transaction.stmt.modified_non_trans_table &&
|
||||||
!(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
|
!(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
|
||||||
|
(!all && thd->transaction.stmt.modified_non_trans_table &&
|
||||||
|
!trx_data->at_least_one_stmt_committed &&
|
||||||
|
thd->current_stmt_binlog_row_based) ||
|
||||||
((thd->options & OPTION_KEEP_LOG)))
|
((thd->options & OPTION_KEEP_LOG)))
|
||||||
{
|
{
|
||||||
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
|
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
|
||||||
|
@ -1853,6 +1853,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
|
|||||||
{
|
{
|
||||||
const uchar *value0= value;
|
const uchar *value0= value;
|
||||||
const uchar *null_bits= value;
|
const uchar *null_bits= value;
|
||||||
|
uint null_bit_index= 0;
|
||||||
char typestr[64]= "";
|
char typestr[64]= "";
|
||||||
|
|
||||||
value+= (m_width + 7) / 8;
|
value+= (m_width + 7) / 8;
|
||||||
@ -1861,7 +1862,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
|
|||||||
|
|
||||||
for (size_t i= 0; i < td->size(); i ++)
|
for (size_t i= 0; i < td->size(); i ++)
|
||||||
{
|
{
|
||||||
int is_null= (null_bits[i / 8] >> (i % 8)) & 0x01;
|
int is_null= (null_bits[null_bit_index / 8]
|
||||||
|
>> (null_bit_index % 8)) & 0x01;
|
||||||
|
|
||||||
if (bitmap_is_set(cols_bitmap, i) == 0)
|
if (bitmap_is_set(cols_bitmap, i) == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -1898,6 +1900,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_b_printf(file, "\n");
|
my_b_printf(file, "\n");
|
||||||
|
|
||||||
|
null_bit_index++;
|
||||||
}
|
}
|
||||||
return value - value0;
|
return value - value0;
|
||||||
}
|
}
|
||||||
@ -3856,6 +3860,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
|
|||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
|
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
|
||||||
{
|
{
|
||||||
|
int ret= 0;
|
||||||
DBUG_ENTER("Format_description_log_event::do_apply_event");
|
DBUG_ENTER("Format_description_log_event::do_apply_event");
|
||||||
|
|
||||||
#ifdef USING_TRANSACTIONS
|
#ifdef USING_TRANSACTIONS
|
||||||
@ -3897,17 +3902,21 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
0, then 96, then jump to first really asked event (which is
|
0, then 96, then jump to first really asked event (which is
|
||||||
>96). So this is ok.
|
>96). So this is ok.
|
||||||
*/
|
*/
|
||||||
DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
|
ret= Start_log_event_v3::do_apply_event(rli);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
/* Save the information describing this binlog */
|
||||||
|
delete rli->relay_log.description_event_for_exec;
|
||||||
|
const_cast<Relay_log_info *>(rli)->relay_log.description_event_for_exec= this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
|
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
/* save the information describing this binlog */
|
|
||||||
delete rli->relay_log.description_event_for_exec;
|
|
||||||
rli->relay_log.description_event_for_exec= this;
|
|
||||||
|
|
||||||
if (server_id == (uint32) ::server_id)
|
if (server_id == (uint32) ::server_id)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -7497,6 +7506,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
thd->reset_current_stmt_binlog_row_based();
|
thd->reset_current_stmt_binlog_row_based();
|
||||||
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
|
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
|
||||||
thd->is_slave_error= 1;
|
thd->is_slave_error= 1;
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
This code would ideally be placed in do_update_pos() instead, but
|
This code would ideally be placed in do_update_pos() instead, but
|
||||||
@ -7525,6 +7535,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
|
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_flags(STMT_END_F))
|
||||||
|
if (error= rows_event_stmt_cleanup(rli, thd))
|
||||||
|
rli->report(ERROR_LEVEL, error,
|
||||||
|
"Error in %s event: commit of row events failed, "
|
||||||
|
"table `%s`.`%s`",
|
||||||
|
get_type_str(), m_table->s->db.str,
|
||||||
|
m_table->s->table_name.str);
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7623,33 +7641,19 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
|
|||||||
|
|
||||||
if (get_flags(STMT_END_F))
|
if (get_flags(STMT_END_F))
|
||||||
{
|
{
|
||||||
if ((error= rows_event_stmt_cleanup(rli, thd)) == 0)
|
/*
|
||||||
{
|
Indicate that a statement is finished.
|
||||||
/*
|
Step the group log position if we are not in a transaction,
|
||||||
Indicate that a statement is finished.
|
otherwise increase the event log position.
|
||||||
Step the group log position if we are not in a transaction,
|
*/
|
||||||
otherwise increase the event log position.
|
rli->stmt_done(log_pos, when);
|
||||||
*/
|
/*
|
||||||
rli->stmt_done(log_pos, when);
|
Clear any errors in thd->net.last_err*. It is not known if this is
|
||||||
|
needed or not. It is believed that any errors that may exist in
|
||||||
/*
|
thd->net.last_err* are allowed. Examples of errors are "key not
|
||||||
Clear any errors pushed in thd->net.last_err* if for example "no key
|
found", which is produced in the test case rpl_row_conflicts.test
|
||||||
found" (as this is allowed). This is a safety measure; apparently
|
*/
|
||||||
those errors (e.g. when executing a Delete_rows_log_event of a
|
thd->clear_error();
|
||||||
non-existing row, like in rpl_row_mystery22.test,
|
|
||||||
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
|
|
||||||
do not become visible. We still prefer to wipe them out.
|
|
||||||
*/
|
|
||||||
thd->clear_error();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rli->report(ERROR_LEVEL, error,
|
|
||||||
"Error in %s event: commit of row events failed, "
|
|
||||||
"table `%s`.`%s`",
|
|
||||||
get_type_str(), m_table->s->db.str,
|
|
||||||
m_table->s->table_name.str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1814,7 +1814,56 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
|
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
if (get_flags(STMT_END_F))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is the end of a statement or transaction, so close (and
|
||||||
|
unlock) the tables we opened when processing the
|
||||||
|
Table_map_log_event starting the statement.
|
||||||
|
|
||||||
|
OBSERVER. This will clear *all* mappings, not only those that
|
||||||
|
are open for the table. There is not good handle for on-close
|
||||||
|
actions for tables.
|
||||||
|
|
||||||
|
NOTE. Even if we have no table ('table' == 0) we still need to be
|
||||||
|
here, so that we increase the group relay log position. If we didn't, we
|
||||||
|
could have a group relay log position which lags behind "forever"
|
||||||
|
(assume the last master's transaction is ignored by the slave because of
|
||||||
|
replicate-ignore rules).
|
||||||
|
*/
|
||||||
|
thd->binlog_flush_pending_rows_event(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If this event is not in a transaction, the call below will, if some
|
||||||
|
transactional storage engines are involved, commit the statement into
|
||||||
|
them and flush the pending event to binlog.
|
||||||
|
If this event is in a transaction, the call will do nothing, but a
|
||||||
|
Xid_log_event will come next which will, if some transactional engines
|
||||||
|
are involved, commit the transaction and flush the pending event to the
|
||||||
|
binlog.
|
||||||
|
*/
|
||||||
|
if (error= ha_autocommit_or_rollback(thd, 0))
|
||||||
|
rli->report(ERROR_LEVEL, error,
|
||||||
|
"Error in %s event: commit of row events failed, "
|
||||||
|
"table `%s`.`%s`",
|
||||||
|
get_type_str(), m_table->s->db.str,
|
||||||
|
m_table->s->table_name.str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Now what if this is not a transactional engine? we still need to
|
||||||
|
flush the pending event to the binlog; we did it with
|
||||||
|
thd->binlog_flush_pending_rows_event(). Note that we imitate
|
||||||
|
what is done for real queries: a call to
|
||||||
|
ha_autocommit_or_rollback() (sometimes only if involves a
|
||||||
|
transactional engine), and a call to be sure to have the pending
|
||||||
|
event flushed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
thd->reset_current_stmt_binlog_row_based();
|
||||||
|
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1844,71 +1893,18 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
|
|||||||
if (get_flags(STMT_END_F))
|
if (get_flags(STMT_END_F))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This is the end of a statement or transaction, so close (and
|
Indicate that a statement is finished.
|
||||||
unlock) the tables we opened when processing the
|
Step the group log position if we are not in a transaction,
|
||||||
Table_map_log_event starting the statement.
|
otherwise increase the event log position.
|
||||||
|
*/
|
||||||
OBSERVER. This will clear *all* mappings, not only those that
|
rli->stmt_done(log_pos, when);
|
||||||
are open for the table. There is not good handle for on-close
|
|
||||||
actions for tables.
|
|
||||||
|
|
||||||
NOTE. Even if we have no table ('table' == 0) we still need to be
|
|
||||||
here, so that we increase the group relay log position. If we didn't, we
|
|
||||||
could have a group relay log position which lags behind "forever"
|
|
||||||
(assume the last master's transaction is ignored by the slave because of
|
|
||||||
replicate-ignore rules).
|
|
||||||
*/
|
|
||||||
thd->binlog_flush_pending_rows_event(true);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If this event is not in a transaction, the call below will, if some
|
Clear any errors in thd->net.last_err*. It is not known if this is
|
||||||
transactional storage engines are involved, commit the statement into
|
needed or not. It is believed that any errors that may exist in
|
||||||
them and flush the pending event to binlog.
|
thd->net.last_err* are allowed. Examples of errors are "key not
|
||||||
If this event is in a transaction, the call will do nothing, but a
|
found", which is produced in the test case rpl_row_conflicts.test
|
||||||
Xid_log_event will come next which will, if some transactional engines
|
|
||||||
are involved, commit the transaction and flush the pending event to the
|
|
||||||
binlog.
|
|
||||||
*/
|
*/
|
||||||
error= ha_autocommit_or_rollback(thd, 0);
|
thd->clear_error();
|
||||||
|
|
||||||
/*
|
|
||||||
Now what if this is not a transactional engine? we still need to
|
|
||||||
flush the pending event to the binlog; we did it with
|
|
||||||
thd->binlog_flush_pending_rows_event(). Note that we imitate
|
|
||||||
what is done for real queries: a call to
|
|
||||||
ha_autocommit_or_rollback() (sometimes only if involves a
|
|
||||||
transactional engine), and a call to be sure to have the pending
|
|
||||||
event flushed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
thd->reset_current_stmt_binlog_row_based();
|
|
||||||
rli->cleanup_context(thd, 0);
|
|
||||||
if (error == 0)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Indicate that a statement is finished.
|
|
||||||
Step the group log position if we are not in a transaction,
|
|
||||||
otherwise increase the event log position.
|
|
||||||
*/
|
|
||||||
rli->stmt_done(log_pos, when);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Clear any errors pushed in thd->net.client_last_err* if for
|
|
||||||
example "no key found" (as this is allowed). This is a safety
|
|
||||||
measure; apparently those errors (e.g. when executing a
|
|
||||||
Delete_rows_log_event_old of a non-existing row, like in
|
|
||||||
rpl_row_mystery22.test, thd->net.last_error = "Can't
|
|
||||||
find record in 't1'" and last_errno=1032) do not become
|
|
||||||
visible. We still prefer to wipe them out.
|
|
||||||
*/
|
|
||||||
thd->clear_error();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rli->report(ERROR_LEVEL, error,
|
|
||||||
"Error in %s event: commit of row events failed, "
|
|
||||||
"table `%s`.`%s`",
|
|
||||||
get_type_str(), m_table->s->db.str,
|
|
||||||
m_table->s->table_name.str);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2447,6 +2447,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
|||||||
table->tablenr= tablenr;
|
table->tablenr= tablenr;
|
||||||
table->map= (table_map) 1 << tablenr;
|
table->map= (table_map) 1 << tablenr;
|
||||||
table->force_index= table_list->force_index;
|
table->force_index= table_list->force_index;
|
||||||
|
table->force_index_order= table->force_index_group= 0;
|
||||||
table->covering_keys= table->s->keys_for_keyread;
|
table->covering_keys= table->s->keys_for_keyread;
|
||||||
table->merge_keys.clear_all();
|
table->merge_keys.clear_all();
|
||||||
}
|
}
|
||||||
|
@ -773,7 +773,6 @@ extern int wild_compare(const char *str,const char *wildstr,
|
|||||||
extern WF_PACK *wf_comp(char * str);
|
extern WF_PACK *wf_comp(char * str);
|
||||||
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
|
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
|
||||||
extern void wf_end(struct wild_file_pack *buffer);
|
extern void wf_end(struct wild_file_pack *buffer);
|
||||||
extern size_t strip_sp(char * str);
|
|
||||||
extern my_bool array_append_string_unique(const char *str,
|
extern my_bool array_append_string_unique(const char *str,
|
||||||
const char **array, size_t size);
|
const char **array, size_t size);
|
||||||
extern void get_date(char * to,int timeflag,time_t use_time);
|
extern void get_date(char * to,int timeflag,time_t use_time);
|
||||||
|
@ -5881,6 +5881,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
|
|||||||
if (type == Item_func::LT_FUNC && (value->val_int() > 0))
|
if (type == Item_func::LT_FUNC && (value->val_int() > 0))
|
||||||
type = Item_func::LE_FUNC;
|
type = Item_func::LE_FUNC;
|
||||||
else if (type == Item_func::GT_FUNC &&
|
else if (type == Item_func::GT_FUNC &&
|
||||||
|
(field->type() != FIELD_TYPE_BIT) &&
|
||||||
!((Field_num*)field)->unsigned_flag &&
|
!((Field_num*)field)->unsigned_flag &&
|
||||||
!((Item_int*)value)->unsigned_flag &&
|
!((Item_int*)value)->unsigned_flag &&
|
||||||
(value->val_int() < 0))
|
(value->val_int() < 0))
|
||||||
@ -5918,7 +5919,9 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
|
|||||||
*/
|
*/
|
||||||
if (field->result_type() == INT_RESULT &&
|
if (field->result_type() == INT_RESULT &&
|
||||||
value->result_type() == INT_RESULT &&
|
value->result_type() == INT_RESULT &&
|
||||||
((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
|
((field->type() == FIELD_TYPE_BIT ||
|
||||||
|
((Field_num *) field)->unsigned_flag) &&
|
||||||
|
!((Item_int*) value)->unsigned_flag))
|
||||||
{
|
{
|
||||||
longlong item_val= value->val_int();
|
longlong item_val= value->val_int();
|
||||||
if (item_val < 0)
|
if (item_val < 0)
|
||||||
@ -6514,6 +6517,63 @@ get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Combine two range expression under a common OR. On a logical level, the
|
||||||
|
transformation is key_or( expr1, expr2 ) => expr1 OR expr2.
|
||||||
|
|
||||||
|
Both expressions are assumed to be in the SEL_ARG format. In a logic sense,
|
||||||
|
theformat is reminiscent of DNF, since an expression such as the following
|
||||||
|
|
||||||
|
( 1 < kp1 < 10 AND p1 ) OR ( 10 <= kp2 < 20 AND p2 )
|
||||||
|
|
||||||
|
where there is a key consisting of keyparts ( kp1, kp2, ..., kpn ) and p1
|
||||||
|
and p2 are valid SEL_ARG expressions over keyparts kp2 ... kpn, is a valid
|
||||||
|
SEL_ARG condition. The disjuncts appear ordered by the minimum endpoint of
|
||||||
|
the first range and ranges must not overlap. It follows that they are also
|
||||||
|
ordered by maximum endpoints. Thus
|
||||||
|
|
||||||
|
( 1 < kp1 <= 2 AND ( kp2 = 2 OR kp2 = 3 ) ) OR kp1 = 3
|
||||||
|
|
||||||
|
Is a a valid SER_ARG expression for a key of at least 2 keyparts.
|
||||||
|
|
||||||
|
For simplicity, we will assume that expr2 is a single range predicate,
|
||||||
|
i.e. on the form ( a < x < b AND ... ). It is easy to generalize to a
|
||||||
|
disjunction of several predicates by subsequently call key_or for each
|
||||||
|
disjunct.
|
||||||
|
|
||||||
|
The algorithm iterates over each disjunct of expr1, and for each disjunct
|
||||||
|
where the first keypart's range overlaps with the first keypart's range in
|
||||||
|
expr2:
|
||||||
|
|
||||||
|
If the predicates are equal for the rest of the keyparts, or if there are
|
||||||
|
no more, the range in expr2 has its endpoints copied in, and the SEL_ARG
|
||||||
|
node in expr2 is deallocated. If more ranges became connected in expr1, the
|
||||||
|
surplus is also dealocated. If they differ, two ranges are created.
|
||||||
|
|
||||||
|
- The range leading up to the overlap. Empty if endpoints are equal.
|
||||||
|
|
||||||
|
- The overlapping sub-range. May be the entire range if they are equal.
|
||||||
|
|
||||||
|
Finally, there may be one more range if expr2's first keypart's range has a
|
||||||
|
greater maximum endpoint than the last range in expr1.
|
||||||
|
|
||||||
|
For the overlapping sub-range, we recursively call key_or. Thus in order to
|
||||||
|
compute key_or of
|
||||||
|
|
||||||
|
(1) ( 1 < kp1 < 10 AND 1 < kp2 < 10 )
|
||||||
|
|
||||||
|
(2) ( 2 < kp1 < 20 AND 4 < kp2 < 20 )
|
||||||
|
|
||||||
|
We create the ranges 1 < kp <= 2, 2 < kp1 < 10, 10 <= kp1 < 20. For the
|
||||||
|
first one, we simply hook on the condition for the second keypart from (1)
|
||||||
|
: 1 < kp2 < 10. For the second range 2 < kp1 < 10, key_or( 1 < kp2 < 10, 4
|
||||||
|
< kp2 < 20 ) is called, yielding 1 < kp2 < 20. For the last range, we reuse
|
||||||
|
the range 4 < kp2 < 20 from (2) for the second keypart. The result is thus
|
||||||
|
|
||||||
|
( 1 < kp1 <= 2 AND 1 < kp2 < 10 ) OR
|
||||||
|
( 2 < kp1 < 10 AND 1 < kp2 < 20 ) OR
|
||||||
|
( 10 <= kp1 < 20 AND 4 < kp2 < 20 )
|
||||||
|
*/
|
||||||
static SEL_ARG *
|
static SEL_ARG *
|
||||||
key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
||||||
{
|
{
|
||||||
@ -6665,7 +6725,21 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
|||||||
key1=key1->tree_delete(save);
|
key1=key1->tree_delete(save);
|
||||||
}
|
}
|
||||||
last->copy_min(tmp);
|
last->copy_min(tmp);
|
||||||
if (last->copy_min(key2) || last->copy_max(key2))
|
bool full_range= last->copy_min(key2);
|
||||||
|
if (!full_range)
|
||||||
|
{
|
||||||
|
if (last->next && key2->cmp_max_to_min(last->next) >= 0)
|
||||||
|
{
|
||||||
|
last->max_value= last->next->min_value;
|
||||||
|
if (last->next->min_flag & NEAR_MIN)
|
||||||
|
last->max_flag&= ~NEAR_MAX;
|
||||||
|
else
|
||||||
|
last->max_flag|= NEAR_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
full_range= last->copy_max(key2);
|
||||||
|
}
|
||||||
|
if (full_range)
|
||||||
{ // Full range
|
{ // Full range
|
||||||
key1->free_tree();
|
key1->free_tree();
|
||||||
for (; key2 ; key2=key2->next)
|
for (; key2 ; key2=key2->next)
|
||||||
@ -6675,8 +6749,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key2=key2->next;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
|
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
|
||||||
|
@ -97,7 +97,8 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
|
|||||||
|
|
||||||
@note
|
@note
|
||||||
This function is only called for queries with sum functions and no
|
This function is only called for queries with sum functions and no
|
||||||
GROUP BY part.
|
GROUP BY part. This means that the result set shall contain a single
|
||||||
|
row only
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
0 no errors
|
0 no errors
|
||||||
|
61
sql/slave.cc
61
sql/slave.cc
@ -2083,8 +2083,7 @@ static int has_temporary_error(THD *thd)
|
|||||||
@retval 2 No error calling ev->apply_event(), but error calling
|
@retval 2 No error calling ev->apply_event(), but error calling
|
||||||
ev->update_pos().
|
ev->update_pos().
|
||||||
*/
|
*/
|
||||||
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
|
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
|
||||||
bool skip)
|
|
||||||
{
|
{
|
||||||
int exec_res= 0;
|
int exec_res= 0;
|
||||||
|
|
||||||
@ -2129,38 +2128,34 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
|
|||||||
ev->when= my_time(0);
|
ev->when= my_time(0);
|
||||||
ev->thd = thd; // because up to this point, ev->thd == 0
|
ev->thd = thd; // because up to this point, ev->thd == 0
|
||||||
|
|
||||||
if (skip)
|
int reason= ev->shall_skip(rli);
|
||||||
{
|
if (reason == Log_event::EVENT_SKIP_COUNT)
|
||||||
int reason= ev->shall_skip(rli);
|
--rli->slave_skip_counter;
|
||||||
if (reason == Log_event::EVENT_SKIP_COUNT)
|
pthread_mutex_unlock(&rli->data_lock);
|
||||||
--rli->slave_skip_counter;
|
if (reason == Log_event::EVENT_SKIP_NOT)
|
||||||
pthread_mutex_unlock(&rli->data_lock);
|
|
||||||
if (reason == Log_event::EVENT_SKIP_NOT)
|
|
||||||
exec_res= ev->apply_event(rli);
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
/*
|
|
||||||
This only prints information to the debug trace.
|
|
||||||
|
|
||||||
TODO: Print an informational message to the error log?
|
|
||||||
*/
|
|
||||||
static const char *const explain[] = {
|
|
||||||
// EVENT_SKIP_NOT,
|
|
||||||
"not skipped",
|
|
||||||
// EVENT_SKIP_IGNORE,
|
|
||||||
"skipped because event should be ignored",
|
|
||||||
// EVENT_SKIP_COUNT
|
|
||||||
"skipped because event skip counter was non-zero"
|
|
||||||
};
|
|
||||||
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
|
|
||||||
thd->options & OPTION_BEGIN ? 1 : 0,
|
|
||||||
rli->get_flag(Relay_log_info::IN_STMT)));
|
|
||||||
DBUG_PRINT("skip_event", ("%s event was %s",
|
|
||||||
ev->get_type_str(), explain[reason]));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
exec_res= ev->apply_event(rli);
|
exec_res= ev->apply_event(rli);
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
/*
|
||||||
|
This only prints information to the debug trace.
|
||||||
|
|
||||||
|
TODO: Print an informational message to the error log?
|
||||||
|
*/
|
||||||
|
static const char *const explain[] = {
|
||||||
|
// EVENT_SKIP_NOT,
|
||||||
|
"not skipped",
|
||||||
|
// EVENT_SKIP_IGNORE,
|
||||||
|
"skipped because event should be ignored",
|
||||||
|
// EVENT_SKIP_COUNT
|
||||||
|
"skipped because event skip counter was non-zero"
|
||||||
|
};
|
||||||
|
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
|
||||||
|
thd->options & OPTION_BEGIN ? 1 : 0,
|
||||||
|
rli->get_flag(Relay_log_info::IN_STMT)));
|
||||||
|
DBUG_PRINT("skip_event", ("%s event was %s",
|
||||||
|
ev->get_type_str(), explain[reason]));
|
||||||
|
#endif
|
||||||
|
|
||||||
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
|
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
|
||||||
if (exec_res == 0)
|
if (exec_res == 0)
|
||||||
{
|
{
|
||||||
@ -2279,7 +2274,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
|
|||||||
delete ev;
|
delete ev;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
exec_res= apply_event_and_update_pos(ev, thd, rli, TRUE);
|
exec_res= apply_event_and_update_pos(ev, thd, rli);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Format_description_log_event should not be deleted because it will be
|
Format_description_log_event should not be deleted because it will be
|
||||||
|
@ -190,8 +190,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
|
|||||||
void set_slave_thread_options(THD* thd);
|
void set_slave_thread_options(THD* thd);
|
||||||
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
|
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
|
||||||
void rotate_relay_log(Master_info* mi);
|
void rotate_relay_log(Master_info* mi);
|
||||||
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
|
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
|
||||||
bool skip);
|
|
||||||
|
|
||||||
pthread_handler_t handle_slave_io(void *arg);
|
pthread_handler_t handle_slave_io(void *arg);
|
||||||
pthread_handler_t handle_slave_sql(void *arg);
|
pthread_handler_t handle_slave_sql(void *arg);
|
||||||
|
@ -2311,7 +2311,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
|
|||||||
table->tablenr=thd->current_tablenr++;
|
table->tablenr=thd->current_tablenr++;
|
||||||
table->used_fields=0;
|
table->used_fields=0;
|
||||||
table->const_table=0;
|
table->const_table=0;
|
||||||
table->null_row= table->maybe_null= table->force_index= 0;
|
table->null_row= table->maybe_null= 0;
|
||||||
|
table->force_index= table->force_index_order= table->force_index_group= 0;
|
||||||
table->status=STATUS_NO_RECORD;
|
table->status=STATUS_NO_RECORD;
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
@ -2969,7 +2970,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
table->tablenr=thd->current_tablenr++;
|
table->tablenr=thd->current_tablenr++;
|
||||||
table->used_fields=0;
|
table->used_fields=0;
|
||||||
table->const_table=0;
|
table->const_table=0;
|
||||||
table->null_row= table->maybe_null= table->force_index= 0;
|
table->null_row= table->maybe_null= 0;
|
||||||
|
table->force_index= table->force_index_order= table->force_index_group= 0;
|
||||||
table->status=STATUS_NO_RECORD;
|
table->status=STATUS_NO_RECORD;
|
||||||
table->insert_values= 0;
|
table->insert_values= 0;
|
||||||
table->fulltext_searched= 0;
|
table->fulltext_searched= 0;
|
||||||
|
@ -56,17 +56,20 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
Format_description_event.
|
Format_description_event.
|
||||||
*/
|
*/
|
||||||
my_bool have_fd_event= TRUE;
|
my_bool have_fd_event= TRUE;
|
||||||
if (!thd->rli_fake)
|
int err;
|
||||||
|
Relay_log_info *rli;
|
||||||
|
rli= thd->rli_fake;
|
||||||
|
if (!rli)
|
||||||
{
|
{
|
||||||
thd->rli_fake= new Relay_log_info;
|
rli= thd->rli_fake= new Relay_log_info;
|
||||||
#ifdef HAVE_purify
|
#ifdef HAVE_purify
|
||||||
thd->rli_fake->is_fake= TRUE;
|
rli->is_fake= TRUE;
|
||||||
#endif
|
#endif
|
||||||
have_fd_event= FALSE;
|
have_fd_event= FALSE;
|
||||||
}
|
}
|
||||||
if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
|
if (rli && !rli->relay_log.description_event_for_exec)
|
||||||
{
|
{
|
||||||
thd->rli_fake->relay_log.description_event_for_exec=
|
rli->relay_log.description_event_for_exec=
|
||||||
new Format_description_log_event(4);
|
new Format_description_log_event(4);
|
||||||
have_fd_event= FALSE;
|
have_fd_event= FALSE;
|
||||||
}
|
}
|
||||||
@ -78,16 +81,16 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
/*
|
/*
|
||||||
Out of memory check
|
Out of memory check
|
||||||
*/
|
*/
|
||||||
if (!(thd->rli_fake &&
|
if (!(rli &&
|
||||||
thd->rli_fake->relay_log.description_event_for_exec &&
|
rli->relay_log.description_event_for_exec &&
|
||||||
buf))
|
buf))
|
||||||
{
|
{
|
||||||
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
|
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->rli_fake->sql_thd= thd;
|
rli->sql_thd= thd;
|
||||||
thd->rli_fake->no_storage= TRUE;
|
rli->no_storage= TRUE;
|
||||||
|
|
||||||
for (char const *strptr= thd->lex->comment.str ;
|
for (char const *strptr= thd->lex->comment.str ;
|
||||||
strptr < thd->lex->comment.str + thd->lex->comment.length ; )
|
strptr < thd->lex->comment.str + thd->lex->comment.length ; )
|
||||||
@ -170,8 +173,7 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ev= Log_event::read_log_event(bufptr, event_len, &error,
|
ev= Log_event::read_log_event(bufptr, event_len, &error,
|
||||||
thd->rli_fake->relay_log.
|
rli->relay_log.description_event_for_exec);
|
||||||
description_event_for_exec);
|
|
||||||
|
|
||||||
DBUG_PRINT("info",("binlog base64 err=%s", error));
|
DBUG_PRINT("info",("binlog base64 err=%s", error));
|
||||||
if (!ev)
|
if (!ev)
|
||||||
@ -209,18 +211,10 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
reporting.
|
reporting.
|
||||||
*/
|
*/
|
||||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||||
if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE))
|
err= ev->apply_event(rli);
|
||||||
{
|
#else
|
||||||
delete ev;
|
err= 0;
|
||||||
/*
|
|
||||||
TODO: Maybe a better error message since the BINLOG statement
|
|
||||||
now contains several events.
|
|
||||||
*/
|
|
||||||
my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Format_description_log_event should not be deleted because it
|
Format_description_log_event should not be deleted because it
|
||||||
will be used to read info about the relay log's format; it
|
will be used to read info about the relay log's format; it
|
||||||
@ -228,8 +222,17 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
i.e. when this thread terminates.
|
i.e. when this thread terminates.
|
||||||
*/
|
*/
|
||||||
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
|
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
|
||||||
delete ev;
|
delete ev;
|
||||||
ev= 0;
|
ev= 0;
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO: Maybe a better error message since the BINLOG statement
|
||||||
|
now contains several events.
|
||||||
|
*/
|
||||||
|
my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
thd->rli_fake->clear_tables_to_lock();
|
rli->clear_tables_to_lock();
|
||||||
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -2649,7 +2649,32 @@ public:
|
|||||||
MI_COLUMNDEF *recinfo,*start_recinfo;
|
MI_COLUMNDEF *recinfo,*start_recinfo;
|
||||||
KEY *keyinfo;
|
KEY *keyinfo;
|
||||||
ha_rows end_write_records;
|
ha_rows end_write_records;
|
||||||
uint field_count,sum_func_count,func_count;
|
/**
|
||||||
|
Number of normal fields in the query, including those referred to
|
||||||
|
from aggregate functions. Hence, "SELECT `field1`,
|
||||||
|
SUM(`field2`) from t1" sets this counter to 2.
|
||||||
|
|
||||||
|
@see count_field_types
|
||||||
|
*/
|
||||||
|
uint field_count;
|
||||||
|
/**
|
||||||
|
Number of fields in the query that have functions. Includes both
|
||||||
|
aggregate functions (e.g., SUM) and non-aggregates (e.g., RAND).
|
||||||
|
Also counts functions referred to from aggregate functions, i.e.,
|
||||||
|
"SELECT SUM(RAND())" sets this counter to 2.
|
||||||
|
|
||||||
|
@see count_field_types
|
||||||
|
*/
|
||||||
|
uint func_count;
|
||||||
|
/**
|
||||||
|
Number of fields in the query that have aggregate functions. Note
|
||||||
|
that the optimizer may choose to optimize away these fields by
|
||||||
|
replacing them with constants, in which case sum_func_count will
|
||||||
|
need to be updated.
|
||||||
|
|
||||||
|
@see opt_sum_query, count_field_types
|
||||||
|
*/
|
||||||
|
uint sum_func_count;
|
||||||
uint hidden_field_count;
|
uint hidden_field_count;
|
||||||
uint group_parts,group_length,group_null_parts;
|
uint group_parts,group_length,group_null_parts;
|
||||||
uint quick_group;
|
uint quick_group;
|
||||||
|
@ -6335,6 +6335,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
ptr->table_name_length=table->table.length;
|
ptr->table_name_length=table->table.length;
|
||||||
ptr->lock_type= lock_type;
|
ptr->lock_type= lock_type;
|
||||||
ptr->updating= test(table_options & TL_OPTION_UPDATING);
|
ptr->updating= test(table_options & TL_OPTION_UPDATING);
|
||||||
|
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
|
||||||
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
|
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
|
||||||
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
|
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
|
||||||
ptr->derived= table->sel;
|
ptr->derived= table->sel;
|
||||||
|
@ -648,8 +648,11 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
this->group= group_list != 0;
|
this->group= group_list != 0;
|
||||||
unit= unit_arg;
|
unit= unit_arg;
|
||||||
|
|
||||||
|
if (tmp_table_param.sum_func_count && !group_list)
|
||||||
|
implicit_grouping= TRUE;
|
||||||
|
|
||||||
#ifdef RESTRICTED_GROUP
|
#ifdef RESTRICTED_GROUP
|
||||||
if (sum_func_count && !group_list && (func_count || field_count))
|
if (implicit_grouping)
|
||||||
{
|
{
|
||||||
my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
|
my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
|
||||||
goto err;
|
goto err;
|
||||||
@ -885,15 +888,23 @@ JOIN::optimize()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Optimize count(*), min() and max() */
|
/*
|
||||||
if (tables_list && tmp_table_param.sum_func_count && ! group_list)
|
Try to optimize count(*), min() and max() to const fields if
|
||||||
|
there is implicit grouping (aggregate functions but no
|
||||||
|
group_list). In this case, the result set shall only contain one
|
||||||
|
row.
|
||||||
|
*/
|
||||||
|
if (tables_list && implicit_grouping)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
/*
|
/*
|
||||||
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
|
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
|
||||||
to the WHERE conditions,
|
to the WHERE conditions,
|
||||||
or 1 if all items were resolved,
|
or 1 if all items were resolved (optimized away),
|
||||||
or 0, or an error number HA_ERR_...
|
or 0, or an error number HA_ERR_...
|
||||||
|
|
||||||
|
If all items were resolved by opt_sum_query, there is no need to
|
||||||
|
open any tables.
|
||||||
*/
|
*/
|
||||||
if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
|
if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
|
||||||
{
|
{
|
||||||
@ -1239,13 +1250,22 @@ JOIN::optimize()
|
|||||||
sort_and_group= 0;
|
sort_and_group= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't use sort on head table if using row cache
|
// Can't use sort on head table if using join buffering
|
||||||
if (full_join)
|
if (full_join)
|
||||||
{
|
{
|
||||||
if (group_list)
|
TABLE *stable= (sort_by_table == (TABLE *) 1 ?
|
||||||
simple_group=0;
|
join_tab[const_tables].table : sort_by_table);
|
||||||
if (order)
|
/*
|
||||||
simple_order=0;
|
FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
|
||||||
|
sorting on the first table.
|
||||||
|
*/
|
||||||
|
if (!stable || !stable->force_index_order)
|
||||||
|
{
|
||||||
|
if (group_list)
|
||||||
|
simple_group= 0;
|
||||||
|
if (order)
|
||||||
|
simple_order= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2035,7 +2055,8 @@ JOIN::exec()
|
|||||||
count_field_types(select_lex, &curr_join->tmp_table_param,
|
count_field_types(select_lex, &curr_join->tmp_table_param,
|
||||||
*curr_all_fields, 0);
|
*curr_all_fields, 0);
|
||||||
|
|
||||||
if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
|
if (curr_join->group || curr_join->implicit_grouping ||
|
||||||
|
curr_join->tmp_table_param.sum_func_count ||
|
||||||
(procedure && (procedure->flags & PROC_GROUP)))
|
(procedure && (procedure->flags & PROC_GROUP)))
|
||||||
{
|
{
|
||||||
if (make_group_fields(this, curr_join))
|
if (make_group_fields(this, curr_join))
|
||||||
@ -10905,6 +10926,12 @@ Next_select_func setup_end_select_func(JOIN *join)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Choose method for presenting result to user. Use end_send_group
|
||||||
|
if the query requires grouping (has a GROUP BY clause and/or one or
|
||||||
|
more aggregate functions). Use end_send if the query should not
|
||||||
|
be grouped.
|
||||||
|
*/
|
||||||
if ((join->sort_and_group ||
|
if ((join->sort_and_group ||
|
||||||
(join->procedure && join->procedure->flags & PROC_GROUP)) &&
|
(join->procedure && join->procedure->flags & PROC_GROUP)) &&
|
||||||
!tmp_tbl->precomputed_group_by)
|
!tmp_tbl->precomputed_group_by)
|
||||||
|
@ -283,7 +283,14 @@ public:
|
|||||||
TABLE **table,**all_tables,*sort_by_table;
|
TABLE **table,**all_tables,*sort_by_table;
|
||||||
uint tables,const_tables;
|
uint tables,const_tables;
|
||||||
uint send_group_parts;
|
uint send_group_parts;
|
||||||
bool sort_and_group,first_record,full_join,group, no_field_update;
|
/**
|
||||||
|
Indicates that grouping will be performed on the result set during
|
||||||
|
query execution. This field belongs to query execution.
|
||||||
|
|
||||||
|
@see make_group_fields, alloc_group_fields, JOIN::exec
|
||||||
|
*/
|
||||||
|
bool sort_and_group;
|
||||||
|
bool first_record,full_join,group, no_field_update;
|
||||||
bool do_send_rows;
|
bool do_send_rows;
|
||||||
/**
|
/**
|
||||||
TRUE when we want to resume nested loop iterations when
|
TRUE when we want to resume nested loop iterations when
|
||||||
@ -362,6 +369,8 @@ public:
|
|||||||
simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
|
simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
|
||||||
to other tables than the first non-constant table in the JOIN.
|
to other tables than the first non-constant table in the JOIN.
|
||||||
It's also set if ORDER/GROUP BY is empty.
|
It's also set if ORDER/GROUP BY is empty.
|
||||||
|
Used for deciding for or against using a temporary table to compute
|
||||||
|
GROUP/ORDER BY.
|
||||||
*/
|
*/
|
||||||
bool simple_order, simple_group;
|
bool simple_order, simple_group;
|
||||||
/**
|
/**
|
||||||
@ -431,6 +440,7 @@ public:
|
|||||||
tables= 0;
|
tables= 0;
|
||||||
const_tables= 0;
|
const_tables= 0;
|
||||||
join_list= 0;
|
join_list= 0;
|
||||||
|
implicit_grouping= FALSE;
|
||||||
sort_and_group= 0;
|
sort_and_group= 0;
|
||||||
first_record= 0;
|
first_record= 0;
|
||||||
do_send_rows= 1;
|
do_send_rows= 1;
|
||||||
@ -536,6 +546,11 @@ public:
|
|||||||
select_lex == unit->fake_select_lex));
|
select_lex == unit->fake_select_lex));
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
TRUE if the query contains an aggregate function but has no GROUP
|
||||||
|
BY clause.
|
||||||
|
*/
|
||||||
|
bool implicit_grouping;
|
||||||
bool make_simple_join(JOIN *join, TABLE *tmp_table);
|
bool make_simple_join(JOIN *join, TABLE *tmp_table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
25
sql/table.cc
25
sql/table.cc
@ -4638,7 +4638,8 @@ Item_subselect *TABLE_LIST::containing_subselect()
|
|||||||
(TABLE_LIST::index_hints). Using the information in this tagged list
|
(TABLE_LIST::index_hints). Using the information in this tagged list
|
||||||
this function sets the members st_table::keys_in_use_for_query,
|
this function sets the members st_table::keys_in_use_for_query,
|
||||||
st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
|
st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
|
||||||
st_table::force_index and st_table::covering_keys.
|
st_table::force_index, st_table::force_index_order,
|
||||||
|
st_table::force_index_group and st_table::covering_keys.
|
||||||
|
|
||||||
Current implementation of the runtime does not allow mixing FORCE INDEX
|
Current implementation of the runtime does not allow mixing FORCE INDEX
|
||||||
and USE INDEX, so this is checked here. Then the FORCE INDEX list
|
and USE INDEX, so this is checked here. Then the FORCE INDEX list
|
||||||
@ -4766,14 +4767,28 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* process FORCE INDEX as USE INDEX with a flag */
|
/* process FORCE INDEX as USE INDEX with a flag */
|
||||||
|
if (!index_order[INDEX_HINT_FORCE].is_clear_all())
|
||||||
|
{
|
||||||
|
tbl->force_index_order= TRUE;
|
||||||
|
index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!index_group[INDEX_HINT_FORCE].is_clear_all())
|
||||||
|
{
|
||||||
|
tbl->force_index_group= TRUE;
|
||||||
|
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and
|
||||||
|
create tbl->force_index_join instead.
|
||||||
|
Then use the correct force_index_XX instead of the global one.
|
||||||
|
*/
|
||||||
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
|
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
|
||||||
!index_order[INDEX_HINT_FORCE].is_clear_all() ||
|
tbl->force_index_group || tbl->force_index_order)
|
||||||
!index_group[INDEX_HINT_FORCE].is_clear_all())
|
|
||||||
{
|
{
|
||||||
tbl->force_index= TRUE;
|
tbl->force_index= TRUE;
|
||||||
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
|
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
|
||||||
index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
|
|
||||||
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply USE INDEX */
|
/* apply USE INDEX */
|
||||||
|
12
sql/table.h
12
sql/table.h
@ -752,6 +752,18 @@ struct st_table {
|
|||||||
bytes, it would take up 4.
|
bytes, it would take up 4.
|
||||||
*/
|
*/
|
||||||
my_bool force_index;
|
my_bool force_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flag set when the statement contains FORCE INDEX FOR ORDER BY
|
||||||
|
See TABLE_LIST::process_index_hints().
|
||||||
|
*/
|
||||||
|
my_bool force_index_order;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flag set when the statement contains FORCE INDEX FOR GROUP BY
|
||||||
|
See TABLE_LIST::process_index_hints().
|
||||||
|
*/
|
||||||
|
my_bool force_index_group;
|
||||||
my_bool distinct,const_table,no_rows;
|
my_bool distinct,const_table,no_rows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,8 +16,21 @@
|
|||||||
# This is the CMakeLists for InnoDB Plugin
|
# This is the CMakeLists for InnoDB Plugin
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: remove the two FLAGS_DEBUG settings when merging into
|
||||||
|
# 6.0-based trees, like is already the case for other engines in
|
||||||
|
# those trees.
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||||
|
|
||||||
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
|
# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
|
||||||
|
# CMakeLists.txt still needs to work with previous versions of MySQL.
|
||||||
|
IF (MYSQL_VERSION_ID GREATER "50137")
|
||||||
|
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
|
||||||
|
ENDIF (MYSQL_VERSION_ID GREATER "50137")
|
||||||
|
|
||||||
|
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||||
|
SET(WIN64 TRUE)
|
||||||
|
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||||
|
|
||||||
# Include directories under innobase
|
# Include directories under innobase
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
|
||||||
@ -32,10 +45,10 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
|||||||
|
|
||||||
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
|
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
|
||||||
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
|
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
|
||||||
IF(MSVC AND CMAKE_SIZEOF_VOID_P MATCHES 8)
|
IF (MSVC AND $(WIN64))
|
||||||
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
|
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
|
||||||
PROPERTIES COMPILE_FLAGS -Od)
|
PROPERTIES COMPILE_FLAGS -Od)
|
||||||
ENDIF(MSVC AND CMAKE_SIZEOF_VOID_P MATCHES 8)
|
ENDIF (MSVC AND $(WIN64))
|
||||||
|
|
||||||
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||||
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
|
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
|
||||||
@ -70,5 +83,5 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
|||||||
usr/usr0sess.c
|
usr/usr0sess.c
|
||||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
|
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
|
||||||
ut/ut0list.c ut/ut0wqueue.c)
|
ut/ut0list.c ut/ut0wqueue.c)
|
||||||
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
|
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
|
||||||
MYSQL_STORAGE_ENGINE(INNOBASE)
|
MYSQL_STORAGE_ENGINE(INNOBASE)
|
||||||
|
@ -1,3 +1,149 @@
|
|||||||
|
2009-10-01 The InnoDB Team
|
||||||
|
|
||||||
|
* fsp/fsp0fsp.c, row/row0merge.c:
|
||||||
|
Clean up after a crash during DROP INDEX. When InnoDB crashes
|
||||||
|
while dropping an index, ensure that the index will be completely
|
||||||
|
dropped during crash recovery. The MySQL .frm file may still
|
||||||
|
contain the dropped index, but there is little that we can do
|
||||||
|
about it.
|
||||||
|
|
||||||
|
2009-09-28 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc:
|
||||||
|
When a secondary index exists in the MySQL .frm file but not in
|
||||||
|
the InnoDB data dictionary, return an error instead of letting an
|
||||||
|
assertion fail in index_read.
|
||||||
|
|
||||||
|
2009-09-28 The InnoDB Team
|
||||||
|
|
||||||
|
* btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
|
||||||
|
include/page0zip.h, page/page0cur.c, page/page0page.c,
|
||||||
|
page/page0zip.c:
|
||||||
|
Do not write to PAGE_INDEX_ID when restoring an uncompressed page
|
||||||
|
after a compression failure. The field should only be written
|
||||||
|
when creating a B-tree page. This fix addresses a race condition
|
||||||
|
in a debug assertion.
|
||||||
|
|
||||||
|
2009-09-28 The InnoDB Team
|
||||||
|
|
||||||
|
* fil/fil0fil.c:
|
||||||
|
Try to prevent the reuse of tablespace identifiers after InnoDB
|
||||||
|
has crashed during table creation. Also, refuse to start if files
|
||||||
|
with duplicate tablespace identifiers are encountered.
|
||||||
|
|
||||||
|
2009-09-25 The InnoDB Team
|
||||||
|
|
||||||
|
* include/os0file.h, os/os0file.c:
|
||||||
|
Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
|
||||||
|
1453 (0x5AD) for InnoDB backend
|
||||||
|
|
||||||
|
2009-09-19 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
|
||||||
|
mysql-test/innodb-consistent.result,
|
||||||
|
mysql-test/innodb-consistent.test:
|
||||||
|
Fix Bug#37232 Innodb might get too many read locks for DML with
|
||||||
|
repeatable-read
|
||||||
|
|
||||||
|
2009-09-19 The InnoDB Team
|
||||||
|
|
||||||
|
* fsp/fsp0fsp.c:
|
||||||
|
Fix Bug#31183 Tablespace full problems not reported in error log,
|
||||||
|
error message unclear
|
||||||
|
|
||||||
|
2009-09-17 The InnoDB Team
|
||||||
|
|
||||||
|
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
|
||||||
|
Make the test pass with zlib 1.2.3.3. Apparently, the definition
|
||||||
|
of compressBound() has changed between zlib versions, and the
|
||||||
|
maximum record size of a table with 1K compressed page size has
|
||||||
|
been reduced by one byte. This is an arbitrary test. In practical
|
||||||
|
applications, for good write performance, the compressed page size
|
||||||
|
should be chosen to be bigger than the absolute minimum.
|
||||||
|
|
||||||
|
2009-09-16 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc:
|
||||||
|
Fix Bug#46256 drop table with unknown collation crashes innodb
|
||||||
|
|
||||||
|
2009-09-16 The InnoDB Team
|
||||||
|
|
||||||
|
* dict/dict0dict.c, handler/ha_innodb.cc,
|
||||||
|
mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
|
||||||
|
row/row0mysql.c:
|
||||||
|
Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
|
||||||
|
names
|
||||||
|
|
||||||
|
2009-09-16 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc, include/db0err.h,
|
||||||
|
mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
|
||||||
|
Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
|
||||||
|
|
||||||
|
2009-09-02 The InnoDB Team
|
||||||
|
|
||||||
|
* include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
|
||||||
|
row/row0mysql.c:
|
||||||
|
Fix a regression introduced by the fix for MySQL bug#26316. We check
|
||||||
|
whether a transaction holds any AUTOINC locks before we acquire
|
||||||
|
the kernel mutex and release those locks.
|
||||||
|
|
||||||
|
2009-08-27 The InnoDB Team
|
||||||
|
|
||||||
|
* dict/dict0dict.c, include/dict0dict.h,
|
||||||
|
mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
|
||||||
|
Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
|
||||||
|
|
||||||
|
2009-08-27 The InnoDB Team
|
||||||
|
|
||||||
|
* row/row0merge.c:
|
||||||
|
Fix a bug in the merge sort that can corrupt indexes in fast index
|
||||||
|
creation. Add some consistency checks. Check that the number of
|
||||||
|
records remains constant in every merge sort pass.
|
||||||
|
|
||||||
|
2009-08-27 The InnoDB Team
|
||||||
|
|
||||||
|
* buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
|
||||||
|
include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
|
||||||
|
include/ut0ut.h, ut/ut0ut.c:
|
||||||
|
Make it possible to tune the buffer pool LRU eviction policy to be
|
||||||
|
more resistant against index scans. Introduce the settable global
|
||||||
|
variables innodb_old_blocks_pct and innodb_old_blocks_time for
|
||||||
|
controlling the buffer pool eviction policy. The parameter
|
||||||
|
innodb_old_blocks_pct (5..95) controls the desired amount of "old"
|
||||||
|
blocks in the LRU list. The default is 37, corresponding to the
|
||||||
|
old fixed ratio of 3/8. Each time a block is accessed, it will be
|
||||||
|
moved to the "new" blocks if its first access was at least
|
||||||
|
innodb_old_blocks_time milliseconds ago (default 0, meaning every
|
||||||
|
block). The idea is that in index scans, blocks will be accessed
|
||||||
|
a few times within innodb_old_blocks_time, and they will remain in
|
||||||
|
the "old" section of the LRU list. Thus, when innodb_old_blocks_time
|
||||||
|
is nonzero, blocks retrieved for one-time index scans will be more
|
||||||
|
likely candidates for eviction than blocks that are accessed in
|
||||||
|
random patterns.
|
||||||
|
|
||||||
|
2009-08-26 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc, os/os0file.c:
|
||||||
|
Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
|
||||||
|
thread wakeups
|
||||||
|
|
||||||
|
2009-08-20 The InnoDB Team
|
||||||
|
|
||||||
|
* lock/lock0lock.c:
|
||||||
|
Fix Bug#46650 Innodb assertion autoinc_lock == lock in
|
||||||
|
lock_table_remove_low on INSERT SELECT
|
||||||
|
|
||||||
|
2009-08-13 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/handler0alter.cc:
|
||||||
|
Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
|
||||||
|
(Valgrind)
|
||||||
|
|
||||||
|
2009-08-11 The InnoDB Team
|
||||||
|
|
||||||
|
InnoDB Plugin 1.0.4 released
|
||||||
|
|
||||||
2009-07-20 The InnoDB Team
|
2009-07-20 The InnoDB Team
|
||||||
|
|
||||||
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
|
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
|
||||||
|
@ -31,7 +31,6 @@ DEFS= @DEFS@
|
|||||||
|
|
||||||
noinst_HEADERS= \
|
noinst_HEADERS= \
|
||||||
handler/ha_innodb.h \
|
handler/ha_innodb.h \
|
||||||
handler/handler0vars.h \
|
|
||||||
handler/i_s.h \
|
handler/i_s.h \
|
||||||
include/btr0btr.h \
|
include/btr0btr.h \
|
||||||
include/btr0btr.ic \
|
include/btr0btr.ic \
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
This is the source of the InnoDB Plugin 1.0.4 for MySQL 5.1
|
|
||||||
===========================================================
|
|
||||||
|
|
||||||
Instructions for compiling the plugin:
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
1. Get the latest MySQL 5.1 sources from
|
|
||||||
http://dev.mysql.com/downloads/mysql/5.1.html#source
|
|
||||||
|
|
||||||
2. Replace the contents of the mysql-5.1.N/storage/innobase/ directory
|
|
||||||
with the contents of this directory.
|
|
||||||
|
|
||||||
3. Optional (only necessary if you are going to run tests from the
|
|
||||||
mysql-test suite): cd into the innobase directory and run ./setup.sh
|
|
||||||
|
|
||||||
4. Compile MySQL as usual.
|
|
||||||
|
|
||||||
5. Enjoy!
|
|
||||||
|
|
||||||
See the online documentation for more detailed instructions:
|
|
||||||
http://www.innodb.com/doc/innodb_plugin-1.0/innodb-plugin-installation.html
|
|
||||||
|
|
||||||
For more information about InnoDB visit
|
|
||||||
http://www.innodb.com
|
|
||||||
|
|
||||||
Please report any problems or issues with the plugin in the InnoDB Forums
|
|
||||||
http://forums.innodb.com/ or in the MySQL Bugs database http://bugs.mysql.com
|
|
||||||
|
|
||||||
Thank you for using the InnoDB plugin!
|
|
@ -797,7 +797,7 @@ btr_create(
|
|||||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new index page on the the allocated segment page */
|
/* Create a new index page on the allocated segment page */
|
||||||
page_zip = buf_block_get_page_zip(block);
|
page_zip = buf_block_get_page_zip(block);
|
||||||
|
|
||||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||||
@ -1011,7 +1011,26 @@ btr_page_reorganize_low(
|
|||||||
(!page_zip_compress(page_zip, page, index, NULL))) {
|
(!page_zip_compress(page_zip, page, index, NULL))) {
|
||||||
|
|
||||||
/* Restore the old page and exit. */
|
/* Restore the old page and exit. */
|
||||||
buf_frame_copy(page, temp_page);
|
|
||||||
|
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||||
|
/* Check that the bytes that we skip are identical. */
|
||||||
|
ut_a(!memcmp(page, temp_page, PAGE_HEADER));
|
||||||
|
ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
|
||||||
|
PAGE_HEADER + PAGE_N_RECS + temp_page,
|
||||||
|
PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
|
||||||
|
ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
|
||||||
|
UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
|
||||||
|
FIL_PAGE_DATA_END));
|
||||||
|
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||||
|
|
||||||
|
memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
|
||||||
|
PAGE_N_RECS - PAGE_N_DIR_SLOTS);
|
||||||
|
memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
|
||||||
|
UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
|
||||||
|
|
||||||
|
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||||
|
ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
|
||||||
|
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||||
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
@ -1902,7 +1921,7 @@ func_start:
|
|||||||
n_uniq, &heap);
|
n_uniq, &heap);
|
||||||
|
|
||||||
/* If the new record is less than the existing record
|
/* If the new record is less than the existing record
|
||||||
the the split in the middle will copy the existing
|
the split in the middle will copy the existing
|
||||||
record to the new node. */
|
record to the new node. */
|
||||||
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
|
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
|
||||||
split_rec = page_get_middle_rec(page);
|
split_rec = page_get_middle_rec(page);
|
||||||
|
@ -957,7 +957,7 @@ btr_search_guess_on_hash(
|
|||||||
/* Increment the page get statistics though we did not really
|
/* Increment the page get statistics though we did not really
|
||||||
fix the page: for user info only */
|
fix the page: for user info only */
|
||||||
|
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
|
||||||
|
@ -837,16 +837,35 @@ buf_chunk_not_freed(
|
|||||||
block = chunk->blocks;
|
block = chunk->blocks;
|
||||||
|
|
||||||
for (i = chunk->size; i--; block++) {
|
for (i = chunk->size; i--; block++) {
|
||||||
mutex_enter(&block->mutex);
|
ibool ready;
|
||||||
|
|
||||||
if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
|
|
||||||
&& !buf_flush_ready_for_replace(&block->page)) {
|
|
||||||
|
|
||||||
|
switch (buf_block_get_state(block)) {
|
||||||
|
case BUF_BLOCK_ZIP_FREE:
|
||||||
|
case BUF_BLOCK_ZIP_PAGE:
|
||||||
|
case BUF_BLOCK_ZIP_DIRTY:
|
||||||
|
/* The uncompressed buffer pool should never
|
||||||
|
contain compressed block descriptors. */
|
||||||
|
ut_error;
|
||||||
|
break;
|
||||||
|
case BUF_BLOCK_NOT_USED:
|
||||||
|
case BUF_BLOCK_READY_FOR_USE:
|
||||||
|
case BUF_BLOCK_MEMORY:
|
||||||
|
case BUF_BLOCK_REMOVE_HASH:
|
||||||
|
/* Skip blocks that are not being used for
|
||||||
|
file pages. */
|
||||||
|
break;
|
||||||
|
case BUF_BLOCK_FILE_PAGE:
|
||||||
|
mutex_enter(&block->mutex);
|
||||||
|
ready = buf_flush_ready_for_replace(&block->page);
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
return(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
if (!ready) {
|
||||||
|
|
||||||
|
return(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -966,8 +985,6 @@ buf_pool_init(void)
|
|||||||
buf_pool->no_flush[i] = os_event_create(NULL);
|
buf_pool->no_flush[i] = os_event_create(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_pool->ulint_clock = 1;
|
|
||||||
|
|
||||||
/* 3. Initialize LRU fields
|
/* 3. Initialize LRU fields
|
||||||
--------------------------- */
|
--------------------------- */
|
||||||
/* All fields are initialized by mem_zalloc(). */
|
/* All fields are initialized by mem_zalloc(). */
|
||||||
@ -1470,34 +1487,9 @@ buf_pool_resize(void)
|
|||||||
buf_pool_page_hash_rebuild();
|
buf_pool_page_hash_rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
Moves the block to the start of the LRU list if there is a danger
|
|
||||||
that the block would drift out of the buffer pool. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
buf_block_make_young(
|
|
||||||
/*=================*/
|
|
||||||
buf_page_t* bpage) /*!< in: block to make younger */
|
|
||||||
{
|
|
||||||
ut_ad(!buf_pool_mutex_own());
|
|
||||||
|
|
||||||
/* Note that we read freed_page_clock's without holding any mutex:
|
|
||||||
this is allowed since the result is used only in heuristics */
|
|
||||||
|
|
||||||
if (buf_page_peek_if_too_old(bpage)) {
|
|
||||||
|
|
||||||
buf_pool_mutex_enter();
|
|
||||||
/* There has been freeing activity in the LRU list:
|
|
||||||
best to move to the head of the LRU list */
|
|
||||||
|
|
||||||
buf_LRU_make_block_young(bpage);
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Moves a page to the start of the buffer pool LRU list. This high-level
|
Moves a page to the start of the buffer pool LRU list. This high-level
|
||||||
function can be used to prevent an important page from from slipping out of
|
function can be used to prevent an important page from slipping out of
|
||||||
the buffer pool. */
|
the buffer pool. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
@ -1514,6 +1506,36 @@ buf_page_make_young(
|
|||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************//**
|
||||||
|
Sets the time of the first access of a page and moves a page to the
|
||||||
|
start of the buffer pool LRU list if it is too old. This high-level
|
||||||
|
function can be used to prevent an important page from slipping
|
||||||
|
out of the buffer pool. */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
buf_page_set_accessed_make_young(
|
||||||
|
/*=============================*/
|
||||||
|
buf_page_t* bpage, /*!< in/out: buffer block of a
|
||||||
|
file page */
|
||||||
|
unsigned access_time) /*!< in: bpage->access_time
|
||||||
|
read under mutex protection,
|
||||||
|
or 0 if unknown */
|
||||||
|
{
|
||||||
|
ut_ad(!buf_pool_mutex_own());
|
||||||
|
ut_a(buf_page_in_file(bpage));
|
||||||
|
|
||||||
|
if (buf_page_peek_if_too_old(bpage)) {
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
buf_LRU_make_block_young(bpage);
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
} else if (!access_time) {
|
||||||
|
ulint time_ms = ut_time_ms();
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
buf_page_set_accessed(bpage, time_ms);
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Resets the check_index_page_at_flush field of a page if found in the buffer
|
Resets the check_index_page_at_flush field of a page if found in the buffer
|
||||||
pool. */
|
pool. */
|
||||||
@ -1645,11 +1667,12 @@ buf_page_get_zip(
|
|||||||
buf_page_t* bpage;
|
buf_page_t* bpage;
|
||||||
mutex_t* block_mutex;
|
mutex_t* block_mutex;
|
||||||
ibool must_read;
|
ibool must_read;
|
||||||
|
unsigned access_time;
|
||||||
|
|
||||||
#ifndef UNIV_LOG_DEBUG
|
#ifndef UNIV_LOG_DEBUG
|
||||||
ut_ad(!ibuf_inside());
|
ut_ad(!ibuf_inside());
|
||||||
#endif
|
#endif
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
buf_pool_mutex_enter();
|
buf_pool_mutex_enter();
|
||||||
@ -1712,14 +1735,13 @@ err_exit:
|
|||||||
|
|
||||||
got_block:
|
got_block:
|
||||||
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
|
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
|
||||||
|
access_time = buf_page_is_accessed(bpage);
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
|
|
||||||
buf_page_set_accessed(bpage, TRUE);
|
|
||||||
|
|
||||||
mutex_exit(block_mutex);
|
mutex_exit(block_mutex);
|
||||||
|
|
||||||
buf_block_make_young(bpage);
|
buf_page_set_accessed_make_young(bpage, access_time);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||||
ut_a(!bpage->file_page_was_freed);
|
ut_a(!bpage->file_page_was_freed);
|
||||||
@ -1812,7 +1834,7 @@ buf_zip_decompress(
|
|||||||
switch (fil_page_get_type(frame)) {
|
switch (fil_page_get_type(frame)) {
|
||||||
case FIL_PAGE_INDEX:
|
case FIL_PAGE_INDEX:
|
||||||
if (page_zip_decompress(&block->page.zip,
|
if (page_zip_decompress(&block->page.zip,
|
||||||
block->frame)) {
|
block->frame, TRUE)) {
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2000,7 +2022,7 @@ buf_page_get_gen(
|
|||||||
mtr_t* mtr) /*!< in: mini-transaction */
|
mtr_t* mtr) /*!< in: mini-transaction */
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
ibool accessed;
|
unsigned access_time;
|
||||||
ulint fix_type;
|
ulint fix_type;
|
||||||
ibool must_read;
|
ibool must_read;
|
||||||
|
|
||||||
@ -2016,7 +2038,7 @@ buf_page_get_gen(
|
|||||||
#ifndef UNIV_LOG_DEBUG
|
#ifndef UNIV_LOG_DEBUG
|
||||||
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
|
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
|
||||||
#endif
|
#endif
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
loop:
|
loop:
|
||||||
block = guess;
|
block = guess;
|
||||||
buf_pool_mutex_enter();
|
buf_pool_mutex_enter();
|
||||||
@ -2243,17 +2265,16 @@ wait_until_unfixed:
|
|||||||
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
|
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
|
||||||
|
|
||||||
buf_block_buf_fix_inc(block, file, line);
|
buf_block_buf_fix_inc(block, file, line);
|
||||||
buf_pool_mutex_exit();
|
|
||||||
|
|
||||||
/* Check if this is the first access to the page */
|
|
||||||
|
|
||||||
accessed = buf_page_is_accessed(&block->page);
|
|
||||||
|
|
||||||
buf_page_set_accessed(&block->page, TRUE);
|
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
|
|
||||||
buf_block_make_young(&block->page);
|
/* Check if this is the first access to the page */
|
||||||
|
|
||||||
|
access_time = buf_page_is_accessed(&block->page);
|
||||||
|
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
|
||||||
|
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||||
ut_a(!block->page.file_page_was_freed);
|
ut_a(!block->page.file_page_was_freed);
|
||||||
@ -2306,7 +2327,7 @@ wait_until_unfixed:
|
|||||||
|
|
||||||
mtr_memo_push(mtr, block, fix_type);
|
mtr_memo_push(mtr, block, fix_type);
|
||||||
|
|
||||||
if (!accessed) {
|
if (!access_time) {
|
||||||
/* In the case of a first access, try to apply linear
|
/* In the case of a first access, try to apply linear
|
||||||
read-ahead */
|
read-ahead */
|
||||||
|
|
||||||
@ -2336,7 +2357,7 @@ buf_page_optimistic_get_func(
|
|||||||
ulint line, /*!< in: line where called */
|
ulint line, /*!< in: line where called */
|
||||||
mtr_t* mtr) /*!< in: mini-transaction */
|
mtr_t* mtr) /*!< in: mini-transaction */
|
||||||
{
|
{
|
||||||
ibool accessed;
|
unsigned access_time;
|
||||||
ibool success;
|
ibool success;
|
||||||
ulint fix_type;
|
ulint fix_type;
|
||||||
|
|
||||||
@ -2353,14 +2374,16 @@ buf_page_optimistic_get_func(
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf_block_buf_fix_inc(block, file, line);
|
buf_block_buf_fix_inc(block, file, line);
|
||||||
accessed = buf_page_is_accessed(&block->page);
|
|
||||||
buf_page_set_accessed(&block->page, TRUE);
|
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
|
|
||||||
buf_block_make_young(&block->page);
|
/* Check if this is the first access to the page.
|
||||||
|
We do a dirty read on purpose, to avoid mutex contention.
|
||||||
|
This field is only used for heuristic purposes; it does not
|
||||||
|
affect correctness. */
|
||||||
|
|
||||||
/* Check if this is the first access to the page */
|
access_time = buf_page_is_accessed(&block->page);
|
||||||
|
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||||
|
|
||||||
ut_ad(!ibuf_inside()
|
ut_ad(!ibuf_inside()
|
||||||
|| ibuf_page(buf_block_get_space(block),
|
|| ibuf_page(buf_block_get_space(block),
|
||||||
@ -2412,7 +2435,7 @@ buf_page_optimistic_get_func(
|
|||||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||||
ut_a(block->page.file_page_was_freed == FALSE);
|
ut_a(block->page.file_page_was_freed == FALSE);
|
||||||
#endif
|
#endif
|
||||||
if (UNIV_UNLIKELY(!accessed)) {
|
if (UNIV_UNLIKELY(!access_time)) {
|
||||||
/* In the case of a first access, try to apply linear
|
/* In the case of a first access, try to apply linear
|
||||||
read-ahead */
|
read-ahead */
|
||||||
|
|
||||||
@ -2425,7 +2448,7 @@ buf_page_optimistic_get_func(
|
|||||||
ut_a(ibuf_count_get(buf_block_get_space(block),
|
ut_a(ibuf_count_get(buf_block_get_space(block),
|
||||||
buf_block_get_page_no(block)) == 0);
|
buf_block_get_page_no(block)) == 0);
|
||||||
#endif
|
#endif
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
@ -2473,8 +2496,20 @@ buf_page_get_known_nowait(
|
|||||||
|
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
|
|
||||||
if (mode == BUF_MAKE_YOUNG) {
|
if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
|
||||||
buf_block_make_young(&block->page);
|
buf_pool_mutex_enter();
|
||||||
|
buf_LRU_make_block_young(&block->page);
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
} else if (!buf_page_is_accessed(&block->page)) {
|
||||||
|
/* Above, we do a dirty read on purpose, to avoid
|
||||||
|
mutex contention. The field buf_page_t::access_time
|
||||||
|
is only used for heuristic purposes. Writes to the
|
||||||
|
field must be protected by mutex, however. */
|
||||||
|
ulint time_ms = ut_time_ms();
|
||||||
|
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
buf_page_set_accessed(&block->page, time_ms);
|
||||||
|
buf_pool_mutex_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
|
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
|
||||||
@ -2513,7 +2548,7 @@ buf_page_get_known_nowait(
|
|||||||
|| (ibuf_count_get(buf_block_get_space(block),
|
|| (ibuf_count_get(buf_block_get_space(block),
|
||||||
buf_block_get_page_no(block)) == 0));
|
buf_block_get_page_no(block)) == 0));
|
||||||
#endif
|
#endif
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
@ -2589,7 +2624,7 @@ buf_page_try_get_func(
|
|||||||
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
||||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||||
|
|
||||||
buf_pool->n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||||
ut_a(ibuf_count_get(buf_block_get_space(block),
|
ut_a(ibuf_count_get(buf_block_get_space(block),
|
||||||
@ -2608,10 +2643,10 @@ buf_page_init_low(
|
|||||||
buf_page_t* bpage) /*!< in: block to init */
|
buf_page_t* bpage) /*!< in: block to init */
|
||||||
{
|
{
|
||||||
bpage->flush_type = BUF_FLUSH_LRU;
|
bpage->flush_type = BUF_FLUSH_LRU;
|
||||||
bpage->accessed = FALSE;
|
|
||||||
bpage->io_fix = BUF_IO_NONE;
|
bpage->io_fix = BUF_IO_NONE;
|
||||||
bpage->buf_fix_count = 0;
|
bpage->buf_fix_count = 0;
|
||||||
bpage->freed_page_clock = 0;
|
bpage->freed_page_clock = 0;
|
||||||
|
bpage->access_time = 0;
|
||||||
bpage->newest_modification = 0;
|
bpage->newest_modification = 0;
|
||||||
bpage->oldest_modification = 0;
|
bpage->oldest_modification = 0;
|
||||||
HASH_INVALIDATE(bpage, hash);
|
HASH_INVALIDATE(bpage, hash);
|
||||||
@ -2907,6 +2942,7 @@ buf_page_create(
|
|||||||
buf_frame_t* frame;
|
buf_frame_t* frame;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
buf_block_t* free_block = NULL;
|
buf_block_t* free_block = NULL;
|
||||||
|
ulint time_ms = ut_time_ms();
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
ut_ad(space || !zip_size);
|
ut_ad(space || !zip_size);
|
||||||
@ -2953,7 +2989,7 @@ buf_page_create(
|
|||||||
buf_LRU_add_block(&block->page, FALSE);
|
buf_LRU_add_block(&block->page, FALSE);
|
||||||
|
|
||||||
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
||||||
buf_pool->n_pages_created++;
|
buf_pool->stat.n_pages_created++;
|
||||||
|
|
||||||
if (zip_size) {
|
if (zip_size) {
|
||||||
void* data;
|
void* data;
|
||||||
@ -2990,12 +3026,12 @@ buf_page_create(
|
|||||||
rw_lock_x_unlock(&block->lock);
|
rw_lock_x_unlock(&block->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf_page_set_accessed(&block->page, time_ms);
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
|
|
||||||
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
|
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
|
||||||
|
|
||||||
buf_page_set_accessed(&block->page, TRUE);
|
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
|
|
||||||
/* Delete possible entries for the page from the insert buffer:
|
/* Delete possible entries for the page from the insert buffer:
|
||||||
@ -3201,7 +3237,7 @@ corrupt:
|
|||||||
|
|
||||||
ut_ad(buf_pool->n_pend_reads > 0);
|
ut_ad(buf_pool->n_pend_reads > 0);
|
||||||
buf_pool->n_pend_reads--;
|
buf_pool->n_pend_reads--;
|
||||||
buf_pool->n_pages_read++;
|
buf_pool->stat.n_pages_read++;
|
||||||
|
|
||||||
if (uncompressed) {
|
if (uncompressed) {
|
||||||
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
|
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
|
||||||
@ -3221,7 +3257,7 @@ corrupt:
|
|||||||
BUF_IO_WRITE);
|
BUF_IO_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_pool->n_pages_written++;
|
buf_pool->stat.n_pages_written++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3251,7 +3287,32 @@ void
|
|||||||
buf_pool_invalidate(void)
|
buf_pool_invalidate(void)
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
{
|
{
|
||||||
ibool freed;
|
ibool freed;
|
||||||
|
enum buf_flush i;
|
||||||
|
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
|
||||||
|
for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
|
||||||
|
|
||||||
|
/* As this function is called during startup and
|
||||||
|
during redo application phase during recovery, InnoDB
|
||||||
|
is single threaded (apart from IO helper threads) at
|
||||||
|
this stage. No new write batch can be in intialization
|
||||||
|
stage at this point. */
|
||||||
|
ut_ad(buf_pool->init_flush[i] == FALSE);
|
||||||
|
|
||||||
|
/* However, it is possible that a write batch that has
|
||||||
|
been posted earlier is still not complete. For buffer
|
||||||
|
pool invalidation to proceed we must ensure there is NO
|
||||||
|
write activity happening. */
|
||||||
|
if (buf_pool->n_flush[i] > 0) {
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
buf_flush_wait_batch_end(i);
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
|
||||||
ut_ad(buf_all_freed());
|
ut_ad(buf_all_freed());
|
||||||
|
|
||||||
@ -3266,6 +3327,14 @@ buf_pool_invalidate(void)
|
|||||||
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
|
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
|
||||||
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
|
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
|
||||||
|
|
||||||
|
buf_pool->freed_page_clock = 0;
|
||||||
|
buf_pool->LRU_old = NULL;
|
||||||
|
buf_pool->LRU_old_len = 0;
|
||||||
|
buf_pool->LRU_flush_ended = 0;
|
||||||
|
|
||||||
|
memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
|
||||||
|
buf_refresh_io_stats();
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3528,6 +3597,7 @@ buf_print(void)
|
|||||||
"n pending decompressions %lu\n"
|
"n pending decompressions %lu\n"
|
||||||
"n pending reads %lu\n"
|
"n pending reads %lu\n"
|
||||||
"n pending flush LRU %lu list %lu single page %lu\n"
|
"n pending flush LRU %lu list %lu single page %lu\n"
|
||||||
|
"pages made young %lu, not young %lu\n"
|
||||||
"pages read %lu, created %lu, written %lu\n",
|
"pages read %lu, created %lu, written %lu\n",
|
||||||
(ulong) size,
|
(ulong) size,
|
||||||
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
||||||
@ -3538,8 +3608,11 @@ buf_print(void)
|
|||||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
|
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
|
||||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
|
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
|
||||||
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
|
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
|
||||||
(ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
|
(ulong) buf_pool->stat.n_pages_made_young,
|
||||||
(ulong) buf_pool->n_pages_written);
|
(ulong) buf_pool->stat.n_pages_not_made_young,
|
||||||
|
(ulong) buf_pool->stat.n_pages_read,
|
||||||
|
(ulong) buf_pool->stat.n_pages_created,
|
||||||
|
(ulong) buf_pool->stat.n_pages_written);
|
||||||
|
|
||||||
/* Count the number of blocks belonging to each index in the buffer */
|
/* Count the number of blocks belonging to each index in the buffer */
|
||||||
|
|
||||||
@ -3744,10 +3817,9 @@ buf_print_io(
|
|||||||
{
|
{
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
double time_elapsed;
|
double time_elapsed;
|
||||||
ulint size;
|
ulint n_gets_diff;
|
||||||
|
|
||||||
ut_ad(buf_pool);
|
ut_ad(buf_pool);
|
||||||
size = buf_pool->curr_size;
|
|
||||||
|
|
||||||
buf_pool_mutex_enter();
|
buf_pool_mutex_enter();
|
||||||
|
|
||||||
@ -3755,12 +3827,14 @@ buf_print_io(
|
|||||||
"Buffer pool size %lu\n"
|
"Buffer pool size %lu\n"
|
||||||
"Free buffers %lu\n"
|
"Free buffers %lu\n"
|
||||||
"Database pages %lu\n"
|
"Database pages %lu\n"
|
||||||
|
"Old database pages %lu\n"
|
||||||
"Modified db pages %lu\n"
|
"Modified db pages %lu\n"
|
||||||
"Pending reads %lu\n"
|
"Pending reads %lu\n"
|
||||||
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
|
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
|
||||||
(ulong) size,
|
(ulong) buf_pool->curr_size,
|
||||||
(ulong) UT_LIST_GET_LEN(buf_pool->free),
|
(ulong) UT_LIST_GET_LEN(buf_pool->free),
|
||||||
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
||||||
|
(ulong) buf_pool->LRU_old_len,
|
||||||
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
|
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
|
||||||
(ulong) buf_pool->n_pend_reads,
|
(ulong) buf_pool->n_pend_reads,
|
||||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
|
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
|
||||||
@ -3772,37 +3846,66 @@ buf_print_io(
|
|||||||
current_time = time(NULL);
|
current_time = time(NULL);
|
||||||
time_elapsed = 0.001 + difftime(current_time,
|
time_elapsed = 0.001 + difftime(current_time,
|
||||||
buf_pool->last_printout_time);
|
buf_pool->last_printout_time);
|
||||||
buf_pool->last_printout_time = current_time;
|
|
||||||
|
|
||||||
fprintf(file,
|
fprintf(file,
|
||||||
|
"Pages made young %lu, not young %lu\n"
|
||||||
|
"%.2f youngs/s, %.2f non-youngs/s\n"
|
||||||
"Pages read %lu, created %lu, written %lu\n"
|
"Pages read %lu, created %lu, written %lu\n"
|
||||||
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
|
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
|
||||||
(ulong) buf_pool->n_pages_read,
|
(ulong) buf_pool->stat.n_pages_made_young,
|
||||||
(ulong) buf_pool->n_pages_created,
|
(ulong) buf_pool->stat.n_pages_not_made_young,
|
||||||
(ulong) buf_pool->n_pages_written,
|
(buf_pool->stat.n_pages_made_young
|
||||||
(buf_pool->n_pages_read - buf_pool->n_pages_read_old)
|
- buf_pool->old_stat.n_pages_made_young)
|
||||||
/ time_elapsed,
|
/ time_elapsed,
|
||||||
(buf_pool->n_pages_created - buf_pool->n_pages_created_old)
|
(buf_pool->stat.n_pages_not_made_young
|
||||||
|
- buf_pool->old_stat.n_pages_not_made_young)
|
||||||
/ time_elapsed,
|
/ time_elapsed,
|
||||||
(buf_pool->n_pages_written - buf_pool->n_pages_written_old)
|
(ulong) buf_pool->stat.n_pages_read,
|
||||||
|
(ulong) buf_pool->stat.n_pages_created,
|
||||||
|
(ulong) buf_pool->stat.n_pages_written,
|
||||||
|
(buf_pool->stat.n_pages_read
|
||||||
|
- buf_pool->old_stat.n_pages_read)
|
||||||
|
/ time_elapsed,
|
||||||
|
(buf_pool->stat.n_pages_created
|
||||||
|
- buf_pool->old_stat.n_pages_created)
|
||||||
|
/ time_elapsed,
|
||||||
|
(buf_pool->stat.n_pages_written
|
||||||
|
- buf_pool->old_stat.n_pages_written)
|
||||||
/ time_elapsed);
|
/ time_elapsed);
|
||||||
|
|
||||||
if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
|
n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
|
||||||
fprintf(file, "Buffer pool hit rate %lu / 1000\n",
|
|
||||||
|
if (n_gets_diff) {
|
||||||
|
fprintf(file,
|
||||||
|
"Buffer pool hit rate %lu / 1000,"
|
||||||
|
" young-making rate %lu / 1000 not %lu / 1000\n",
|
||||||
(ulong)
|
(ulong)
|
||||||
(1000 - ((1000 * (buf_pool->n_pages_read
|
(1000 - ((1000 * (buf_pool->stat.n_pages_read
|
||||||
- buf_pool->n_pages_read_old))
|
- buf_pool->old_stat.n_pages_read))
|
||||||
/ (buf_pool->n_page_gets
|
/ (buf_pool->stat.n_page_gets
|
||||||
- buf_pool->n_page_gets_old))));
|
- buf_pool->old_stat.n_page_gets))),
|
||||||
|
(ulong)
|
||||||
|
(1000 * (buf_pool->stat.n_pages_made_young
|
||||||
|
- buf_pool->old_stat.n_pages_made_young)
|
||||||
|
/ n_gets_diff),
|
||||||
|
(ulong)
|
||||||
|
(1000 * (buf_pool->stat.n_pages_not_made_young
|
||||||
|
- buf_pool->old_stat.n_pages_not_made_young)
|
||||||
|
/ n_gets_diff));
|
||||||
} else {
|
} else {
|
||||||
fputs("No buffer pool page gets since the last printout\n",
|
fputs("No buffer pool page gets since the last printout\n",
|
||||||
file);
|
file);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
|
/* Statistics about read ahead algorithm */
|
||||||
buf_pool->n_pages_read_old = buf_pool->n_pages_read;
|
fprintf(file, "Pages read ahead %.2f/s,"
|
||||||
buf_pool->n_pages_created_old = buf_pool->n_pages_created;
|
" evicted without access %.2f/s\n",
|
||||||
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
|
(buf_pool->stat.n_ra_pages_read
|
||||||
|
- buf_pool->old_stat.n_ra_pages_read)
|
||||||
|
/ time_elapsed,
|
||||||
|
(buf_pool->stat.n_ra_pages_evicted
|
||||||
|
- buf_pool->old_stat.n_ra_pages_evicted)
|
||||||
|
/ time_elapsed);
|
||||||
|
|
||||||
/* Print some values to help us with visualizing what is
|
/* Print some values to help us with visualizing what is
|
||||||
happening with LRU eviction. */
|
happening with LRU eviction. */
|
||||||
@ -3814,6 +3917,7 @@ buf_print_io(
|
|||||||
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
|
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
|
||||||
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
|
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
|
||||||
|
|
||||||
|
buf_refresh_io_stats();
|
||||||
buf_pool_mutex_exit();
|
buf_pool_mutex_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3825,10 +3929,7 @@ buf_refresh_io_stats(void)
|
|||||||
/*======================*/
|
/*======================*/
|
||||||
{
|
{
|
||||||
buf_pool->last_printout_time = time(NULL);
|
buf_pool->last_printout_time = time(NULL);
|
||||||
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
|
buf_pool->old_stat = buf_pool->stat;
|
||||||
buf_pool->n_pages_read_old = buf_pool->n_pages_read;
|
|
||||||
buf_pool->n_pages_created_old = buf_pool->n_pages_created;
|
|
||||||
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -49,18 +49,22 @@ Created 11/5/1995 Heikki Tuuri
|
|||||||
#include "log0recv.h"
|
#include "log0recv.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
|
||||||
/** The number of blocks from the LRU_old pointer onward, including the block
|
/** The number of blocks from the LRU_old pointer onward, including
|
||||||
pointed to, must be 3/8 of the whole LRU list length, except that the
|
the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
|
||||||
tolerance defined below is allowed. Note that the tolerance must be small
|
of the whole LRU list length, except that the tolerance defined below
|
||||||
enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
|
is allowed. Note that the tolerance must be small enough such that for
|
||||||
LRU_old pointer is not allowed to point to either end of the LRU list. */
|
even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
|
||||||
|
allowed to point to either end of the LRU list. */
|
||||||
|
|
||||||
#define BUF_LRU_OLD_TOLERANCE 20
|
#define BUF_LRU_OLD_TOLERANCE 20
|
||||||
|
|
||||||
/** The whole LRU list length is divided by this number to determine an
|
/** The minimum amount of non-old blocks when the LRU_old list exists
|
||||||
initial segment in buf_LRU_get_recent_limit */
|
(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
|
||||||
|
@see buf_LRU_old_adjust_len */
|
||||||
#define BUF_LRU_INITIAL_RATIO 8
|
#define BUF_LRU_NON_OLD_MIN_LEN 5
|
||||||
|
#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
|
||||||
|
# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** When dropping the search hash index entries before deleting an ibd
|
/** When dropping the search hash index entries before deleting an ibd
|
||||||
file, we build a local array of pages belonging to that tablespace
|
file, we build a local array of pages belonging to that tablespace
|
||||||
@ -107,6 +111,15 @@ UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
|
|||||||
|
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
|
/** @name Heuristics for detecting index scan @{ */
|
||||||
|
/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
|
||||||
|
"old" blocks. Protected by buf_pool_mutex. */
|
||||||
|
UNIV_INTERN uint buf_LRU_old_ratio;
|
||||||
|
/** Move blocks to "new" LRU list only if the first access was at
|
||||||
|
least this many milliseconds ago. Not protected by any mutex or latch. */
|
||||||
|
UNIV_INTERN uint buf_LRU_old_threshold_ms;
|
||||||
|
/* @} */
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
Takes a block out of the LRU list and page hash table.
|
Takes a block out of the LRU list and page hash table.
|
||||||
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
|
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
|
||||||
@ -428,42 +441,6 @@ next_page:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Gets the minimum LRU_position field for the blocks in an initial segment
|
|
||||||
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
|
|
||||||
guaranteed to be precise, because the ulint_clock may wrap around.
|
|
||||||
@return the limit; zero if could not determine it */
|
|
||||||
UNIV_INTERN
|
|
||||||
ulint
|
|
||||||
buf_LRU_get_recent_limit(void)
|
|
||||||
/*==========================*/
|
|
||||||
{
|
|
||||||
const buf_page_t* bpage;
|
|
||||||
ulint len;
|
|
||||||
ulint limit;
|
|
||||||
|
|
||||||
buf_pool_mutex_enter();
|
|
||||||
|
|
||||||
len = UT_LIST_GET_LEN(buf_pool->LRU);
|
|
||||||
|
|
||||||
if (len < BUF_LRU_OLD_MIN_LEN) {
|
|
||||||
/* The LRU list is too short to do read-ahead */
|
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
|
||||||
|
|
||||||
limit = buf_page_get_LRU_position(bpage);
|
|
||||||
len /= BUF_LRU_INITIAL_RATIO;
|
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
|
|
||||||
return(limit > len ? (limit - len) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
|
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
@ -594,6 +571,7 @@ buf_LRU_free_from_common_LRU_list(
|
|||||||
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
|
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
|
||||||
|
|
||||||
enum buf_lru_free_block_status freed;
|
enum buf_lru_free_block_status freed;
|
||||||
|
unsigned accessed;
|
||||||
mutex_t* block_mutex
|
mutex_t* block_mutex
|
||||||
= buf_page_get_mutex(bpage);
|
= buf_page_get_mutex(bpage);
|
||||||
|
|
||||||
@ -601,11 +579,18 @@ buf_LRU_free_from_common_LRU_list(
|
|||||||
ut_ad(bpage->in_LRU_list);
|
ut_ad(bpage->in_LRU_list);
|
||||||
|
|
||||||
mutex_enter(block_mutex);
|
mutex_enter(block_mutex);
|
||||||
|
accessed = buf_page_is_accessed(bpage);
|
||||||
freed = buf_LRU_free_block(bpage, TRUE, NULL);
|
freed = buf_LRU_free_block(bpage, TRUE, NULL);
|
||||||
mutex_exit(block_mutex);
|
mutex_exit(block_mutex);
|
||||||
|
|
||||||
switch (freed) {
|
switch (freed) {
|
||||||
case BUF_LRU_FREED:
|
case BUF_LRU_FREED:
|
||||||
|
/* Keep track of pages that are evicted without
|
||||||
|
ever being accessed. This gives us a measure of
|
||||||
|
the effectiveness of readahead */
|
||||||
|
if (!accessed) {
|
||||||
|
++buf_pool->stat.n_ra_pages_evicted;
|
||||||
|
}
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
|
||||||
case BUF_LRU_NOT_FREED:
|
case BUF_LRU_NOT_FREED:
|
||||||
@ -953,8 +938,10 @@ buf_LRU_old_adjust_len(void)
|
|||||||
|
|
||||||
ut_a(buf_pool->LRU_old);
|
ut_a(buf_pool->LRU_old);
|
||||||
ut_ad(buf_pool_mutex_own());
|
ut_ad(buf_pool_mutex_own());
|
||||||
#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
|
ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
|
||||||
# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
|
ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
|
||||||
|
#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
|
||||||
|
# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
|
||||||
#endif
|
#endif
|
||||||
#ifdef UNIV_LRU_DEBUG
|
#ifdef UNIV_LRU_DEBUG
|
||||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||||
@ -966,34 +953,39 @@ buf_LRU_old_adjust_len(void)
|
|||||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||||
#endif /* UNIV_LRU_DEBUG */
|
#endif /* UNIV_LRU_DEBUG */
|
||||||
|
|
||||||
for (;;) {
|
old_len = buf_pool->LRU_old_len;
|
||||||
old_len = buf_pool->LRU_old_len;
|
new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
|
||||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
* buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
|
||||||
|
UT_LIST_GET_LEN(buf_pool->LRU)
|
||||||
|
- (BUF_LRU_OLD_TOLERANCE
|
||||||
|
+ BUF_LRU_NON_OLD_MIN_LEN));
|
||||||
|
|
||||||
ut_ad(buf_pool->LRU_old->in_LRU_list);
|
for (;;) {
|
||||||
ut_a(buf_pool->LRU_old);
|
buf_page_t* LRU_old = buf_pool->LRU_old;
|
||||||
|
|
||||||
|
ut_a(LRU_old);
|
||||||
|
ut_ad(LRU_old->in_LRU_list);
|
||||||
#ifdef UNIV_LRU_DEBUG
|
#ifdef UNIV_LRU_DEBUG
|
||||||
ut_a(buf_pool->LRU_old->old);
|
ut_a(LRU_old->old);
|
||||||
#endif /* UNIV_LRU_DEBUG */
|
#endif /* UNIV_LRU_DEBUG */
|
||||||
|
|
||||||
/* Update the LRU_old pointer if necessary */
|
/* Update the LRU_old pointer if necessary */
|
||||||
|
|
||||||
if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
|
if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
|
||||||
|
|
||||||
buf_pool->LRU_old = UT_LIST_GET_PREV(
|
buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
|
||||||
LRU, buf_pool->LRU_old);
|
LRU, LRU_old);
|
||||||
#ifdef UNIV_LRU_DEBUG
|
#ifdef UNIV_LRU_DEBUG
|
||||||
ut_a(!buf_pool->LRU_old->old);
|
ut_a(!LRU_old->old);
|
||||||
#endif /* UNIV_LRU_DEBUG */
|
#endif /* UNIV_LRU_DEBUG */
|
||||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
buf_page_set_old(LRU_old, TRUE);
|
||||||
buf_pool->LRU_old_len++;
|
old_len = ++buf_pool->LRU_old_len;
|
||||||
|
|
||||||
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
|
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
|
||||||
|
|
||||||
buf_page_set_old(buf_pool->LRU_old, FALSE);
|
buf_page_set_old(LRU_old, FALSE);
|
||||||
buf_pool->LRU_old = UT_LIST_GET_NEXT(
|
buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
|
||||||
LRU, buf_pool->LRU_old);
|
old_len = --buf_pool->LRU_old_len;
|
||||||
buf_pool->LRU_old_len--;
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1021,6 +1013,7 @@ buf_LRU_old_init(void)
|
|||||||
|
|
||||||
while (bpage != NULL) {
|
while (bpage != NULL) {
|
||||||
ut_ad(bpage->in_LRU_list);
|
ut_ad(bpage->in_LRU_list);
|
||||||
|
ut_ad(buf_page_in_file(bpage));
|
||||||
buf_page_set_old(bpage, TRUE);
|
buf_page_set_old(bpage, TRUE);
|
||||||
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||||
}
|
}
|
||||||
@ -1075,16 +1068,19 @@ buf_LRU_remove_block(
|
|||||||
|
|
||||||
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
|
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
|
||||||
|
|
||||||
/* Below: the previous block is guaranteed to exist, because
|
/* Below: the previous block is guaranteed to exist,
|
||||||
the LRU_old pointer is only allowed to differ by the
|
because the LRU_old pointer is only allowed to differ
|
||||||
tolerance value from strict 3/8 of the LRU list length. */
|
by BUF_LRU_OLD_TOLERANCE from strict
|
||||||
|
buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
|
||||||
|
list length. */
|
||||||
|
buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||||
|
|
||||||
buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
|
ut_a(prev_bpage);
|
||||||
ut_a(buf_pool->LRU_old);
|
|
||||||
#ifdef UNIV_LRU_DEBUG
|
#ifdef UNIV_LRU_DEBUG
|
||||||
ut_a(!buf_pool->LRU_old->old);
|
ut_a(!prev_bpage->old);
|
||||||
#endif /* UNIV_LRU_DEBUG */
|
#endif /* UNIV_LRU_DEBUG */
|
||||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
buf_pool->LRU_old = prev_bpage;
|
||||||
|
buf_page_set_old(prev_bpage, TRUE);
|
||||||
|
|
||||||
buf_pool->LRU_old_len++;
|
buf_pool->LRU_old_len++;
|
||||||
}
|
}
|
||||||
@ -1149,39 +1145,25 @@ buf_LRU_add_block_to_end_low(
|
|||||||
/*=========================*/
|
/*=========================*/
|
||||||
buf_page_t* bpage) /*!< in: control block */
|
buf_page_t* bpage) /*!< in: control block */
|
||||||
{
|
{
|
||||||
buf_page_t* last_bpage;
|
|
||||||
|
|
||||||
ut_ad(buf_pool);
|
ut_ad(buf_pool);
|
||||||
ut_ad(bpage);
|
ut_ad(bpage);
|
||||||
ut_ad(buf_pool_mutex_own());
|
ut_ad(buf_pool_mutex_own());
|
||||||
|
|
||||||
ut_a(buf_page_in_file(bpage));
|
ut_a(buf_page_in_file(bpage));
|
||||||
|
|
||||||
last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
|
||||||
|
|
||||||
if (last_bpage) {
|
|
||||||
bpage->LRU_position = last_bpage->LRU_position;
|
|
||||||
} else {
|
|
||||||
bpage->LRU_position = buf_pool_clock_tic();
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!bpage->in_LRU_list);
|
ut_ad(!bpage->in_LRU_list);
|
||||||
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
|
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
|
||||||
ut_d(bpage->in_LRU_list = TRUE);
|
ut_d(bpage->in_LRU_list = TRUE);
|
||||||
|
|
||||||
buf_page_set_old(bpage, TRUE);
|
buf_page_set_old(bpage, TRUE);
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
|
|
||||||
|
|
||||||
buf_pool->LRU_old_len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||||
|
|
||||||
ut_ad(buf_pool->LRU_old);
|
ut_ad(buf_pool->LRU_old);
|
||||||
|
|
||||||
/* Adjust the length of the old block list if necessary */
|
/* Adjust the length of the old block list if necessary */
|
||||||
|
|
||||||
|
buf_pool->LRU_old_len++;
|
||||||
buf_LRU_old_adjust_len();
|
buf_LRU_old_adjust_len();
|
||||||
|
|
||||||
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
|
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
|
||||||
@ -1189,6 +1171,7 @@ buf_LRU_add_block_to_end_low(
|
|||||||
/* The LRU list is now long enough for LRU_old to become
|
/* The LRU list is now long enough for LRU_old to become
|
||||||
defined: init it */
|
defined: init it */
|
||||||
|
|
||||||
|
buf_pool->LRU_old_len++;
|
||||||
buf_LRU_old_init();
|
buf_LRU_old_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,7 +1205,6 @@ buf_LRU_add_block_low(
|
|||||||
|
|
||||||
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
|
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
|
||||||
|
|
||||||
bpage->LRU_position = buf_pool_clock_tic();
|
|
||||||
bpage->freed_page_clock = buf_pool->freed_page_clock;
|
bpage->freed_page_clock = buf_pool->freed_page_clock;
|
||||||
} else {
|
} else {
|
||||||
#ifdef UNIV_LRU_DEBUG
|
#ifdef UNIV_LRU_DEBUG
|
||||||
@ -1237,11 +1219,6 @@ buf_LRU_add_block_low(
|
|||||||
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
|
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
|
||||||
bpage);
|
bpage);
|
||||||
buf_pool->LRU_old_len++;
|
buf_pool->LRU_old_len++;
|
||||||
|
|
||||||
/* We copy the LRU position field of the previous block
|
|
||||||
to the new block */
|
|
||||||
|
|
||||||
bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_d(bpage->in_LRU_list = TRUE);
|
ut_d(bpage->in_LRU_list = TRUE);
|
||||||
@ -1295,6 +1272,12 @@ buf_LRU_make_block_young(
|
|||||||
/*=====================*/
|
/*=====================*/
|
||||||
buf_page_t* bpage) /*!< in: control block */
|
buf_page_t* bpage) /*!< in: control block */
|
||||||
{
|
{
|
||||||
|
ut_ad(buf_pool_mutex_own());
|
||||||
|
|
||||||
|
if (bpage->old) {
|
||||||
|
buf_pool->stat.n_pages_made_young++;
|
||||||
|
}
|
||||||
|
|
||||||
buf_LRU_remove_block(bpage);
|
buf_LRU_remove_block(bpage);
|
||||||
buf_LRU_add_block_low(bpage, FALSE);
|
buf_LRU_add_block_low(bpage, FALSE);
|
||||||
}
|
}
|
||||||
@ -1847,6 +1830,50 @@ buf_LRU_block_free_hashed_page(
|
|||||||
buf_LRU_block_free_non_file_page(block);
|
buf_LRU_block_free_non_file_page(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
Updates buf_LRU_old_ratio.
|
||||||
|
@return updated old_pct */
|
||||||
|
UNIV_INTERN
|
||||||
|
uint
|
||||||
|
buf_LRU_old_ratio_update(
|
||||||
|
/*=====================*/
|
||||||
|
uint old_pct,/*!< in: Reserve this percentage of
|
||||||
|
the buffer pool for "old" blocks. */
|
||||||
|
ibool adjust) /*!< in: TRUE=adjust the LRU list;
|
||||||
|
FALSE=just assign buf_LRU_old_ratio
|
||||||
|
during the initialization of InnoDB */
|
||||||
|
{
|
||||||
|
uint ratio;
|
||||||
|
|
||||||
|
ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
|
||||||
|
if (ratio < BUF_LRU_OLD_RATIO_MIN) {
|
||||||
|
ratio = BUF_LRU_OLD_RATIO_MIN;
|
||||||
|
} else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
|
||||||
|
ratio = BUF_LRU_OLD_RATIO_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adjust) {
|
||||||
|
buf_pool_mutex_enter();
|
||||||
|
|
||||||
|
if (ratio != buf_LRU_old_ratio) {
|
||||||
|
buf_LRU_old_ratio = ratio;
|
||||||
|
|
||||||
|
if (UT_LIST_GET_LEN(buf_pool->LRU)
|
||||||
|
>= BUF_LRU_OLD_MIN_LEN) {
|
||||||
|
buf_LRU_old_adjust_len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_pool_mutex_exit();
|
||||||
|
} else {
|
||||||
|
buf_LRU_old_ratio = ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the reverse of
|
||||||
|
ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
|
||||||
|
return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Update the historical stats that we are collecting for LRU eviction
|
Update the historical stats that we are collecting for LRU eviction
|
||||||
policy at the end of each interval. */
|
policy at the end of each interval. */
|
||||||
@ -1896,7 +1923,6 @@ buf_LRU_validate(void)
|
|||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
ulint old_len;
|
ulint old_len;
|
||||||
ulint new_len;
|
ulint new_len;
|
||||||
ulint LRU_pos;
|
|
||||||
|
|
||||||
ut_ad(buf_pool);
|
ut_ad(buf_pool);
|
||||||
buf_pool_mutex_enter();
|
buf_pool_mutex_enter();
|
||||||
@ -1905,7 +1931,11 @@ buf_LRU_validate(void)
|
|||||||
|
|
||||||
ut_a(buf_pool->LRU_old);
|
ut_a(buf_pool->LRU_old);
|
||||||
old_len = buf_pool->LRU_old_len;
|
old_len = buf_pool->LRU_old_len;
|
||||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
|
||||||
|
* buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
|
||||||
|
UT_LIST_GET_LEN(buf_pool->LRU)
|
||||||
|
- (BUF_LRU_OLD_TOLERANCE
|
||||||
|
+ BUF_LRU_NON_OLD_MIN_LEN));
|
||||||
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
|
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
|
||||||
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
|
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
|
||||||
}
|
}
|
||||||
@ -1943,16 +1973,7 @@ buf_LRU_validate(void)
|
|||||||
ut_a(buf_pool->LRU_old == bpage);
|
ut_a(buf_pool->LRU_old == bpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
LRU_pos = buf_page_get_LRU_position(bpage);
|
|
||||||
|
|
||||||
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||||
|
|
||||||
if (bpage) {
|
|
||||||
/* If the following assert fails, it may
|
|
||||||
not be an error: just the buf_pool clock
|
|
||||||
has wrapped around */
|
|
||||||
ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_pool->LRU_old) {
|
if (buf_pool->LRU_old) {
|
||||||
@ -2000,9 +2021,6 @@ buf_LRU_print(void)
|
|||||||
ut_ad(buf_pool);
|
ut_ad(buf_pool);
|
||||||
buf_pool_mutex_enter();
|
buf_pool_mutex_enter();
|
||||||
|
|
||||||
fprintf(stderr, "Pool ulint clock %lu\n",
|
|
||||||
(ulong) buf_pool->ulint_clock);
|
|
||||||
|
|
||||||
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||||
|
|
||||||
while (bpage != NULL) {
|
while (bpage != NULL) {
|
||||||
@ -2033,18 +2051,16 @@ buf_LRU_print(void)
|
|||||||
const byte* frame;
|
const byte* frame;
|
||||||
case BUF_BLOCK_FILE_PAGE:
|
case BUF_BLOCK_FILE_PAGE:
|
||||||
frame = buf_block_get_frame((buf_block_t*) bpage);
|
frame = buf_block_get_frame((buf_block_t*) bpage);
|
||||||
fprintf(stderr, "\nLRU pos %lu type %lu"
|
fprintf(stderr, "\ntype %lu"
|
||||||
" index id %lu\n",
|
" index id %lu\n",
|
||||||
(ulong) buf_page_get_LRU_position(bpage),
|
|
||||||
(ulong) fil_page_get_type(frame),
|
(ulong) fil_page_get_type(frame),
|
||||||
(ulong) ut_dulint_get_low(
|
(ulong) ut_dulint_get_low(
|
||||||
btr_page_get_index_id(frame)));
|
btr_page_get_index_id(frame)));
|
||||||
break;
|
break;
|
||||||
case BUF_BLOCK_ZIP_PAGE:
|
case BUF_BLOCK_ZIP_PAGE:
|
||||||
frame = bpage->zip.data;
|
frame = bpage->zip.data;
|
||||||
fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
|
fprintf(stderr, "\ntype %lu size %lu"
|
||||||
" index id %lu\n",
|
" index id %lu\n",
|
||||||
(ulong) buf_page_get_LRU_position(bpage),
|
|
||||||
(ulong) fil_page_get_type(frame),
|
(ulong) fil_page_get_type(frame),
|
||||||
(ulong) buf_page_get_zip_size(bpage),
|
(ulong) buf_page_get_zip_size(bpage),
|
||||||
(ulong) ut_dulint_get_low(
|
(ulong) ut_dulint_get_low(
|
||||||
@ -2052,8 +2068,7 @@ buf_LRU_print(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
|
fprintf(stderr, "\n!state %lu!\n",
|
||||||
(ulong) buf_page_get_LRU_position(bpage),
|
|
||||||
(ulong) buf_page_get_state(bpage));
|
(ulong) buf_page_get_state(bpage));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
|
|||||||
#include "srv0start.h"
|
#include "srv0start.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
|
||||||
/** The size in blocks of the area where the random read-ahead algorithm counts
|
|
||||||
the accessed pages when deciding whether to read-ahead */
|
|
||||||
#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
|
|
||||||
|
|
||||||
/** There must be at least this many pages in buf_pool in the area to start
|
|
||||||
a random read-ahead */
|
|
||||||
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
|
|
||||||
|
|
||||||
/** The linear read-ahead area size */
|
/** The linear read-ahead area size */
|
||||||
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
|
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
|
||||||
|
|
||||||
@ -62,7 +54,8 @@ flag is cleared and the x-lock released by an i/o-handler thread.
|
|||||||
@return 1 if a read request was queued, 0 if the page already resided
|
@return 1 if a read request was queued, 0 if the page already resided
|
||||||
in buf_pool, or if the page is in the doublewrite buffer blocks in
|
in buf_pool, or if the page is in the doublewrite buffer blocks in
|
||||||
which case it is never read into the pool, or if the tablespace does
|
which case it is never read into the pool, or if the tablespace does
|
||||||
not exist or is being dropped */
|
not exist or is being dropped
|
||||||
|
@return 1 if read request is issued. 0 if it is not */
|
||||||
static
|
static
|
||||||
ulint
|
ulint
|
||||||
buf_read_page_low(
|
buf_read_page_low(
|
||||||
@ -164,175 +157,14 @@ buf_read_page_low(
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
Applies a random read-ahead in buf_pool if there are at least a threshold
|
|
||||||
value of accessed pages from the random read-ahead area. Does not read any
|
|
||||||
page, not even the one at the position (space, offset), if the read-ahead
|
|
||||||
mechanism is not activated. NOTE 1: the calling thread may own latches on
|
|
||||||
pages: to avoid deadlocks this function must be written such that it cannot
|
|
||||||
end up waiting for these latches! NOTE 2: the calling thread must want
|
|
||||||
access to the page given: this rule is set to prevent unintended read-aheads
|
|
||||||
performed by ibuf routines, a situation which could result in a deadlock if
|
|
||||||
the OS does not support asynchronous i/o.
|
|
||||||
@return number of page read requests issued; NOTE that if we read ibuf
|
|
||||||
pages, it may happen that the page at the given page number does not
|
|
||||||
get read even if we return a positive value! */
|
|
||||||
static
|
|
||||||
ulint
|
|
||||||
buf_read_ahead_random(
|
|
||||||
/*==================*/
|
|
||||||
ulint space, /*!< in: space id */
|
|
||||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
|
||||||
ulint offset) /*!< in: page number of a page which the current thread
|
|
||||||
wants to access */
|
|
||||||
{
|
|
||||||
ib_int64_t tablespace_version;
|
|
||||||
ulint recent_blocks = 0;
|
|
||||||
ulint count;
|
|
||||||
ulint LRU_recent_limit;
|
|
||||||
ulint ibuf_mode;
|
|
||||||
ulint low, high;
|
|
||||||
ulint err;
|
|
||||||
ulint i;
|
|
||||||
ulint buf_read_ahead_random_area;
|
|
||||||
|
|
||||||
/* We have currently disabled random readahead */
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
if (srv_startup_is_before_trx_rollback_phase) {
|
|
||||||
/* No read-ahead to avoid thread deadlocks */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ibuf_bitmap_page(zip_size, offset)
|
|
||||||
|| trx_sys_hdr_page(space, offset)) {
|
|
||||||
|
|
||||||
/* If it is an ibuf bitmap page or trx sys hdr, we do
|
|
||||||
no read-ahead, as that could break the ibuf page access
|
|
||||||
order */
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remember the tablespace version before we ask te tablespace size
|
|
||||||
below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
|
|
||||||
do not try to read outside the bounds of the tablespace! */
|
|
||||||
|
|
||||||
tablespace_version = fil_space_get_version(space);
|
|
||||||
|
|
||||||
buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
|
|
||||||
|
|
||||||
low = (offset / buf_read_ahead_random_area)
|
|
||||||
* buf_read_ahead_random_area;
|
|
||||||
high = (offset / buf_read_ahead_random_area + 1)
|
|
||||||
* buf_read_ahead_random_area;
|
|
||||||
if (high > fil_space_get_size(space)) {
|
|
||||||
|
|
||||||
high = fil_space_get_size(space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the minimum LRU_position field value for an initial segment
|
|
||||||
of the LRU list, to determine which blocks have recently been added
|
|
||||||
to the start of the list. */
|
|
||||||
|
|
||||||
LRU_recent_limit = buf_LRU_get_recent_limit();
|
|
||||||
|
|
||||||
buf_pool_mutex_enter();
|
|
||||||
|
|
||||||
if (buf_pool->n_pend_reads
|
|
||||||
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Count how many blocks in the area have been recently accessed,
|
|
||||||
that is, reside near the start of the LRU list. */
|
|
||||||
|
|
||||||
for (i = low; i < high; i++) {
|
|
||||||
const buf_page_t* bpage = buf_page_hash_get(space, i);
|
|
||||||
|
|
||||||
if (bpage
|
|
||||||
&& buf_page_is_accessed(bpage)
|
|
||||||
&& (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
|
|
||||||
|
|
||||||
recent_blocks++;
|
|
||||||
|
|
||||||
if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
|
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
goto read_ahead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf_pool_mutex_exit();
|
|
||||||
/* Do nothing */
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
read_ahead:
|
|
||||||
/* Read all the suitable blocks within the area */
|
|
||||||
|
|
||||||
if (ibuf_inside()) {
|
|
||||||
ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
|
|
||||||
} else {
|
|
||||||
ibuf_mode = BUF_READ_ANY_PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
for (i = low; i < high; i++) {
|
|
||||||
/* It is only sensible to do read-ahead in the non-sync aio
|
|
||||||
mode: hence FALSE as the first parameter */
|
|
||||||
|
|
||||||
if (!ibuf_bitmap_page(zip_size, i)) {
|
|
||||||
count += buf_read_page_low(
|
|
||||||
&err, FALSE,
|
|
||||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
|
||||||
space, zip_size, FALSE,
|
|
||||||
tablespace_version, i);
|
|
||||||
if (err == DB_TABLESPACE_DELETED) {
|
|
||||||
ut_print_timestamp(stderr);
|
|
||||||
fprintf(stderr,
|
|
||||||
" InnoDB: Warning: in random"
|
|
||||||
" readahead trying to access\n"
|
|
||||||
"InnoDB: tablespace %lu page %lu,\n"
|
|
||||||
"InnoDB: but the tablespace does not"
|
|
||||||
" exist or is just being dropped.\n",
|
|
||||||
(ulong) space, (ulong) i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In simulated aio we wake the aio handler threads only after
|
|
||||||
queuing all aio requests, in native aio the following call does
|
|
||||||
nothing: */
|
|
||||||
|
|
||||||
os_aio_simulated_wake_handler_threads();
|
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
if (buf_debug_prints && (count > 0)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Random read-ahead space %lu offset %lu pages %lu\n",
|
|
||||||
(ulong) space, (ulong) offset,
|
|
||||||
(ulong) count);
|
|
||||||
}
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
|
|
||||||
++srv_read_ahead_rnd;
|
|
||||||
return(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
High-level function which reads a page asynchronously from a file to the
|
High-level function which reads a page asynchronously from a file to the
|
||||||
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
||||||
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
||||||
released by the i/o-handler thread. Does a random read-ahead if it seems
|
released by the i/o-handler thread.
|
||||||
sensible.
|
@return TRUE if page has been read in, FALSE in case of failure */
|
||||||
@return number of page read requests issued: this can be greater than
|
|
||||||
1 if read-ahead occurred */
|
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ulint
|
ibool
|
||||||
buf_read_page(
|
buf_read_page(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
@ -341,20 +173,17 @@ buf_read_page(
|
|||||||
{
|
{
|
||||||
ib_int64_t tablespace_version;
|
ib_int64_t tablespace_version;
|
||||||
ulint count;
|
ulint count;
|
||||||
ulint count2;
|
|
||||||
ulint err;
|
ulint err;
|
||||||
|
|
||||||
tablespace_version = fil_space_get_version(space);
|
tablespace_version = fil_space_get_version(space);
|
||||||
|
|
||||||
count = buf_read_ahead_random(space, zip_size, offset);
|
|
||||||
|
|
||||||
/* We do the i/o in the synchronous aio mode to save thread
|
/* We do the i/o in the synchronous aio mode to save thread
|
||||||
switches: hence TRUE */
|
switches: hence TRUE */
|
||||||
|
|
||||||
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
||||||
zip_size, FALSE,
|
zip_size, FALSE,
|
||||||
tablespace_version, offset);
|
tablespace_version, offset);
|
||||||
srv_buf_pool_reads+= count2;
|
srv_buf_pool_reads += count;
|
||||||
if (err == DB_TABLESPACE_DELETED) {
|
if (err == DB_TABLESPACE_DELETED) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -371,14 +200,14 @@ buf_read_page(
|
|||||||
/* Increment number of I/O operations used for LRU policy. */
|
/* Increment number of I/O operations used for LRU policy. */
|
||||||
buf_LRU_stat_inc_io();
|
buf_LRU_stat_inc_io();
|
||||||
|
|
||||||
return(count + count2);
|
return(count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Applies linear read-ahead if in the buf_pool the page is a border page of
|
Applies linear read-ahead if in the buf_pool the page is a border page of
|
||||||
a linear read-ahead area and all the pages in the area have been accessed.
|
a linear read-ahead area and all the pages in the area have been accessed.
|
||||||
Does not read any page if the read-ahead mechanism is not activated. Note
|
Does not read any page if the read-ahead mechanism is not activated. Note
|
||||||
that the the algorithm looks at the 'natural' adjacent successor and
|
that the algorithm looks at the 'natural' adjacent successor and
|
||||||
predecessor of the page, which on the leaf level of a B-tree are the next
|
predecessor of the page, which on the leaf level of a B-tree are the next
|
||||||
and previous page in the chain of leaves. To know these, the page specified
|
and previous page in the chain of leaves. To know these, the page specified
|
||||||
in (space, offset) must already be present in the buf_pool. Thus, the
|
in (space, offset) must already be present in the buf_pool. Thus, the
|
||||||
@ -498,9 +327,17 @@ buf_read_ahead_linear(
|
|||||||
fail_count++;
|
fail_count++;
|
||||||
|
|
||||||
} else if (pred_bpage) {
|
} else if (pred_bpage) {
|
||||||
int res = (ut_ulint_cmp(
|
/* Note that buf_page_is_accessed() returns
|
||||||
buf_page_get_LRU_position(bpage),
|
the time of the first access. If some blocks
|
||||||
buf_page_get_LRU_position(pred_bpage)));
|
of the extent existed in the buffer pool at
|
||||||
|
the time of a linear access pattern, the first
|
||||||
|
access times may be nonmonotonic, even though
|
||||||
|
the latest access times were linear. The
|
||||||
|
threshold (srv_read_ahead_factor) should help
|
||||||
|
a little against this. */
|
||||||
|
int res = ut_ulint_cmp(
|
||||||
|
buf_page_is_accessed(bpage),
|
||||||
|
buf_page_is_accessed(pred_bpage));
|
||||||
/* Accesses not in the right order */
|
/* Accesses not in the right order */
|
||||||
if (res != 0 && res != asc_or_desc) {
|
if (res != 0 && res != asc_or_desc) {
|
||||||
fail_count++;
|
fail_count++;
|
||||||
@ -643,7 +480,7 @@ buf_read_ahead_linear(
|
|||||||
LRU policy decision. */
|
LRU policy decision. */
|
||||||
buf_LRU_stat_inc_io();
|
buf_LRU_stat_inc_io();
|
||||||
|
|
||||||
++srv_read_ahead_seq;
|
buf_pool->stat.n_ra_pages_read += count;
|
||||||
return(count);
|
return(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1379,7 +1379,7 @@ dict_create_add_foreign_field_to_dictionary(
|
|||||||
Add a single foreign key definition to the data dictionary tables in the
|
Add a single foreign key definition to the data dictionary tables in the
|
||||||
database. We also generate names to constraints that were not named by the
|
database. We also generate names to constraints that were not named by the
|
||||||
user. A generated constraint has a name of the format
|
user. A generated constraint has a name of the format
|
||||||
databasename/tablename_ibfk_<number>, where the numbers start from 1, and
|
databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
|
||||||
are given locally for this table, that is, the number is not global, as in
|
are given locally for this table, that is, the number is not global, as in
|
||||||
the old format constraints < 4.0.18 it used to be.
|
the old format constraints < 4.0.18 it used to be.
|
||||||
@return error code or DB_SUCCESS */
|
@return error code or DB_SUCCESS */
|
||||||
|
@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_";
|
|||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Tries to find column names for the index and sets the col field of the
|
Tries to find column names for the index and sets the col field of the
|
||||||
index. */
|
index.
|
||||||
|
@return TRUE if the column names were found */
|
||||||
static
|
static
|
||||||
void
|
ibool
|
||||||
dict_index_find_cols(
|
dict_index_find_cols(
|
||||||
/*=================*/
|
/*=================*/
|
||||||
dict_table_t* table, /*!< in: table */
|
dict_table_t* table, /*!< in: table */
|
||||||
@ -1169,7 +1170,7 @@ dict_col_name_is_reserved(
|
|||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
|
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
|
||||||
if (strcmp(name, reserved_names[i]) == 0) {
|
if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
@ -1431,7 +1432,7 @@ add_field_size:
|
|||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Adds an index to the dictionary cache.
|
Adds an index to the dictionary cache.
|
||||||
@return DB_SUCCESS or DB_TOO_BIG_RECORD */
|
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ulint
|
ulint
|
||||||
dict_index_add_to_cache(
|
dict_index_add_to_cache(
|
||||||
@ -1457,7 +1458,10 @@ dict_index_add_to_cache(
|
|||||||
ut_a(!dict_index_is_clust(index)
|
ut_a(!dict_index_is_clust(index)
|
||||||
|| UT_LIST_GET_LEN(table->indexes) == 0);
|
|| UT_LIST_GET_LEN(table->indexes) == 0);
|
||||||
|
|
||||||
dict_index_find_cols(table, index);
|
if (!dict_index_find_cols(table, index)) {
|
||||||
|
|
||||||
|
return(DB_CORRUPTION);
|
||||||
|
}
|
||||||
|
|
||||||
/* Build the cache internal representation of the index,
|
/* Build the cache internal representation of the index,
|
||||||
containing also the added system fields */
|
containing also the added system fields */
|
||||||
@ -1665,9 +1669,10 @@ dict_index_remove_from_cache(
|
|||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Tries to find column names for the index and sets the col field of the
|
Tries to find column names for the index and sets the col field of the
|
||||||
index. */
|
index.
|
||||||
|
@return TRUE if the column names were found */
|
||||||
static
|
static
|
||||||
void
|
ibool
|
||||||
dict_index_find_cols(
|
dict_index_find_cols(
|
||||||
/*=================*/
|
/*=================*/
|
||||||
dict_table_t* table, /*!< in: table */
|
dict_table_t* table, /*!< in: table */
|
||||||
@ -1692,17 +1697,21 @@ dict_index_find_cols(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/* It is an error not to find a matching column. */
|
/* It is an error not to find a matching column. */
|
||||||
fputs("InnoDB: Error: no matching column for ", stderr);
|
fputs("InnoDB: Error: no matching column for ", stderr);
|
||||||
ut_print_name(stderr, NULL, FALSE, field->name);
|
ut_print_name(stderr, NULL, FALSE, field->name);
|
||||||
fputs(" in ", stderr);
|
fputs(" in ", stderr);
|
||||||
dict_index_name_print(stderr, NULL, index);
|
dict_index_name_print(stderr, NULL, index);
|
||||||
fputs("!\n", stderr);
|
fputs("!\n", stderr);
|
||||||
ut_error;
|
#endif /* UNIV_DEBUG */
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
found:
|
found:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
|
@ -594,6 +594,11 @@ fil_node_create(
|
|||||||
|
|
||||||
UT_LIST_ADD_LAST(chain, space->chain, node);
|
UT_LIST_ADD_LAST(chain, space->chain, node);
|
||||||
|
|
||||||
|
if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
|
||||||
|
|
||||||
|
fil_system->max_assigned_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,12 +618,10 @@ fil_node_open_file(
|
|||||||
ulint size_high;
|
ulint size_high;
|
||||||
ibool ret;
|
ibool ret;
|
||||||
ibool success;
|
ibool success;
|
||||||
#ifndef UNIV_HOTBACKUP
|
|
||||||
byte* buf2;
|
byte* buf2;
|
||||||
byte* page;
|
byte* page;
|
||||||
ulint space_id;
|
ulint space_id;
|
||||||
ulint flags;
|
ulint flags;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(system->mutex)));
|
ut_ad(mutex_own(&(system->mutex)));
|
||||||
ut_a(node->n_pending == 0);
|
ut_a(node->n_pending == 0);
|
||||||
@ -654,9 +657,11 @@ fil_node_open_file(
|
|||||||
size_bytes = (((ib_int64_t)size_high) << 32)
|
size_bytes = (((ib_int64_t)size_high) << 32)
|
||||||
+ (ib_int64_t)size_low;
|
+ (ib_int64_t)size_low;
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
|
if (space->id == 0) {
|
||||||
/* TODO: adjust to zip_size, like below? */
|
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
|
||||||
#else
|
goto add_size;
|
||||||
|
}
|
||||||
|
#endif /* UNIV_HOTBACKUP */
|
||||||
ut_a(space->purpose != FIL_LOG);
|
ut_a(space->purpose != FIL_LOG);
|
||||||
ut_a(space->id != 0);
|
ut_a(space->id != 0);
|
||||||
|
|
||||||
@ -735,7 +740,10 @@ fil_node_open_file(
|
|||||||
(size_bytes
|
(size_bytes
|
||||||
/ dict_table_flags_to_zip_size(flags));
|
/ dict_table_flags_to_zip_size(flags));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#ifdef UNIV_HOTBACKUP
|
||||||
|
add_size:
|
||||||
|
#endif /* UNIV_HOTBACKUP */
|
||||||
space->size += node->size;
|
space->size += node->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,7 +963,7 @@ close_more:
|
|||||||
" while the maximum\n"
|
" while the maximum\n"
|
||||||
"InnoDB: allowed value would be %lu.\n"
|
"InnoDB: allowed value would be %lu.\n"
|
||||||
"InnoDB: You may need to raise the value of"
|
"InnoDB: You may need to raise the value of"
|
||||||
" innodb_max_files_open in\n"
|
" innodb_open_files in\n"
|
||||||
"InnoDB: my.cnf.\n",
|
"InnoDB: my.cnf.\n",
|
||||||
(ulong) fil_system->n_open,
|
(ulong) fil_system->n_open,
|
||||||
(ulong) fil_system->max_n_open);
|
(ulong) fil_system->max_n_open);
|
||||||
@ -1535,7 +1543,7 @@ fil_open_log_and_system_tablespace_files(void)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Warning: you must"
|
"InnoDB: Warning: you must"
|
||||||
" raise the value of"
|
" raise the value of"
|
||||||
" innodb_max_open_files in\n"
|
" innodb_open_files in\n"
|
||||||
"InnoDB: my.cnf! Remember that"
|
"InnoDB: my.cnf! Remember that"
|
||||||
" InnoDB keeps all log files"
|
" InnoDB keeps all log files"
|
||||||
" and all system\n"
|
" and all system\n"
|
||||||
@ -2923,7 +2931,6 @@ fil_open_single_table_tablespace(
|
|||||||
byte* page;
|
byte* page;
|
||||||
ulint space_id;
|
ulint space_id;
|
||||||
ulint space_flags;
|
ulint space_flags;
|
||||||
ibool ret = TRUE;
|
|
||||||
|
|
||||||
filepath = fil_make_ibd_name(name, FALSE);
|
filepath = fil_make_ibd_name(name, FALSE);
|
||||||
|
|
||||||
@ -3001,7 +3008,7 @@ fil_open_single_table_tablespace(
|
|||||||
(ulong) space_id, (ulong) space_flags,
|
(ulong) space_id, (ulong) space_flags,
|
||||||
(ulong) id, (ulong) flags);
|
(ulong) id, (ulong) flags);
|
||||||
|
|
||||||
ret = FALSE;
|
success = FALSE;
|
||||||
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
@ -3021,7 +3028,7 @@ func_exit:
|
|||||||
os_file_close(file);
|
os_file_close(file);
|
||||||
mem_free(filepath);
|
mem_free(filepath);
|
||||||
|
|
||||||
return(ret);
|
return(success);
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
@ -3299,7 +3306,17 @@ fil_load_single_table_tablespace(
|
|||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
||||||
goto func_exit;
|
if (srv_force_recovery > 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: innodb_force_recovery"
|
||||||
|
" was set to %lu. Continuing crash recovery\n"
|
||||||
|
"InnoDB: even though the tablespace creation"
|
||||||
|
" of this table failed.\n",
|
||||||
|
srv_force_recovery);
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do not use the size information we have about the file, because
|
/* We do not use the size information we have about the file, because
|
||||||
|
@ -232,6 +232,9 @@ the extent are free and which contain old tuple version to clean. */
|
|||||||
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
|
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
|
||||||
|
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
|
/* Flag to indicate if we have printed the tablespace full error. */
|
||||||
|
static ibool fsp_tbs_full_error_printed = FALSE;
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Returns an extent to the free list of a space. */
|
Returns an extent to the free list of a space. */
|
||||||
static
|
static
|
||||||
@ -1099,7 +1102,7 @@ fsp_header_inc_size(
|
|||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Gets the current free limit of the system tablespace. The free limit
|
Gets the current free limit of the system tablespace. The free limit
|
||||||
means the place of the first page which has never been put to the the
|
means the place of the first page which has never been put to the
|
||||||
free list for allocation. The space above that address is initialized
|
free list for allocation. The space above that address is initialized
|
||||||
to zero. Sets also the global variable log_fsp_current_free_limit.
|
to zero. Sets also the global variable log_fsp_current_free_limit.
|
||||||
@return free limit in megabytes */
|
@return free limit in megabytes */
|
||||||
@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
|
|||||||
|
|
||||||
if (space == 0 && !srv_auto_extend_last_data_file) {
|
if (space == 0 && !srv_auto_extend_last_data_file) {
|
||||||
|
|
||||||
|
/* We print the error message only once to avoid
|
||||||
|
spamming the error log. Note that we don't need
|
||||||
|
to reset the flag to FALSE as dealing with this
|
||||||
|
error requires server restart. */
|
||||||
|
if (fsp_tbs_full_error_printed == FALSE) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: Data file(s) ran"
|
||||||
|
" out of space.\n"
|
||||||
|
"Please add another data file or"
|
||||||
|
" use \'autoextend\' for the last"
|
||||||
|
" data file.\n");
|
||||||
|
fsp_tbs_full_error_printed = TRUE;
|
||||||
|
}
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
|
|||||||
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
|
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
|
||||||
/* This is used */
|
/* This is used */
|
||||||
|
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
return(i);
|
return(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
|
|||||||
|
|
||||||
return(i);
|
return(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ULINT_UNDEFINED);
|
return(ULINT_UNDEFINED);
|
||||||
@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
|
|||||||
page + FSEG_INODE_PAGE_NODE, mtr);
|
page + FSEG_INODE_PAGE_NODE, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
|
||||||
|
|| mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
return(inode);
|
return(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
|
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
|
||||||
mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
|
mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
|
||||||
|
|
||||||
if (ULINT_UNDEFINED
|
if (ULINT_UNDEFINED
|
||||||
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
|
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
|
||||||
@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
|
|||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Returns the file segment inode, page x-latched.
|
Returns the file segment inode, page x-latched.
|
||||||
@return segment inode, page x-latched */
|
@return segment inode, page x-latched; NULL if the inode is free */
|
||||||
static
|
static
|
||||||
fseg_inode_t*
|
fseg_inode_t*
|
||||||
fseg_inode_get(
|
fseg_inode_try_get(
|
||||||
/*===========*/
|
/*===============*/
|
||||||
fseg_header_t* header, /*!< in: segment header */
|
fseg_header_t* header, /*!< in: segment header */
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
ulint zip_size,/*!< in: compressed page size in bytes
|
ulint zip_size,/*!< in: compressed page size in bytes
|
||||||
@ -2054,8 +2077,34 @@ fseg_inode_get(
|
|||||||
|
|
||||||
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
|
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
|
||||||
|
|
||||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
if (UNIV_UNLIKELY
|
||||||
|
(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
|
||||||
|
|
||||||
|
inode = NULL;
|
||||||
|
} else {
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
Returns the file segment inode, page x-latched.
|
||||||
|
@return segment inode, page x-latched */
|
||||||
|
static
|
||||||
|
fseg_inode_t*
|
||||||
|
fseg_inode_get(
|
||||||
|
/*===========*/
|
||||||
|
fseg_header_t* header, /*!< in: segment header */
|
||||||
|
ulint space, /*!< in: space id */
|
||||||
|
ulint zip_size,/*!< in: compressed page size in bytes
|
||||||
|
or 0 for uncompressed pages */
|
||||||
|
mtr_t* mtr) /*!< in: mtr handle */
|
||||||
|
{
|
||||||
|
fseg_inode_t* inode
|
||||||
|
= fseg_inode_try_get(header, space, zip_size, mtr);
|
||||||
|
ut_a(inode);
|
||||||
return(inode);
|
return(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
|
|||||||
ut_ad(inode && mtr);
|
ut_ad(inode && mtr);
|
||||||
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
||||||
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
return(mach_read_from_4(inode + FSEG_FRAG_ARR
|
return(mach_read_from_4(inode + FSEG_FRAG_ARR
|
||||||
+ n * FSEG_FRAG_SLOT_SIZE));
|
+ n * FSEG_FRAG_SLOT_SIZE));
|
||||||
}
|
}
|
||||||
@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
|
|||||||
ut_ad(inode && mtr);
|
ut_ad(inode && mtr);
|
||||||
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
||||||
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
|
|
||||||
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
|
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
|
||||||
page_no, MLOG_4BYTES, mtr);
|
page_no, MLOG_4BYTES, mtr);
|
||||||
@ -2451,6 +2502,8 @@ fseg_fill_free_list(
|
|||||||
xdes_set_state(descr, XDES_FSEG, mtr);
|
xdes_set_state(descr, XDES_FSEG, mtr);
|
||||||
|
|
||||||
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
|
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
|
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
|
||||||
|
|
||||||
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
|
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
|
||||||
@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
|
|||||||
fil_addr_t first;
|
fil_addr_t first;
|
||||||
|
|
||||||
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
|
|
||||||
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
|
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
|
||||||
/* Segment free list is not empty, allocate from it */
|
/* Segment free list is not empty, allocate from it */
|
||||||
@ -3136,6 +3190,8 @@ fseg_mark_page_used(
|
|||||||
|
|
||||||
ut_ad(seg_inode && mtr);
|
ut_ad(seg_inode && mtr);
|
||||||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||||
|
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
|
|
||||||
descr = xdes_get_descriptor(space, zip_size, page, mtr);
|
descr = xdes_get_descriptor(space, zip_size, page, mtr);
|
||||||
|
|
||||||
@ -3373,6 +3429,8 @@ fseg_free_extent(
|
|||||||
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
|
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
|
||||||
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
|
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
|
||||||
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
|
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
|
||||||
|
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||||
|
== FSEG_MAGIC_N_VALUE);
|
||||||
|
|
||||||
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
|
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
|
||||||
|
|
||||||
@ -3463,7 +3521,13 @@ fseg_free_step(
|
|||||||
ut_a(descr);
|
ut_a(descr);
|
||||||
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
|
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
|
||||||
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
|
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
|
||||||
inode = fseg_inode_get(header, space, zip_size, mtr);
|
inode = fseg_inode_try_get(header, space, zip_size, mtr);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(inode == NULL)) {
|
||||||
|
fprintf(stderr, "double free of inode from %u:%u\n",
|
||||||
|
(unsigned) space, (unsigned) header_page);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
|
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
|
||||||
|
|
||||||
@ -3587,6 +3651,7 @@ fseg_get_first_extent(
|
|||||||
ut_ad(inode && mtr);
|
ut_ad(inode && mtr);
|
||||||
|
|
||||||
ut_ad(space == page_get_space_id(page_align(inode)));
|
ut_ad(space == page_get_space_id(page_align(inode)));
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
|
|
||||||
first = fil_addr_null;
|
first = fil_addr_null;
|
||||||
|
|
||||||
@ -3801,6 +3866,7 @@ fseg_print_low(
|
|||||||
(ulong) reserved, (ulong) used, (ulong) n_full,
|
(ulong) reserved, (ulong) used, (ulong) n_full,
|
||||||
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
|
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
|
||||||
(ulong) n_used);
|
(ulong) n_used);
|
||||||
|
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_BTR_PRINT
|
#ifdef UNIV_BTR_PRINT
|
||||||
|
@ -72,6 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
/* Include necessary InnoDB headers */
|
/* Include necessary InnoDB headers */
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "univ.i"
|
#include "univ.i"
|
||||||
|
#include "buf0lru.h"
|
||||||
#include "btr0sea.h"
|
#include "btr0sea.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "os0thread.h"
|
#include "os0thread.h"
|
||||||
@ -106,6 +107,9 @@ extern "C" {
|
|||||||
#include "i_s.h"
|
#include "i_s.h"
|
||||||
|
|
||||||
#ifndef MYSQL_SERVER
|
#ifndef MYSQL_SERVER
|
||||||
|
# ifndef MYSQL_PLUGIN_IMPORT
|
||||||
|
# define MYSQL_PLUGIN_IMPORT /* nothing */
|
||||||
|
# endif /* MYSQL_PLUGIN_IMPORT */
|
||||||
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
|
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
|
||||||
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
|
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
|
||||||
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
|
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
|
||||||
@ -152,6 +156,10 @@ static ulong innobase_write_io_threads;
|
|||||||
|
|
||||||
static long long innobase_buffer_pool_size, innobase_log_file_size;
|
static long long innobase_buffer_pool_size, innobase_log_file_size;
|
||||||
|
|
||||||
|
/** Percentage of the buffer pool to reserve for 'old' blocks.
|
||||||
|
Connected to buf_LRU_old_ratio. */
|
||||||
|
static uint innobase_old_blocks_pct;
|
||||||
|
|
||||||
/* The default values for the following char* start-up parameters
|
/* The default values for the following char* start-up parameters
|
||||||
are determined in innobase_init below: */
|
are determined in innobase_init below: */
|
||||||
|
|
||||||
@ -166,9 +174,7 @@ file formats in the configuration file, but can only be set to any
|
|||||||
of the supported file formats during runtime. */
|
of the supported file formats during runtime. */
|
||||||
static char* innobase_file_format_check = NULL;
|
static char* innobase_file_format_check = NULL;
|
||||||
|
|
||||||
/* The following has a misleading name: starting from 4.0.5, this also
|
static char* innobase_file_flush_method = NULL;
|
||||||
affects Windows: */
|
|
||||||
static char* innobase_unix_file_flush_method = NULL;
|
|
||||||
|
|
||||||
/* Below we have boolean-valued start-up parameters, and their default
|
/* Below we have boolean-valued start-up parameters, and their default
|
||||||
values */
|
values */
|
||||||
@ -214,15 +220,34 @@ static void free_share(INNOBASE_SHARE *share);
|
|||||||
static int innobase_close_connection(handlerton *hton, THD* thd);
|
static int innobase_close_connection(handlerton *hton, THD* thd);
|
||||||
static int innobase_commit(handlerton *hton, THD* thd, bool all);
|
static int innobase_commit(handlerton *hton, THD* thd, bool all);
|
||||||
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
|
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
|
||||||
static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
|
static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
|
||||||
void *savepoint);
|
void *savepoint);
|
||||||
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
|
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
|
||||||
static int innobase_release_savepoint(handlerton *hton, THD* thd,
|
static int innobase_release_savepoint(handlerton *hton, THD* thd,
|
||||||
void *savepoint);
|
void *savepoint);
|
||||||
static handler *innobase_create_handler(handlerton *hton,
|
static handler *innobase_create_handler(handlerton *hton,
|
||||||
TABLE_SHARE *table,
|
TABLE_SHARE *table,
|
||||||
MEM_ROOT *mem_root);
|
MEM_ROOT *mem_root);
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
This function checks each index name for a table against reserved
|
||||||
|
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
|
||||||
|
this function pushes an error message to the client, and returns true. */
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
innobase_index_name_is_reserved(
|
||||||
|
/*============================*/
|
||||||
|
/* out: true if index name matches a
|
||||||
|
reserved name */
|
||||||
|
const trx_t* trx, /* in: InnoDB transaction handle */
|
||||||
|
const TABLE* form, /* in: information on table
|
||||||
|
columns and indexes */
|
||||||
|
const char* norm_name); /* in: table name */
|
||||||
|
|
||||||
|
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
|
||||||
|
system primary index. */
|
||||||
|
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
|
||||||
|
|
||||||
/** @brief Initialize the default value of innodb_commit_concurrency.
|
/** @brief Initialize the default value of innodb_commit_concurrency.
|
||||||
|
|
||||||
Once InnoDB is running, the innodb_commit_concurrency must not change
|
Once InnoDB is running, the innodb_commit_concurrency must not change
|
||||||
@ -492,10 +517,10 @@ static SHOW_VAR innodb_status_variables[]= {
|
|||||||
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
|
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
|
||||||
{"buffer_pool_pages_total",
|
{"buffer_pool_pages_total",
|
||||||
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
|
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
|
||||||
{"buffer_pool_read_ahead_rnd",
|
{"buffer_pool_read_ahead",
|
||||||
(char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
|
(char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
|
||||||
{"buffer_pool_read_ahead_seq",
|
{"buffer_pool_read_ahead_evicted",
|
||||||
(char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
|
(char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
|
||||||
{"buffer_pool_read_requests",
|
{"buffer_pool_read_requests",
|
||||||
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
|
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
|
||||||
{"buffer_pool_reads",
|
{"buffer_pool_reads",
|
||||||
@ -865,17 +890,14 @@ convert_error_code_to_mysql(
|
|||||||
return(ER_PRIMARY_CANT_HAVE_NULL);
|
return(ER_PRIMARY_CANT_HAVE_NULL);
|
||||||
|
|
||||||
case DB_TOO_MANY_CONCURRENT_TRXS:
|
case DB_TOO_MANY_CONCURRENT_TRXS:
|
||||||
/* Once MySQL add the appropriate code to errmsg.txt then
|
/* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
|
||||||
we can get rid of this #ifdef. NOTE: The code checked by
|
available in 5.1.38 and later, but the plugin should still
|
||||||
the #ifdef is the suggested name for the error condition
|
work with previous versions of MySQL. */
|
||||||
and the actual error code name could very well be different.
|
#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
|
||||||
This will require some monitoring, ie. the status
|
return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
|
||||||
of this request on our part.*/
|
#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
|
||||||
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
|
|
||||||
return(ER_TOO_MANY_CONCURRENT_TRXS);
|
|
||||||
#else
|
|
||||||
return(HA_ERR_RECORD_FILE_FULL);
|
return(HA_ERR_RECORD_FILE_FULL);
|
||||||
#endif
|
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
|
||||||
case DB_UNSUPPORTED:
|
case DB_UNSUPPORTED:
|
||||||
return(HA_ERR_UNSUPPORTED);
|
return(HA_ERR_UNSUPPORTED);
|
||||||
}
|
}
|
||||||
@ -949,7 +971,23 @@ innobase_get_cset_width(
|
|||||||
*mbminlen = cs->mbminlen;
|
*mbminlen = cs->mbminlen;
|
||||||
*mbmaxlen = cs->mbmaxlen;
|
*mbmaxlen = cs->mbmaxlen;
|
||||||
} else {
|
} else {
|
||||||
ut_a(cset == 0);
|
THD* thd = current_thd;
|
||||||
|
|
||||||
|
if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
|
||||||
|
|
||||||
|
/* Fix bug#46256: allow tables to be dropped if the
|
||||||
|
collation is not found, but issue a warning. */
|
||||||
|
if ((global_system_variables.log_warnings)
|
||||||
|
&& (cset != 0)){
|
||||||
|
|
||||||
|
sql_print_warning(
|
||||||
|
"Unknown collation #%lu.", cset);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ut_a(cset == 0);
|
||||||
|
}
|
||||||
|
|
||||||
*mbminlen = *mbmaxlen = 0;
|
*mbminlen = *mbmaxlen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2173,7 +2211,7 @@ innobase_change_buffering_inited_ok:
|
|||||||
|
|
||||||
/* --------------------------------------------------*/
|
/* --------------------------------------------------*/
|
||||||
|
|
||||||
srv_file_flush_method_str = innobase_unix_file_flush_method;
|
srv_file_flush_method_str = innobase_file_flush_method;
|
||||||
|
|
||||||
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
|
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
|
||||||
srv_n_log_files = (ulint) innobase_log_files_in_group;
|
srv_n_log_files = (ulint) innobase_log_files_in_group;
|
||||||
@ -2228,6 +2266,9 @@ innobase_change_buffering_inited_ok:
|
|||||||
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
|
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
|
||||||
srv_latin1_ordering = my_charset_latin1.sort_order;
|
srv_latin1_ordering = my_charset_latin1.sort_order;
|
||||||
|
|
||||||
|
innobase_old_blocks_pct = buf_LRU_old_ratio_update(
|
||||||
|
innobase_old_blocks_pct, FALSE);
|
||||||
|
|
||||||
innobase_commit_concurrency_init_default();
|
innobase_commit_concurrency_init_default();
|
||||||
|
|
||||||
/* Since we in this module access directly the fields of a trx
|
/* Since we in this module access directly the fields of a trx
|
||||||
@ -2481,6 +2522,19 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The following calls to read the MySQL binary log
|
||||||
|
file name and the position return consistent results:
|
||||||
|
1) Other InnoDB transactions cannot intervene between
|
||||||
|
these calls as we are holding prepare_commit_mutex.
|
||||||
|
2) Binary logging of other engines is not relevant
|
||||||
|
to InnoDB as all InnoDB requires is that committing
|
||||||
|
InnoDB transactions appear in the same order in the
|
||||||
|
MySQL binary log as they appear in InnoDB logs.
|
||||||
|
3) A MySQL log file rotation cannot happen because
|
||||||
|
MySQL protects against this by having a counter of
|
||||||
|
transactions in prepared state and it only allows
|
||||||
|
a rotation when the counter drops to zero. See
|
||||||
|
LOCK_prep_xids and COND_prep_xids in log.cc. */
|
||||||
trx->mysql_log_file_name = mysql_bin_log_file_name();
|
trx->mysql_log_file_name = mysql_bin_log_file_name();
|
||||||
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
|
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
|
||||||
|
|
||||||
@ -3127,7 +3181,7 @@ retry:
|
|||||||
|
|
||||||
if (is_part) {
|
if (is_part) {
|
||||||
sql_print_error("Failed to open table %s after "
|
sql_print_error("Failed to open table %s after "
|
||||||
"%lu attemtps.\n", norm_name,
|
"%lu attempts.\n", norm_name,
|
||||||
retries);
|
retries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5028,6 +5082,11 @@ ha_innobase::index_read(
|
|||||||
|
|
||||||
index = prebuilt->index;
|
index = prebuilt->index;
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(index == NULL)) {
|
||||||
|
prebuilt->index_usable = FALSE;
|
||||||
|
DBUG_RETURN(HA_ERR_CRASHED);
|
||||||
|
}
|
||||||
|
|
||||||
/* Note that if the index for which the search template is built is not
|
/* Note that if the index for which the search template is built is not
|
||||||
necessarily prebuilt->index, but can also be the clustered index */
|
necessarily prebuilt->index, but can also be the clustered index */
|
||||||
|
|
||||||
@ -5187,6 +5246,7 @@ ha_innobase::change_active_index(
|
|||||||
if (UNIV_UNLIKELY(!prebuilt->index)) {
|
if (UNIV_UNLIKELY(!prebuilt->index)) {
|
||||||
sql_print_warning("InnoDB: change_active_index(%u) failed",
|
sql_print_warning("InnoDB: change_active_index(%u) failed",
|
||||||
keynr);
|
keynr);
|
||||||
|
prebuilt->index_usable = FALSE;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5679,6 +5739,28 @@ create_table_def(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First check whether the column to be added has a
|
||||||
|
system reserved name. */
|
||||||
|
if (dict_col_name_is_reserved(field->field_name)){
|
||||||
|
push_warning_printf(
|
||||||
|
(THD*) trx->mysql_thd,
|
||||||
|
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||||
|
ER_CANT_CREATE_TABLE,
|
||||||
|
"Error creating table '%s' with "
|
||||||
|
"column name '%s'. '%s' is a "
|
||||||
|
"reserved name. Please try to "
|
||||||
|
"re-create the table with a "
|
||||||
|
"different column name.",
|
||||||
|
table->name, (char*) field->field_name,
|
||||||
|
(char*) field->field_name);
|
||||||
|
|
||||||
|
dict_mem_table_free(table);
|
||||||
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
|
error = DB_ERROR;
|
||||||
|
goto error_ret;
|
||||||
|
}
|
||||||
|
|
||||||
dict_mem_table_add_col(table, table->heap,
|
dict_mem_table_add_col(table, table->heap,
|
||||||
(char*) field->field_name,
|
(char*) field->field_name,
|
||||||
col_type,
|
col_type,
|
||||||
@ -5692,6 +5774,7 @@ create_table_def(
|
|||||||
|
|
||||||
error = row_create_table_for_mysql(table, trx);
|
error = row_create_table_for_mysql(table, trx);
|
||||||
|
|
||||||
|
error_ret:
|
||||||
error = convert_error_code_to_mysql(error, flags, NULL);
|
error = convert_error_code_to_mysql(error, flags, NULL);
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
@ -5730,6 +5813,9 @@ create_index(
|
|||||||
|
|
||||||
n_fields = key->key_parts;
|
n_fields = key->key_parts;
|
||||||
|
|
||||||
|
/* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
|
||||||
|
ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
|
||||||
|
|
||||||
ind_type = 0;
|
ind_type = 0;
|
||||||
|
|
||||||
if (key_num == form->s->primary_key) {
|
if (key_num == form->s->primary_key) {
|
||||||
@ -5838,8 +5924,8 @@ create_clustered_index_when_no_primary(
|
|||||||
|
|
||||||
/* We pass 0 as the space id, and determine at a lower level the space
|
/* We pass 0 as the space id, and determine at a lower level the space
|
||||||
id where to store the table */
|
id where to store the table */
|
||||||
|
index = dict_mem_index_create(table_name,
|
||||||
index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
|
innobase_index_reserve_name,
|
||||||
0, DICT_CLUSTERED, 0);
|
0, DICT_CLUSTERED, 0);
|
||||||
|
|
||||||
error = row_create_index_for_mysql(index, trx, NULL);
|
error = row_create_index_for_mysql(index, trx, NULL);
|
||||||
@ -6265,14 +6351,6 @@ ha_innobase::create(
|
|||||||
flags = DICT_TF_COMPACT;
|
flags = DICT_TF_COMPACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = create_table_def(trx, form, norm_name,
|
|
||||||
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a primary key */
|
/* Look for a primary key */
|
||||||
|
|
||||||
primary_key_no= (form->s->primary_key != MAX_KEY ?
|
primary_key_no= (form->s->primary_key != MAX_KEY ?
|
||||||
@ -6284,6 +6362,22 @@ ha_innobase::create(
|
|||||||
|
|
||||||
ut_a(primary_key_no == -1 || primary_key_no == 0);
|
ut_a(primary_key_no == -1 || primary_key_no == 0);
|
||||||
|
|
||||||
|
/* Check for name conflicts (with reserved name) for
|
||||||
|
any user indices to be created. */
|
||||||
|
if (innobase_index_name_is_reserved(trx, form, norm_name)) {
|
||||||
|
error = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = create_table_def(trx, form, norm_name,
|
||||||
|
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create the keys */
|
/* Create the keys */
|
||||||
|
|
||||||
if (form->s->keys == 0 || primary_key_no == -1) {
|
if (form->s->keys == 0 || primary_key_no == -1) {
|
||||||
@ -8468,6 +8562,7 @@ ha_innobase::store_lock(
|
|||||||
&& isolation_level != TRX_ISO_SERIALIZABLE
|
&& isolation_level != TRX_ISO_SERIALIZABLE
|
||||||
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
|
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
|
||||||
&& (sql_command == SQLCOM_INSERT_SELECT
|
&& (sql_command == SQLCOM_INSERT_SELECT
|
||||||
|
|| sql_command == SQLCOM_REPLACE_SELECT
|
||||||
|| sql_command == SQLCOM_UPDATE
|
|| sql_command == SQLCOM_UPDATE
|
||||||
|| sql_command == SQLCOM_CREATE_TABLE)) {
|
|| sql_command == SQLCOM_CREATE_TABLE)) {
|
||||||
|
|
||||||
@ -8475,10 +8570,11 @@ ha_innobase::store_lock(
|
|||||||
option set or this session is using READ COMMITTED
|
option set or this session is using READ COMMITTED
|
||||||
isolation level and isolation level of the transaction
|
isolation level and isolation level of the transaction
|
||||||
is not set to serializable and MySQL is doing
|
is not set to serializable and MySQL is doing
|
||||||
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
|
INSERT INTO...SELECT or REPLACE INTO...SELECT
|
||||||
CREATE ... SELECT... without FOR UPDATE or
|
or UPDATE ... = (SELECT ...) or CREATE ...
|
||||||
IN SHARE MODE in select, then we use consistent
|
SELECT... without FOR UPDATE or IN SHARE
|
||||||
read for select. */
|
MODE in select, then we use consistent read
|
||||||
|
for select. */
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_NONE;
|
prebuilt->select_lock_type = LOCK_NONE;
|
||||||
prebuilt->stored_select_lock_type = LOCK_NONE;
|
prebuilt->stored_select_lock_type = LOCK_NONE;
|
||||||
@ -9634,6 +9730,25 @@ innodb_adaptive_hash_index_update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************//**
|
||||||
|
Update the system variable innodb_old_blocks_pct using the "saved"
|
||||||
|
value. This function is registered as a callback with MySQL. */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
innodb_old_blocks_pct_update(
|
||||||
|
/*=========================*/
|
||||||
|
THD* thd, /*!< in: thread handle */
|
||||||
|
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||||
|
system variable */
|
||||||
|
void* var_ptr,/*!< out: where the
|
||||||
|
formal string goes */
|
||||||
|
const void* save) /*!< in: immediate result
|
||||||
|
from check function */
|
||||||
|
{
|
||||||
|
innobase_old_blocks_pct = buf_LRU_old_ratio_update(
|
||||||
|
*static_cast<const uint*>(save), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Check if it is a valid value of innodb_change_buffering. This function is
|
Check if it is a valid value of innodb_change_buffering. This function is
|
||||||
registered as a callback with MySQL.
|
registered as a callback with MySQL.
|
||||||
@ -9707,6 +9822,46 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
This function checks each index name for a table against reserved
|
||||||
|
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
|
||||||
|
this function pushes an error message to the client, and returns true. */
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
innobase_index_name_is_reserved(
|
||||||
|
/*============================*/
|
||||||
|
/* out: true if an index name
|
||||||
|
matches the reserved name */
|
||||||
|
const trx_t* trx, /* in: InnoDB transaction handle */
|
||||||
|
const TABLE* form, /* in: information on table
|
||||||
|
columns and indexes */
|
||||||
|
const char* norm_name) /* in: table name */
|
||||||
|
{
|
||||||
|
KEY* key;
|
||||||
|
uint key_num; /* index number */
|
||||||
|
|
||||||
|
for (key_num = 0; key_num < form->s->keys; key_num++) {
|
||||||
|
key = form->key_info + key_num;
|
||||||
|
|
||||||
|
if (innobase_strcasecmp(key->name,
|
||||||
|
innobase_index_reserve_name) == 0) {
|
||||||
|
/* Push warning to mysql */
|
||||||
|
push_warning_printf((THD*) trx->mysql_thd,
|
||||||
|
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||||
|
ER_CANT_CREATE_TABLE,
|
||||||
|
"Cannot Create Index with name "
|
||||||
|
"'%s'. The name is reserved "
|
||||||
|
"for the system default primary "
|
||||||
|
"index.",
|
||||||
|
innobase_index_reserve_name);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
static SHOW_VAR innodb_status_variables_export[]= {
|
static SHOW_VAR innodb_status_variables_export[]= {
|
||||||
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
|
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
|
||||||
{NullS, NullS, SHOW_LONG}
|
{NullS, NullS, SHOW_LONG}
|
||||||
@ -9775,7 +9930,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
|
|||||||
" or 2 (write at commit, flush once per second).",
|
" or 2 (write at commit, flush once per second).",
|
||||||
NULL, NULL, 1, 0, 2, 0);
|
NULL, NULL, 1, 0, 2, 0);
|
||||||
|
|
||||||
static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
|
static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
|
||||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||||
"With which method to flush data.", NULL, NULL, NULL);
|
"With which method to flush data.", NULL, NULL, NULL);
|
||||||
|
|
||||||
@ -9871,7 +10026,7 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
|
|||||||
NULL, NULL, 500L, 1L, ~0L, 0);
|
NULL, NULL, 500L, 1L, ~0L, 0);
|
||||||
|
|
||||||
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
|
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
|
||||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
|
||||||
"Number of file I/O threads in InnoDB.",
|
"Number of file I/O threads in InnoDB.",
|
||||||
NULL, NULL, 4, 4, 64, 0);
|
NULL, NULL, 4, 4, 64, 0);
|
||||||
|
|
||||||
@ -9910,6 +10065,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
|
|||||||
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
|
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
|
||||||
NULL, NULL, 1, 1, 10, 0);
|
NULL, NULL, 1, 1, 10, 0);
|
||||||
|
|
||||||
|
static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
|
||||||
|
PLUGIN_VAR_RQCMDARG,
|
||||||
|
"Percentage of the buffer pool to reserve for 'old' blocks.",
|
||||||
|
NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
|
||||||
|
|
||||||
|
static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
|
||||||
|
PLUGIN_VAR_RQCMDARG,
|
||||||
|
"Move blocks to the 'new' end of the buffer pool if the first access"
|
||||||
|
" was at least this many milliseconds ago."
|
||||||
|
" The timeout is disabled if 0 (the default).",
|
||||||
|
NULL, NULL, 0, 0, UINT_MAX32, 0);
|
||||||
|
|
||||||
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
|
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
|
||||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||||
"How many files at the maximum InnoDB keeps open at the same time.",
|
"How many files at the maximum InnoDB keeps open at the same time.",
|
||||||
@ -10008,6 +10175,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||||||
MYSQL_SYSVAR(adaptive_flushing),
|
MYSQL_SYSVAR(adaptive_flushing),
|
||||||
MYSQL_SYSVAR(max_purge_lag),
|
MYSQL_SYSVAR(max_purge_lag),
|
||||||
MYSQL_SYSVAR(mirrored_log_groups),
|
MYSQL_SYSVAR(mirrored_log_groups),
|
||||||
|
MYSQL_SYSVAR(old_blocks_pct),
|
||||||
|
MYSQL_SYSVAR(old_blocks_time),
|
||||||
MYSQL_SYSVAR(open_files),
|
MYSQL_SYSVAR(open_files),
|
||||||
MYSQL_SYSVAR(rollback_on_timeout),
|
MYSQL_SYSVAR(rollback_on_timeout),
|
||||||
MYSQL_SYSVAR(stats_on_metadata),
|
MYSQL_SYSVAR(stats_on_metadata),
|
||||||
|
@ -663,7 +663,7 @@ ha_innobase::add_index(
|
|||||||
if (UNIV_UNLIKELY(error)) {
|
if (UNIV_UNLIKELY(error)) {
|
||||||
err_exit:
|
err_exit:
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
trx_general_rollback_for_mysql(trx, NULL);
|
||||||
trx_free_for_mysql(trx);
|
trx_free_for_mysql(trx);
|
||||||
trx_commit_for_mysql(prebuilt->trx);
|
trx_commit_for_mysql(prebuilt->trx);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
@ -801,7 +801,7 @@ error_handling:
|
|||||||
alter table t drop index b, add index (b);
|
alter table t drop index b, add index (b);
|
||||||
|
|
||||||
The fix will have to parse the SQL and note that the index
|
The fix will have to parse the SQL and note that the index
|
||||||
being added has the same name as the the one being dropped and
|
being added has the same name as the one being dropped and
|
||||||
ignore that in the dup index check.*/
|
ignore that in the dup index check.*/
|
||||||
//dict_table_check_for_dup_indexes(prebuilt->table);
|
//dict_table_check_for_dup_indexes(prebuilt->table);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2008, 2009, Innobase Oy. 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 the Free Software
|
|
||||||
Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
||||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
@file handler/handler0vars.h
|
|
||||||
This file contains accessor functions for dynamic plugin on Windows.
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
|
|
||||||
/*******************************************************************//**
|
|
||||||
This is a list of externals that can not be resolved by delay loading.
|
|
||||||
They have to be resolved indirectly via their addresses in the .map file.
|
|
||||||
All of them are external variables. */
|
|
||||||
extern CHARSET_INFO* wdl_my_charset_bin;
|
|
||||||
extern CHARSET_INFO* wdl_my_charset_latin1;
|
|
||||||
extern CHARSET_INFO* wdl_my_charset_filename;
|
|
||||||
extern CHARSET_INFO** wdl_system_charset_info;
|
|
||||||
extern CHARSET_INFO** wdl_default_charset_info;
|
|
||||||
extern CHARSET_INFO** wdl_all_charsets;
|
|
||||||
extern system_variables* wdl_global_system_variables;
|
|
||||||
extern char* wdl_mysql_real_data_home;
|
|
||||||
extern char** wdl_mysql_data_home;
|
|
||||||
extern char** wdl_tx_isolation_names;
|
|
||||||
extern char** wdl_binlog_format_names;
|
|
||||||
extern char* wdl_reg_ext;
|
|
||||||
extern pthread_mutex_t* wdl_LOCK_thread_count;
|
|
||||||
extern key_map* wdl_key_map_full;
|
|
||||||
extern MY_TMPDIR* wdl_mysql_tmpdir_list;
|
|
||||||
extern bool* wdl_mysqld_embedded;
|
|
||||||
extern uint* wdl_lower_case_table_names;
|
|
||||||
extern ulong* wdl_specialflag;
|
|
||||||
extern int* wdl_my_umask;
|
|
||||||
|
|
||||||
#define my_charset_bin (*wdl_my_charset_bin)
|
|
||||||
#define my_charset_latin1 (*wdl_my_charset_latin1)
|
|
||||||
#define my_charset_filename (*wdl_my_charset_filename)
|
|
||||||
#define system_charset_info (*wdl_system_charset_info)
|
|
||||||
#define default_charset_info (*wdl_default_charset_info)
|
|
||||||
#define all_charsets (wdl_all_charsets)
|
|
||||||
#define global_system_variables (*wdl_global_system_variables)
|
|
||||||
#define mysql_real_data_home (wdl_mysql_real_data_home)
|
|
||||||
#define mysql_data_home (*wdl_mysql_data_home)
|
|
||||||
#define tx_isolation_names (wdl_tx_isolation_names)
|
|
||||||
#define binlog_format_names (wdl_binlog_format_names)
|
|
||||||
#define reg_ext (wdl_reg_ext)
|
|
||||||
#define LOCK_thread_count (*wdl_LOCK_thread_count)
|
|
||||||
#define key_map_full (*wdl_key_map_full)
|
|
||||||
#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
|
|
||||||
#define mysqld_embedded (*wdl_mysqld_embedded)
|
|
||||||
#define lower_case_table_names (*wdl_lower_case_table_names)
|
|
||||||
#define specialflag (*wdl_specialflag)
|
|
||||||
#define my_umask (*wdl_my_umask)
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user