3891 Marko Mäkelä 2012-04-18
recv_recovery_from_checkpoint_start_func(): Fix a compiler warning about
uninitialized variable group_scanned_lsn.
modified:
storage/innobase/log/log0recv.cc
3890 Marko Mäkelä 2012-04-18
Bug#13955083 ALLOW IN-PLACE DDL OPERATIONS ON MISSING OR DISCARDED TABLESPACES
Allow in-place ALTER TABLE operations even if the tablespace is
missing or it has been discarded.
Add a test for ensuring that DISCARD TABLESPACE is being blocked by an
in-place ALTER operation. (The DISCARD TABLESPACE will time out the
meta-data lock upgrade at the end of the ALTER, but that is a separate
matter.)
ha_innobase::check_if_supported_inplace_alter(): Check for
innodb_force_recovery and innodb_data_file_path=newraw already here
and not in the prepare step.
ha_innobase::prepare_inplace_alter_table(), inplace_alter_table():
Move the update_thd() and trx_search_latch_release_if_reserved() calls
already to the check_if phase.
prepare_inplace_alter_table_dict(): If the tablespace is missing, skip
the row_log_allocate().
ha_innobase::inplace_alter_table(): Skip the row_merge_build_indexes()
if the tablespace is missing.
rb:1032 approved by Jimmy Yang
added:
mysql-test/suite/innodb/r/innodb-alter-discard.result
mysql-test/suite/innodb/t/innodb-alter-discard.test
modified:
mysql-test/suite/innodb/r/innodb-index-online.result
mysql-test/suite/innodb/t/innodb-index-online.test
storage/innobase/handler/handler0alter.cc
3889 Chaithra Gopalareddy 2012-04-18 [merge]
Merge from 5.5 to 5.6
=== added file 'mysql-test/suite/innodb/r/innodb-alter-discard.result'
--- a/mysql-test/suite/innodb/r/innodb-alter-discard.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb-alter-discard.result revid:marko.makela@strippeda48agz6l0jz8rrz6
@@ -0,0 +1,15 @@
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t(a INT)ENGINE=InnoDB;
+call mtr.add_suppression("InnoDB: Error: trying to open a table, but could not$");
+call mtr.add_suppression("MySQL is trying to open a table handle but the \.ibd file for$");
+call mtr.add_suppression("InnoDB: Error: table 'test/t'$");
+SELECT * FROM t;
+ERROR 42S02: Table 'test.t' doesn't exist
+ALTER TABLE t ADD INDEX (a), ALGORITHM=INPLACE;
+ERROR 42S02: Table 'test.t' doesn't exist
+ALTER TABLE t1 ADD INDEX (a), ALGORITHM=COPY;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call mtr.add_suppression("InnoDB: (Error|Warning): cannot delete tablespace ");
+ALTER TABLE t DISCARD TABLESPACE;
+ERROR HY000: Got error -1 from storage engine
+DROP TABLE t;
=== modified file 'mysql-test/suite/innodb/r/innodb-index-online.result'
--- a/mysql-test/suite/innodb/r/innodb-index-online.result revid:chaithra.gopalareddy@strippedi
+++ b/mysql-test/suite/innodb/r/innodb-index-online.result revid:marko.makela@stripped0jz8rrz6
@@ -4,6 +4,9 @@ SET DEBUG='d,query,debug_sync_exec:i:t:A
call mtr.add_suppression("InnoDB: Warning: Small buffer pool size");
call mtr.add_suppression("Cannot find index .*c2 in InnoDB index translation table");
call mtr.add_suppression("Find index .*c2 in InnoDB index list but not its MySQL index number");
+call mtr.add_suppression("InnoDB: Error: table 'test/t1'$");
+call mtr.add_suppression("MySQL is trying to open a table handle but the .ibd file for$");
+SET GLOBAL innodb_file_per_table=on;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
SET GLOBAL innodb_monitor_enable=module_ddl;
@@ -257,6 +260,35 @@ COUNT(c2)
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+SET DEBUG_SYNC='row_log_apply_before SIGNAL c2g_created WAIT_FOR dml4_done';
+SET lock_wait_timeout=1;
+ALTER TABLE t1 DROP INDEX c2f, ADD INDEX c2g(c2);
+SET DEBUG_SYNC='now WAIT_FOR c2g_created';
+SET lock_wait_timeout=10;
+ALTER TABLE t1 DISCARD TABLESPACE;
+SELECT state FROM information_schema.processlist
+WHERE info='ALTER TABLE t1 DISCARD TABLESPACE';
+state
+Waiting for table level lock
+SET DEBUG_SYNC='now SIGNAL dml4_done';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2d` (`c2`),
+ KEY `c2f` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='testing if c2e will be dropped'
+ALTER TABLE t1 DROP INDEX c2d, DROP INDEX c2f;
+ERROR 42S02: Table 'test.t1' doesn't exist
+ALTER TABLE t1 ADD INDEX c2h(c2), ALGORITHM=INPLACE;
+ERROR 42S02: Table 'test.t1' doesn't exist
+ALTER TABLE t1 ADD INDEX c2h(c2), ALGORITHM=COPY;
+ERROR 42S02: Table 'test.t1' doesn't exist
+SET GLOBAL innodb_file_per_table=0;
SET DEBUG_SYNC='RESET';
SET DEBUG='-d,debug_sync_abort_on_timeout';
SET DEBUG='';
=== added file 'mysql-test/suite/innodb/t/innodb-alter-discard.test'
--- a/mysql-test/suite/innodb/t/innodb-alter-discard.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb-alter-discard.test revid:marko.makela@stripped
@@ -0,0 +1,42 @@
+#Bug#13955083 ALLOW IN-PLACE DDL OPERATIONS ON MISSING OR DISCARDED TABLESPACES
+
+--source include/have_innodb.inc
+
+let $MYSQLD_DATADIR=`select @@datadir`;
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t(a INT)ENGINE=InnoDB;
+
+# Shut down the server
+-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+-- shutdown_server
+-- source include/wait_until_disconnected.inc
+
+# Remove the tablespace file.
+let IBD=$MYSQLD_DATADIR/test/t.ibd;
+perl;
+unlink "$ENV{IBD}" || die "Unable to unlink $ENV{IBD}\n";
+EOF
+
+# Restart the server.
+-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+-- enable_reconnect
+-- source include/wait_until_connected_again.inc
+
+call mtr.add_suppression("InnoDB: Error: trying to open a table, but could not$");
+call mtr.add_suppression("MySQL is trying to open a table handle but the \.ibd file for$");
+call mtr.add_suppression("InnoDB: Error: table 'test/t'$");
+
+# The ER_NO_SUCH_TABLE is being thrown by ha_innobase::open().
+# The table does exist, only the tablespace does not exist.
+--error ER_NO_SUCH_TABLE
+SELECT * FROM t;
+
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t ADD INDEX (a), ALGORITHM=INPLACE;
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 ADD INDEX (a), ALGORITHM=COPY;
+
+call mtr.add_suppression("InnoDB: (Error|Warning): cannot delete tablespace ");
+--error ER_GET_ERRNO
+ALTER TABLE t DISCARD TABLESPACE;
+DROP TABLE t;
=== modified file 'mysql-test/suite/innodb/t/innodb-index-online.test'
--- a/mysql-test/suite/innodb/t/innodb-index-online.test revid:chaithra.gopalareddy@stripped060733-j54gj268jrfee3fi
+++ b/mysql-test/suite/innodb/t/innodb-index-online.test revid:marko.makela@stripped20418062559-a48agz6l0jz8rrz6
@@ -9,6 +9,13 @@ call mtr.add_suppression("InnoDB: Warnin
# These will be triggered by INSERT INTO t1 VALUES(6,3,1);
call mtr.add_suppression("Cannot find index .*c2 in InnoDB index translation table");
call mtr.add_suppression("Find index .*c2 in InnoDB index list but not its MySQL index number");
+# these will be triggered by DISCARD TABLESPACE
+call mtr.add_suppression("InnoDB: Error: table 'test/t1'$");
+call mtr.add_suppression("MySQL is trying to open a table handle but the .ibd file for$");
+
+# DISCARD TABLESPACE needs file-per-table
+let $per_table=`select @@innodb_file_per_table`;
+SET GLOBAL innodb_file_per_table=on;
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
@@ -256,10 +263,49 @@ SELECT name,count FROM INFORMATION_SCHEM
SELECT COUNT(c2) FROM t1;
CHECK TABLE t1;
-disconnect con1;
+connection default;
+SET DEBUG_SYNC='row_log_apply_before SIGNAL c2g_created WAIT_FOR dml4_done';
+# The lock upgrade at the end of the ALTER will conflict with the DISCARD.
+SET lock_wait_timeout=1;
+--send
+ALTER TABLE t1 DROP INDEX c2f, ADD INDEX c2g(c2);
+
+connection con1;
+SET DEBUG_SYNC='now WAIT_FOR c2g_created';
+
+connect (con2,localhost,root,,);
+connection con2;
+
+# This will conflict with the ALTER in connection default, above.
+SET lock_wait_timeout=10;
+--send
+ALTER TABLE t1 DISCARD TABLESPACE;
+connection con1;
+SELECT state FROM information_schema.processlist
+WHERE info='ALTER TABLE t1 DISCARD TABLESPACE';
+
+SET DEBUG_SYNC='now SIGNAL dml4_done';
+disconnect con1;
connection default;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+connection con2;
+reap;
+disconnect con2;
+connection default;
+
+SHOW CREATE TABLE t1;
+# The ER_NO_SUCH_TABLE is being thrown by ha_innobase::open().
+# The table does exist, only the tablespace does not exist.
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 DROP INDEX c2d, DROP INDEX c2f;
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 ADD INDEX c2h(c2), ALGORITHM=INPLACE;
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 ADD INDEX c2h(c2), ALGORITHM=COPY;
+eval SET GLOBAL innodb_file_per_table=$per_table;
SET DEBUG_SYNC='RESET';
SET DEBUG='-d,debug_sync_abort_on_timeout';
SET DEBUG='';
=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc revid:chaithra.gopalareddy@stripped8jrfee3fi
+++ b/storage/innobase/handler/handler0alter.cc revid:marko.makela@stripped8rrz6
@@ -151,6 +151,10 @@ ha_innobase::check_if_supported_inplace_
{
DBUG_ENTER("check_if_supported_inplace_alter");
+ if (srv_created_new_raw || srv_force_recovery) {
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+ }
+
HA_CREATE_INFO* create_info = ha_alter_info->create_info;
if (ha_alter_info->handler_flags
@@ -186,6 +190,7 @@ ha_innobase::check_if_supported_inplace_
}
update_thd();
+ trx_search_latch_release_if_reserved(prebuilt->trx);
/* Fix the key parts. */
for (KEY* new_key = ha_alter_info->key_info_buffer;
@@ -1625,7 +1630,9 @@ col_fail:
log is unnecessary. */
if (!num_fts_index
&& !(ha_alter_info->handler_flags
- & ~INNOBASE_ONLINE_OPERATIONS)) {
+ & ~INNOBASE_ONLINE_OPERATIONS)
+ && !user_table->ibd_file_missing
+ && !user_table->tablespace_discarded) {
DBUG_EXECUTE_IF("innodb_OOM_prepare_inplace_alter",
error = DB_OUT_OF_MEMORY;
goto error_handling;);
@@ -1825,19 +1832,11 @@ ha_innobase::prepare_inplace_alter_table
goto func_exit;
}
- if (srv_created_new_raw || srv_force_recovery) {
- my_error(ER_OPEN_AS_READONLY, MYF(0),
- table->s->table_name.str);
- DBUG_RETURN(true);
- }
-
ut_d(mutex_enter(&dict_sys->mutex));
ut_d(dict_table_check_for_dup_indexes(
prebuilt->table, CHECK_ABORTED_OK));
ut_d(mutex_exit(&dict_sys->mutex));
- update_thd();
-
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads. */
trx_search_latch_release_if_reserved(prebuilt->trx);
@@ -2116,9 +2115,6 @@ ha_innobase::inplace_alter_table(
DBUG_RETURN(false);
}
- update_thd();
- trx_search_latch_release_if_reserved(prebuilt->trx);
-
class ha_innobase_inplace_ctx* ctx
= static_cast<class ha_innobase_inplace_ctx*>
(ha_alter_info->handler_ctx);
@@ -2126,6 +2122,11 @@ ha_innobase::inplace_alter_table(
DBUG_ASSERT(ctx);
DBUG_ASSERT(ctx->trx);
+ if (prebuilt->table->ibd_file_missing
+ || prebuilt->table->tablespace_discarded) {
+ goto all_done;
+ }
+
/* Read the clustered index of the table and build
indexes based on this information using temporary
files and merge sort. */
@@ -2145,6 +2146,7 @@ oom:
switch (error) {
KEY* dup_key;
+ all_done:
case DB_SUCCESS:
ut_d(mutex_enter(&dict_sys->mutex));
ut_d(dict_table_check_for_dup_indexes(
=== modified file 'storage/innobase/log/log0recv.cc'
--- a/storage/innobase/log/log0recv.cc revid:chaithra.gopalareddy@stripped0733-j54gj268jrfee3fi
+++ b/storage/innobase/log/log0recv.cc revid:marko.makela@stripped0jz8rrz6
@@ -2894,7 +2894,7 @@ recv_recovery_from_checkpoint_start_func
lsn_t checkpoint_lsn;
ib_uint64_t checkpoint_no;
lsn_t old_scanned_lsn;
- lsn_t group_scanned_lsn;
+ lsn_t group_scanned_lsn = 0;
lsn_t contiguous_lsn;
#ifdef UNIV_LOG_ARCHIVE
lsn_t archived_lsn;
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk branch (marko.makela:3889 to 3891) | marko.makela | 20 Apr |