#At file:///home/mysql_src/bzrrepos/mysql-6.0-maria/
2670 Guilhem Bichot 2008-06-30 [merge]
merge of 5.1-maria (mysql-maria branch) into mysql-6.0-maria
added:
mysql-test/r/maria-recovery2.result
mysql-test/r/row-checksum-old.result
mysql-test/r/row-checksum.result
mysql-test/t/maria-recovery2-master.opt
mysql-test/t/maria-recovery2.test
mysql-test/t/row-checksum-old-master.opt
mysql-test/t/row-checksum-old.test
mysql-test/t/row-checksum.test
modified:
KNOWN_BUGS.txt
mysql-test/r/maria-recovery.result
mysql-test/r/old-mode.result
mysql-test/t/maria-recovery.test
mysql-test/t/old-mode.test
sql/ha_partition.cc
sql/handler.cc
sql/handler.h
sql/sql_show.cc
sql/sql_table.cc
storage/maria/ha_maria.cc
storage/maria/ha_maria.h
storage/maria/ma_blockrec.c
storage/maria/ma_check.c
storage/maria/ma_open.c
storage/maria/ma_test1.c
storage/maria/unittest/ma_test_loghandler_multithread-t.c
storage/myisam/ha_myisam.cc
storage/myisam/ha_myisam.h
storage/myisam/mi_open.c
storage/myisam/myisamdef.h
=== modified file 'KNOWN_BUGS.txt'
--- a/KNOWN_BUGS.txt 2008-06-02 20:53:25 +0000
+++ b/KNOWN_BUGS.txt 2008-06-28 15:09:03 +0000
@@ -27,9 +27,15 @@ Known bugs that we are working on and wi
- We have some instabilities in log writing that is under investigatation
This causes mainly assert to triggers in the code and sometimes
the log handler doesn't start up after restart.
+ Most of this should now be fixed...
+
+- INSERT on a duplicate key against a key inserted by another connection
+ that has not yet ended will give a duplicate key error instead of
+ waiting for the other statement to end.
-Known bugs that are planned to be fixed before Beta
-===================================================
+
+Known bugs that are planned to be fixed before Gamma/RC
+=======================================================
- If we get a write failure on disk (disk full or disk error) for the
log, we should stop all usage of transactional tables and mark all
@@ -44,18 +50,31 @@ Known bugs that are planned to be fixed
or kill mysqld, remove logs and repair tables.
+Known bugs that are planned to be fixed later
+=============================================
+
+LOCK TABLES .. WRITE CONCURRENT is mainly done for testing MVCC. Don't
+use this in production. Things that is not working if you are using
+this on a table:
+
+- INSERT/REPLACE ... SELECT on an empty table may cause crashes or
+ wrong results if someone else is doing writes on the table during repair
+ or someone is doing selects during the repair index phase.
+
+INSERT ... SELECT, REPLACE ... SELECT and LOAD DATA are blocking
+inserts and SELECT for the table. They should only have to do this if
+the destination is empty (as then we are using fast index rebuild).
+
Missing features that is planned to fix before Beta
===================================================
-- Multiple concurrent inserts & multiple concurrent readers at same time
- with full MVCC control. Note that UPDATE and DELETE will still be
- blocking (as with MyISAM)
-- COUNT(*) and TABLE CHECKSUM under MVCC (ie, they are instant and kept up
- to date even with multiple inserter)
-
+None
Features planned for future releases
====================================
+Most notable is full transaction support and multiple reader/writers
+in Maria 2.0
+
http://forge.mysql.com/worklog/
(you can enter "maria" in the "quick search" field there).
=== modified file 'mysql-test/r/maria-recovery.result'
--- a/mysql-test/r/maria-recovery.result 2008-06-26 17:48:42 +0000
+++ b/mysql-test/r/maria-recovery.result 2008-06-30 09:59:59 +0000
@@ -237,145 +237,6 @@ t1 CREATE TABLE `t1` (
) ENGINE=MARIA AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
insert into t1 values(null, "f");
drop table t1;
-* TEST of removing logs manually
-* shut down mysqld, removed logs, restarted it
-* TEST of UNDO_ROW_DELETE preserving rowid
-create table t1(a int) engine=maria;
-insert into t1 values(1),(2);
-flush table t1;
-* copied t1 for comparison
-lock tables t1 write;
-insert into t1 values(3);
-delete from t1 where a in (1,2,3);
-SET SESSION debug="+d,maria_flush_whole_log,maria_crash";
-* crashing mysqld intentionally
-set global maria_checkpoint_interval=1;
-ERROR HY000: Lost connection to MySQL server during query
-* recovery happens
-check table t1 extended;
-Table Op Msg_type Msg_text
-mysqltest.t1 check status OK
-* testing that checksum after recovery is as expected
-Checksum-check
-ok
-use mysqltest;
-drop table t1;
-* TEST of checkpoint
-set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect";
-set global maria_checkpoint_interval=10000;
-create table t1(a int, b varchar(10), index(a,b)) engine=maria;
-insert into t1 values(1,"a"),(2,"b"),(3,"c");
-delete from t1 where b="b";
-update t1 set b="d" where a=1;
-flush table t1;
-* copied t1 for comparison
-lock tables t1 write;
-insert into t1 values(4,"e"),(5,"f"),(6,"g");
-update t1 set b="h" where a=5;
-delete from t1 where b="g";
-show status like "Maria_pagecache_blocks_not_flushed";
-Variable_name Value
-Maria_pagecache_blocks_not_flushed 3
-set global maria_checkpoint_interval=10000;
-update t1 set b="i" where a=5;
-SET SESSION debug="+d,maria_crash";
-* crashing mysqld intentionally
-set global maria_checkpoint_interval=1;
-ERROR HY000: Lost connection to MySQL server during query
-* recovery happens
-check table t1 extended;
-Table Op Msg_type Msg_text
-mysqltest.t1 check status OK
-* testing that checksum after recovery is as expected
-Checksum-check
-ok
-use mysqltest;
-drop table t1;
-Test of REPAIR's implicit commit
-create table t1 (a varchar(100), key(a)) engine=maria;
-insert into t1 values(3);
-flush table t1;
-* copied t1 for comparison
-lock tables t1 write;
-insert into t1 values (1);
-repair table t1;
-Table Op Msg_type Msg_text
-mysqltest.t1 repair status OK
-insert into t1 values(2);
-select * from t1;
-a
-1
-2
-3
-SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
-* crashing mysqld intentionally
-set global maria_checkpoint_interval=1;
-ERROR HY000: Lost connection to MySQL server during query
-* recovery happens
-check table t1 extended;
-Table Op Msg_type Msg_text
-mysqltest.t1 check status OK
-* testing that checksum after recovery is as expected
-Checksum-check
-failure
-use mysqltest;
-select * from t1;
-a
-1
-3
-drop table t1;
-* TEST of recovery when crash before bulk-insert-with-repair is committed
-create table t1 (a varchar(100), key(a)) engine=maria;
-create table t2 (a varchar(100)) engine=myisam;
-set rand_seed1=12, rand_seed2=254;
-insert into t2 values (rand());
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t1 values(30);
-flush table t1;
-* copied t1 for comparison
-lock tables t1 write, t2 read;
-delete from t1 limit 1;
-insert into t1 select * from t2;
-SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
-* crashing mysqld intentionally
-set global maria_checkpoint_interval=1;
-ERROR HY000: Lost connection to MySQL server during query
-* recovery happens
-check table t1 extended;
-Table Op Msg_type Msg_text
-mysqltest.t1 check status OK
-* testing that checksum after recovery is as expected
-Checksum-check
-ok
-use mysqltest;
-show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_Comment
-t1 1 a 1 a A 1 NULL NULL YES BTREE
-drop table t1;
-* TEST of recovery when OPTIMIZE has replaced the index file and crash
-create table t_corrupted1 (a varchar(100), key(a)) engine=maria;
-insert into t_corrupted1 select (rand()) from t2;
-flush table t_corrupted1;
-* copied t_corrupted1 for comparison
-SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash_sort_index";
-* crashing mysqld intentionally
-optimize table t_corrupted1;
-ERROR HY000: Lost connection to MySQL server during query
-* recovery happens
-check table t_corrupted1 extended;
-Table Op Msg_type Msg_text
-mysqltest.t_corrupted1 check warning Table is marked as crashed and last repair failed
-mysqltest.t_corrupted1 check status OK
-* testing that checksum after recovery is as expected
-Checksum-check
-ok
-use mysqltest;
-drop table t_corrupted1, t2;
drop database mysqltest_for_feeding_recovery;
drop database mysqltest_for_comparison;
drop database mysqltest;
=== added file 'mysql-test/r/maria-recovery2.result'
--- a/mysql-test/r/maria-recovery2.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/maria-recovery2.result 2008-06-30 09:59:59 +0000
@@ -0,0 +1,145 @@
+set global maria_log_file_size=4294967295;
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+* TEST of removing logs manually
+* shut down mysqld, removed logs, restarted it
+* TEST of UNDO_ROW_DELETE preserving rowid
+create table t1(a int) engine=maria;
+insert into t1 values(1),(2);
+flush table t1;
+* copied t1 for comparison
+lock tables t1 write;
+insert into t1 values(3);
+delete from t1 where a in (1,2,3);
+SET SESSION debug="+d,maria_flush_whole_log,maria_crash";
+* crashing mysqld intentionally
+set global maria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+drop table t1;
+* TEST of checkpoint
+set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect";
+set global maria_checkpoint_interval=10000;
+create table t1(a int, b varchar(10), index(a,b)) engine=maria;
+insert into t1 values(1,"a"),(2,"b"),(3,"c");
+delete from t1 where b="b";
+update t1 set b="d" where a=1;
+flush table t1;
+* copied t1 for comparison
+lock tables t1 write;
+insert into t1 values(4,"e"),(5,"f"),(6,"g");
+update t1 set b="h" where a=5;
+delete from t1 where b="g";
+show status like "Maria_pagecache_blocks_not_flushed";
+Variable_name Value
+Maria_pagecache_blocks_not_flushed 3
+set global maria_checkpoint_interval=10000;
+update t1 set b="i" where a=5;
+SET SESSION debug="+d,maria_crash";
+* crashing mysqld intentionally
+set global maria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+drop table t1;
+Test of REPAIR's implicit commit
+create table t1 (a varchar(100), key(a)) engine=maria;
+insert into t1 values(3);
+flush table t1;
+* copied t1 for comparison
+lock tables t1 write;
+insert into t1 values (1);
+repair table t1;
+Table Op Msg_type Msg_text
+mysqltest.t1 repair status OK
+insert into t1 values(2);
+select * from t1;
+a
+1
+2
+3
+SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
+* crashing mysqld intentionally
+set global maria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+failure
+use mysqltest;
+select * from t1;
+a
+1
+3
+drop table t1;
+* TEST of recovery when crash before bulk-insert-with-repair is committed
+create table t1 (a varchar(100), key(a)) engine=maria;
+create table t2 (a varchar(100)) engine=myisam;
+set rand_seed1=12, rand_seed2=254;
+insert into t2 values (rand());
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t1 values(30);
+flush table t1;
+* copied t1 for comparison
+lock tables t1 write, t2 read;
+delete from t1 limit 1;
+insert into t1 select * from t2;
+SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
+* crashing mysqld intentionally
+set global maria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_Comment
+t1 1 a 1 a A 1 NULL NULL YES BTREE
+drop table t1;
+* TEST of recovery when OPTIMIZE has replaced the index file and crash
+create table t_corrupted1 (a varchar(100), key(a)) engine=maria;
+insert into t_corrupted1 select (rand()) from t2;
+flush table t_corrupted1;
+* copied t_corrupted1 for comparison
+SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash_sort_index";
+* crashing mysqld intentionally
+optimize table t_corrupted1;
+ERROR HY000: Lost connection to MySQL server during query
+* recovery happens
+check table t_corrupted1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t_corrupted1 check warning Table is marked as crashed and last repair failed
+mysqltest.t_corrupted1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+drop table t_corrupted1, t2;
+drop database mysqltest_for_comparison;
+drop database mysqltest;
=== modified file 'mysql-test/r/old-mode.result'
--- a/mysql-test/r/old-mode.result 2007-12-04 21:23:42 +0000
+++ b/mysql-test/r/old-mode.result 2008-06-28 12:45:15 +0000
@@ -5,8 +5,12 @@ insert t1 values (1, "aaa", "bbb"), (NUL
insert t2 select * from t1;
checksum table t1, t2;
Table Checksum
-test.t1 3442722830
+test.t1 2948697075
test.t2 2948697075
+checksum table t1, t2 quick;
+Table Checksum
+test.t1 NULL
+test.t2 NULL
checksum table t1, t2 extended;
Table Checksum
test.t1 2948697075
=== added file 'mysql-test/r/row-checksum-old.result'
--- a/mysql-test/r/row-checksum-old.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/row-checksum-old.result 2008-06-28 12:45:15 +0000
@@ -0,0 +1,85 @@
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 452555338
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 452555338
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 452555338
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 452555338
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 452555338
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 452555338
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=maria checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 452555338
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 452555338
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=maria checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 452555338
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 452555338
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 4108368782
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 4108368782
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 4108368782
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 4108368782
+drop table t1;
=== added file 'mysql-test/r/row-checksum.result'
--- a/mysql-test/r/row-checksum.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/row-checksum.result 2008-06-28 12:45:15 +0000
@@ -0,0 +1,85 @@
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 229851577
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 229851577
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 229851577
+checksum table t1 quick;
+Table Checksum
+test.t1 229851577
+checksum table t1 extended;
+Table Checksum
+test.t1 229851577
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 229851577
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 229851577
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=maria checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 229851577
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 229851577
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=maria checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 229851577
+checksum table t1 quick;
+Table Checksum
+test.t1 229851577
+checksum table t1 extended;
+Table Checksum
+test.t1 229851577
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 3885665021
+checksum table t1 quick;
+Table Checksum
+test.t1 3885665021
+checksum table t1 extended;
+Table Checksum
+test.t1 3885665021
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+Table Checksum
+test.t1 3885665021
+checksum table t1 quick;
+Table Checksum
+test.t1 NULL
+checksum table t1 extended;
+Table Checksum
+test.t1 3885665021
+drop table t1;
=== modified file 'mysql-test/t/maria-recovery.test'
--- a/mysql-test/t/maria-recovery.test 2008-06-27 13:30:49 +0000
+++ b/mysql-test/t/maria-recovery.test 2008-06-30 09:59:59 +0000
@@ -195,129 +195,6 @@ show create table t1;
insert into t1 values(null, "f");
drop table t1;
-# Test of removing logs manually
---echo * TEST of removing logs manually
-let $mel_keep_control_file=1;
-# this will shut mysqld down cleanly (so, take a checkpoint) and
-# remove only logs; at restart Maria will create a new log with a high
-# number
--- source include/maria_empty_logs.inc
-let $mel_keep_control_file=0;
-# next test will help us verify that a next recovery is ok
-
---echo * TEST of UNDO_ROW_DELETE preserving rowid
-# we want recovery to use the tables as they were at time of crash
-let $mvr_restore_old_snapshot=0;
-# UNDO phase prevents physical comparison, normally,
-# so we'll only use checksums to compare.
-let $mms_compare_physically=0;
-let $mvr_crash_statement= set global maria_checkpoint_interval=1;
-create table t1(a int) engine=maria;
-insert into t1 values(1),(2);
--- source include/maria_make_snapshot_for_comparison.inc
-lock tables t1 write;
-insert into t1 values(3);
-delete from t1 where a in (1,2,3);
--- source include/maria_verify_recovery.inc
-drop table t1;
-
-# A basic checkpoint test
---echo * TEST of checkpoint
-# Don't take a full checkpoints, we want to test checkpoint vs dirty pages
-set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect";
-# restart checkpoint thread for it to notice the above
-set global maria_checkpoint_interval=10000;
-create table t1(a int, b varchar(10), index(a,b)) engine=maria;
-insert into t1 values(1,"a"),(2,"b"),(3,"c");
-delete from t1 where b="b";
-update t1 set b="d" where a=1;
--- source include/maria_make_snapshot_for_comparison.inc
-lock tables t1 write;
-insert into t1 values(4,"e"),(5,"f"),(6,"g");
-update t1 set b="h" where a=5;
-delete from t1 where b="g";
-show status like "Maria_pagecache_blocks_not_flushed";
-# force a checkpoint; there should be dirty pages and an open transaction
-set global maria_checkpoint_interval=10000;
-# do some more work
-update t1 set b="i" where a=5;
-let $mvr_restore_old_snapshot=0;
-let $mms_compare_physically=0;
-let $mvr_debug_option="+d,maria_crash";
-let $mvr_crash_statement= set global maria_checkpoint_interval=1;
-# Now we have a recovery, which should use the checkpoint record
-# and its dirty pages list.
--- source include/maria_verify_recovery.inc
-drop table t1;
-
---echo Test of REPAIR's implicit commit
-let $mms_tables=1;
-create table t1 (a varchar(100), key(a)) engine=maria;
-let $mvr_restore_old_snapshot=0;
-let $mms_compare_physically=0;
-let $mvr_crash_statement= set global maria_checkpoint_interval=1;
-
-let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
-insert into t1 values(3);
--- source include/maria_make_snapshot_for_comparison.inc
-lock tables t1 write;
-insert into t1 values (1);
-repair table t1;
-insert into t1 values(2);
-select * from t1;
-
-# checksum comparison failure is expected, SELECT output matters
--- source include/maria_verify_recovery.inc
-# 2 should be missing (rolled back) but 1 should be committed
-select * from t1;
-drop table t1;
-
---echo * TEST of recovery when crash before bulk-insert-with-repair is committed
-create table t1 (a varchar(100), key(a)) engine=maria;
-create table t2 (a varchar(100)) engine=myisam;
-let $mvr_restore_old_snapshot=0;
-let $mms_compare_physically=0;
-let $mvr_crash_statement= set global maria_checkpoint_interval=1;
-let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
-set rand_seed1=12, rand_seed2=254; # repeatable
-insert into t2 values (rand());
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t2 select (rand()) from t2;
-insert into t1 values(30);
--- source include/maria_make_snapshot_for_comparison.inc
-lock tables t1 write, t2 read;
-delete from t1 limit 1;
-# 127 rows in t2, >100, so this will use repair-at-end
-insert into t1 select * from t2;
--- source include/maria_verify_recovery.inc
-show keys from t1; # should be enabled
-drop table t1;
-
---echo * TEST of recovery when OPTIMIZE has replaced the index file and crash
-create table t_corrupted1 (a varchar(100), key(a)) engine=maria;
-# we use a special name because this test portion will generate
-# corruption warnings, which we tell mtr_report.pl to ignore by
-# putting the message in mtr_report.pl, but we don't want to it ignore
-# corruption messages of other tests, hence the special name
-# 't_corrupted' and not just 't'.
-let $mms_tname=t_corrupted;
-let $mvr_restore_old_snapshot=0;
-let $mms_compare_physically=0;
-let $mvr_crash_statement= optimize table t_corrupted1;
-let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash_sort_index";
-insert into t_corrupted1 select (rand()) from t2;
--- source include/maria_make_snapshot_for_comparison.inc
-# Recovery will not fix the table, but we expect to see it marked
-# "crashed on repair".
-# Because crash is mild, the table is actually not corrupted, so the
-# "check table extended" done below fixes the table.
--- source include/maria_verify_recovery.inc
-drop table t_corrupted1, t2;
-
# clean up everything
let $mms_purpose=feeding_recovery;
eval drop database mysqltest_for_$mms_purpose;
=== added file 'mysql-test/t/maria-recovery2-master.opt'
--- a/mysql-test/t/maria-recovery2-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/maria-recovery2-master.opt 2008-06-30 09:59:59 +0000
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp
=== added file 'mysql-test/t/maria-recovery2.test'
--- a/mysql-test/t/maria-recovery2.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/maria-recovery2.test 2008-06-30 09:34:58 +0000
@@ -0,0 +1,159 @@
+--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur as we crash
+--source include/not_valgrind.inc
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug.inc
+--source include/have_maria.inc
+
+set global maria_log_file_size=4294967295;
+let $MARIA_LOG=../tmp;
+
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+let $mms_tname=t;
+
+# Include scripts can perform SQL. For it to not influence the main test
+# they use a separate connection. This way if they use a DDL it would
+# not autocommit in the main test.
+connect (admin, 127.0.0.1, root,,mysqltest,,);
+--enable_reconnect
+
+connection default;
+use mysqltest;
+--enable_reconnect
+
+let $mms_tables=1;
+let $mvr_restore_old_snapshot=0;
+let $mms_compare_physically=0;
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash";
+let $mvr_crash_statement= set global maria_checkpoint_interval=1;
+
+# Test of removing logs manually
+--echo * TEST of removing logs manually
+let $mel_keep_control_file=1;
+# this will shut mysqld down cleanly (so, take a checkpoint) and
+# remove only logs; at restart Maria will create a new log with a high
+# number
+-- source include/maria_empty_logs.inc
+let $mel_keep_control_file=0;
+# next test will help us verify that a next recovery is ok
+
+--echo * TEST of UNDO_ROW_DELETE preserving rowid
+# we want recovery to use the tables as they were at time of crash
+let $mvr_restore_old_snapshot=0;
+# UNDO phase prevents physical comparison, normally,
+# so we'll only use checksums to compare.
+let $mms_compare_physically=0;
+let $mvr_crash_statement= set global maria_checkpoint_interval=1;
+create table t1(a int) engine=maria;
+insert into t1 values(1),(2);
+-- source include/maria_make_snapshot_for_comparison.inc
+lock tables t1 write;
+insert into t1 values(3);
+delete from t1 where a in (1,2,3);
+-- source include/maria_verify_recovery.inc
+drop table t1;
+
+# A basic checkpoint test
+--echo * TEST of checkpoint
+# Don't take a full checkpoints, we want to test checkpoint vs dirty pages
+set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect";
+# restart checkpoint thread for it to notice the above
+set global maria_checkpoint_interval=10000;
+create table t1(a int, b varchar(10), index(a,b)) engine=maria;
+insert into t1 values(1,"a"),(2,"b"),(3,"c");
+delete from t1 where b="b";
+update t1 set b="d" where a=1;
+-- source include/maria_make_snapshot_for_comparison.inc
+lock tables t1 write;
+insert into t1 values(4,"e"),(5,"f"),(6,"g");
+update t1 set b="h" where a=5;
+delete from t1 where b="g";
+show status like "Maria_pagecache_blocks_not_flushed";
+# force a checkpoint; there should be dirty pages and an open transaction
+set global maria_checkpoint_interval=10000;
+# do some more work
+update t1 set b="i" where a=5;
+let $mvr_restore_old_snapshot=0;
+let $mms_compare_physically=0;
+let $mvr_debug_option="+d,maria_crash";
+let $mvr_crash_statement= set global maria_checkpoint_interval=1;
+# Now we have a recovery, which should use the checkpoint record
+# and its dirty pages list.
+-- source include/maria_verify_recovery.inc
+drop table t1;
+
+--echo Test of REPAIR's implicit commit
+let $mms_tables=1;
+create table t1 (a varchar(100), key(a)) engine=maria;
+let $mvr_restore_old_snapshot=0;
+let $mms_compare_physically=0;
+let $mvr_crash_statement= set global maria_checkpoint_interval=1;
+
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
+insert into t1 values(3);
+-- source include/maria_make_snapshot_for_comparison.inc
+lock tables t1 write;
+insert into t1 values (1);
+repair table t1;
+insert into t1 values(2);
+select * from t1;
+
+# checksum comparison failure is expected, SELECT output matters
+-- source include/maria_verify_recovery.inc
+# 2 should be missing (rolled back) but 1 should be committed
+select * from t1;
+drop table t1;
+
+--echo * TEST of recovery when crash before bulk-insert-with-repair is committed
+create table t1 (a varchar(100), key(a)) engine=maria;
+create table t2 (a varchar(100)) engine=myisam;
+let $mvr_restore_old_snapshot=0;
+let $mms_compare_physically=0;
+let $mvr_crash_statement= set global maria_checkpoint_interval=1;
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash";
+set rand_seed1=12, rand_seed2=254; # repeatable
+insert into t2 values (rand());
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t2 select (rand()) from t2;
+insert into t1 values(30);
+-- source include/maria_make_snapshot_for_comparison.inc
+lock tables t1 write, t2 read;
+delete from t1 limit 1;
+# 127 rows in t2, >100, so this will use repair-at-end
+insert into t1 select * from t2;
+-- source include/maria_verify_recovery.inc
+show keys from t1; # should be enabled
+drop table t1;
+
+--echo * TEST of recovery when OPTIMIZE has replaced the index file and crash
+create table t_corrupted1 (a varchar(100), key(a)) engine=maria;
+# we use a special name because this test portion will generate
+# corruption warnings, which we tell mtr_report.pl to ignore by
+# putting the message in mtr_report.pl, but we don't want to it ignore
+# corruption messages of other tests, hence the special name
+# 't_corrupted' and not just 't'.
+let $mms_tname=t_corrupted;
+let $mvr_restore_old_snapshot=0;
+let $mms_compare_physically=0;
+let $mvr_crash_statement= optimize table t_corrupted1;
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash_sort_index";
+insert into t_corrupted1 select (rand()) from t2;
+-- source include/maria_make_snapshot_for_comparison.inc
+# Recovery will not fix the table, but we expect to see it marked
+# "crashed on repair".
+# Because crash is mild, the table is actually not corrupted, so the
+# "check table extended" done below fixes the table.
+-- source include/maria_verify_recovery.inc
+drop table t_corrupted1, t2;
+
+# clean up everything
+let $mms_purpose=comparison;
+eval drop database mysqltest_for_$mms_purpose;
+drop database mysqltest;
=== modified file 'mysql-test/t/old-mode.test'
--- a/mysql-test/t/old-mode.test 2007-12-04 21:23:42 +0000
+++ b/mysql-test/t/old-mode.test 2008-06-28 12:45:15 +0000
@@ -12,5 +12,6 @@ create table t2 (a int, b varchar(200),
insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
insert t2 select * from t1;
checksum table t1, t2;
+checksum table t1, t2 quick;
checksum table t1, t2 extended;
drop table t1,t2;
=== added file 'mysql-test/t/row-checksum-old-master.opt'
--- a/mysql-test/t/row-checksum-old-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/row-checksum-old-master.opt 2008-06-28 12:45:15 +0000
@@ -0,0 +1 @@
+--old
=== added file 'mysql-test/t/row-checksum-old.test'
--- a/mysql-test/t/row-checksum-old.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/row-checksum-old.test 2008-06-28 12:45:15 +0000
@@ -0,0 +1,4 @@
+#
+# Run row-checksum.test with old mode
+#
+--source t/row-checksum.test
=== added file 'mysql-test/t/row-checksum.test'
--- a/mysql-test/t/row-checksum.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/row-checksum.test 2008-06-28 12:45:15 +0000
@@ -0,0 +1,62 @@
+#
+# Test checksum
+#
+
+-- source include/have_innodb.inc
+-- source include/have_maria.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table if exists t1;
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table if exists t1;
+
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table t1;
+
+create table t1 (a int null, v varchar(100)) engine=maria checksum=0;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table t1;
+create table t1 (a int null, v varchar(100)) engine=maria checksum=1;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table t1;
+
+
+#
+# These checksums will be different prefixes fixed sizes rows with one extra
+# flag byte
+#
+create table t1 (a int null, v varchar(100)) engine=myisam checksum=1 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table if exists t1;
+
+create table t1 (a int null, v varchar(100)) engine=innodb checksum=0 row_format=fixed;
+insert into t1 values(null, null), (1, "hello");
+checksum table t1;
+checksum table t1 quick;
+checksum table t1 extended;
+drop table t1;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2008-06-28 11:00:59 +0000
+++ b/sql/ha_partition.cc 2008-06-30 09:59:59 +0000
@@ -4746,7 +4746,7 @@ void ha_partition::get_dynamic_partition
stat_info->update_time= file->stats.update_time;
stat_info->check_time= file->stats.check_time;
stat_info->check_sum= 0;
- if (file->ha_table_flags() & HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= file->checksum();
return;
}
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2008-06-28 11:00:59 +0000
+++ b/sql/handler.cc 2008-06-30 09:59:59 +0000
@@ -3457,7 +3457,7 @@ void handler::get_dynamic_partition_info
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
- if (table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_OLD_CHECKSUM))
stat_info->check_sum= checksum();
return;
}
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2008-06-17 20:04:19 +0000
+++ b/sql/handler.h 2008-06-30 09:59:59 +0000
@@ -163,7 +163,8 @@ typedef Bitmap<HA_MAX_ALTER_FLAGS> HA_AL
#define HA_CAN_FULLTEXT (1 << 21)
#define HA_CAN_SQL_HANDLER (1 << 22)
#define HA_NO_AUTO_INCREMENT (1 << 23)
-#define HA_HAS_CHECKSUM (1 << 24)
+/* Has automatic checksums and uses the old checksum format */
+#define HA_HAS_OLD_CHECKSUM (1 << 24)
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
#define HA_NO_VARCHAR (1 << 27)
@@ -184,6 +185,8 @@ typedef Bitmap<HA_MAX_ALTER_FLAGS> HA_AL
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 36)
#define HA_ONLINE_ALTER (LL(1) << 37)
+/* Has automatic checksums and uses the new checksum format */
+#define HA_HAS_NEW_CHECKSUM (LL(1) << 38)
/*
Set of all binlog flags. Currently only contain the capabilities
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2008-06-28 11:00:59 +0000
+++ b/sql/sql_show.cc 2008-06-30 09:59:59 +0000
@@ -3714,7 +3714,7 @@ static int get_schema_tables_record(THD
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
table->field[16]->set_notnull();
}
- if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
{
table->field[18]->store((longlong) file->checksum(), TRUE);
table->field[18]->set_notnull();
@@ -5061,7 +5061,7 @@ static void store_schema_partitions_reco
table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
table->field[20]->set_notnull();
}
- if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
{
table->field[21]->store((longlong) stat_info.check_sum, TRUE);
table->field[21]->set_notnull();
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-06-28 11:00:59 +0000
+++ b/sql/sql_table.cc 2008-06-30 09:59:59 +0000
@@ -7483,11 +7483,14 @@ bool mysql_checksum_table(THD *thd, TABL
}
else
{
- if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
- !(check_opt->flags & T_EXTEND))
+ /* Call ->checksum() if the table checksum matches 'old_mode' settings */
+ if (!(check_opt->flags & T_EXTEND) &&
+ (((t->file->ha_table_flags() & HA_HAS_OLD_CHECKSUM) &&
+ thd->variables.old_mode) ||
+ ((t->file->ha_table_flags() & HA_HAS_NEW_CHECKSUM) &&
+ !thd->variables.old_mode)))
protocol->store((ulonglong)t->file->checksum());
- else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
- (check_opt->flags & T_QUICK))
+ else if (check_opt->flags & T_QUICK)
protocol->store_null();
else
{
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2008-06-28 11:00:59 +0000
+++ b/storage/maria/ha_maria.cc 2008-06-30 09:59:59 +0000
@@ -923,7 +923,7 @@ int ha_maria::open(const char *name, int
int_table_flags|= HA_CAN_INSERT_DELAYED;
}
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- int_table_flags |= HA_HAS_CHECKSUM;
+ int_table_flags |= HA_HAS_NEW_CHECKSUM;
for (i= 0; i < table->s->keys; i++)
{
@@ -1112,15 +1112,20 @@ int ha_maria::repair(THD * thd, HA_CHECK
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
start_records= file->state->records;
- while ((error= repair(thd, param, 0)) && param.retry_repair)
+ while ((error= repair(thd, ¶m, 0)) && param.retry_repair)
{
param.retry_repair= 0;
if (test_all_bits(param.testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
- param.testflag &= ~T_RETRY_WITHOUT_QUICK;
- sql_print_information("Retrying repair of: '%s' without quick",
- table->s->path.str);
+ param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
+ /* Ensure we don't loose any rows when retrying without quick */
+ param.testflag|= T_SAFE_REPAIR;
+ if (thd->vio_ok())
+ _ma_check_print_info(¶m, "Retrying repair without quick");
+ else
+ sql_print_information("Retrying repair of: '%s' without quick",
+ table->s->path.str);
continue;
}
param.testflag &= ~T_QUICK;
@@ -1166,9 +1171,9 @@ int ha_maria::zerofill(THD * thd, HA_CHE
int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
+ HA_CHECK param;
if (!file)
return HA_ADMIN_INTERNAL_ERROR;
- HA_CHECK param;
maria_chk_init(¶m);
param.thd= thd;
@@ -1176,21 +1181,21 @@ int ha_maria::optimize(THD * thd, HA_CHE
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
- if ((error= repair(thd, param, 1)) && param.retry_repair)
+ if ((error= repair(thd, ¶m, 1)) && param.retry_repair)
{
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
param.testflag &= ~T_REP_BY_SORT;
- error= repair(thd, param, 1);
+ error= repair(thd, ¶m, 1);
}
return error;
}
-int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
+int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
{
int error= 0;
- ulonglong local_testflag= param.testflag;
+ ulonglong local_testflag= param->testflag;
bool optimize_done= !do_optimize, statistics_done= 0;
const char *old_proc_info= thd->proc_info;
char fixed_name[FN_REFLEN];
@@ -1222,20 +1227,20 @@ int ha_maria::repair(THD *thd, HA_CHECK
if (share->base.born_transactional && !share->now_transactional)
_ma_copy_nontrans_state_information(file);
- param.db_name= table->s->db.str;
- param.table_name= table->alias;
- param.tmpfile_createflag= O_RDWR | O_TRUNC;
- param.using_global_keycache= 1;
- param.thd= thd;
- param.tmpdir= &mysql_tmpdir_list;
- param.out_flag= 0;
+ param->db_name= table->s->db.str;
+ param->table_name= table->alias;
+ param->tmpfile_createflag= O_RDWR | O_TRUNC;
+ param->using_global_keycache= 1;
+ param->thd= thd;
+ param->tmpdir= &mysql_tmpdir_list;
+ param->out_flag= 0;
strmov(fixed_name, share->open_file_name);
// Don't lock tables if we have used LOCK TABLE
if (!thd->locked_tables_mode &&
maria_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
{
- _ma_check_print_error(¶m, ER(ER_CANT_LOCK), my_errno);
+ _ma_check_print_error(param, ER(ER_CANT_LOCK), my_errno);
DBUG_RETURN(HA_ADMIN_FAILED);
}
@@ -1243,19 +1248,19 @@ int ha_maria::repair(THD *thd, HA_CHECK
((share->data_file_type == BLOCK_RECORD) ?
(share->state.changed & STATE_NOT_OPTIMIZED_ROWS) :
(file->state->del || share->state.split != file->state->records)) &&
- (!(param.testflag & T_QUICK) ||
+ (!(param->testflag & T_QUICK) ||
(share->state.changed & (STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_OPTIMIZED_ROWS))))
{
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
maria_get_mask_all_keys_active(share->base.keys) :
share->state.key_map);
- ulonglong save_testflag= param.testflag;
+ ulonglong save_testflag= param->testflag;
if (maria_test_if_sort_rep(file, file->state->records, key_map, 0) &&
(local_testflag & T_REP_BY_SORT))
{
local_testflag |= T_STATISTICS;
- param.testflag |= T_STATISTICS; // We get this for free
+ param->testflag |= T_STATISTICS; // We get this for free
statistics_done= 1;
/* TODO: Remove BLOCK_RECORD test when parallel works with blocks */
if (THDVAR(thd,repair_threads) > 1 &&
@@ -1265,28 +1270,28 @@ int ha_maria::repair(THD *thd, HA_CHECK
/* TODO: respect maria_repair_threads variable */
my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
thd_proc_info(thd, buf);
- param.testflag|= T_REP_PARALLEL;
- error= maria_repair_parallel(¶m, file, fixed_name,
- test(param.testflag & T_QUICK));
+ param->testflag|= T_REP_PARALLEL;
+ error= maria_repair_parallel(param, file, fixed_name,
+ test(param->testflag & T_QUICK));
/* to reset proc_info, as it was pointing to local buffer */
thd_proc_info(thd, "Repair done");
}
else
{
thd_proc_info(thd, "Repair by sorting");
- param.testflag|= T_REP_BY_SORT;
- error= maria_repair_by_sort(¶m, file, fixed_name,
- test(param.testflag & T_QUICK));
+ param->testflag|= T_REP_BY_SORT;
+ error= maria_repair_by_sort(param, file, fixed_name,
+ test(param->testflag & T_QUICK));
}
}
else
{
thd_proc_info(thd, "Repair with keycache");
- param.testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL);
- error= maria_repair(¶m, file, fixed_name,
- test(param.testflag & T_QUICK));
+ param->testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL);
+ error= maria_repair(param, file, fixed_name,
+ test(param->testflag & T_QUICK));
}
- param.testflag= save_testflag;
+ param->testflag= save_testflag | (param->testflag & T_RETRY_WITHOUT_QUICK);
optimize_done= 1;
}
if (!error)
@@ -1296,7 +1301,7 @@ int ha_maria::repair(THD *thd, HA_CHECK
{
optimize_done= 1;
thd_proc_info(thd, "Sorting index");
- error= maria_sort_index(¶m, file, fixed_name);
+ error= maria_sort_index(param, file, fixed_name);
}
if (!statistics_done && (local_testflag & T_STATISTICS))
{
@@ -1304,7 +1309,7 @@ int ha_maria::repair(THD *thd, HA_CHECK
{
optimize_done= 1;
thd_proc_info(thd, "Analyzing");
- error= maria_chk_key(¶m, file);
+ error= maria_chk_key(param, file);
}
else
local_testflag &= ~T_STATISTICS; // Don't update statistics
@@ -1326,18 +1331,18 @@ int ha_maria::repair(THD *thd, HA_CHECK
if (file->state != &share->state.state)
*file->state= share->state.state;
if (share->base.auto_key)
- _ma_update_auto_increment_key(¶m, file, 1);
+ _ma_update_auto_increment_key(param, file, 1);
if (optimize_done)
- error= maria_update_state_info(¶m, file,
+ error= maria_update_state_info(param, file,
UPDATE_TIME | UPDATE_OPEN_COUNT |
(local_testflag &
T_STATISTICS ? UPDATE_STAT : 0));
info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
HA_STATUS_CONST);
- if (rows != file->state->records && !(param.testflag & T_VERY_SILENT))
+ if (rows != file->state->records && !(param->testflag & T_VERY_SILENT))
{
char llbuff[22], llbuff2[22];
- _ma_check_print_warning(¶m, "Number of rows changed from %s to %s",
+ _ma_check_print_warning(param, "Number of rows changed from %s to %s",
llstr(rows, llbuff),
llstr(file->state->records, llbuff2));
/* Abort if warning was converted to error */
@@ -1349,7 +1354,7 @@ int ha_maria::repair(THD *thd, HA_CHECK
{
maria_mark_crashed_on_repair(file);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
- maria_update_state_info(¶m, file, 0);
+ maria_update_state_info(param, file, 0);
}
pthread_mutex_unlock(&share->intern_lock);
thd_proc_info(thd, old_proc_info);
@@ -1357,7 +1362,7 @@ int ha_maria::repair(THD *thd, HA_CHECK
maria_lock_database(file, F_UNLCK);
error= error ? HA_ADMIN_FAILED :
(optimize_done ?
- (write_log_record_for_repair(¶m, file) ? HA_ADMIN_FAILED :
+ (write_log_record_for_repair(param, file) ? HA_ADMIN_FAILED :
HA_ADMIN_OK) : HA_ADMIN_ALREADY_DONE);
DBUG_RETURN(error);
}
@@ -1587,15 +1592,16 @@ int ha_maria::enable_indexes(uint mode)
param.sort_buffer_length= THDVAR(thd,sort_buffer_size);
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
param.tmpdir= &mysql_tmpdir_list;
- if ((error= (repair(thd, param, 0) != HA_ADMIN_OK)) && param.retry_repair)
+ if ((error= (repair(thd, ¶m, 0) != HA_ADMIN_OK)) && param.retry_repair)
{
- sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
+ sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, "
+ "retrying",
my_errno, param.db_name, param.table_name);
/* This should never fail normally */
DBUG_ASSERT(0);
/* Repairing by sort failed. Now try standard repair method. */
- param.testflag &= ~(T_REP_BY_SORT | T_QUICK);
- error= (repair(thd, param, 0) != HA_ADMIN_OK);
+ param.testflag &= ~T_REP_BY_SORT;
+ error= (repair(thd, ¶m, 0) != HA_ADMIN_OK);
/*
If the standard repair succeeded, clear all error messages which
might have been set by the first repair. They can still be seen
@@ -1761,8 +1767,7 @@ end:
bool ha_maria::check_and_repair(THD *thd)
{
- int error;
- int marked_crashed;
+ int error, crashed;
char *old_query;
uint old_query_length;
HA_CHECK_OPT check_opt;
@@ -1791,7 +1796,6 @@ bool ha_maria::check_and_repair(THD *thd
// Don't use quick if deleted rows
if (!file->state->del && (maria_recover_options & HA_RECOVER_QUICK))
check_opt.flags |= T_QUICK;
- sql_print_warning("Checking table: '%s'", table->s->path.str);
old_query= thd->query;
old_query_length= thd->query_length;
@@ -1800,12 +1804,17 @@ bool ha_maria::check_and_repair(THD *thd
thd->query_length= table->s->table_name.length;
pthread_mutex_unlock(&LOCK_thread_count);
- if ((marked_crashed= maria_is_crashed(file)) || check(thd, &check_opt))
+ if (!(crashed= maria_is_crashed(file)))
+ {
+ sql_print_warning("Checking table: '%s'", table->s->path.str);
+ crashed= check(thd, &check_opt);
+ }
+
+ if (crashed)
{
sql_print_warning("Recovering table: '%s'", table->s->path.str);
check_opt.flags=
((maria_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
- (marked_crashed ? 0 : T_QUICK) |
(maria_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
T_AUTO_REPAIR);
if (repair(thd, &check_opt))
@@ -2350,6 +2359,11 @@ THR_LOCK_DATA **ha_maria::store_lock(THD
thd->lex->sql_command != SQLCOM_LOCK_TABLES) &&
mysql_bin_log.is_open())
lock_type= TL_READ_NO_INSERT;
+ else if (lock_type == TL_WRITE_CONCURRENT_INSERT &&
+ (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+ thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
+ thd->lex->sql_command == SQLCOM_LOAD))
+ lock_type= TL_WRITE;
file->lock.type= lock_type;
}
*to++= &file->lock;
=== modified file 'storage/maria/ha_maria.h'
--- a/storage/maria/ha_maria.h 2008-06-05 16:11:22 +0000
+++ b/storage/maria/ha_maria.h 2008-06-30 09:59:59 +0000
@@ -45,7 +45,7 @@ class ha_maria :public handler
UNDO_BULK_INSERT with/without repair.
*/
uint8 bulk_insert_single_undo;
- int repair(THD * thd, HA_CHECK ¶m, bool optimize);
+ int repair(THD * thd, HA_CHECK *param, bool optimize);
int zerofill(THD * thd, HA_CHECK_OPT *check_opt);
public:
=== modified file 'storage/maria/ma_blockrec.c'
--- a/storage/maria/ma_blockrec.c 2008-06-26 05:18:28 +0000
+++ b/storage/maria/ma_blockrec.c 2008-06-30 09:25:14 +0000
@@ -1345,21 +1345,22 @@ static void calc_record_size(MARIA_HA *i
}
-/*
+/**
Compact page by removing all space between rows
- IMPLEMENTATION
- Move up all rows to start of page.
- Move blocks that are directly after each other with one memmove.
+ Moves up all rows to start of page. Moves blocks that are directly after
+ each other with one memmove.
- SYNOPSIS
- _ma_compact_block_page()
- buff Page to compact
- block_size Size of page
- rownr Put empty data after this row
- extend_block If 1, extend the block at 'rownr' to cover the
+ @note if rownr is the last row in the page, and extend_block is false,
+ caller has to make sure to update bitmap page afterwards to reflect freed
+ space.
+
+ @param buff Page to compact
+ @param block_size Size of page
+ @param rownr Put empty data after this row
+ @param extend_block If 1, extend the block at 'rownr' to cover the
whole block.
- min_read_from If <> 0, remove all trid's that are less than this
+ @param min_read_from If <> 0, remove all trid's that are less than this
*/
void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr,
=== modified file 'storage/maria/ma_check.c'
--- a/storage/maria/ma_check.c 2008-06-26 18:29:30 +0000
+++ b/storage/maria/ma_check.c 2008-06-30 09:59:59 +0000
@@ -99,6 +99,7 @@ static my_bool _ma_flush_table_files_bef
MARIA_HA *info);
static TrID max_trid_in_system(void);
static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid);
+void retry_if_quick(MARIA_SORT_PARAM *param, int error);
/* Initialize check param with default values */
@@ -2233,6 +2234,10 @@ static int initialize_variables_for_repa
{
MARIA_SHARE *share= info->s;
+ /* Repair code relies on share->state.state so we have to update it here */
+ if (share->lock.update_status)
+ (*share->lock.update_status)(info);
+
bzero((char*) sort_info, sizeof(*sort_info));
bzero((char*) sort_param, sizeof(*sort_param));
@@ -3303,11 +3308,16 @@ static my_bool maria_zerofill_data(HA_CH
bzero(buff, LSN_SIZE);
if (max_entry != 0)
{
+ my_bool is_head_page= (page_type == HEAD_PAGE);
dir= dir_entry_pos(buff, block_size, max_entry - 1);
_ma_compact_block_page(buff, block_size, max_entry -1, 0,
- page_type == HEAD_PAGE ? ~(TrID) 0 : 0,
- page_type == HEAD_PAGE ?
+ is_head_page ? ~(TrID) 0 : 0,
+ is_head_page ?
share->base.min_block_length : 0);
+ /* compactation may have increased free space */
+ if (_ma_bitmap_set(info, page, is_head_page,
+ uint2korr(buff + EMPTY_SPACE_OFFSET)))
+ goto err;
/* Zerofill the not used part */
offset= uint2korr(dir) + uint2korr(dir+2);
@@ -3329,10 +3339,9 @@ static my_bool maria_zerofill_data(HA_CH
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
}
- if (flush_pagecache_blocks(share->pagecache, &info->dfile,
- FLUSH_FORCE_WRITE))
- DBUG_RETURN(1);
- DBUG_RETURN(0);
+ DBUG_RETURN(_ma_bitmap_flush(share) ||
+ flush_pagecache_blocks(share->pagecache, &info->dfile,
+ FLUSH_FORCE_WRITE));
err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
@@ -4632,9 +4641,12 @@ static int sort_get_next_record(MARIA_SO
}
/* Retry only if wrong record, not if disk error */
if (flag != HA_ERR_WRONG_IN_RECORD)
+ {
+ retry_if_quick(sort_param, flag);
DBUG_RETURN(flag);
+ }
}
- break;
+ break; /* Impossible */
}
case STATIC_RECORD:
for (;;)
@@ -4644,8 +4656,7 @@ static int sort_get_next_record(MARIA_SO
{
if (sort_param->read_cache.error)
param->out_flag |= O_DATA_LOST;
- param->retry_repair=1;
- param->testflag|=T_RETRY_WITHOUT_QUICK;
+ retry_if_quick(sort_param, my_errno);
DBUG_RETURN(-1);
}
sort_param->start_recpos=sort_param->pos;
@@ -6634,3 +6645,22 @@ static void _ma_check_print_not_visible_
}
}
}
+
+
+/**
+ Mark that we can retry normal repair if we used quick repair
+
+ We shouldn't do this in case of disk error as in this case we are likely
+ to loose much more than expected.
+*/
+
+void retry_if_quick(MARIA_SORT_PARAM *sort_param, int error)
+{
+ HA_CHECK *param=sort_param->sort_info->param;
+
+ if (!sort_param->fix_datafile && error >= HA_ERR_FIRST)
+ {
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ }
+}
=== modified file 'storage/maria/ma_open.c'
--- a/storage/maria/ma_open.c 2008-06-26 17:48:42 +0000
+++ b/storage/maria/ma_open.c 2008-06-30 09:59:59 +0000
@@ -601,6 +601,15 @@ MARIA_HA *maria_open(const char *name, i
pos->null_bit=0;
pos->flag=0; /* For purify */
pos++;
+
+ if ((share->keyinfo[i].flag & HA_NOSAME) && i != 0)
+ {
+ /*
+ We can't yet have versioning if there is more than one unique
+ key
+ */
+ versioning= 0;
+ }
}
for (i=0 ; i < uniques ; i++)
{
@@ -1345,8 +1354,10 @@ static uchar *_ma_state_info_read(uchar
@param state state which will be filled
*/
-uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state)
+uint _ma_state_info_read_dsk(File file __attribute__((unused)),
+ MARIA_STATE_INFO *state __attribute__((unused)))
{
+#ifdef EXTERNAL_LOCKING
uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
/* trick to detect transactional tables */
@@ -1357,6 +1368,7 @@ uint _ma_state_info_read_dsk(File file,
return 1;
_ma_state_info_read(buff, state);
}
+#endif
return 0;
}
=== modified file 'storage/maria/ma_test1.c'
--- a/storage/maria/ma_test1.c 2008-06-26 17:48:42 +0000
+++ b/storage/maria/ma_test1.c 2008-06-30 09:59:59 +0000
@@ -130,7 +130,8 @@ static int run_test(const char *filename
recinfo[2].type=FIELD_CHECK;
recinfo[2].length=MARIA_UNIQUE_HASH_LENGTH;
}
- rec_length= recinfo[0].length+recinfo[1].length+recinfo[2].length;
+ rec_length= recinfo[0].length + recinfo[1].length + recinfo[2].length +
+ create_info.null_bytes;
if (key_type == HA_KEYTYPE_VARTEXT1 &&
key_length > 255)
=== modified file 'storage/maria/unittest/ma_test_loghandler_multithread-t.c'
--- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c 2008-06-16 16:31:25 +0000
+++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c 2008-06-30 09:59:59 +0000
@@ -269,6 +269,11 @@ int main(int argc __attribute__((unused)
int *param, error;
int rc;
+ /* Disabled until Sanja tests */
+ plan(1);
+ ok(1, "disabled");
+ exit(0);
+
plan(WRITERS + FLUSHERS +
ITERATIONS * WRITERS * 3 + FLUSH_ITERATIONS * FLUSHERS );
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2008-06-28 11:00:59 +0000
+++ b/storage/myisam/ha_myisam.cc 2008-06-30 09:59:59 +0000
@@ -645,9 +645,22 @@ int ha_myisam::open(const char *name, in
if (!table->s->db_record_offset)
int_table_flags|=HA_REC_NOT_IN_SEQ;
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- int_table_flags|=HA_HAS_CHECKSUM;
+ {
+ /*
+ Set which type of automatic checksum we have
+ The old checksum and new checksum are identical if there is no
+ null fields.
+ Files with new checksum has the HA_OPTION_NULL_FIELDS bit set.
+ */
+ if ((file->s->options & HA_OPTION_NULL_FIELDS) ||
+ !file->s->has_null_fields)
+ int_table_flags|= HA_HAS_NEW_CHECKSUM;
+ if (!(file->s->options & HA_OPTION_NULL_FIELDS))
+ int_table_flags|= HA_HAS_OLD_CHECKSUM;
+ }
keys_with_parts.clear_all();
+
for (i= 0; i < table->s->keys; i++)
{
plugin_ref parser= table->key_info[i].parser;
@@ -856,7 +869,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK
if (test_all_bits(param.testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
- param.testflag&= ~T_RETRY_WITHOUT_QUICK;
+ param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
+ /* Ensure we don't loose any rows when retrying without quick */
+ param.testflag|= T_SAFE_REPAIR;
sql_print_information("Retrying repair of: '%s' without quick",
table->s->path.str);
continue;
@@ -990,7 +1005,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK
error= mi_repair(¶m, file, fixed_name,
test(param.testflag & T_QUICK));
}
- param.testflag=testflag;
+ param.testflag= testflag | (param.testflag & T_RETRY_WITHOUT_QUICK);
optimize_done=1;
}
if (!error)
@@ -1969,6 +1984,27 @@ bool ha_myisam::check_if_incompatible_da
return COMPATIBLE_DATA_YES;
}
+
+/**
+ Check if a table is incompatible with the current version.
+
+ The cases are:
+ - Table has checksum, varchars and are not of dynamic record type
+*/
+
+int ha_myisam::check_for_upgrade(HA_CHECK_OPT *check_opt)
+{
+ if (!(file->s->options & HA_OPTION_NULL_FIELDS) &&
+ !(file->s->options & HA_OPTION_PACK_RECORD) &&
+ file->s->has_varchar_fields)
+ {
+ /* We need alter there to get the HA_OPTION_NULL_FIELDS flag to be set */
+ return HA_ADMIN_NEEDS_ALTER;
+ }
+ return HA_ADMIN_OK;
+}
+
+
extern int mi_panic(enum ha_panic_function flag);
int myisam_panic(handlerton *hton, ha_panic_function flag)
{
=== modified file 'storage/myisam/ha_myisam.h'
--- a/storage/myisam/ha_myisam.h 2008-06-05 16:11:22 +0000
+++ b/storage/myisam/ha_myisam.h 2008-06-30 09:59:59 +0000
@@ -126,6 +126,7 @@ class ha_myisam: public handler
ulonglong *nb_reserved_values);
int rename_table(const char * from, const char * to);
int delete_table(const char *name);
+ int check_for_upgrade(HA_CHECK_OPT *check_opt);
int check(THD* thd, HA_CHECK_OPT* check_opt);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
=== modified file 'storage/myisam/mi_open.c'
--- a/storage/myisam/mi_open.c 2008-05-29 15:44:11 +0000
+++ b/storage/myisam/mi_open.c 2008-06-30 09:59:59 +0000
@@ -19,6 +19,7 @@
#include "sp_defs.h"
#include "rt_index.h"
#include <m_ctype.h>
+#include <mysql_version.h>
#if defined(MSDOS) || defined(__WIN__)
#ifdef __WIN__
@@ -453,13 +454,20 @@ MI_INFO *mi_open(const char *name, int m
share->rec[i].pack_type=0;
share->rec[i].huff_tree=0;
share->rec[i].offset=offset;
- if (share->rec[i].type == (int) FIELD_BLOB)
+ if (share->rec[i].type == FIELD_BLOB)
{
share->blobs[j].pack_length=
share->rec[i].length - portable_sizeof_char_ptr;
share->blobs[j].offset=offset;
j++;
}
+#if MYSQL_VERSION_ID <= 60100
+ /* This is to detect old checksum option */
+ if (share->rec[i].null_bit)
+ share->has_null_fields= 1;
+ if (share->rec[i].type == FIELD_VARCHAR)
+ share->has_varchar_fields= 1;
+#endif
offset+=share->rec[i].length;
}
share->rec[i].type=(int) FIELD_LAST; /* End marker */
=== modified file 'storage/myisam/myisamdef.h'
--- a/storage/myisam/myisamdef.h 2008-06-05 16:11:22 +0000
+++ b/storage/myisam/myisamdef.h 2008-06-30 09:59:59 +0000
@@ -211,6 +211,9 @@ typedef struct st_mi_isam_share
enum data_file_type data_file_type;
/* Below flag is needed to make log tables work with concurrent insert */
my_bool is_log_table;
+ /* This is 1 if they table checksum is of old type */
+ my_bool has_null_fields;
+ my_bool has_varchar_fields;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (guilhem:2670) | Guilhem Bichot | 30 Jun |