polardbxengine/mysql-test/extra/binlog_tests/binlog_crash_safe_ddl.inc

212 lines
5.8 KiB
PHP

#
# The macro processes a DDL statement while its handling is
# interrupted by simulated crashes at time of the query
# has not yet been logged and upon that.
# The first, pre-binlog crash happens right after prepare in SEs
# (storage engines), before binary log event for the statement is
# flushed to the disk. In this case statement should be correctly
# rolled back by recovery. The second, post-binlog crash to the
# repeated statement occurs after binary log event is flushed to the
# disk, before commit in the SEs.
# The query results must be found committed upon the server restart.
# The binlog is rotated at the beginning of either crash simulation
# and its resulted file is memorized to optionally print out
# its events which must contain a new XID field.
#
# Another purpose of the macro to run simply as a load
# generator e.g for a slave server without crash simulations
# ($do_only_regular_logging).
#
# The macro increments
# $count_ddl_queries
# per its invocation which serves as a counter for the number of
# processed queries.
#
# Usage, e.g:
#
# --let $do_pre_binlog=1
# --let $do_post_binlog=1
# --let $do_only_regular_logging=1 # run only query no crash simulation
# --let $ddl_query=CREATE USER user1
# --let $pre_binlog_crash_check= [SELECT count(*) = 0 FROM mysql.user WHERE user = 'user1']
# --let $post_binlog_crash_check= [SELECT count(*) = 1 FROM mysql.user WHERE user = 'user1']
#
# --let $do_show_binlog_events=1 # invoke show-binlog-events at the
# # end of query execution
# --let $do_count_queries # When set the processed queries are counted in $count_ddl_queries
# --let $master_log_table # DDL query and post-recovery checks can be logged in a table
# --let $master_log_db # The database of the log table
#
# here a value in [] can be just empty to indicate no check after
# the corresponding crash is done.
#
if ($do_count_queries)
{
--inc $count_ddl_queries
}
--disable_query_log
if ($master_log_table)
{
--let $save_curr_db=`SELECT database()`
if ($master_log_db)
{
--eval USE $master_log_db
}
--eval INSERT INTO $master_log_table SET id= NULL, ddl_query= "$ddl_query", pre_binlog_check= "$pre_binlog_crash_check", post_binlog_check= "$post_binlog_crash_check"
--eval USE $save_curr_db
}
--enable_query_log
# $do_only_regular_logging is incompatible with crash simulating $do:s.
if ($do_only_regular_logging)
{
if ($do_pre_binlog)
{
--echo *** Wrong option combination! ***
--die
}
if ($do_post_binlog)
{
--echo *** Wrong option combination! ***
--die
}
}
--source include/gtid_step_reset.inc
if ($do_pre_binlog)
{
FLUSH LOGS;
--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
#
# prepare, the first CRASH, /* log, commit */
#
--let $gen_ddl_query = `SELECT REPLACE("$ddl_query",'.so','_LIB')`
--let $gen_ddl_query = `SELECT REPLACE("$gen_ddl_query",'.dll','_LIB')`
--echo *** Crash right after '$gen_ddl_query' has been prepared in the engine before being logged ***
--source include/expect_crash.inc
SET @@SESSION.debug="+d,crash_commit_before_log";
--disable_query_log
if ($manual_gtid_next)
{
--eval $manual_gtid_next
}
--enable_query_log
--replace_result .so _LIB .dll _LIB
--error 2013
--eval $ddl_query
#
# restart the server
#
--source include/start_mysqld.inc
if ($pre_binlog_crash_check)
{
if (!`$pre_binlog_crash_check`)
{
--echo *** State check upon recovery after pre-binlog crash fails ***
--die
}
}
if ($do_show_binlog_events)
{
--let $keep_ddl_xid=1
--let $show_binlog_events_mask_columns=1,2,4,5
--source include/show_binlog_events.inc
}
# The Gtid check, when its mode ON.
# After rollback-recovery of this branch Gtid executed must
# remain as was before the query execution.
--let $gtid_step_count=0
--source include/gtid_step_assert.inc
} # end of $do_pre_binlog
if ($do_post_binlog)
{
FLUSH LOGS;
--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
#
# prepare, log, the 2nd CRASH, /* commit */
#
--let $gen_ddl_query = `SELECT REPLACE("$ddl_query",'.so','_LIB')`
--let $gen_ddl_query = `SELECT REPLACE("$gen_ddl_query",'.dll','_LIB')`
--echo *** Crash right after '$gen_ddl_query' has been binary-logged before committed in the engine ***
--source include/expect_crash.inc
SET @@SESSION.debug="+d,crash_commit_after_log";
# End of Debug
--disable_query_log
if ($manual_gtid_next)
{
--eval $manual_gtid_next
}
--enable_query_log
--replace_result .so _LIB .dll _LIB
--error 2013
--eval $ddl_query
#
# restart the server
#
--source include/start_mysqld.inc
if ($post_binlog_crash_check)
{
if (!`$post_binlog_crash_check`)
{
--echo *** State check upon recovery after pre-commit crash fails ***
--die
}
}
if ($do_show_binlog_events)
{
--let $keep_ddl_xid=1
--let $show_binlog_events_mask_columns=1,2,4,5
--source include/show_binlog_events.inc
}
# The Gtid check, when its mode ON.
# After commit-recovery of this branch Gtid executed must
# receive a new gtid item of the current DDL transaction.
--let $gtid_step_count=1
--source include/gtid_step_assert.inc
} # end of $do_post_binlog
if ($do_only_regular_logging)
{
FLUSH LOGS;
# Some uses of this involve the name of a library, mask OS difference
--replace_result .so _LIB .dll _LIB
--eval $ddl_query
if ($do_show_binlog_events)
{
--let $keep_ddl_xid=1
--let $show_binlog_events_mask_columns=1,2,4,5
--source include/show_binlog_events.inc
}
# The Gtid check, when its mode ON.
# After commit-recovery of this branch Gtid executed must
# receive a new gtid item of the current DDL transaction.
--let $gtid_step_count=1
--source include/gtid_step_assert.inc
}
#
# Cleanup
#
--let $keep_ddl_xid=
--let $show_binlog_events_mask_columns=