Ingo,
Can you please review this merge commit? I have added the test case for 5.1
Regards,
Satya
Satya B wrote:
> #At file:///home/satya/WORK/mysql-5.1-bugteam-41330/ based on
> revid:timothy.smith@stripped
>
> 2853 Satya B 2009-04-02 [merge]
> merge 5.0-bugteam to 5.1-bugteam
> added:
> mysql-test/r/myisam_crash_before_flush_keys.result
> mysql-test/t/myisam_crash_before_flush_keys-master.opt
> mysql-test/t/myisam_crash_before_flush_keys.test
> modified:
> storage/myisam/mi_close.c
>
> === added file 'mysql-test/r/myisam_crash_before_flush_keys.result'
> --- a/mysql-test/r/myisam_crash_before_flush_keys.result 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/r/myisam_crash_before_flush_keys.result 2009-04-02 09:47:34 +0000
> @@ -0,0 +1,42 @@
> +#
> +# BUG#41330 - Myisam table open count set to zero before index blocks are written.
> +#
> +# Don't test this under valgrind, memory leaks will occur
> +# Binary must be compiled with debug for crash to occur
> +SET GLOBAL delay_key_write=ALL;
> +CREATE TABLE t1(a INT,
> +b INT,
> +PRIMARY KEY(a , b),
> +KEY(b)) ENGINE=MyISAM DELAY_KEY_WRITE = 1;
> +INSERT INTO t1 VALUES (1,2),(2,3),(3,4),(4,5),(5,6);
> +SHOW GLOBAL STATUS LIKE 'Key_blocks%';
> +Variable_name Value
> +Key_blocks_not_flushed 2
> +Key_blocks_unused 902
> +Key_blocks_used 4
> +# Setup the mysqld to crash at certain point
> +SET SESSION debug="d,crash_before_flush_keys";
> +# Write file to make mysql-test-run.pl expect crash
> +# Run the crashing query
> +FLUSH TABLE t1;
> +ERROR HY000: Lost connection to MySQL server during query
> +# Run MYISAMCHK tool to check the table t1 and repair
> +# Write file to make mysql-test-run.pl start the server
> +# Turn on reconnect
> +# Call script that will poll the server waiting for it to be back online again
> +SHOW CREATE TABLE t1;
> +Table Create Table
> +t1 CREATE TABLE `t1` (
> + `a` int(11) NOT NULL DEFAULT '0',
> + `b` int(11) NOT NULL DEFAULT '0',
> + PRIMARY KEY (`a`,`b`),
> + KEY `b` (`b`)
> +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
> +SELECT * FROM t1 FORCE INDEX (PRIMARY);
> +a b
> +1 2
> +2 3
> +3 4
> +4 5
> +5 6
> +DROP TABLE t1;
>
> === added file 'mysql-test/t/myisam_crash_before_flush_keys-master.opt'
> --- a/mysql-test/t/myisam_crash_before_flush_keys-master.opt 1970-01-01 00:00:00
> +0000
> +++ b/mysql-test/t/myisam_crash_before_flush_keys-master.opt 2009-04-02 09:47:34
> +0000
> @@ -0,0 +1 @@
> +--skip-stack-trace --skip-core-file
>
> === added file 'mysql-test/t/myisam_crash_before_flush_keys.test'
> --- a/mysql-test/t/myisam_crash_before_flush_keys.test 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/t/myisam_crash_before_flush_keys.test 2009-04-02 09:47:34 +0000
> @@ -0,0 +1,47 @@
> +--echo #
> +--echo # BUG#41330 - Myisam table open count set to zero before index blocks are
> written.
> +--echo #
> +--source include/not_embedded.inc
> +--echo # Don't test this under valgrind, memory leaks will occur
> +--source include/not_valgrind.inc
> +
> +--echo # Binary must be compiled with debug for crash to occur
> +--source include/have_debug.inc
> +
> +let $MYSQLD_DATADIR= `select @@datadir`;
> +SET GLOBAL delay_key_write=ALL;
> +CREATE TABLE t1(a INT,
> + b INT,
> + PRIMARY KEY(a , b),
> + KEY(b)) ENGINE=MyISAM DELAY_KEY_WRITE = 1;
> +INSERT INTO t1 VALUES (1,2),(2,3),(3,4),(4,5),(5,6);
> +
> +SHOW GLOBAL STATUS LIKE 'Key_blocks%';
> +
> +--echo # Setup the mysqld to crash at certain point
> +SET SESSION debug="d,crash_before_flush_keys";
> +
> +--echo # Write file to make mysql-test-run.pl expect crash
> +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> +
> +--echo # Run the crashing query
> +--error 2013
> +FLUSH TABLE t1;
> +
> +--echo # Run MYISAMCHK tool to check the table t1 and repair
> +--exec $MYISAMCHK -crs $MYSQLD_DATADIR/test/t1
> +
> +--echo # Write file to make mysql-test-run.pl start the server
> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> +
> +--echo # Turn on reconnect
> +--enable_reconnect
> +
> +--echo # Call script that will poll the server waiting for it to be back online
> again
> +--source include/wait_until_connected_again.inc
> +
> +SHOW CREATE TABLE t1;
> +
> +SELECT * FROM t1 FORCE INDEX (PRIMARY);
> +
> +DROP TABLE t1;
>
> === modified file 'storage/myisam/mi_close.c'
> --- a/storage/myisam/mi_close.c 2007-05-10 09:59:39 +0000
> +++ b/storage/myisam/mi_close.c 2009-04-02 09:47:34 +0000
> @@ -35,8 +35,8 @@ int mi_close(register MI_INFO *info)
> if (info->lock_type == F_EXTRA_LCK)
> info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */
>
> - if (share->reopen == 1 && share->kfile >= 0)
> - _mi_decrement_open_count(info);
> + DBUG_EXECUTE_IF("crash_before_flush_keys",
> + if(info->s->global_changed && (info->s->state.open_count !=0))
> abort(););
>
> if (info->lock_type != F_UNLCK)
> {
> @@ -78,6 +78,8 @@ int mi_close(register MI_INFO *info)
> */
> if (share->mode != O_RDONLY && mi_is_crashed(info))
> mi_state_info_write(share->kfile, &share->state, 1);
> + /* Decrement open count must be last I/O on this file. */
> + _mi_decrement_open_count(info);
> if (my_close(share->kfile,MYF(0)))
> error = my_errno;
> }
>
>
>