1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
#
# 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=
|