Skip to content

Commit e794ff3

Browse files
committed
Bug#26974491 FIXES DATA RESTORE WITH DISABLE INDEXES
Fixes ndb_restore to drop foreign keys when used with the option, --disable-indexes. When metadata restore was done with --disable-indexes, there was no attempt to create indexes or foreign keys dependent on them. But, when ndb_restore was used without --disable-indexes during metadata restore, indexes and foreign keys were created. When the same option was used later while data restore, there was an attempt to drop the indexes created in the previous step. But, it ignored the failure of drop index step whenever there was a foreign key dependent on the index and there was no attempt to drop the foreign keys in the first place. This caused problems while rebuilding indexes when there was an attempt to create foreign keys which already exist. So, ndb_restore is fixed 1) To actively drop the restored foreign keys described in the backup when --disable-indexes is set. 2) To check for the existence of indexes before they are attempted to be dropped. The checks have been added so that data node restores with --disable-indexes option for subsequent data nodes doesn't attempt to drop the non existent indexes. Also, ndb_fk_restore test has been updated with all the use cases involving all the possible combinations of options, --disable-indexes and --rebuild-indexes. Change-Id: I4e9ced7df74a083ce1b0fbfcf584810a83c4d19c
1 parent 4fa12b3 commit e794ff3

File tree

3 files changed

+177
-3
lines changed

3 files changed

+177
-3
lines changed

mysql-test/suite/ndb/r/ndb_fk_restore.result

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,50 @@ drop table db1.t1, db2.t1;
551551
# cleanup
552552
drop database db1;
553553
drop database db2;
554+
# Bug#26974491 FIXES DATA RESTORE WITH DISABLE INDEXES
555+
create database db3;
556+
use db3;
557+
create table t4 (
558+
id int primary key auto_increment
559+
) engine=ndb;
560+
create table t5 (
561+
id int primary key auto_increment,
562+
val int,
563+
constraint fkt3t2 foreign key (val) references t4 (id)
564+
)engine=ndb;
565+
insert into t4 values (1), (2), (3), (4), (5);
566+
insert into t5 values (1,1), (2,2), (3,3), (4,4), (5,5);
567+
# take backup and drop the tables
568+
drop table db3.t5, db3.t4;
569+
# Create more tables before restore in order to verify that ndb_restore restores foreign keys
570+
# appropriately even though the table ids of parent and child tables which make up the name
571+
# of the foreign key in the format, <parent_table_id>/<child_table_id>/fk_name are different
572+
# in backup files than the table ids restored.
573+
create table db3.t6 (
574+
id int primary key auto_increment
575+
) engine=ndb;
576+
create table db3.t7 (
577+
id int primary key auto_increment
578+
) engine=ndb;
579+
create table db3.t8 (
580+
id int primary key auto_increment
581+
) engine=ndb;
582+
create table db3.t9 (
583+
id int primary key auto_increment
584+
) engine=ndb;
585+
# Use case #1: Meta restore done with --disable-indexes (recommended)
586+
# Drop the tables to retore them again with a different use case
587+
drop table db3.t5, db3.t4;
588+
# Use case #2: Separate --disable-indexes step after metadata restore
589+
# Drop the tables to retore them again with a different use case
590+
drop table db3.t5, db3.t4;
591+
# Use case #3: Data restore with --disable-indexes
592+
# Drop the tables to retore them again with a different use case
593+
drop table db3.t5, db3.t4;
594+
# Use case #4: Data restore with --disable-indexes and Data restore with --rebuild-indexes
595+
# Drop the tables to retore them again with a different use case
596+
drop table db3.t5, db3.t4;
597+
# Use case #5: Both metadata and data restore with both --disable-indexes and --rebuild-indexes
598+
# cleanup
599+
drop table db3.t6, db3.t7, db3.t8, db3.t9;
600+
drop database db3;

