Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
f7115f12
Commit
f7115f12
authored
Apr 17, 2007
by
jonas@perch.ndb.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge perch.ndb.mysql.com:/home/jonas/src/51-telco-gca
into perch.ndb.mysql.com:/home/jonas/src/mysql-5.1-new-ndb
parents
527158ba
6a35ddde
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1101 additions
and
495 deletions
+1101
-495
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+165
-255
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
+3
-1
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
+2
-0
storage/ndb/test/include/NdbMixRestarter.hpp
storage/ndb/test/include/NdbMixRestarter.hpp
+74
-0
storage/ndb/test/ndbapi/testDict.cpp
storage/ndb/test/ndbapi/testDict.cpp
+451
-1
storage/ndb/test/ndbapi/testSRBank.cpp
storage/ndb/test/ndbapi/testSRBank.cpp
+81
-237
storage/ndb/test/run-test/daily-basic-tests.txt
storage/ndb/test/run-test/daily-basic-tests.txt
+8
-0
storage/ndb/test/src/Makefile.am
storage/ndb/test/src/Makefile.am
+1
-1
storage/ndb/test/src/NDBT_Test.cpp
storage/ndb/test/src/NDBT_Test.cpp
+4
-0
storage/ndb/test/src/NdbMixRestarter.cpp
storage/ndb/test/src/NdbMixRestarter.cpp
+312
-0
No files found.
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
View file @
f7115f12
...
...
@@ -2659,25 +2659,63 @@ checkSchemaStatus(Uint32 tableType, Uint32 pass)
case
DictTabInfo
:
:
IndexTrigger
:
return
false
;
case
DictTabInfo
:
:
LogfileGroup
:
return
pass
==
0
;
return
pass
==
0
||
pass
==
9
||
pass
==
10
;
case
DictTabInfo
:
:
Tablespace
:
return
pass
==
1
;
return
pass
==
1
||
pass
==
8
||
pass
==
11
;
case
DictTabInfo
:
:
Datafile
:
case
DictTabInfo
:
:
Undofile
:
return
pass
==
2
;
return
pass
==
2
||
pass
==
7
||
pass
==
12
;
case
DictTabInfo
:
:
SystemTable
:
case
DictTabInfo
:
:
UserTable
:
return
pass
==
3
;
return
/* pass == 3 || pass == 6 || */
pass
==
1
3
;
case
DictTabInfo
:
:
UniqueHashIndex
:
case
DictTabInfo
:
:
HashIndex
:
case
DictTabInfo
:
:
UniqueOrderedIndex
:
case
DictTabInfo
:
:
OrderedIndex
:
return
pass
==
4
;
return
/* pass == 4 || pass == 5 || */
pass
==
1
4
;
}
return
false
;
}
static
const
Uint32
CREATE_OLD_PASS
=
4
;
static
const
Uint32
DROP_OLD_PASS
=
9
;
static
const
Uint32
CREATE_NEW_PASS
=
14
;
static
const
Uint32
LAST_PASS
=
14
;
NdbOut
&
operator
<<
(
NdbOut
&
out
,
const
SchemaFile
::
TableEntry
entry
)
{
out
<<
"["
;
out
<<
" state: "
<<
entry
.
m_tableState
;
out
<<
" version: "
<<
hex
<<
entry
.
m_tableVersion
<<
dec
;
out
<<
" type: "
<<
entry
.
m_tableType
;
out
<<
" words: "
<<
entry
.
m_info_words
;
out
<<
" gcp: "
<<
entry
.
m_gcp
;
out
<<
" ]"
;
return
out
;
}
/**
* Pass 0 Create old LogfileGroup
* Pass 1 Create old Tablespace
* Pass 2 Create old Datafile/Undofile
* Pass 3 Create old Table // NOT DONE DUE TO DIH
* Pass 4 Create old Index // NOT DONE DUE TO DIH
* Pass 5 Drop old Index // NOT DONE DUE TO DIH
* Pass 6 Drop old Table // NOT DONE DUE TO DIH
* Pass 7 Drop old Datafile/Undofile
* Pass 8 Drop old Tablespace
* Pass 9 Drop old Logfilegroup
* Pass 10 Create new LogfileGroup
* Pass 11 Create new Tablespace
* Pass 12 Create new Datafile/Undofile
* Pass 13 Create new Table
* Pass 14 Create new Index
*/
void
Dbdict
::
checkSchemaStatus
(
Signal
*
signal
)
{
XSchemaFile
*
newxsf
=
&
c_schemaFile
[
c_schemaRecord
.
schemaPage
!=
0
];
...
...
@@ -2692,287 +2730,132 @@ void Dbdict::checkSchemaStatus(Signal* signal)
Uint32
tableId
=
c_restartRecord
.
activeTable
;
SchemaFile
::
TableEntry
*
newEntry
=
getTableEntry
(
newxsf
,
tableId
);
SchemaFile
::
TableEntry
*
oldEntry
=
getTableEntry
(
oldxsf
,
tableId
);
SchemaFile
::
TableState
s
chemaState
=
SchemaFile
::
TableState
newS
chemaState
=
(
SchemaFile
::
TableState
)
newEntry
->
m_tableState
;
SchemaFile
::
TableState
oldSchemaState
=
(
SchemaFile
::
TableState
)
oldEntry
->
m_tableState
;
if
(
c_restartRecord
.
activeTable
>=
c_tableRecordPool
.
getSize
())
{
jam
();
ndbrequire
(
s
chemaState
==
SchemaFile
::
INIT
);
ndbrequire
(
newS
chemaState
==
SchemaFile
::
INIT
);
ndbrequire
(
oldSchemaState
==
SchemaFile
::
INIT
);
continue
;
}
//if
if
(
!::
checkSchemaStatus
(
oldEntry
->
m_tableType
,
c_restartRecord
.
m_pass
))
continue
;
//#define PRINT_SCHEMA_RESTART
#ifdef PRINT_SCHEMA_RESTART
char
buf
[
100
];
snprintf
(
buf
,
sizeof
(
buf
),
"checkSchemaStatus: pass: %d table: %d"
,
c_restartRecord
.
m_pass
,
tableId
);
#endif
if
(
!::
checkSchemaStatus
(
newEntry
->
m_tableType
,
c_restartRecord
.
m_pass
))
if
(
c_restartRecord
.
m_pass
<=
CREATE_OLD_PASS
)
{
if
(
!::
checkSchemaStatus
(
oldEntry
->
m_tableType
,
c_restartRecord
.
m_pass
))
continue
;
switch
(
schemaState
){
case
SchemaFile
:
:
INIT
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
)
{
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
ok
=
true
;
jam
();
break
;
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
ok
=
true
;
jam
();
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
restartDropTab
(
signal
,
tableId
);
return
;
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
// Temporary table is never written to disk, so just set to INIT.
jam
();
ok
=
true
;
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
break
;
}
//switch
ndbrequire
(
ok
);
break
;
}
case
SchemaFile
:
:
ADD_STARTED
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
)
{
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
ok
=
true
;
break
;
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
switch
(
oldSchemaState
){
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
continue
;
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
jam
();
ok
=
true
;
//------------------------------------------------------------------
// Add Table was started but not completed. Will be dropped in all
// nodes. Update schema information (restore table version).
//------------------------------------------------------------------
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
restartDropTab
(
signal
,
tableId
);
#ifdef PRINT_SCHEMA_RESTART
ndbout_c
(
"%s -> restartCreateTab"
,
buf
);
ndbout
<<
*
newEntry
<<
" "
<<
*
oldEntry
<<
endl
;
#endif
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
oldEntry
,
true
);
return
;
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
ok
=
true
;
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
break
;
}
ndbrequire
(
ok
);
break
;
}
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
)
{
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
ok
=
true
;
//------------------------------------------------------------------
// Table was added in the master node but not in our node. We can
// retrieve the table definition from the master.
//------------------------------------------------------------------
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
return
;
break
;
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
ok
=
true
;
//------------------------------------------------------------------
// Table was added in both our node and the master node. We can
// retrieve the table definition from our own disk.
//------------------------------------------------------------------
if
(
newEntry
->
m_tableVersion
==
oldEntry
->
m_tableVersion
)
{
jam
();
ndbrequire
(
newEntry
->
m_gcp
==
oldEntry
->
m_gcp
);
ndbrequire
(
newEntry
->
m_tableType
==
oldEntry
->
m_tableType
);
Uint32
type
=
oldEntry
->
m_tableType
;
// On NR get index from master because index state is not on file
const
bool
file
=
c_systemRestart
||
!
DictTabInfo
::
isIndex
(
type
);
newEntry
->
m_info_words
=
oldEntry
->
m_info_words
;
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
file
);
return
;
}
else
{
//------------------------------------------------------------------
// Must be a new version of the table if anything differs. Both table
// version and global checkpoint must be different.
// This should not happen for the master node. This can happen after
// drop table followed by add table or after change table.
// Not supported in this version.
//------------------------------------------------------------------
ndbrequire
(
c_masterNodeId
!=
getOwnNodeId
());
ndbrequire
(
newEntry
->
m_tableVersion
!=
oldEntry
->
m_tableVersion
);
jam
();
if
(
c_restartRecord
.
m_pass
<=
DROP_OLD_PASS
)
{
if
(
!::
checkSchemaStatus
(
oldEntry
->
m_tableType
,
c_restartRecord
.
m_pass
))
continue
;
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
switch
(
oldSchemaState
){
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
continue
;
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
#ifdef PRINT_SCHEMA_RESTART
ndbout_c
(
"%s -> restartDropTab"
,
buf
);
ndbout
<<
*
newEntry
<<
" "
<<
*
oldEntry
<<
endl
;
#endif
restartDropTab
(
signal
,
tableId
,
oldEntry
,
newEntry
);
return
;
}
//if
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
ok
=
true
;
// For NR, we must re-create the table.
// For SR, we do nothing as the table was never saved to disk.
if
(
!
c_systemRestart
)
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
if
(
!
(
*
oldEntry
==
*
newEntry
))
{
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
#ifdef PRINT_SCHEMA_RESTART
ndbout_c
(
"%s -> restartDropTab"
,
buf
);
ndbout
<<
*
newEntry
<<
" "
<<
*
oldEntry
<<
endl
;
#endif
restartDropTab
(
signal
,
tableId
,
oldEntry
,
newEntry
);
return
;
}
break
;
}
ndbrequire
(
ok
);
break
;
}
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
){
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
ok
=
true
;
break
;
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
restartDropTab
(
signal
,
tableId
);
return
;
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
ok
=
true
;
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
break
;
continue
;
}
ndbrequire
(
ok
);
break
;
}
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
)
{
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
ok
=
true
;
if
(
!
c_systemRestart
)
if
(
c_restartRecord
.
m_pass
<=
CREATE_NEW_PASS
)
{
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
return
;
}
break
;
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
ok
=
true
;
//------------------------------------------------------------------
// Table was altered in the master node but not in our node. We can
// retrieve the altered table definition from the master.
//------------------------------------------------------------------
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
return
;
break
;
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
ok
=
true
;
if
(
!::
checkSchemaStatus
(
newEntry
->
m_tableType
,
c_restartRecord
.
m_pass
))
continue
;
//------------------------------------------------------------------
// Table was altered in both our node and the master node. We can
// retrieve the table definition from our own disk.
//------------------------------------------------------------------
switch
(
newSchemaState
){
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
*
oldEntry
=
*
newEntry
;
continue
;
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
ndbrequire
(
false
);
return
;
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
if
(
DictTabInfo
::
isIndex
(
newEntry
->
m_tableType
)
||
DictTabInfo
::
isTable
(
newEntry
->
m_tableType
))
{
bool
file
=
*
oldEntry
==
*
newEntry
&&
(
!
DictTabInfo
::
isIndex
(
newEntry
->
m_tableType
)
||
c_systemRestart
);
// On NR get index from master because index state is not on file
Uint32
type
=
oldEntry
->
m_tableType
;
const
bool
file
=
(
*
newEntry
==
*
oldEntry
)
&&
(
c_systemRestart
||
!
DictTabInfo
::
isIndex
(
type
));
newEntry
->
m_info_words
=
oldEntry
->
m_info_words
;
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
file
)
;
#ifdef PRINT_SCHEMA_RESTART
ndbout_c
(
"%s -> restartCreateTab (file: %d)"
,
buf
,
file
)
;
ndbout
<<
*
newEntry
<<
" "
<<
*
oldEntry
<<
endl
;
#endif
restartCreateTab
(
signal
,
tableId
,
newEntry
,
newEntry
,
file
);
*
oldEntry
=
*
newEntry
;
return
;
}
ndbrequire
(
ok
);
break
;
}
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
{
jam
();
bool
ok
=
false
;
switch
(
oldSchemaState
){
case
SchemaFile
:
:
INIT
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
ADD_STARTED
:
jam
();
case
SchemaFile
:
:
TABLE_ADD_COMMITTED
:
jam
();
case
SchemaFile
:
:
DROP_TABLE_STARTED
:
jam
();
case
SchemaFile
:
:
ALTER_TABLE_COMMITTED
:
jam
();
case
SchemaFile
:
:
TEMPORARY_TABLE_COMMITTED
:
jam
();
ok
=
true
;
if
(
!
c_systemRestart
)
else
if
(
!
(
*
oldEntry
==
*
newEntry
))
{
#ifdef PRINT_SCHEMA_RESTART
ndbout_c
(
"%s -> restartCreateTab"
,
buf
);
ndbout
<<
*
newEntry
<<
" "
<<
*
oldEntry
<<
endl
;
#endif
restartCreateTab
(
signal
,
tableId
,
oldEntry
,
newEntry
,
false
);
*
oldEntry
=
*
newEntry
;
return
;
}
else
{
newEntry
->
m_tableState
=
SchemaFile
::
INIT
;
}
break
;
}
ndbrequire
(
ok
)
;
break
;
*
oldEntry
=
*
newEntry
;
continue
;
}
}
}
c_restartRecord
.
m_pass
++
;
c_restartRecord
.
activeTable
=
0
;
if
(
c_restartRecord
.
m_pass
<=
4
)
if
(
c_restartRecord
.
m_pass
<=
LAST_PASS
)
{
checkSchemaStatus
(
signal
);
}
...
...
@@ -3299,7 +3182,33 @@ Dbdict::releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr)
}
void
Dbdict
::
restartDropTab
(
Signal
*
signal
,
Uint32
tableId
){
Dbdict
::
restartDropTab
(
Signal
*
signal
,
Uint32
tableId
,
const
SchemaFile
::
TableEntry
*
old_entry
,
const
SchemaFile
::
TableEntry
*
new_entry
)
{
switch
(
old_entry
->
m_tableType
){
case
DictTabInfo
:
:
UndefTableType
:
case
DictTabInfo
:
:
HashIndexTrigger
:
case
DictTabInfo
:
:
SubscriptionTrigger
:
case
DictTabInfo
:
:
ReadOnlyConstraint
:
case
DictTabInfo
:
:
IndexTrigger
:
ndbrequire
(
false
);
case
DictTabInfo
:
:
SystemTable
:
case
DictTabInfo
:
:
UserTable
:
case
DictTabInfo
:
:
UniqueHashIndex
:
case
DictTabInfo
:
:
HashIndex
:
case
DictTabInfo
:
:
UniqueOrderedIndex
:
case
DictTabInfo
:
:
OrderedIndex
:
break
;
case
DictTabInfo
:
:
Tablespace
:
case
DictTabInfo
:
:
LogfileGroup
:
case
DictTabInfo
:
:
Datafile
:
case
DictTabInfo
:
:
Undofile
:
warningEvent
(
"Dont drop object: %d"
,
tableId
);
c_restartRecord
.
activeTable
++
;
checkSchemaStatus
(
signal
);
return
;
}
const
Uint32
key
=
++
c_opRecordSequence
;
...
...
@@ -3333,6 +3242,7 @@ Dbdict::restartDropTab_complete(Signal* signal,
//@todo check error
releaseTableObject
(
c_restartRecord
.
activeTable
);
c_opDropTable
.
release
(
dropTabPtr
);
c_restartRecord
.
activeTable
++
;
...
...
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
View file @
f7115f12
...
...
@@ -2560,7 +2560,9 @@ private:
void
restartCreateTab_dihComplete
(
Signal
*
signal
,
Uint32
callback
,
Uint32
);
void
restartCreateTab_activateComplete
(
Signal
*
,
Uint32
callback
,
Uint32
);
void
restartDropTab
(
Signal
*
signal
,
Uint32
tableId
);
void
restartDropTab
(
Signal
*
signal
,
Uint32
tableId
,
const
SchemaFile
::
TableEntry
*
,
const
SchemaFile
::
TableEntry
*
);
void
restartDropTab_complete
(
Signal
*
,
Uint32
callback
,
Uint32
);
void
restart_checkSchemaStatusComplete
(
Signal
*
,
Uint32
callback
,
Uint32
);
...
...
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
View file @
f7115f12
...
...
@@ -217,6 +217,8 @@ Ndbfs::execFSOPENREQ(Signal* signal)
releaseSections
(
signal
);
}
file
->
reportTo
(
&
theFromThreads
);
if
(
getenv
(
"NDB_TRACE_OPEN"
))
ndbout_c
(
"open(%s)"
,
file
->
theFileName
.
c_str
());
Request
*
request
=
theRequestPool
->
get
();
request
->
action
=
Request
::
open
;
...
...
storage/ndb/test/include/NdbMixRestarter.hpp
0 → 100644
View file @
f7115f12
/* Copyright (C) 2003 MySQL AB
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 Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NDBT_MIX_RESTARTER_HPP
#define NDBT_MIX_RESTARTER_HPP
#include <mgmapi.h>
#include <Vector.hpp>
#include <BaseString.hpp>
#include "NdbRestarter.hpp"
#include "NDBT_Test.hpp"
#define NMR_SR "SR"
#define NMR_SR_THREADS "SR_ThreadCount"
#define NMR_SR_THREADS_STOPPED "SR_ThreadsStoppedCount"
#define NMR_SR_VALIDATE_THREADS "SR_ValidateThreadCount"
#define NMR_SR_VALIDATE_THREADS_DONE "SR_ValidateThreadsDoneCount"
class
NdbMixRestarter
:
public
NdbRestarter
{
public:
enum
RestartTypeMask
{
RTM_RestartCluster
=
0x01
,
RTM_RestartNode
=
0x02
,
RTM_RestartNodeInitial
=
0x04
,
RTM_StopNode
=
0x08
,
RTM_StopNodeInitial
=
0x10
,
RTM_StartNode
=
0x20
,
RTM_COUNT
=
6
,
RTM_ALL
=
0xFF
,
RTM_SR
=
RTM_RestartCluster
,
RTM_NR
=
0x2
|
0x4
|
0x8
|
0x10
|
0x20
};
enum
SR_State
{
SR_RUNNING
=
0
,
SR_STOPPING
=
1
,
SR_STOPPED
=
2
,
SR_VALIDATING
=
3
};
NdbMixRestarter
(
const
char
*
_addr
=
0
);
~
NdbMixRestarter
();
void
setRestartTypeMask
(
Uint32
mask
);
int
runUntilStopped
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
Uint32
freq
);
int
runPeriod
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
Uint32
time
,
Uint32
freq
);
int
init
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
);
int
dostep
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
);
int
finish
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
);
private:
Uint32
m_mask
;
Vector
<
ndb_mgm_node_state
>
m_nodes
;
int
restart_cluster
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
bool
abort
=
true
);
};
#endif
storage/ndb/test/ndbapi/testDict.cpp
View file @
f7115f12
...
...
@@ -23,6 +23,7 @@
#include <../../include/kernel/ndb_limits.h>
#include <random.h>
#include <NdbAutoPtr.hpp>
#include <NdbMixRestarter.hpp>
#define CHECK(b) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
...
...
@@ -2110,6 +2111,448 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step)
return
result
;
}
int
runBug21755
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
char
buf
[
256
];
NdbRestarter
res
;
NdbDictionary
::
Table
pTab0
=
*
ctx
->
getTab
();
NdbDictionary
::
Table
pTab1
=
pTab0
;
if
(
res
.
getNumDbNodes
()
<
2
)
return
NDBT_OK
;
Ndb
*
pNdb
=
GETNDB
(
step
);
NdbDictionary
::
Dictionary
*
pDic
=
pNdb
->
getDictionary
();
if
(
pDic
->
createTable
(
pTab0
))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
NdbDictionary
::
Index
idx0
;
BaseString
::
snprintf
(
buf
,
sizeof
(
buf
),
"%s-idx"
,
pTab0
.
getName
());
idx0
.
setName
(
buf
);
idx0
.
setType
(
NdbDictionary
::
Index
::
OrderedIndex
);
idx0
.
setTable
(
pTab0
.
getName
());
idx0
.
setStoredIndex
(
false
);
for
(
Uint32
i
=
0
;
i
<
pTab0
.
getNoOfColumns
();
i
++
)
{
const
NdbDictionary
::
Column
*
col
=
pTab0
.
getColumn
(
i
);
if
(
col
->
getPrimaryKey
()){
idx0
.
addIndexColumn
(
col
->
getName
());
}
}
if
(
pDic
->
createIndex
(
idx0
))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
BaseString
::
snprintf
(
buf
,
sizeof
(
buf
),
"%s-2"
,
pTab1
.
getName
());
pTab1
.
setName
(
buf
);
if
(
pDic
->
createTable
(
pTab1
))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
{
HugoTransactions
t0
(
*
pDic
->
getTable
(
pTab0
.
getName
()));
t0
.
loadTable
(
pNdb
,
1000
);
}
{
HugoTransactions
t1
(
*
pDic
->
getTable
(
pTab1
.
getName
()));
t1
.
loadTable
(
pNdb
,
1000
);
}
int
node
=
res
.
getRandomNotMasterNodeId
(
rand
());
res
.
restartOneDbNode
(
node
,
false
,
true
,
true
);
if
(
pDic
->
dropTable
(
pTab1
.
getName
()))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
BaseString
::
snprintf
(
buf
,
sizeof
(
buf
),
"%s-idx2"
,
pTab0
.
getName
());
idx0
.
setName
(
buf
);
if
(
pDic
->
createIndex
(
idx0
))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
res
.
waitNodesNoStart
(
&
node
,
1
);
res
.
startNodes
(
&
node
,
1
);
if
(
res
.
waitClusterStarted
())
{
return
NDBT_FAILED
;
}
if
(
pDic
->
dropTable
(
pTab0
.
getName
()))
{
ndbout
<<
pDic
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
return
NDBT_OK
;
}
struct
RandSchemaOp
{
struct
Obj
{
BaseString
m_name
;
Uint32
m_type
;
struct
Obj
*
m_parent
;
Vector
<
Obj
*>
m_dependant
;
};
Vector
<
Obj
*>
m_objects
;
int
schema_op
(
Ndb
*
);
int
validate
(
Ndb
*
);
int
cleanup
(
Ndb
*
);
Obj
*
get_obj
(
Uint32
mask
);
int
create_table
(
Ndb
*
);
int
create_index
(
Ndb
*
,
Obj
*
);
int
drop_obj
(
Ndb
*
,
Obj
*
);
void
remove_obj
(
Obj
*
);
};
template
class
Vector
<
RandSchemaOp
::
Obj
*
>;
int
RandSchemaOp
::
schema_op
(
Ndb
*
ndb
)
{
struct
Obj
*
obj
=
0
;
Uint32
type
=
0
;
loop:
switch
((
rand
()
>>
16
)
&
3
){
case
0
:
return
create_table
(
ndb
);
case
1
:
if
((
obj
=
get_obj
(
1
<<
NdbDictionary
::
Object
::
UserTable
))
==
0
)
goto
loop
;
return
create_index
(
ndb
,
obj
);
case
2
:
type
=
(
1
<<
NdbDictionary
::
Object
::
UserTable
);
goto
drop_object
;
case
3
:
type
=
(
1
<<
NdbDictionary
::
Object
::
UniqueHashIndex
)
|
(
1
<<
NdbDictionary
::
Object
::
OrderedIndex
);
goto
drop_object
;
default:
goto
loop
;
}
drop_object:
if
((
obj
=
get_obj
(
type
))
==
0
)
goto
loop
;
return
drop_obj
(
ndb
,
obj
);
}
RandSchemaOp
::
Obj
*
RandSchemaOp
::
get_obj
(
Uint32
mask
)
{
Vector
<
Obj
*>
tmp
;
for
(
Uint32
i
=
0
;
i
<
m_objects
.
size
();
i
++
)
{
if
((
1
<<
m_objects
[
i
]
->
m_type
)
&
mask
)
tmp
.
push_back
(
m_objects
[
i
]);
}
if
(
tmp
.
size
())
{
return
tmp
[
rand
()
%
tmp
.
size
()];
}
return
0
;
}
int
RandSchemaOp
::
create_table
(
Ndb
*
ndb
)
{
int
numTables
=
NDBT_Tables
::
getNumTables
();
int
num
=
myRandom48
(
numTables
);
NdbDictionary
::
Table
pTab
=
*
NDBT_Tables
::
getTable
(
num
);
NdbDictionary
::
Dictionary
*
pDict
=
ndb
->
getDictionary
();
if
(
pDict
->
getTable
(
pTab
.
getName
()))
{
char
buf
[
100
];
BaseString
::
snprintf
(
buf
,
sizeof
(
buf
),
"%s-%d"
,
pTab
.
getName
(),
rand
());
pTab
.
setName
(
buf
);
if
(
pDict
->
createTable
(
pTab
))
return
NDBT_FAILED
;
}
else
{
if
(
NDBT_Tables
::
createTable
(
ndb
,
pTab
.
getName
()))
{
return
NDBT_FAILED
;
}
}
ndbout_c
(
"create table %s"
,
pTab
.
getName
());
const
NdbDictionary
::
Table
*
tab2
=
pDict
->
getTable
(
pTab
.
getName
());
HugoTransactions
trans
(
*
tab2
);
trans
.
loadTable
(
ndb
,
1000
);
Obj
*
obj
=
new
Obj
;
obj
->
m_name
.
assign
(
pTab
.
getName
());
obj
->
m_type
=
NdbDictionary
::
Object
::
UserTable
;
obj
->
m_parent
=
0
;
m_objects
.
push_back
(
obj
);
return
NDBT_OK
;
}
int
RandSchemaOp
::
create_index
(
Ndb
*
ndb
,
Obj
*
tab
)
{
NdbDictionary
::
Dictionary
*
pDict
=
ndb
->
getDictionary
();
const
NdbDictionary
::
Table
*
pTab
=
pDict
->
getTable
(
tab
->
m_name
.
c_str
());
if
(
pTab
==
0
)
{
return
NDBT_FAILED
;
}
bool
ordered
=
(
rand
()
>>
16
)
&
1
;
bool
stored
=
(
rand
()
>>
16
)
&
1
;
Uint32
type
=
ordered
?
NdbDictionary
::
Index
::
OrderedIndex
:
NdbDictionary
::
Index
::
UniqueHashIndex
;
char
buf
[
255
];
BaseString
::
snprintf
(
buf
,
sizeof
(
buf
),
"%s-%s"
,
pTab
->
getName
(),
ordered
?
"OI"
:
"UI"
);
if
(
pDict
->
getIndex
(
buf
,
pTab
->
getName
()))
{
// Index exists...let it be ok
return
NDBT_OK
;
}
ndbout_c
(
"create index %s"
,
buf
);
NdbDictionary
::
Index
idx0
;
idx0
.
setName
(
buf
);
idx0
.
setType
((
NdbDictionary
::
Index
::
Type
)
type
);
idx0
.
setTable
(
pTab
->
getName
());
idx0
.
setStoredIndex
(
ordered
?
false
:
stored
);
for
(
Uint32
i
=
0
;
i
<
pTab
->
getNoOfColumns
();
i
++
)
{
if
(
pTab
->
getColumn
(
i
)
->
getPrimaryKey
())
idx0
.
addColumn
(
pTab
->
getColumn
(
i
)
->
getName
());
}
if
(
pDict
->
createIndex
(
idx0
))
{
ndbout
<<
pDict
->
getNdbError
()
<<
endl
;
return
NDBT_FAILED
;
}
Obj
*
obj
=
new
Obj
;
obj
->
m_name
.
assign
(
buf
);
obj
->
m_type
=
type
;
obj
->
m_parent
=
tab
;
m_objects
.
push_back
(
obj
);
tab
->
m_dependant
.
push_back
(
obj
);
return
NDBT_OK
;
}
int
RandSchemaOp
::
drop_obj
(
Ndb
*
ndb
,
Obj
*
obj
)
{
NdbDictionary
::
Dictionary
*
pDict
=
ndb
->
getDictionary
();
if
(
obj
->
m_type
==
NdbDictionary
::
Object
::
UserTable
)
{
ndbout_c
(
"drop table %s"
,
obj
->
m_name
.
c_str
());
/**
* Drop of table automatically drops all indexes
*/
if
(
pDict
->
dropTable
(
obj
->
m_name
.
c_str
()))
{
return
NDBT_FAILED
;
}
while
(
obj
->
m_dependant
.
size
())
{
remove_obj
(
obj
->
m_dependant
[
0
]);
}
remove_obj
(
obj
);
}
else
if
(
obj
->
m_type
==
NdbDictionary
::
Object
::
UniqueHashIndex
||
obj
->
m_type
==
NdbDictionary
::
Object
::
OrderedIndex
)
{
ndbout_c
(
"drop index %s"
,
obj
->
m_name
.
c_str
());
if
(
pDict
->
dropIndex
(
obj
->
m_name
.
c_str
(),
obj
->
m_parent
->
m_name
.
c_str
()))
{
return
NDBT_FAILED
;
}
remove_obj
(
obj
);
}
return
NDBT_OK
;
}
void
RandSchemaOp
::
remove_obj
(
Obj
*
obj
)
{
Uint32
i
;
if
(
obj
->
m_parent
)
{
bool
found
=
false
;
for
(
i
=
0
;
i
<
obj
->
m_parent
->
m_dependant
.
size
();
i
++
)
{
if
(
obj
->
m_parent
->
m_dependant
[
i
]
==
obj
)
{
found
=
true
;
obj
->
m_parent
->
m_dependant
.
erase
(
i
);
break
;
}
}
assert
(
found
);
}
{
bool
found
=
false
;
for
(
i
=
0
;
i
<
m_objects
.
size
();
i
++
)
{
if
(
m_objects
[
i
]
==
obj
)
{
found
=
true
;
m_objects
.
erase
(
i
);
break
;
}
}
assert
(
found
);
}
delete
obj
;
}
int
RandSchemaOp
::
validate
(
Ndb
*
ndb
)
{
NdbDictionary
::
Dictionary
*
pDict
=
ndb
->
getDictionary
();
for
(
Uint32
i
=
0
;
i
<
m_objects
.
size
();
i
++
)
{
if
(
m_objects
[
i
]
->
m_type
==
NdbDictionary
::
Object
::
UserTable
)
{
const
NdbDictionary
::
Table
*
tab2
=
pDict
->
getTable
(
m_objects
[
i
]
->
m_name
.
c_str
());
HugoTransactions
trans
(
*
tab2
);
trans
.
scanUpdateRecords
(
ndb
,
1000
);
trans
.
clearTable
(
ndb
);
trans
.
loadTable
(
ndb
,
1000
);
}
}
return
NDBT_OK
;
}
/*
SystemTable = 1, ///< System table
UserTable = 2, ///< User table (may be temporary)
UniqueHashIndex = 3, ///< Unique un-ordered hash index
OrderedIndex = 6, ///< Non-unique ordered index
HashIndexTrigger = 7, ///< Index maintenance, internal
IndexTrigger = 8, ///< Index maintenance, internal
SubscriptionTrigger = 9,///< Backup or replication, internal
ReadOnlyConstraint = 10,///< Trigger, internal
Tablespace = 20, ///< Tablespace
LogfileGroup = 21, ///< Logfile group
Datafile = 22, ///< Datafile
Undofile = 23 ///< Undofile
*/
int
RandSchemaOp
::
cleanup
(
Ndb
*
ndb
)
{
Int32
i
;
for
(
i
=
m_objects
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
switch
(
m_objects
[
i
]
->
m_type
){
case
NdbDictionary
:
:
Object
::
UniqueHashIndex
:
case
NdbDictionary
:
:
Object
::
OrderedIndex
:
if
(
drop_obj
(
ndb
,
m_objects
[
i
]))
return
NDBT_FAILED
;
break
;
default:
break
;
}
}
for
(
i
=
m_objects
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
switch
(
m_objects
[
i
]
->
m_type
){
case
NdbDictionary
:
:
Object
::
UserTable
:
if
(
drop_obj
(
ndb
,
m_objects
[
i
]))
return
NDBT_FAILED
;
break
;
default:
break
;
}
}
assert
(
m_objects
.
size
()
==
0
);
return
NDBT_OK
;
}
int
runDictRestart
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
Ndb
*
pNdb
=
GETNDB
(
step
);
int
loops
=
ctx
->
getNumLoops
();
NdbMixRestarter
res
;
RandSchemaOp
dict
;
if
(
res
.
getNumDbNodes
()
<
2
)
return
NDBT_OK
;
if
(
res
.
init
(
ctx
,
step
))
return
NDBT_FAILED
;
for
(
Uint32
i
=
0
;
i
<
loops
;
i
++
)
{
for
(
Uint32
j
=
0
;
j
<
10
;
j
++
)
if
(
dict
.
schema_op
(
pNdb
))
return
NDBT_FAILED
;
if
(
res
.
dostep
(
ctx
,
step
))
return
NDBT_FAILED
;
if
(
dict
.
validate
(
pNdb
))
return
NDBT_FAILED
;
}
if
(
res
.
finish
(
ctx
,
step
))
return
NDBT_FAILED
;
if
(
dict
.
validate
(
pNdb
))
return
NDBT_FAILED
;
if
(
dict
.
cleanup
(
pNdb
))
return
NDBT_FAILED
;
return
NDBT_OK
;
}
NDBT_TESTSUITE
(
testDict
);
TESTCASE
(
"CreateAndDrop"
,
"Try to create and drop the table loop number of times
\n
"
){
...
...
@@ -2256,7 +2699,14 @@ TESTCASE("Restart_NR2",
STEP
(
runRestarts
);
STEP
(
runDictOps
);
}
TESTCASE
(
"Bug21755"
,
""
){
INITIALIZER
(
runBug21755
);
}
TESTCASE
(
"DictRestart"
,
""
){
INITIALIZER
(
runDictRestart
);
}
NDBT_TESTSUITE_END
(
testDict
);
int
main
(
int
argc
,
const
char
**
argv
){
...
...
storage/ndb/test/ndbapi/testSRBank.cpp
View file @
f7115f12
...
...
@@ -20,9 +20,16 @@
#include <NdbBackup.hpp>
#include "bank/Bank.hpp"
#include <NdbMixRestarter.hpp>
bool
disk
=
false
;
#define CHECK(b) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
continue; }
int
runCreateBank
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
Bank
bank
(
ctx
->
m_cluster_connection
);
int
overWriteExisting
=
true
;
...
...
@@ -37,21 +44,25 @@ int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
* SR 1 - shutdown in progress
* SR 2 - restart in progress
*/
int
runBankTimer
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
int
runBankTimer
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
int
wait
=
5
;
// Max seconds between each "day"
int
yield
=
1
;
// Loops before bank returns
ctx
->
incProperty
(
"ThreadCount"
);
ctx
->
incProperty
(
NMR_SR_THREADS
);
while
(
!
ctx
->
isTestStopped
())
{
Bank
bank
(
ctx
->
m_cluster_connection
);
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
"SR"
)
<=
1
)
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
NMR_SR
)
<=
NdbMixRestarter
::
SR_STOPPING
)
{
if
(
bank
.
performIncreaseTime
(
wait
,
yield
)
==
NDBT_FAILED
)
break
;
}
ndbout_c
(
"runBankTimer is stopped"
);
ctx
->
incProperty
(
"ThreadStopped"
);
if
(
ctx
->
getPropertyWait
(
"SR"
,
(
Uint32
)
0
))
ctx
->
incProperty
(
NMR_SR_THREADS_STOPPED
);
if
(
ctx
->
getPropertyWait
(
NMR_SR
,
NdbMixRestarter
::
SR_RUNNING
))
break
;
}
return
NDBT_OK
;
...
...
@@ -61,17 +72,18 @@ int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
int
wait
=
0
;
// Max ms between each transaction
int
yield
=
1
;
// Loops before bank returns
ctx
->
incProperty
(
"ThreadCount"
);
ctx
->
incProperty
(
NMR_SR_THREADS
);
while
(
!
ctx
->
isTestStopped
())
{
Bank
bank
(
ctx
->
m_cluster_connection
);
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
"SR"
)
<=
1
)
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
NMR_SR
)
<=
NdbMixRestarter
::
SR_STOPPING
)
if
(
bank
.
performTransactions
(
0
,
1
)
==
NDBT_FAILED
)
break
;
ndbout_c
(
"runBankTransactions is stopped"
);
ctx
->
incProperty
(
"ThreadStopped"
);
if
(
ctx
->
getPropertyWait
(
"SR"
,
(
Uint32
)
0
))
ctx
->
incProperty
(
NMR_SR_THREADS_STOPPED
);
if
(
ctx
->
getPropertyWait
(
NMR_SR
,
NdbMixRestarter
::
SR_RUNNING
))
break
;
}
return
NDBT_OK
;
...
...
@@ -81,269 +93,98 @@ int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
int
yield
=
1
;
// Loops before bank returns
int
result
=
NDBT_OK
;
ctx
->
incProperty
(
"ThreadCount"
);
ctx
->
incProperty
(
NMR_SR_THREADS
);
while
(
ctx
->
isTestStopped
()
==
false
)
{
Bank
bank
(
ctx
->
m_cluster_connection
);
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
"SR"
)
<=
1
)
while
(
!
ctx
->
isTestStopped
()
&&
ctx
->
getProperty
(
NMR_SR
)
<=
NdbMixRestarter
::
SR_STOPPING
)
if
(
bank
.
performMakeGLs
(
yield
)
!=
NDBT_OK
)
{
if
(
ctx
->
getProperty
(
"SR"
)
!=
0
)
if
(
ctx
->
getProperty
(
NMR_SR
)
!=
NdbMixRestarter
::
SR_RUNNING
)
break
;
ndbout
<<
"bank.performMakeGLs FAILED"
<<
endl
;
abort
();
return
NDBT_FAILED
;
}
ndbout_c
(
"runBankGL is stopped"
);
ctx
->
incProperty
(
"ThreadStopped"
);
if
(
ctx
->
getPropertyWait
(
"SR"
,
(
Uint32
)
0
))
ctx
->
incProperty
(
NMR_SR_THREADS_STOPPED
);
if
(
ctx
->
getPropertyWait
(
NMR_SR
,
NdbMixRestarter
::
SR_RUNNING
))
break
;
}
return
NDBT_OK
;
}
int
runBankSum
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
Bank
bank
(
ctx
->
m_cluster_connection
);
int
wait
=
2000
;
// Max ms between each sum of accounts
int
yield
=
1
;
// Loops before bank returns
int
result
=
NDBT_OK
;
while
(
ctx
->
isTestStopped
()
==
false
)
{
if
(
bank
.
performSumAccounts
(
wait
,
yield
)
!=
NDBT_OK
){
ndbout
<<
"bank.performSumAccounts FAILED"
<<
endl
;
result
=
NDBT_FAILED
;
}
}
return
result
;
}
#define CHECK(b) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
continue; }
static
int
r
estart_cluster
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
NdbRestarter
&
restarter
)
r
unBankSrValidator
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
bool
abort
=
true
;
int
timeout
=
180
;
int
result
=
NDBT_OK
;
do
{
ndbout
<<
" -- Shutting down "
<<
endl
;
ctx
->
setProperty
(
"SR"
,
1
);
CHECK
(
restarter
.
restartAll
(
false
,
true
,
abort
)
==
0
);
ctx
->
setProperty
(
"SR"
,
2
);
CHECK
(
restarter
.
waitClusterNoStart
(
timeout
)
==
0
);
Uint32
cnt
=
ctx
->
getProperty
(
"ThreadCount"
);
Uint32
curr
=
ctx
->
getProperty
(
"ThreadStopped"
);
while
(
curr
!=
cnt
&&
!
ctx
->
isTestStopped
())
{
ndbout_c
(
"%d %d"
,
curr
,
cnt
);
NdbSleep_MilliSleep
(
100
);
curr
=
ctx
->
getProperty
(
"ThreadStopped"
);
}
ctx
->
incProperty
(
NMR_SR_VALIDATE_THREADS
);
ctx
->
setProperty
(
"ThreadStopped"
,
(
Uint32
)
0
);
CHECK
(
restarter
.
startAll
()
==
0
);
CHECK
(
restarter
.
waitClusterStarted
(
timeout
)
==
0
);
ndbout
<<
" -- Validating starts "
<<
endl
;
while
(
!
ctx
->
isTestStopped
())
{
if
(
ctx
->
getPropertyWait
(
NMR_SR
,
NdbMixRestarter
::
SR_VALIDATING
))
break
;
int
wait
=
0
;
int
yield
=
1
;
Bank
bank
(
ctx
->
m_cluster_connection
);
if
(
bank
.
performSumAccounts
(
wait
,
yield
)
!=
0
)
{
ndbout
<<
"bank.performSumAccounts FAILED"
<<
endl
;
abort
();
return
NDBT_FAILED
;
}
if
(
bank
.
performValidateAllGLs
()
!=
0
)
{
ndbout
<<
"bank.performValidateAllGLs FAILED"
<<
endl
;
abort
();
return
NDBT_FAILED
;
}
}
ndbout
<<
" -- Validating complete "
<<
endl
;
}
while
(
0
);
ctx
->
setProperty
(
"SR"
,
(
Uint32
)
0
);
ctx
->
broadcast
();
return
result
;
}
ctx
->
incProperty
(
NMR_SR_VALIDATE_THREADS_DONE
);
static
ndb_mgm_node_state
*
select_node_to_stop
(
Vector
<
ndb_mgm_node_state
>&
nodes
)
{
Uint32
i
,
j
;
Vector
<
ndb_mgm_node_state
*>
alive_nodes
;
for
(
i
=
0
;
i
<
nodes
.
size
();
i
++
)
{
ndb_mgm_node_state
*
node
=
&
nodes
[
i
];
if
(
node
->
node_status
==
NDB_MGM_NODE_STATUS_STARTED
)
alive_nodes
.
push_back
(
node
);
}
Vector
<
ndb_mgm_node_state
*>
victims
;
// Remove those with one in node group
for
(
i
=
0
;
i
<
alive_nodes
.
size
();
i
++
)
{
int
group
=
alive_nodes
[
i
]
->
node_group
;
for
(
j
=
0
;
j
<
alive_nodes
.
size
();
j
++
)
{
if
(
i
!=
j
&&
alive_nodes
[
j
]
->
node_group
==
group
)
{
victims
.
push_back
(
alive_nodes
[
i
]);
if
(
ctx
->
getPropertyWait
(
NMR_SR
,
NdbMixRestarter
::
SR_RUNNING
))
break
;
}
}
}
if
(
victims
.
size
())
{
int
victim
=
rand
()
%
victims
.
size
();
return
victims
[
victim
];
}
else
{
return
0
;
}
return
NDBT_OK
;
}
static
ndb_mgm_node_state
*
select_node_to_start
(
Vector
<
ndb_mgm_node_state
>&
nodes
)
{
Uint32
i
,
j
;
Vector
<
ndb_mgm_node_state
*>
victims
;
for
(
i
=
0
;
i
<
nodes
.
size
();
i
++
)
{
ndb_mgm_node_state
*
node
=
&
nodes
[
i
];
if
(
node
->
node_status
==
NDB_MGM_NODE_STATUS_NOT_STARTED
)
victims
.
push_back
(
node
);
}
#if 0
int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
Bank bank(ctx->m_cluster_connection);
int wait = 2000; // Max ms between each sum of accounts
int yield = 1; // Loops before bank returns
int result = NDBT_OK;
if
(
victims
.
size
())
while (ctx->isTestStopped() == false)
{
int
victim
=
rand
()
%
victims
.
size
();
return
victims
[
victim
];
if (bank.performSumAccounts(wait, yield) != NDBT_OK){
ndbout << "bank.performSumAccounts FAILED" << endl;
result = NDBT_FAILED;
}
else
{
return
0
;
}
return result ;
}
#endif
enum
Action
{
AA_RestartCluster
=
0x1
,
AA_RestartNode
=
0x2
,
AA_StopNode
=
0x4
,
AA_StartNode
=
0x8
,
AA_COUNT
=
4
};
int
runMixRestart
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
int
result
=
NDBT_OK
;
NdbMixRestarter
res
;
int
runtime
=
ctx
->
getNumLoops
();
int
sleeptime
=
ctx
->
getNumRecords
();
NdbRestarter
restarter
;
int
timeout
=
180
;
Uint32
type
=
ctx
->
getProperty
(
"Type"
,
~
(
Uint32
)
0
);
restarter
.
waitClusterStarted
();
Vector
<
ndb_mgm_node_state
>
nodes
;
nodes
=
restarter
.
ndbNodes
;
#if 0
for (Uint32 i = 0; i<restarter.ndbNodes.size(); i++)
nodes.push_back(restarter.ndbNodes[i]);
#endif
Uint32
now
;
const
Uint32
stop
=
time
(
0
)
+
runtime
;
while
(
!
ctx
->
isTestStopped
()
&&
((
now
=
time
(
0
))
<
stop
)
&&
result
==
NDBT_OK
)
{
ndbout
<<
" -- Sleep "
<<
sleeptime
<<
"s "
<<
endl
;
int
cnt
=
sleeptime
;
while
(
cnt
--
&&
!
ctx
->
isTestStopped
())
NdbSleep_SecSleep
(
1
);
if
(
ctx
->
isTestStopped
())
return
NDBT_FAILED
;
ndb_mgm_node_state
*
node
=
0
;
int
action
;
loop:
while
(((
action
=
(
1
<<
(
rand
()
%
AA_COUNT
)))
&
type
)
==
0
);
switch
(
action
){
case
AA_RestartCluster
:
if
(
restart_cluster
(
ctx
,
step
,
restarter
))
return
NDBT_FAILED
;
for
(
Uint32
i
=
0
;
i
<
nodes
.
size
();
i
++
)
nodes
[
i
].
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
break
;
case
AA_RestartNode
:
case
AA_StopNode
:
{
if
((
node
=
select_node_to_stop
(
nodes
))
==
0
)
goto
loop
;
if
(
action
==
AA_RestartNode
)
g_err
<<
"Restarting "
<<
node
->
node_id
<<
endl
;
else
g_err
<<
"Stopping "
<<
node
->
node_id
<<
endl
;
Uint32
mask
=
ctx
->
getProperty
(
"Type"
,
~
(
Uint32
)
0
);
res
.
setRestartTypeMask
(
mask
);
if
(
restarter
.
restartOneDbNode
(
node
->
node_id
,
false
,
true
,
true
))
return
NDBT_FAILED
;
if
(
restarter
.
waitNodesNoStart
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
node
->
node_status
=
NDB_MGM_NODE_STATUS_NOT_STARTED
;
if
(
action
==
AA_StopNode
)
break
;
else
goto
start
;
}
case
AA_StartNode
:
if
((
node
=
select_node_to_start
(
nodes
))
==
0
)
goto
loop
;
start:
g_err
<<
"Starting "
<<
node
->
node_id
<<
endl
;
if
(
restarter
.
startNodes
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
if
(
restarter
.
waitNodesStarted
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
node
->
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
break
;
}
}
Vector
<
int
>
not_started
;
{
ndb_mgm_node_state
*
node
=
0
;
while
((
node
=
select_node_to_start
(
nodes
)))
if
(
res
.
runPeriod
(
ctx
,
step
,
runtime
,
sleeptime
))
{
not_started
.
push_back
(
node
->
node_id
);
node
->
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
}
}
if
(
not_started
.
size
())
{
g_err
<<
"Starting stopped nodes "
<<
endl
;
if
(
restarter
.
startNodes
(
not_started
.
getBase
(),
not_started
.
size
()))
return
NDBT_FAILED
;
if
(
restarter
.
waitClusterStarted
())
abort
();
return
NDBT_FAILED
;
}
...
...
@@ -351,7 +192,8 @@ loop:
return
NDBT_OK
;
}
int
runDropBank
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
int
runDropBank
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
){
Bank
bank
(
ctx
->
m_cluster_connection
);
if
(
bank
.
dropBank
()
!=
NDBT_OK
)
return
NDBT_FAILED
;
...
...
@@ -367,7 +209,7 @@ TESTCASE("SR",
"3. Restart ndb and verify consistency
\n
"
"4. Drop bank
\n
"
)
{
TC_PROPERTY
(
"Type"
,
AA_RestartCluster
);
TC_PROPERTY
(
"Type"
,
NdbMixRestarter
::
RTM_SR
);
INITIALIZER
(
runCreateBank
);
STEP
(
runBankTimer
);
STEP
(
runBankTransactions
);
...
...
@@ -381,6 +223,7 @@ TESTCASE("SR",
STEP
(
runBankTransactions
);
STEP
(
runBankTransactions
);
STEP
(
runBankGL
);
STEP
(
runBankSrValidator
);
STEP
(
runMixRestart
);
}
TESTCASE
(
"NR"
,
...
...
@@ -390,7 +233,7 @@ TESTCASE("NR",
"3. Restart ndb and verify consistency
\n
"
"4. Drop bank
\n
"
)
{
TC_PROPERTY
(
"Type"
,
AA_RestartNode
|
AA_StopNode
|
AA_StartNode
);
TC_PROPERTY
(
"Type"
,
NdbMixRestarter
::
RTM_NR
);
INITIALIZER
(
runCreateBank
);
STEP
(
runBankTimer
);
STEP
(
runBankTransactions
);
...
...
@@ -414,7 +257,7 @@ TESTCASE("Mix",
"3. Restart ndb and verify consistency
\n
"
"4. Drop bank
\n
"
)
{
TC_PROPERTY
(
"Type"
,
~
0
);
TC_PROPERTY
(
"Type"
,
NdbMixRestarter
::
RTM_ALL
);
INITIALIZER
(
runCreateBank
);
STEP
(
runBankTimer
);
STEP
(
runBankTransactions
);
...
...
@@ -429,6 +272,7 @@ TESTCASE("Mix",
STEP
(
runBankTransactions
);
STEP
(
runBankGL
);
STEP
(
runMixRestart
);
STEP
(
runBankSrValidator
);
FINALIZER
(
runDropBank
);
}
NDBT_TESTSUITE_END
(
testSRBank
);
...
...
storage/ndb/test/run-test/daily-basic-tests.txt
View file @
f7115f12
...
...
@@ -599,6 +599,14 @@ max-time: 1500
cmd: testDict
args: -n Restart_NR2 T1 I3
max-time: 500
cmd: testDict
args: -n Bug21755 T1
max-time: 1500
cmd: testDict
args: -l 25 -n DictRestart T1
#
# TEST NDBAPI
#
...
...
storage/ndb/test/src/Makefile.am
View file @
f7115f12
...
...
@@ -24,7 +24,7 @@ libNDBT_a_SOURCES = \
NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp
\
NdbBackup.cpp NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp
\
NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c
\
CpcClient.cpp
CpcClient.cpp
NdbMixRestarter.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/storage/ndb/src/common/mgmcommon
-I
$(top_srcdir)
/storage/ndb/include/mgmcommon
-I
$(top_srcdir)
/storage/ndb/include/kernel
-I
$(top_srcdir)
/storage/ndb/src/mgmapi
...
...
storage/ndb/test/src/NDBT_Test.cpp
View file @
f7115f12
...
...
@@ -146,8 +146,10 @@ void NDBT_Context::setProperty(const char* _name, Uint32 _val){
NdbMutex_Lock
(
propertyMutexPtr
);
const
bool
b
=
props
.
put
(
_name
,
_val
,
true
);
assert
(
b
==
true
);
NdbCondition_Broadcast
(
propertyCondPtr
);
NdbMutex_Unlock
(
propertyMutexPtr
);
}
void
NDBT_Context
::
decProperty
(
const
char
*
name
){
NdbMutex_Lock
(
propertyMutexPtr
);
...
...
@@ -159,6 +161,7 @@ NDBT_Context::decProperty(const char * name){
NdbCondition_Broadcast
(
propertyCondPtr
);
NdbMutex_Unlock
(
propertyMutexPtr
);
}
void
NDBT_Context
::
incProperty
(
const
char
*
name
){
NdbMutex_Lock
(
propertyMutexPtr
);
...
...
@@ -173,6 +176,7 @@ void NDBT_Context::setProperty(const char* _name, const char* _val){
NdbMutex_Lock
(
propertyMutexPtr
);
const
bool
b
=
props
.
put
(
_name
,
_val
);
assert
(
b
==
true
);
NdbCondition_Broadcast
(
propertyCondPtr
);
NdbMutex_Unlock
(
propertyMutexPtr
);
}
...
...
storage/ndb/test/src/NdbMixRestarter.cpp
0 → 100644
View file @
f7115f12
/* Copyright (C) 2003 MySQL AB
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 Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbMixRestarter.hpp"
NdbMixRestarter
::
NdbMixRestarter
(
const
char
*
_addr
)
:
NdbRestarter
(
_addr
),
m_mask
(
~
(
Uint32
)
0
)
{
}
NdbMixRestarter
::~
NdbMixRestarter
()
{
}
#define CHECK(b) if (!(b)) { \
ndbout << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
continue; }
int
NdbMixRestarter
::
restart_cluster
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
bool
stopabort
)
{
int
timeout
=
180
;
int
result
=
NDBT_OK
;
do
{
ctx
->
setProperty
(
NMR_SR_THREADS_STOPPED
,
(
Uint32
)
0
);
ctx
->
setProperty
(
NMR_SR_VALIDATE_THREADS_DONE
,
(
Uint32
)
0
);
ndbout
<<
" -- Shutting down "
<<
endl
;
ctx
->
setProperty
(
NMR_SR
,
NdbMixRestarter
::
SR_STOPPING
);
CHECK
(
restartAll
(
false
,
true
,
stopabort
)
==
0
);
ctx
->
setProperty
(
NMR_SR
,
NdbMixRestarter
::
SR_STOPPED
);
CHECK
(
waitClusterNoStart
(
timeout
)
==
0
);
Uint32
cnt
=
ctx
->
getProperty
(
NMR_SR_THREADS
);
Uint32
curr
=
ctx
->
getProperty
(
NMR_SR_THREADS_STOPPED
);
while
(
curr
!=
cnt
&&
!
ctx
->
isTestStopped
())
{
if
(
curr
>
cnt
)
{
ndbout_c
(
"stopping: curr: %d cnt: %d"
,
curr
,
cnt
);
abort
();
}
NdbSleep_MilliSleep
(
100
);
curr
=
ctx
->
getProperty
(
NMR_SR_THREADS_STOPPED
);
}
CHECK
(
ctx
->
isTestStopped
()
==
false
);
CHECK
(
startAll
()
==
0
);
CHECK
(
waitClusterStarted
(
timeout
)
==
0
);
cnt
=
ctx
->
getProperty
(
NMR_SR_VALIDATE_THREADS
);
if
(
cnt
)
{
ndbout
<<
" -- Validating starts "
<<
endl
;
ctx
->
setProperty
(
NMR_SR_VALIDATE_THREADS_DONE
,
(
Uint32
)
0
);
ctx
->
setProperty
(
NMR_SR
,
NdbMixRestarter
::
SR_VALIDATING
);
curr
=
ctx
->
getProperty
(
NMR_SR_VALIDATE_THREADS_DONE
);
while
(
curr
!=
cnt
&&
!
ctx
->
isTestStopped
())
{
if
(
curr
>
cnt
)
{
ndbout_c
(
"validating: curr: %d cnt: %d"
,
curr
,
cnt
);
abort
();
}
NdbSleep_MilliSleep
(
100
);
curr
=
ctx
->
getProperty
(
NMR_SR_VALIDATE_THREADS_DONE
);
}
ndbout
<<
" -- Validating complete "
<<
endl
;
}
CHECK
(
ctx
->
isTestStopped
()
==
false
);
ctx
->
setProperty
(
NMR_SR
,
NdbMixRestarter
::
SR_RUNNING
);
}
while
(
0
);
return
result
;
}
static
ndb_mgm_node_state
*
select_node_to_stop
(
Vector
<
ndb_mgm_node_state
>&
nodes
)
{
Uint32
i
,
j
;
Vector
<
ndb_mgm_node_state
*>
alive_nodes
;
for
(
i
=
0
;
i
<
nodes
.
size
();
i
++
)
{
ndb_mgm_node_state
*
node
=
&
nodes
[
i
];
if
(
node
->
node_status
==
NDB_MGM_NODE_STATUS_STARTED
)
alive_nodes
.
push_back
(
node
);
}
Vector
<
ndb_mgm_node_state
*>
victims
;
// Remove those with one in node group
for
(
i
=
0
;
i
<
alive_nodes
.
size
();
i
++
)
{
int
group
=
alive_nodes
[
i
]
->
node_group
;
for
(
j
=
0
;
j
<
alive_nodes
.
size
();
j
++
)
{
if
(
i
!=
j
&&
alive_nodes
[
j
]
->
node_group
==
group
)
{
victims
.
push_back
(
alive_nodes
[
i
]);
break
;
}
}
}
if
(
victims
.
size
())
{
int
victim
=
rand
()
%
victims
.
size
();
return
victims
[
victim
];
}
else
{
return
0
;
}
}
static
ndb_mgm_node_state
*
select_node_to_start
(
Vector
<
ndb_mgm_node_state
>&
nodes
)
{
Uint32
i
;
Vector
<
ndb_mgm_node_state
*>
victims
;
for
(
i
=
0
;
i
<
nodes
.
size
();
i
++
)
{
ndb_mgm_node_state
*
node
=
&
nodes
[
i
];
if
(
node
->
node_status
==
NDB_MGM_NODE_STATUS_NOT_STARTED
)
victims
.
push_back
(
node
);
}
if
(
victims
.
size
())
{
int
victim
=
rand
()
%
victims
.
size
();
return
victims
[
victim
];
}
else
{
return
0
;
}
}
void
NdbMixRestarter
::
setRestartTypeMask
(
Uint32
mask
)
{
m_mask
=
mask
;
}
int
NdbMixRestarter
::
runUntilStopped
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
Uint32
freq
)
{
if
(
init
(
ctx
,
step
))
return
NDBT_FAILED
;
while
(
!
ctx
->
isTestStopped
())
{
if
(
dostep
(
ctx
,
step
))
return
NDBT_FAILED
;
NdbSleep_SecSleep
(
freq
);
}
if
(
!
finish
(
ctx
,
step
))
return
NDBT_FAILED
;
return
NDBT_OK
;
}
int
NdbMixRestarter
::
runPeriod
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
,
Uint32
period
,
Uint32
freq
)
{
if
(
init
(
ctx
,
step
))
return
NDBT_FAILED
;
Uint32
stop
=
time
(
0
)
+
period
;
while
(
!
ctx
->
isTestStopped
()
&&
(
time
(
0
)
<
stop
))
{
if
(
dostep
(
ctx
,
step
))
{
return
NDBT_FAILED
;
}
NdbSleep_SecSleep
(
freq
);
}
if
(
finish
(
ctx
,
step
))
{
return
NDBT_FAILED
;
}
ctx
->
stopTest
();
return
NDBT_OK
;
}
int
NdbMixRestarter
::
init
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
waitClusterStarted
();
m_nodes
=
ndbNodes
;
return
0
;
}
int
NdbMixRestarter
::
dostep
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
ndb_mgm_node_state
*
node
=
0
;
int
action
;
loop:
while
(((
action
=
(
1
<<
(
rand
()
%
RTM_COUNT
)))
&
m_mask
)
==
0
);
switch
(
action
){
case
RTM_RestartCluster
:
if
(
restart_cluster
(
ctx
,
step
))
return
NDBT_FAILED
;
for
(
Uint32
i
=
0
;
i
<
m_nodes
.
size
();
i
++
)
m_nodes
[
i
].
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
break
;
case
RTM_RestartNode
:
case
RTM_RestartNodeInitial
:
case
RTM_StopNode
:
case
RTM_StopNodeInitial
:
{
if
((
node
=
select_node_to_stop
(
m_nodes
))
==
0
)
goto
loop
;
if
(
action
==
RTM_RestartNode
||
action
==
RTM_RestartNodeInitial
)
ndbout
<<
"Restarting "
<<
node
->
node_id
;
else
ndbout
<<
"Stopping "
<<
node
->
node_id
;
bool
initial
=
action
==
RTM_RestartNodeInitial
||
action
==
RTM_StopNodeInitial
;
if
(
initial
)
ndbout
<<
" inital"
;
ndbout
<<
endl
;
if
(
restartOneDbNode
(
node
->
node_id
,
initial
,
true
,
true
))
return
NDBT_FAILED
;
if
(
waitNodesNoStart
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
node
->
node_status
=
NDB_MGM_NODE_STATUS_NOT_STARTED
;
if
(
action
==
RTM_StopNode
||
action
==
RTM_StopNodeInitial
)
break
;
else
goto
start
;
}
case
RTM_StartNode
:
if
((
node
=
select_node_to_start
(
m_nodes
))
==
0
)
goto
loop
;
start:
ndbout
<<
"Starting "
<<
node
->
node_id
<<
endl
;
if
(
startNodes
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
if
(
waitNodesStarted
(
&
node
->
node_id
,
1
))
return
NDBT_FAILED
;
node
->
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
break
;
}
return
NDBT_OK
;
}
int
NdbMixRestarter
::
finish
(
NDBT_Context
*
ctx
,
NDBT_Step
*
step
)
{
Vector
<
int
>
not_started
;
{
ndb_mgm_node_state
*
node
=
0
;
while
((
node
=
select_node_to_start
(
m_nodes
)))
{
not_started
.
push_back
(
node
->
node_id
);
node
->
node_status
=
NDB_MGM_NODE_STATUS_STARTED
;
}
}
if
(
not_started
.
size
())
{
ndbout
<<
"Starting stopped nodes "
<<
endl
;
if
(
startNodes
(
not_started
.
getBase
(),
not_started
.
size
()))
return
NDBT_FAILED
;
if
(
waitClusterStarted
())
return
NDBT_FAILED
;
}
return
NDBT_OK
;
}
template
class
Vector
<
ndb_mgm_node_state
*
>;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment