mariadb/mysql-test/suite/binlog/t/binlog_unsafe.test

511 lines
15 KiB
Text
Raw Normal View History

BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
# ==== Purpose ====
#
# Some statements can not be written to the binlog in a safe manner
# with statement-based replication, either because they rely on
# features that are local to the server they are replicated from
# (e.g., @@variables), or because they include nondeterministic
# queries (e.g., LIMIT), or because the time at which the query is
# executed cannot be determined (e.g., INSERT DELAYED). Such
# statements should be marked unsafe. All unsafe statements should
# give a warning.
# Yet the warning/error message isn't issued when SQL_LOG_BIN is turned off.
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
#
# This test verifies that a warning is generated for statements that
# should be unsafe, when they are executed under statement mode
# logging.
#
# All variables should be unsafe, with some exceptions. Therefore,
# this test also verifies that the exceptions do *not* generare a
# warning.
#
#
# ==== Method ====
#
# We try an INSERT DELAYED statement and verify that a warning is
# issued.
#
# We try to insert unsafe variables into a table in several ways:
# directly with an INSERT statement, from a stored procedure, from a
# stored function, from a trigger, from a prepared statement, and from
# a complicated nesting of triggers, functions, procedures, and
# prepared statements. In all cases, a warning should be issued.
#
# We try to insert the variables that should not be unsafe into a
# table, and verify that *no* warning is issued.
#
# Execute a unsafe statement calling a trigger or stored function
# or neither when SQL_LOG_BIN is turned ON, a warning/error should be issued
# Execute a unsafe statement calling a trigger or stored function
# or neither when @@SQL_LOG_BIN is turned OFF,
# no warning/error is issued
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
# ==== Related bugs and worklogs ====
#
# WL#3339: Issue warnings when statement-based replication may fail
# BUG#31168: @@hostname does not replicate
# BUG#34732: mysqlbinlog does not print default values for auto_increment variables
# BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed
# BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0
# BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode)
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
#
# ==== Related test cases ====
#
# rpl.rpl_variables verifies that variables which cannot be replicated
# safely in statement mode are replicated correctly in mixed or row
# mode.
#
# rpl.rpl_variables_stm tests the small subset of variables that
# actually can be replicated safely in statement mode.
#
#
# ==== Todo ====
#
# There are several other ways to create unsafe statements: see, e.g.,
# WL#3339, BUG#34768.
WL#3339 (Issue warnings when statement-based replication may fail): Replacing binlog_row_based_if_mixed with variable binlog_stmt_flags holding several flags and adding member functions to manipulate the flags. Added code to generate a warning when an attempt to log an unsafe statement to the binary log was made. The warning is both pushed to the SHOW WARNINGS table and written to the error log. The prevent flooding the error log, the warning is just written to the error log once per open session. sql/item_create.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.h: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_base.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_class.cc: Adding THD::binlog_flags to store thread-specific binary log state. Adding code to push a warning and write an entry into the error log when an attempt is made to log an unsafe statement. sql/sql_class.h: Adding THD::binlog_flags to store thread-specific binary log state. Adding BINLOG_FLAG_UNSAFE_STMT_PRINTED to denote that a warning for an unsafe statement has already been generated for this thread. sql/sql_insert.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_lex.cc: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/sql_lex.h: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/share/errmsg.txt: Adding error message to indicate that an attempt to log an unsafe statement was made. sql/sql_view.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. mysql-test/r/binlog_unsafe.result: New BitKeeper file ``mysql-test/r/binlog_unsafe.result'' mysql-test/t/binlog_unsafe.test: New BitKeeper file ``mysql-test/t/binlog_unsafe.test''
2007-05-14 14:45:38 +02:00
source include/have_log_bin.inc;
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
source include/have_binlog_format_statement.inc;
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
--echo ==== Setup tables ====
WL#3339 (Issue warnings when statement-based replication may fail): Replacing binlog_row_based_if_mixed with variable binlog_stmt_flags holding several flags and adding member functions to manipulate the flags. Added code to generate a warning when an attempt to log an unsafe statement to the binary log was made. The warning is both pushed to the SHOW WARNINGS table and written to the error log. The prevent flooding the error log, the warning is just written to the error log once per open session. sql/item_create.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.h: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_base.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_class.cc: Adding THD::binlog_flags to store thread-specific binary log state. Adding code to push a warning and write an entry into the error log when an attempt is made to log an unsafe statement. sql/sql_class.h: Adding THD::binlog_flags to store thread-specific binary log state. Adding BINLOG_FLAG_UNSAFE_STMT_PRINTED to denote that a warning for an unsafe statement has already been generated for this thread. sql/sql_insert.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_lex.cc: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/sql_lex.h: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/share/errmsg.txt: Adding error message to indicate that an attempt to log an unsafe statement was made. sql/sql_view.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. mysql-test/r/binlog_unsafe.result: New BitKeeper file ``mysql-test/r/binlog_unsafe.result'' mysql-test/t/binlog_unsafe.test: New BitKeeper file ``mysql-test/t/binlog_unsafe.test''
2007-05-14 14:45:38 +02:00
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a CHAR(40));
CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE trigger_table (a CHAR(7));
CREATE TABLE trigger_table2 (a INT);
WL#3339 (Issue warnings when statement-based replication may fail): Replacing binlog_row_based_if_mixed with variable binlog_stmt_flags holding several flags and adding member functions to manipulate the flags. Added code to generate a warning when an attempt to log an unsafe statement to the binary log was made. The warning is both pushed to the SHOW WARNINGS table and written to the error log. The prevent flooding the error log, the warning is just written to the error log once per open session. sql/item_create.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.h: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_base.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_class.cc: Adding THD::binlog_flags to store thread-specific binary log state. Adding code to push a warning and write an entry into the error log when an attempt is made to log an unsafe statement. sql/sql_class.h: Adding THD::binlog_flags to store thread-specific binary log state. Adding BINLOG_FLAG_UNSAFE_STMT_PRINTED to denote that a warning for an unsafe statement has already been generated for this thread. sql/sql_insert.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_lex.cc: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/sql_lex.h: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/share/errmsg.txt: Adding error message to indicate that an attempt to log an unsafe statement was made. sql/sql_view.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. mysql-test/r/binlog_unsafe.result: New BitKeeper file ``mysql-test/r/binlog_unsafe.result'' mysql-test/t/binlog_unsafe.test: New BitKeeper file ``mysql-test/t/binlog_unsafe.test''
2007-05-14 14:45:38 +02:00
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
--echo ==== Non-deterministic statements ====
WL#3339 (Issue warnings when statement-based replication may fail): Replacing binlog_row_based_if_mixed with variable binlog_stmt_flags holding several flags and adding member functions to manipulate the flags. Added code to generate a warning when an attempt to log an unsafe statement to the binary log was made. The warning is both pushed to the SHOW WARNINGS table and written to the error log. The prevent flooding the error log, the warning is just written to the error log once per open session. sql/item_create.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sp_head.h: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_base.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_class.cc: Adding THD::binlog_flags to store thread-specific binary log state. Adding code to push a warning and write an entry into the error log when an attempt is made to log an unsafe statement. sql/sql_class.h: Adding THD::binlog_flags to store thread-specific binary log state. Adding BINLOG_FLAG_UNSAFE_STMT_PRINTED to denote that a warning for an unsafe statement has already been generated for this thread. sql/sql_insert.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. sql/sql_lex.cc: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/sql_lex.h: Replacing binlog_row_based_if_mixed with a variable binlog_stmt_flags holding several flags. sql/share/errmsg.txt: Adding error message to indicate that an attempt to log an unsafe statement was made. sql/sql_view.cc: Using {is,set,clear}_stmt_unsafe() member functions instead of binlog_row_based_if_mixed member variable. mysql-test/r/binlog_unsafe.result: New BitKeeper file ``mysql-test/r/binlog_unsafe.result'' mysql-test/t/binlog_unsafe.test: New BitKeeper file ``mysql-test/t/binlog_unsafe.test''
2007-05-14 14:45:38 +02:00
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
INSERT DELAYED INTO t1 VALUES (5);
--echo ==== Some variables that *should* be unsafe ====
--echo ---- Insert directly ----
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
--echo ---- Insert from stored procedure ----
DELIMITER |;
CREATE PROCEDURE proc()
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
CALL proc();
--echo ---- Insert from stored function ----
DELIMITER |;
CREATE FUNCTION func()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
RETURN 0;
END|
DELIMITER ;|
SELECT func();
--echo ---- Insert from trigger ----
DELIMITER |;
CREATE TRIGGER trig
BEFORE INSERT ON trigger_table
FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
INSERT INTO trigger_table VALUES ('bye.');
--echo ---- Insert from prepared statement ----
PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)';
PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)';
PREPARE p3 FROM 'INSERT INTO t1 VALUES (@@global.auto_increment_increment)';
PREPARE p4 FROM 'INSERT INTO t2 SELECT UUID()';
PREPARE p5 FROM 'INSERT INTO t2 VALUES (@@session.sql_mode)';
PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)';
PREPARE p7 FROM 'INSERT INTO t2 VALUES (@@hostname)';
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
EXECUTE p1; EXECUTE p2; EXECUTE p3; EXECUTE p4; EXECUTE p5;
EXECUTE p6; EXECUTE p7;
BUG#31168: @@hostname does not replicate Problem: in mixed and statement mode, a query that refers to a system variable will use the slave's value when replayed on slave. So if the value of a system variable is inserted into a table, the slave will differ from the master. Fix: mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode and produce a warning in statement mode. There are some exceptions: some variables are actually replicated. Those should *not* be marked as unsafe. BUG#34732: mysqlbinlog does not print default values for auto_increment variables Problem: mysqlbinlog does not print default values for some variables, including auto_increment_increment and others. So if a client executing the output of mysqlbinlog has different default values, replication will be wrong. Fix: Always print default values for all variables that are replicated. I need to fix the two bugs at the same time, because the test cases would fail if I only fixed one of them. include/m_ctype.h: Added definition of ILLEGAL_CHARSET_INFO_NUMBER. We just need a symbol for a number that will never be used by any charset. ~0U should be safe since charset numbers are sequential, starting from 0. mysql-test/include/commit.inc: Upated test to avoid making statements unsafe. mysql-test/r/commit_1innodb.result: Updated test needs updated result file. mysql-test/r/mysqlbinlog.result: Updated result file. mysql-test/r/mysqlbinlog2.result: Updated result file. mysql-test/r/user_var-binlog.result: Updated result file. mysql-test/suite/binlog/r/binlog_base64_flag.result: Updated result file. mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: Modified test file needs modified result file. mysql-test/suite/binlog/t/binlog_base64_flag.test: Need to filter out pseudo_thread_id from result since it is nondeterministic. mysql-test/suite/binlog/t/binlog_unsafe.test: Add tests that using variables is unsafe. The 'CREATE VIEW' tests didn't make sense, so I removed them. SHOW WARNINGS is not necessary either, because we get warnings for each statement in the result file. mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Updated result file. mysql-test/suite/rpl/r/rpl_skip_error.result: Updated result file. mysql-test/suite/rpl/t/rpl_skip_error.test: The test used @@server_id, which is not safe to replicate, so it would have given a warning. The way it used @@server_id was hackish (issue a query on master that removes rows only on master), so I replaced it by a more robust way to do the same thing (connect to slave and insert the rows only there). Also clarified what the test case does. mysql-test/t/mysqlbinlog2.test: Use --short-form instead of manually filtering out nondeterministic stuff from mysqlbinlog (because we added the nondeterministic @@pseudo_thread_id to the output). sql/item_func.cc: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/item_func.h: Added method of Item_func_get_system_var that indicates whether the given system variable will be written to the binlog or not. sql/log_event.cc: - auto_increment_offset was not written to the binlog if auto_increment_increment=1 - mysqlbinlog did not output default values for some variables (BUG#34732). In st_print_event_info, we remember for each variable whether it has been printed or not. This is achieved in different ways for different variables: - For auto_increment_*, lc_time_names, charset_database_number, we set the default values in st_print_event_info to something illegal, so that it will look like they have changed the first time they are seen. - For charset, sql_mode, pseudo_thread_id, we add a flag to st_print_event_info which indicates whether the variable has been printed. - Since pseudo_thread_id is now printed more often, and its value is not guaranteed to be constant across different runs of the same test script, I replaced it by a constant if --short-form is used. - Moved st_print_event_info constructor from log_event.h to log_event.cc, since it now depends on ILLEGAL_CHARSET_NUMBER, which is defined in m_ctype.h, which is better to include from a .cc file than from a header file. sql/log_event.h: Added fields to st_print_event_info that indicate whether some of the variables have been written or not. Since the initialization of charset_database_number now depends on ILLEGAL_CHARSET_INFO_NUMBER, which is defined in a header file, which we'd better not include from this header file -- I moved the constructor from here to log_event.cc. sql/set_var.cc: System variables now have a flag binlog_status, which indicates if they are written to the binlog. If nothing is specified, all variables are marked as not written to the binlog (NOT_IN_BINLOG) when created. In this file, the variables that are written to the binlog are marked with SESSION_VARIABLE_IN_BINLOG. sql/set_var.h: Added flag binlog_status to class sys_var. Added a getter and a constructor parameter that sets it. Since I had to change sys_var_thd_enum constructor anyways, I simplified it to use default values of arguments instead of three copies of the constructor. sql/sql_yacc.yy: Mark statements that refer to a system variable as "unsafe", meaning they will be replicated by row in mixed mode. Added comment to explain strange piece of code just above. mysql-test/include/diff_tables.inc: New auxiliary test file that tests whether two tables (possibly one on master and one on slave) differ. mysql-test/suite/rpl/r/rpl_variables.result: New test case needs new result file. mysql-test/suite/rpl/r/rpl_variables_stm.result: New test file needs new result file. mysql-test/suite/rpl/t/rpl_variables.test: Test that INSERT of @@variables is replicated correctly (by switching to row-based mode). mysql-test/suite/rpl/t/rpl_variables_stm.test: Test that replication of @@variables which are replicated explicitly works as expected in statement mode (without giving warnings).
2008-03-07 13:59:36 +01:00
--echo ---- Insert from nested call of triggers / functions / procedures ----
DELIMITER |;
# proc1: cause trigger 'trig' above to be triggered.
CREATE PROCEDURE proc1()
INSERT INTO trigger_table VALUES ('ha!')|
# func2: call proc1 above.
CREATE FUNCTION func2()
RETURNS INT
BEGIN
CALL proc1();
RETURN 0;
END|
# trig3: call func2 above
CREATE TRIGGER trig3
BEFORE INSERT ON trigger_table2
FOR EACH ROW
BEGIN
DECLARE tmp INT;
SELECT func2() INTO tmp;
END|
# proc4: cause trig3 above to be triggered.
CREATE PROCEDURE proc4()
INSERT INTO trigger_table2 VALUES (1)|
# func5: call proc4 above.
CREATE FUNCTION func5()
RETURNS INT
BEGIN
CALL proc4;
RETURN 0;
END|
# prep6: call func5() above.
PREPARE prep6 FROM 'SELECT func5()'|
DELIMITER ;|
# try a complicated call path to trigger 'trig'.
EXECUTE prep6;
--echo ==== Variables that should *not* be unsafe ====
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.foreign_key_checks);
INSERT INTO t1 VALUES (@@session.sql_auto_is_null);
INSERT INTO t1 VALUES (@@session.unique_checks);
INSERT INTO t1 VALUES (@@session.auto_increment_increment);
INSERT INTO t1 VALUES (@@session.auto_increment_offset);
INSERT INTO t2 VALUES (@@session.character_set_client);
INSERT INTO t2 VALUES (@@session.collation_connection);
INSERT INTO t2 VALUES (@@session.collation_server);
INSERT INTO t2 VALUES (@@session.time_zone);
INSERT INTO t2 VALUES (@@session.lc_time_names);
INSERT INTO t2 VALUES (@@session.collation_database);
INSERT INTO t2 VALUES (@@session.timestamp);
INSERT INTO t2 VALUES (@@session.last_insert_id);
SET @my_var= 4711;
INSERT INTO t1 VALUES (@my_var);
# using insert_id implicitly should be ok.
SET insert_id=12;
INSERT INTO t3 VALUES (NULL);
--echo ==== Clean up ====
DROP PROCEDURE proc;
DROP FUNCTION func;
DROP TRIGGER trig;
DROP PROCEDURE proc1;
DROP FUNCTION func2;
DROP TRIGGER trig3;
DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
#
# BUG#34768 - nondeterministic INSERT using LIMIT logged in stmt mode if
# binlog_format=mixed
#
CREATE TABLE t1(a INT, b INT, KEY(a), PRIMARY KEY(b));
INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
UPDATE t1 SET a=1 LIMIT 1;
DELETE FROM t1 LIMIT 1;
delimiter |;
CREATE PROCEDURE p1()
BEGIN
INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
UPDATE t1 SET a=1 LIMIT 1;
DELETE FROM t1 LIMIT 1;
END|
delimiter ;|
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Bug#42634: % character in query can cause mysqld signal 11 segfault
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100));
INSERT INTO t1 VALUES ('a','b');
UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1;
DROP TABLE t1;
#
#For bug#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0
#
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1(i INT PRIMARY KEY);
CREATE TABLE t2(i INT PRIMARY KEY);
CREATE TABLE t3(i INT, ch CHAR(50));
--echo "Should issue message Statement may not be safe to log in statement format."
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
DELIMITER |;
CREATE FUNCTION func6()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (11);
INSERT INTO t1 VALUES (12);
RETURN 0;
END|
DELIMITER ;|
--echo "Should issue message Statement may not be safe to log in statement format only once"
INSERT INTO t3 VALUES(func6(), UUID());
--echo "Check whether SET @@SQL_LOG_BIN = 0/1 doesn't work in substatements"
DELIMITER |;
CREATE FUNCTION fun_check_log_bin() RETURNS INT
BEGIN
SET @@SQL_LOG_BIN = 0;
INSERT INTO t1 VALUES(@@global.sync_binlog);
RETURN 100;
END|
DELIMITER ;|
--echo "One unsafe warning should be issued in the following statement"
SELECT fun_check_log_bin();
--echo "SQL_LOG_BIN should be ON still"
SHOW VARIABLES LIKE "SQL_LOG_BIN";
set @save_log_bin = @@SESSION.SQL_LOG_BIN;
set @@SESSION.SQL_LOG_BIN = 0;
--echo "Should NOT have any warning message issued in the following statements"
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
DROP TABLE t1,t2;
--echo "Should NOT have any warning message issued in the following func7() and trig"
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a CHAR(40));
CREATE TABLE trigger_table (a CHAR(7));
DELIMITER |;
CREATE FUNCTION func7()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
RETURN 0;
END|
DELIMITER ;|
SHOW VARIABLES LIKE "SQL_LOG_BIN";
SELECT func7();
--echo ---- Insert from trigger ----
DELIMITER |;
CREATE TRIGGER trig
BEFORE INSERT ON trigger_table
FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
INSERT INTO trigger_table VALUES ('bye.');
#clean up
DROP FUNCTION fun_check_log_bin;
DROP FUNCTION func6;
DROP FUNCTION func7;
DROP TRIGGER trig;
DROP TABLE t1, t2, t3, trigger_table;
set @@SESSION.SQL_LOG_BIN = @save_log_bin;
#
# For BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode)
#
SET @save_sql_mode = @@SESSION.SQL_MODE;
SET @@SESSION.SQL_MODE = STRICT_ALL_TABLES;
CREATE TABLE t1(i INT PRIMARY KEY);
CREATE TABLE t2(i INT PRIMARY KEY);
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
INSERT INTO t1 VALUES(@@global.sync_binlog);
UPDATE t1 SET i = 999 LIMIT 1;
DELETE FROM t1 LIMIT 1;
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
#
# BUG#45827
# The test verifies if stmt that have more than one
# different tables to update with autoinc columns
# will produce unsafe warning
#
# Test case1: stmt that have more than one different tables
# to update with autoinc columns should produce
# unsafe warning when calling a function
CREATE TABLE t1 (a INT, b INT PRIMARY KEY AUTO_INCREMENT);
CREATE TABLE t2 (a INT, b INT PRIMARY KEY AUTO_INCREMENT);
# The purpose of this function is to insert into t1 so that the second
# column is auto_increment'ed.
DELIMITER |;
CREATE FUNCTION func_modify_t1 ()
RETURNS INT
BEGIN
INSERT INTO t1 SET a = 1;
RETURN 0;
END|
DELIMITER ;|
--echo # The following statement causes auto-incrementation
--echo # of both t1 and t2. It is logged in statement format,
--echo # so it should produce unsafe warning.
INSERT INTO t2 SET a = func_modify_t1();
SET SESSION binlog_format = MIXED;
--echo # Check if the statement is logged in row format.
let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1);
INSERT INTO t2 SET a = func_modify_t1();
eval SHOW BINLOG EVENTS FROM $pos0_master;
# clean up
DROP TABLE t1,t2;
DROP FUNCTION func_modify_t1;
# Test case2: stmt that have more than one different tables
# to update with autoinc columns should produce
# unsafe warning when invoking a trigger
SET SESSION binlog_format = STATEMENT;
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT, b INT PRIMARY KEY AUTO_INCREMENT);
CREATE TABLE t3 (a INT, b INT PRIMARY KEY AUTO_INCREMENT);
# The purpose of this function is to insert into t1 so that the second
# column is auto_increment'ed.
delimiter |;
create trigger tri_modify_two_tables before insert on t1 for each row begin
insert into t2(a) values(new.a);
insert into t3(a) values(new.a);
end |
delimiter ;|
--echo # The following statement causes auto-incrementation
--echo # of both t2 and t3. It is logged in statement format,
--echo # so it should produce unsafe warning
INSERT INTO t1 SET a = 1;
SET SESSION binlog_format = MIXED;
--echo # Check if the statement is logged in row format.
let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1);
INSERT INTO t1 SET a = 2;
eval SHOW BINLOG EVENTS FROM $pos1_master;
# clean up
DROP TABLE t1,t2,t3;
BUG#47995: Mark system functions as unsafe Problem: Some system functions that could return different values on master and slave were not marked unsafe. In particular: GET_LOCK IS_FREE_LOCK IS_USED_LOCK MASTER_POS_WAIT RELEASE_LOCK SLEEP SYSDATE VERSION Fix: Mark these functions unsafe. mysql-test/extra/rpl_tests/rpl_stm_000001.test: - The test does not work in mixed mode any more, since it tries to simulate an error in the sql thread in a query that uses get_lock. Since get_lock now causes the query to be logged in row format, the error didn't happen. Hence, we now force statement mode. - Warnings must be disabled when the unsafe query is issued. - Replaced some save_master_pos+connection slave+sync_with_master by sync_slave_with_master. mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: updated result file mysql-test/suite/binlog/r/binlog_stm_row.result: updated result file mysql-test/suite/binlog/r/binlog_unsafe.result: updated result file mysql-test/suite/binlog/t/binlog_killed.test: binlog_killed only works in statement format now, since it switches to row mode in mixed mode. mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: suppress warnings for unsafe statements mysql-test/suite/binlog/t/binlog_stm_row.test: - Suppress warnings in test that causes warnings. - The test sets binlog format explicitly, so no need to execute it twice. mysql-test/suite/binlog/t/binlog_unsafe.test: Added test for all unsafe system functions. This test also includes system functions that were unsafe prior to BUG#47995. mysql-test/suite/rpl/r/rpl_err_ignoredtable.result: updated result file mysql-test/suite/rpl/r/rpl_get_lock.result: updated result file mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result: new result file mysql-test/suite/rpl/r/rpl_stm_000001.result: updated result file mysql-test/suite/rpl/r/rpl_trigger.result: updated result file mysql-test/suite/rpl/t/rpl_err_ignoredtable.test: - suppress warnings for unsafe statement - replaced save_master_pos+connection slave+sync_with_master with sync_slave_with_master mysql-test/suite/rpl/t/rpl_get_lock.test: update test case that causes new warnings mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test: Added new test case for nondeterministic functions. mysql-test/suite/rpl/t/rpl_trigger.test: update test case that causes new warnings sql/item_create.cc: Marked some system functions unsafe. sql/item_strfunc.cc: Clarified comment related to this bug. sql/sql_yacc.yy: Marked sysdate unsafe.
2009-11-18 15:50:31 +01:00
#
# BUG#47995: Mark user functions as unsafe
#
# Test that the system functions that are supposed to be marked unsafe
# generate a warning. Each INSERT statement below should generate a
# warning.
#
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SLEEP(1));
INSERT INTO t1 VALUES (SYSDATE());
INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (VERSION());
DELETE FROM t1;
# Since we replicate the TIMESTAMP variable, functions affected by the
# TIMESTAMP variable are safe to replicate. So we check that the
# following following functions depend on the TIMESTAMP variable and
# don't generate a warning.
SET TIMESTAMP=1000000;
INSERT INTO t1 VALUES
(CURDATE()),
(CURRENT_DATE()),
(CURRENT_TIME()),
(CURRENT_TIMESTAMP()),
(CURTIME()),
(LOCALTIME()),
(LOCALTIMESTAMP()),
(NOW()),
(UNIX_TIMESTAMP()),
(UTC_DATE()),
(UTC_TIME()),
(UTC_TIMESTAMP());
SELECT * FROM t1;
DROP TABLE t1;
--echo "End of tests"