mysql-test/suite/ndb/t/ndb_fk_restore.test

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,84 @@ drop table db1.t1, db2.t1;
212212
--echo # cleanup
213213
drop database db1;
214214
drop database db2;
215+
216+
--echo # Bug#26974491 FIXES DATA RESTORE WITH DISABLE INDEXES
217+
create database db3;
218+
use db3;
219+
create table t4 (
220+
id int primary key auto_increment
221+
) engine=ndb;
222+
create table t5 (
223+
id int primary key auto_increment,
224+
val int,
225+
constraint fkt3t2 foreign key (val) references t4 (id)
226+
)engine=ndb;
227+
insert into t4 values (1), (2), (3), (4), (5);
228+
insert into t5 values (1,1), (2,2), (3,3), (4,4), (5,5);
229+
230+
-- echo # take backup and drop the tables
231+
-- source include/ndb_backup.inc
232+
drop table db3.t5, db3.t4;
233+
234+
-- echo # Create more tables before restore in order to verify that ndb_restore restores foreign keys
235+
-- echo # appropriately even though the table ids of parent and child tables which make up the name
236+
-- echo # of the foreign key in the format, <parent_table_id>/<child_table_id>/fk_name are different
237+
-- echo # in backup files than the table ids restored.
238+
create table db3.t6 (
239+
id int primary key auto_increment
240+
) engine=ndb;
241+
create table db3.t7 (
242+
id int primary key auto_increment
243+
) engine=ndb;
244+
create table db3.t8 (
245+
id int primary key auto_increment
246+
) engine=ndb;
247+
create table db3.t9 (
248+
id int primary key auto_increment
249+
) engine=ndb;
250+
251+
-- echo # Use case #1: Meta restore done with --disable-indexes (recommended)
252+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-meta --print_meta --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
253+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-data $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
254+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --restore-data $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
255+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --rebuild-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
256+
257+
-- echo # Drop the tables to retore them again with a different use case
258+
drop table db3.t5, db3.t4;
259+
260+
-- echo # Use case #2: Separate --disable-indexes step after metadata restore
261+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-meta --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
262+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
263+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-data --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
264+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --restore-data --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
265+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --rebuild-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
266+
267+
-- echo # Drop the tables to retore them again with a different use case
268+
drop table db3.t5, db3.t4;
269+
270+
-- echo # Use case #3: Data restore with --disable-indexes
271+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-meta --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
272+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-data --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
273+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --restore-data --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
274+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --rebuild-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
275+
276+
-- echo # Drop the tables to retore them again with a different use case
277+
drop table db3.t5, db3.t4;
278+
279+
-- echo # Use case #4: Data restore with --disable-indexes and Data restore with --rebuild-indexes
280+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-meta --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
281+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-data --disable-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
282+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --restore-data --rebuild-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
283+
284+
-- echo # Drop the tables to retore them again with a different use case
285+
drop table db3.t5, db3.t4;
286+
287+
-- echo # Use case #5: Both metadata and data restore with both --disable-indexes and --rebuild-indexes
288+
--exec $NDB_RESTORE -b $the_backup_id -n 1 --restore-meta --restore-data --disable-indexes --rebuild-indexes $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
289+
--exec $NDB_RESTORE -b $the_backup_id -n 2 --restore-data $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
290+
291+
--echo # cleanup
292+
drop table db3.t6, db3.t7, db3.t8, db3.t9;
293+
drop database db3;
294+
295+
--remove_file $NDB_TOOLS_OUTPUT

storage/ndb/tools/restore/consumer_restore.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3063,6 +3063,42 @@ BackupRestore::fk(Uint32 type, const void * ptr)
30633063
}
30643064
m_fks.push_back(fk_ptr);
30653065
info << "Save FK " << fk_ptr->getName() << endl;
3066+
3067+
if (m_disable_indexes)
3068+
{
3069+
// Extract foreign key name from format
3070+
// like 10/14/fk1 where 10,14 are old table ids
3071+
const char *fkname = 0;
3072+
Vector<BaseString> splitname;
3073+
BaseString tmpname(fk_ptr->getName());
3074+
int n = tmpname.split(splitname, "/");
3075+
if (n == 3)
3076+
{
3077+
fkname = splitname[2].c_str();
3078+
}
3079+
else
3080+
{
3081+
err << "Invalid foreign key name " << tmpname.c_str() << endl;
3082+
return false;
3083+
}
3084+
NdbDictionary::ForeignKey fk;
3085+
char fullname[MAX_TAB_NAME_SIZE];
3086+
sprintf(fullname, "%d/%d/%s", parent->getObjectId(),
3087+
child->getObjectId(), fkname);
3088+
3089+
// Drop foreign keys if they exist
3090+
if (dict->getForeignKey(fk, fullname) == 0)
3091+
{
3092+
info << "Dropping Foreign key " << fkname;
3093+
if (dict->dropForeignKey(fk) != 0)
3094+
{
3095+
err << "Failed to drop fk '" << fk_ptr->getName()
3096+
<< "' : " << dict->getNdbError().code << " "
3097+
<< dict->getNdbError().message << endl;
3098+
return false;
3099+
}
3100+
}
3101+
}
30663102
}
30673103
return true;
30683104
break;
@@ -3158,11 +3194,21 @@ BackupRestore::endOfTables(){
31583194
}
31593195
else if (m_disable_indexes)
31603196
{
3161-
int res = dict->dropIndex(idx->getName(), prim->getName());
3162-
if (res == 0)
3197+
// Drop indexes if they exist
3198+
if(dict->getIndex(idx->getName(), prim->getName()))
31633199
{
3164-
info << "Dropped index `" << split_idx[3].c_str()
3200+
if (dict->dropIndex(idx->getName(), prim->getName()) == 0)
3201+
{
3202+
info << "Dropped index `" << split_idx[3].c_str()
31653203
<< "` on `" << table_name << "`" << endl;
3204+
}
3205+
else
3206+
{
3207+
err << "Failed to drop index `" << split_idx[3].c_str() << "` on `"
3208+
<< table_name.c_str() << "`: " << dict->getNdbError().code << " "
3209+
<< dict->getNdbError().message << endl;
3210+
return false;
3211+
}
31663212
}
31673213
}
31683214
Uint32 id = prim->getObjectId();

0 commit comments

Comments
 (0)