summaryrefslogtreecommitdiff
path: root/mysql-test/r/merge_recover.result
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-12-08 16:57:25 +0300
committerKonstantin Osipov <kostja@sun.com>2009-12-08 16:57:25 +0300
commit463dcbb51ccea25b07e7b6d0d3787120c4fa895d (patch)
tree793d0dad1581ef83133f9fc62cb89d7823dea4a3 /mysql-test/r/merge_recover.result
parentce5c87a3d359d528111d84b5c75bdb8acfe3fb9c (diff)
downloadmariadb-git-463dcbb51ccea25b07e7b6d0d3787120c4fa895d.tar.gz
Backport of revid 2617.69.21, 2617.69.22, 2617.29.23:
---------------------------------------------------------- revno: 2617.69.21 committer: Konstantin Osipov <kostja@sun.com> branch nick: 5.4-4284-1-assert timestamp: Thu 2009-08-13 20:13:55 +0400 message: A fix and a test case for Bug#46610 "MySQL 5.4.4: MyISAM MRG engine crash on auto-repair of child". Also fixes Bug#42862 "Crash on failed attempt to open a children of a merge table". MERGE engine needs to extend the global table list with TABLE_LIST elements for child tables, so that they are opened and locked. Previously these table list elements were allocated in memory of ha_myisammrg object (MERGE engine handler). That would lead to access to freed memory in recover_from_failed_open_table_attempt(), which would try to recover a MERGE table child (MyISAM table) and use for that TABLE_LIST of that child. But by the time recover_from_failed_open_table_attempt() is invoked, ha_myisammrg object that owns this TABLE_LIST may be destroyed, and thus TABLE_LIST memory freed. The fix is to ensure that TABLE_LIST elements that are added to the global table list (lex->query_tables) are always allocated in thd->mem_root, which is not destroyed until end of execution. If previously TABLE_LIST elements were allocated at ha_myisammrg::open() (i.e. when the TABLE object was created and added to the table cache), now they are allocated in ha_myisammrg::add_chidlren_list() (i.e. right after "open" of the merge parent in open_tables()). We still create a list of children names at ha_myisammrg::open() to use as a basis for creation of TABLE_LISTs, that allows to avoid reading the merge handler data file on every execution. mysql-test/r/merge_recover.result: Test results for Bug#46610. mysql-test/t/merge_recover-master.opt: Option file for Bug#46610 test (need a new test because of that option, which is not tested anywhere else). mysql-test/t/merge_recover.test: Add a test case for Bug#46610. sql/table.h: MERGE child child_def_version is now moved from TABLE_LIST to MERGE engine specific data structure. storage/myisammrg/ha_myisammrg.cc: Introduce an auxiliary structure to keep MERGE child name and definition version. A list of Mrg_child_def is created in ha_myisammrg::open() and reused in ha_myisammrg::add_children_list().
Diffstat (limited to 'mysql-test/r/merge_recover.result')
-rw-r--r--mysql-test/r/merge_recover.result103
1 files changed, 103 insertions, 0 deletions
diff --git a/mysql-test/r/merge_recover.result b/mysql-test/r/merge_recover.result
new file mode 100644
index 00000000000..871c12ca4c0
--- /dev/null
+++ b/mysql-test/r/merge_recover.result
@@ -0,0 +1,103 @@
+#
+# Test of MyISAM MRG tables with corrupted children.
+# Run with --myisam-recover=force option.
+#
+# Preparation: we need to make sure that the merge parent
+# is never left in the table cache when closed, since this may
+# have effect on merge children.
+# For that, we set the table cache to minimal size and populate it
+# in a concurrent connection.
+#
+# Switching to connection con1
+#
+#
+# Minimal values.
+#
+call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
+call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
+call mtr.add_suppression(" '\..test.t1'");
+set global table_open_cache=256;
+set global table_definition_cache=400;
+drop procedure if exists p_create;
+create procedure p_create()
+begin
+declare i int default 1;
+set @lock_table_stmt="lock table ";
+set @drop_table_stmt="drop table ";
+while i < @@global.table_definition_cache + 1 do
+set @table_name=concat("t_", i);
+set @opt_comma=if(i=1, "", ", ");
+set @lock_table_stmt=concat(@lock_table_stmt, @opt_comma,
+@table_name, " read");
+set @drop_table_stmt=concat(@drop_table_stmt, @opt_comma, @table_name);
+set @create_table_stmt=concat("create table if not exists ",
+@table_name, " (a int)");
+prepare stmt from @create_table_stmt;
+execute stmt;
+deallocate prepare stmt;
+set i= i+1;
+end while;
+end|
+call p_create();
+drop procedure p_create;
+#
+# Switching to connection 'default'
+#
+#
+# We have to disable the ps-protocol, to avoid
+# "Prepared statement needs to be re-prepared" errors
+# -- table def versions change all the time with full table cache.
+#
+drop table if exists t1, t1_mrg, t1_copy;
+#
+# Prepare a MERGE engine table, that refers to a corrupted
+# child.
+#
+create table t1 (a int, key(a)) engine=myisam;
+create table t1_mrg (a int) union (t1) engine=merge;
+#
+# Create a table with a corrupted index file:
+# save an old index file, insert more rows,
+# overwrite the new index file with the old one.
+#
+insert into t1 (a) values (1), (2), (3);
+flush table t1;
+insert into t1 (a) values (4), (5), (6);
+flush table t1;
+# check table is needed to mark the table as crashed.
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Size of datafile is: 42 Should be: 21
+test.t1 check error Record-count is not ok; is 6 Should be: 3
+test.t1 check warning Found 6 key parts. Should be: 3
+test.t1 check error Corrupt
+#
+# At this point we have a merge table t1_mrg pointing to t1,
+# and t1 is corrupted, and will be auto-repaired at open.
+# Check that this doesn't lead to memory corruption.
+#
+select * from t1_mrg;
+a
+1
+2
+3
+4
+5
+6
+Warnings:
+Error 145 Table 't1' is marked as crashed and should be repaired
+Error 1194 Table 't1' is marked as crashed and should be repaired
+Error 1034 Number of rows changed from 3 to 6
+#
+# Cleanup
+#
+drop table t1, t1_mrg;
+#
+# Switching to connection con1
+#
+unlock tables;
+prepare stmt from @drop_table_stmt;
+execute stmt;
+deallocate prepare stmt;
+set @@global.table_definition_cache=default;
+set @@global.table_open_cache=default;