Permalink
Browse files

BUG#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES

Problem :
---------
While importing table, we are getting the index columns
from cfg by name and hence if a column is repeated we get
the first reference always. If the first and second reference
has different prefix length, the validation fails.

Solution :
----------
Check all index column in dictionary and cfg one to one. The
fix expects cfg and dictionary to match exactly.

Reviewed-by: Kevin Lewis <kevin.lewis@oracle.com>
Reviewed-by: Marko Makela <marko.makela@oracle.com>

RB: 8774
  • Loading branch information...
Debarun Banerjee
Debarun Banerjee committed May 6, 2015
1 parent d3cfb44 commit db23392bac27ad3e84319229ee3db9921b734abd
@@ -0,0 +1,21 @@
# Export Table and Import from saved files .cfg and .ibd
# Caller should create t1 table definition and populate table
let $MYSQLD_DATADIR = `SELECT @@datadir`;
FLUSH TABLES t1 FOR EXPORT;
--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/t1.cfg_back
--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/t1.ibd_back
UNLOCK TABLES;
ALTER TABLE t1 DISCARD TABLESPACE;
--move_file $MYSQLD_DATADIR/t1.cfg_back $MYSQLD_DATADIR/test/t1.cfg
--move_file $MYSQLD_DATADIR/t1.ibd_back $MYSQLD_DATADIR/test/t1.ibd
ALTER TABLE t1 IMPORT TABLESPACE;
CHECK TABLE t1;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
@@ -0,0 +1,56 @@
#
# Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES
#
CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32),
PRIMARY KEY (c1, c2, c3))
ENGINE=InnoDB;
ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3);
ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2);
ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20));
INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3');
# Test with 2ndary index having prefix
FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t1 DISCARD TABLESPACE;
ALTER TABLE t1 IMPORT TABLESPACE;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(32) NOT NULL DEFAULT '',
`c2` varchar(32) NOT NULL DEFAULT '',
`c3` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`c1`,`c2`,`c3`),
KEY `ind1` (`c1`(5),`c2`,`c3`),
KEY `ind2` (`c3`,`c1`(10),`c2`),
KEY `ind3` (`c2`,`c3`,`c1`(20))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
SELECT * FROM t1;
c1 c2 c3
Test Data -1 Test Data -2 Test Data -3
# Test with PK & 2ndary index with prefix
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20));
FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
ALTER TABLE t1 DISCARD TABLESPACE;
ALTER TABLE t1 IMPORT TABLESPACE;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(32) NOT NULL DEFAULT '',
`c2` varchar(32) NOT NULL DEFAULT '',
`c3` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`c1`(5),`c2`(10),`c3`(20)),
KEY `ind1` (`c1`(5),`c2`,`c3`),
KEY `ind2` (`c3`,`c1`(10),`c2`),
KEY `ind3` (`c2`,`c3`,`c1`(20))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
SELECT * FROM t1;
c1 c2 c3
Test Data -1 Test Data -2 Test Data -3
DROP TABLE t1;
@@ -0,0 +1,25 @@
# Test "ALTER TABLE ... IMPORT TABLESPACE" in InnoDB
--source include/have_innodb.inc
--echo #
--echo # Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES
--echo #
CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32),
PRIMARY KEY (c1, c2, c3))
ENGINE=InnoDB;
ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3);
ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2);
ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20));
INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3');
--echo # Test with 2ndary index having prefix
--source suite/innodb/include/import.inc
--echo # Test with PK & 2ndary index with prefix
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20));
--source suite/innodb/include/import.inc
DROP TABLE t1;
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2012, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -138,14 +138,6 @@ struct row_import {
@return ULINT_UNDEFINED if not found. */
ulint find_col(const char* name) const UNIV_NOTHROW;
/**
Find the index field entry in in the cfg indexes fields.
@name - of the index to look for
@return instance if found else 0. */
const dict_field_t* find_field(
const row_index_t* cfg_index,
const char* name) const UNIV_NOTHROW;
/**
Get the number of rows for which purge failed during the convert phase.
@param name - index name
@@ -1140,30 +1132,6 @@ row_import::find_col(
return(ULINT_UNDEFINED);
}
/**
Find the index field entry in in the cfg indexes fields.
@name - of the index to look for
@return instance if found else 0. */
const dict_field_t*
row_import::find_field(
const row_index_t* cfg_index,
const char* name) const UNIV_NOTHROW
{
const dict_field_t* field = cfg_index->m_fields;
for (ulint i = 0; i < cfg_index->m_n_fields; ++i, ++field) {
const char* field_name;
field_name = reinterpret_cast<const char*>(field->name);
if (strcmp(field_name, name) == 0) {
return(field);
}
}
return(0);
}
/**
Check if the index schema that was read from the .cfg file matches the
in memory index definition.
@@ -1187,51 +1155,60 @@ row_import::match_index_columns(
return(DB_ERROR);
}
cfg_index->m_srv_index = index;
if (cfg_index->m_n_fields != index->n_fields) {
const dict_field_t* field = index->fields;
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index field count %lu doesn't match"
" tablespace metadata file value %lu",
(ulong) index->n_fields,
(ulong) cfg_index->m_n_fields);
for (ulint i = 0; i < index->n_fields; ++i, ++field) {
return(DB_ERROR);
}
const dict_field_t* cfg_field;
cfg_index->m_srv_index = index;
cfg_field = find_field(cfg_index, field->name);
const dict_field_t* field = index->fields;
const dict_field_t* cfg_field = cfg_index->m_fields;
if (cfg_field == 0) {
for (ulint i = 0; i < index->n_fields; ++i, ++field, ++cfg_field) {
if (strcmp(field->name, cfg_field->name) != 0) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index %s field %s not found in tablespace "
"meta-data file.",
index->name, field->name);
"Index field name %s doesn't match"
" tablespace metadata field name %s"
" for field position %lu",
field->name, cfg_field->name, (ulong) i);
err = DB_ERROR;
} else {
}
if (cfg_field->prefix_len != field->prefix_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index %s field %s prefix len %lu "
"doesn't match meta-data file value "
"%lu",
index->name, field->name,
(ulong) field->prefix_len,
(ulong) cfg_field->prefix_len);
if (cfg_field->prefix_len != field->prefix_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index %s field %s prefix len %lu"
" doesn't match metadata file value"
" %lu",
index->name, field->name,
(ulong) field->prefix_len,
(ulong) cfg_field->prefix_len);
err = DB_ERROR;
}
err = DB_ERROR;
}
if (cfg_field->fixed_len != field->fixed_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index %s field %s fixed len %lu "
"doesn't match meta-data file value "
"%lu",
index->name, field->name,
(ulong) field->fixed_len,
(ulong) cfg_field->fixed_len);
if (cfg_field->fixed_len != field->fixed_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Index %s field %s fixed len %lu"
" doesn't match metadata file value"
" %lu",
index->name, field->name,
(ulong) field->fixed_len,
(ulong) cfg_field->fixed_len);
err = DB_ERROR;
}
err = DB_ERROR;
}
}

0 comments on commit db23392

Please sign in to comment.