mirror of
https://github.com/MariaDB/server.git
synced 2025-02-12 00:15:35 +01:00
![Monty](/assets/img/avatar_default.png)
There are a few different cases to consider Logging of CREATE TABLE and CREATE TABLE ... LIKE - If REPLACE is used and there was an existing table, DDL log the drop of the table. - If discovery of table is to be done - DDL LOG create table else - DDL log create table (with engine type) - create the table - If table was created - Log entry to binary log with xid - Mark DDL log completed Crash recovery: - If query was in binary log do nothing and exit - If discoverted table - Delete the .frm file -else - Drop created table and frm file - If table was dropped, write a DROP TABLE statement in binary log CREATE TABLE ... SELECT required a little more work as when one is using statement logging the query is written to the binary log before commit is done. This was fixed by adding a DROP TABLE to the binary log during crash recovery if the ddl log entry was not closed. In this case the binary log will contain: CREATE TABLE xxx ... SELECT .... DROP TABLE xxx; Other things: - Added debug_crash_here() functionality to Aria to be able to test crash in create table between the creation of the .MAI and the .MAD files.
105 lines
3.6 KiB
Text
105 lines
3.6 KiB
Text
--source include/have_innodb.inc
|
|
--source include/have_debug_sync.inc
|
|
--source include/have_log_bin.inc
|
|
--source include/have_binlog_format_mixed_or_statement.inc
|
|
--source include/binlog_start_pos.inc
|
|
|
|
# Need DBUG to crash the server intentionally
|
|
--source include/have_debug.inc
|
|
# Don't test this under valgrind, memory leaks will occur as we crash
|
|
--source include/not_valgrind.inc
|
|
|
|
# The test case currently uses sed and tail, which may be unavailable on
|
|
# some windows systems. But see MWL#191 for how to remove the need for grep.
|
|
--source include/not_windows.inc
|
|
|
|
# XtraDB stores the binlog position corresponding to the last commit, and
|
|
# prints it during crash recovery.
|
|
# Test that we get the correct position when we group commit several
|
|
# transactions together.
|
|
|
|
# What we really want to test here is what happens when a group of
|
|
# transactions get written only partially to disk inside InnoDB before
|
|
# the crash. But that is hard to test in mysql-test-run automated
|
|
# tests. Instead, we use debug_sync to tightly control when each
|
|
# transaction is written to the redo log. And we set
|
|
# innodb_flush_log_at_trx_commit=3 so that we can write out
|
|
# transactions individually - as with
|
|
# innodb_flush_log_at_trx_commit=1, all commits are written together,
|
|
# as part of a commit_checkpoint.
|
|
# (Note that we do not have to restore innodb_flush_log_at_trx_commit, as
|
|
# we crash the server).
|
|
SET GLOBAL innodb_flush_log_at_trx_commit=3;
|
|
|
|
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
|
|
INSERT INTO t1 VALUES (0);
|
|
|
|
connect(con1,localhost,root,,);
|
|
connect(con2,localhost,root,,);
|
|
connect(con3,localhost,root,,);
|
|
|
|
# Queue up three commits for group commit.
|
|
|
|
connection con1;
|
|
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
|
|
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont EXECUTE 3";
|
|
send INSERT INTO t1 VALUES (1);
|
|
|
|
connection con2;
|
|
SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
|
|
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
|
|
send INSERT INTO t1 VALUES (2);
|
|
|
|
connection con3;
|
|
SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
|
|
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
|
|
send INSERT INTO t1 VALUES (3);
|
|
|
|
connection default;
|
|
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
|
# At this point, no transactions are committed.
|
|
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
|
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
|
# At this point, 1 transaction is committed.
|
|
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
|
|
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
|
|
|
|
# At this point, 2 transactions are committed.
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
connection con2;
|
|
reap;
|
|
|
|
# Now crash the server with 1+2 in-memory committed, 3 only prepared.
|
|
connection default;
|
|
system echo wait-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
|
SET SESSION debug_dbug="+d,crash_dispatch_command_before";
|
|
--error 2006,2013
|
|
SELECT 1;
|
|
|
|
connection con1;
|
|
--error 2006,2013
|
|
reap;
|
|
connection con3;
|
|
--error 2006,2013
|
|
reap;
|
|
|
|
system echo restart-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
|
|
|
connection default;
|
|
--enable_reconnect
|
|
--source include/wait_until_connected_again.inc
|
|
|
|
# Crash recovery should recover all three transactions.
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
# Check that the binlog position reported by InnoDB is the correct one
|
|
# for the end of the second transaction (as can be checked with
|
|
# mysqlbinlog).
|
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
|
let pos=`select $binlog_start_pos + 739`;
|
|
--replace_result $pos <pos>
|
|
--exec sed -ne 's/.*\(InnoDB: Last binlog file .* position.*\)/\1/p' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
|
|
|
|
SET DEBUG_SYNC= 'RESET';
|
|
DROP TABLE t1;
|