Skip to content

Commit f6a78ae

Browse files
author
Priyanka Sangam
committed
Bug #21178339: 'NDB_RESTORE -M' SOMETIMES: "FAILED TO CREATE INDEX ENTRY_KEY$UNIQUE" ERROR 1
Unique index creation requires a DBUTIL PREPARE which is initiated from TRIX. DBUTIL allows only one PREPARE at a time. If a PREPARE request is received in DBUTIL while a PREPARE is already running, a PREPARE_SEIZE_ERROR is returned. This occurs if a CREATE_EVENT has requested a PREPARE before unique index creation. For unique index creation, the PREPARE_SEIZE_ERROR is not mapped to an equivalent error code, so an error 1 "Unknown error" is returned. Mapped PREPARE_SEIZE_ERROR to error 748 "Busy during read of event table". Fixed ndb_restore to retry index creation on temporary errors.
1 parent 7e9360b commit f6a78ae

File tree

8 files changed

+107
-16
lines changed

8 files changed

+107
-16
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,7 @@ lock tables t3 read;
198198
delete t2 from t2, t3 where t2.id = t3.id;
199199
unlock tables;
200200
drop table t2, t3;
201+
create table t1 (id int primary key, val int) engine=ndb;
202+
create unique index val_unique on t1(val);
203+
ERROR HY000: Got temporary error 748 'Busy during read of event table' from NDBCLUSTER
204+
drop table t1;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,10 @@ unlock tables;
266266

267267
connection con1;
268268
drop table t2, t3;
269+
270+
create table t1 (id int primary key, val int) engine=ndb;
271+
--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "all error 19000" >> $NDB_TOOLS_OUTPUT
272+
--error 1297
273+
create unique index val_unique on t1(val);
274+
--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "all error 0" >> $NDB_TOOLS_OUTPUT
275+
drop table t1;

storage/ndb/include/kernel/signaldata/BuildIndx.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -76,7 +76,8 @@ struct BuildIndxRef {
7676
AllocationFailure = 4252,
7777
InternalError = 4346,
7878
IndexNotFound = 4243,
79-
DeadlockError = 4351
79+
DeadlockError = 4351,
80+
UtilBusy = 748
8081
};
8182

8283
STATIC_CONST( SignalLength = 10 );

storage/ndb/src/kernel/blocks/ERROR_codes.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License as published by
@@ -24,13 +24,14 @@ Next DBDIH 7245
2424
Next DBTC 8109
2525
Next CMVMI 9000
2626
Next BACKUP 10042
27-
Next DBUTIL 11002
27+
Next PGMAN 11010
2828
Next DBTUX 12010
2929
Next SUMA 13049
3030
Next LGMAN 15001
3131
Next TSMAN 16001
3232
Next DBSPJ 17000
3333
Next TRIX 18000
34+
Next DBUTIL 19001
3435

3536
TESTING NODE FAILURE, ARBITRATION
3637
---------------------------------
@@ -795,3 +796,7 @@ Index stats:
795796
18022: fail RT_CLEAN_OLD (non-fatal) - as in 18021
796797
18023: fail RT_CLEAN_ALL (non-fatal) - as in 18021
797798
18024: fail RT_SCAN_FRAG - simulate TC error 630
799+
800+
DBUTIL
801+
-------
802+
19000: fail UTIL_PREPARE_REQ with PREPARE_SEIZE_ERROR

storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -1212,8 +1212,8 @@ void Cmvmi::execTAMPER_ORD(Signal* signal)
12121212
}
12131213
else if (errNo < 12000)
12141214
{
1215-
// DBUTIL_REF ?
12161215
jam();
1216+
tuserblockref = PGMAN_REF;
12171217
}
12181218
else if (errNo < 13000)
12191219
{
@@ -1250,6 +1250,11 @@ void Cmvmi::execTAMPER_ORD(Signal* signal)
12501250
jam();
12511251
tuserblockref = TRIX_REF;
12521252
}
1253+
else if (errNo < 20000)
1254+
{
1255+
jam();
1256+
tuserblockref = DBUTIL_REF;
1257+
}
12531258
else if (errNo < 30000)
12541259
{
12551260
/*--------------------------------------------------------------------*/

storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -42,6 +42,9 @@
4242

4343
#include <NdbTick.h>
4444

45+
#include <EventLogger.hpp>
46+
extern EventLogger * g_eventLogger;
47+
4548
#include <signaldata/DbinfoScan.hpp>
4649
#include <signaldata/TransIdAI.hpp>
4750

@@ -957,7 +960,6 @@ DbUtil::sendUtilPrepareRef(Signal* signal, UtilPrepareRef::ErrorCode error,
957960
ref->errorCode = error;
958961
ref->senderData = senderData;
959962
ref->dictErrCode = errCode2;
960-
961963
sendSignal(recipient, GSN_UTIL_PREPARE_REF, signal,
962964
UtilPrepareRef::SignalLength, JBB);
963965
}
@@ -1010,7 +1012,19 @@ DbUtil::execUTIL_PREPARE_REQ(Signal* signal)
10101012
SectionHandle handle(this, signal);
10111013

10121014
jam();
1013-
if (!c_runningPrepares.seizeFirst(prepPtr)) {
1015+
1016+
if(ERROR_INSERTED(19000))
1017+
{
1018+
jam();
1019+
CLEAR_ERROR_INSERT_VALUE;
1020+
g_eventLogger->info("Simulating DBUTIL prepare seize fail");
1021+
releaseSections(handle);
1022+
sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR,
1023+
senderRef, senderData);
1024+
return;
1025+
}
1026+
if (!c_runningPrepares.seizeFirst(prepPtr))
1027+
{
10141028
jam();
10151029
releaseSections(handle);
10161030
sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR,

storage/ndb/src/kernel/blocks/trix/Trix.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -701,6 +701,20 @@ void Trix::execUTIL_PREPARE_REF(Signal* signal)
701701
}
702702
subRecPtr.p = subRec;
703703
subRec->errorCode = (BuildIndxRef::ErrorCode)utilPrepareRef->errorCode;
704+
switch (utilPrepareRef->errorCode) {
705+
case UtilPrepareRef::PREPARE_SEIZE_ERROR:
706+
case UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR:
707+
case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
708+
case UtilPrepareRef::DICT_TAB_INFO_ERROR:
709+
subRec->errorCode = BuildIndxRef::UtilBusy;
710+
break;
711+
case UtilPrepareRef::MISSING_PROPERTIES_SECTION:
712+
subRec->errorCode = BuildIndxRef::BadRequestType;
713+
break;
714+
default:
715+
ndbrequire(false);
716+
break;
717+
}
704718

705719
UtilReleaseConf* conf = (UtilReleaseConf*)signal->getDataPtrSend();
706720
conf->senderData = subRecPtr.i;

storage/ndb/tools/restore/consumer_restore.cpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -979,14 +979,36 @@ BackupRestore::rebuild_indexes(const TableS& table)
979979
const NDB_TICKS start = NdbTick_getCurrentTicks();
980980
info << "Rebuilding index `" << idx_name << "` on table `"
981981
<< tab_name << "` ..." << flush;
982-
if ((dict->getIndex(idx_name, tab_name) == NULL)
983-
&& (dict->createIndex(* idx, 1) != 0))
982+
bool done = false;
983+
for(int retries = 0; retries<11; retries++)
984+
{
985+
if ((dict->getIndex(idx_name, tab_name) == NULL)
986+
&& (dict->createIndex(* idx, 1) != 0))
987+
{
988+
if(dict->getNdbError().status == NdbError::TemporaryError)
989+
{
990+
err << "retry sleep 50 ms on error " <<
991+
dict->getNdbError().code << endl;
992+
NdbSleep_MilliSleep(50);
993+
continue; // retry on temporary error
994+
}
995+
else
996+
{
997+
break;
998+
}
999+
}
1000+
else
1001+
{
1002+
done = true;
1003+
break;
1004+
}
1005+
}
1006+
if(!done)
9841007
{
9851008
info << "FAIL!" << endl;
9861009
err << "Rebuilding index `" << idx_name << "` on table `"
9871010
<< tab_name <<"` failed: ";
9881011
err << dict->getNdbError() << endl;
989-
9901012
return false;
9911013
}
9921014
const NDB_TICKS stop = NdbTick_getCurrentTicks();
@@ -2511,13 +2533,32 @@ BackupRestore::endOfTables(){
25112533
idx->setName(split_idx[3].c_str());
25122534
if (m_restore_meta && !m_disable_indexes && !m_rebuild_indexes)
25132535
{
2514-
if (dict->createIndex(* idx) != 0)
2536+
bool done = false;
2537+
for(unsigned int retries = 0; retries < 11; retries++)
2538+
{
2539+
if(dict->createIndex(* idx) == 0)
2540+
{
2541+
done = true; // success
2542+
break;
2543+
}
2544+
else if(dict->getNdbError().status == NdbError::TemporaryError)
2545+
{
2546+
err << "retry sleep 50 ms on error " <<
2547+
dict->getNdbError().code << endl;
2548+
NdbSleep_MilliSleep(50);
2549+
continue; // retry on temporary error
2550+
}
2551+
else
2552+
{
2553+
break; // error out on permanent error
2554+
}
2555+
}
2556+
if(!done)
25152557
{
25162558
delete idx;
25172559
err << "Failed to create index `" << split_idx[3].c_str()
25182560
<< "` on `" << table_name << "`" << endl
25192561
<< dict->getNdbError() << endl;
2520-
25212562
return false;
25222563
}
25232564
info << "Successfully created index `" << split_idx[3].c_str()

0 commit comments

Comments
 (0)