1 /* Copyright (c) 2003-2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <ndb_global.h>
24 static int clear_table(Ndb
* pNdb
, const NdbDictionary::Table
* pTab
,
25 bool fetch_across_commit
, int parallelism
=240);
29 const char *load_default_groups
[]= { "mysql_cluster",0 };
31 static const char* _dbname
= "TEST_DB";
32 static my_bool _transactional
= false;
33 static my_bool _tupscan
= 0;
34 static my_bool _diskscan
= 0;
35 static struct my_option my_long_options
[] =
37 NDB_STD_OPTS("ndb_desc"),
38 { "database", 'd', "Name of database table is in",
39 (uchar
**) &_dbname
, (uchar
**) &_dbname
, 0,
40 GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0 },
41 { "transactional", 't', "Single transaction (may run out of operations)",
42 (uchar
**) &_transactional
, (uchar
**) &_transactional
, 0,
43 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
44 { "tupscan", 999, "Run tupscan",
45 (uchar
**) &_tupscan
, (uchar
**) &_tupscan
, 0,
46 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
47 { "diskscan", 999, "Run diskcan",
48 (uchar
**) &_diskscan
, (uchar
**) &_diskscan
, 0,
49 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
50 { 0, 0, 0, 0, 0, 0, GET_NO_ARG
, NO_ARG
, 0, 0, 0, 0, 0, 0}
57 "This program will delete all records in the specified table using scan delete.\n";
59 ndb_std_print_version();
60 print_defaults(MYSQL_CONFIG_NAME
,load_default_groups
);
62 my_print_help(my_long_options
);
63 my_print_variables(my_long_options
);
66 int main(int argc
, char** argv
){
68 load_defaults("my",load_default_groups
,&argc
,&argv
);
71 opt_debug
= "d:t:O,/tmp/ndb_delete_all.trace";
73 if ((ho_error
=handle_options(&argc
, &argv
, my_long_options
,
74 ndb_std_get_one_option
)))
75 return NDBT_ProgramExit(NDBT_WRONGARGS
);
77 Ndb_cluster_connection
con(opt_connect_str
);
78 con
.set_name("ndb_delete_all");
79 if(con
.connect(12, 5, 1) != 0)
81 ndbout
<< "Unable to connect to management server." << endl
;
82 return NDBT_ProgramExit(NDBT_FAILED
);
84 if (con
.wait_until_ready(30,0) < 0)
86 ndbout
<< "Cluster nodes not ready in 30 seconds." << endl
;
87 return NDBT_ProgramExit(NDBT_FAILED
);
90 Ndb
MyNdb(&con
, _dbname
);
91 if(MyNdb
.init() != 0){
92 ERR(MyNdb
.getNdbError());
93 return NDBT_ProgramExit(NDBT_FAILED
);
96 // Check if table exists in db
98 for(int i
= 0; i
<argc
; i
++){
99 const NdbDictionary::Table
* pTab
= NDBT_Table::discoverTableFromDb(&MyNdb
, argv
[i
]);
101 ndbout
<< " Table " << argv
[i
] << " does not exist!" << endl
;
102 return NDBT_ProgramExit(NDBT_WRONGARGS
);
104 ndbout
<< "Deleting all from " << argv
[i
];
105 if (! _transactional
)
106 ndbout
<< " (non-transactional)";
108 if(clear_table(&MyNdb
, pTab
, ! _transactional
) == NDBT_FAILED
){
110 ndbout
<< "FAILED" << endl
;
113 return NDBT_ProgramExit(res
);
117 int clear_table(Ndb
* pNdb
, const NdbDictionary::Table
* pTab
,
118 bool fetch_across_commit
, int parallelism
)
120 // Scan all records exclusive and delete
122 int retryAttempt
= 0;
123 const int retryMax
= 10;
126 NdbTransaction
*pTrans
;
127 NdbScanOperation
*pOp
;
130 int par
= parallelism
;
133 if (retryAttempt
++ >= retryMax
){
134 g_info
<< "ERROR: has retried this operation " << retryAttempt
135 << " times, failing!" << endl
;
139 pTrans
= pNdb
->startTransaction();
140 if (pTrans
== NULL
) {
141 err
= pNdb
->getNdbError();
142 if (err
.status
== NdbError::TemporaryError
){
144 NdbSleep_MilliSleep(50);
150 pOp
= pTrans
->getNdbScanOperation(pTab
->getName());
156 flags
|= _tupscan
? NdbScanOperation::SF_TupScan
: 0;
157 flags
|= _diskscan
? NdbScanOperation::SF_DiskScan
: 0;
158 if( pOp
->readTuples(NdbOperation::LM_Exclusive
,
163 if(pTrans
->execute(NdbTransaction::NoCommit
) != 0){
164 err
= pTrans
->getNdbError();
165 if(err
.status
== NdbError::TemporaryError
){
167 pNdb
->closeTransaction(pTrans
);
168 NdbSleep_MilliSleep(50);
174 while((check
= pOp
->nextResult(true)) == 0){
176 if (pOp
->deleteCurrentTuple() != 0){
180 } while((check
= pOp
->nextResult(false)) == 0);
183 if (fetch_across_commit
) {
184 check
= pTrans
->execute(NdbTransaction::Commit
);
185 pTrans
->restart(); // new tx id
187 check
= pTrans
->execute(NdbTransaction::NoCommit
);
191 err
= pTrans
->getNdbError();
193 if(err
.status
== NdbError::TemporaryError
){
195 pNdb
->closeTransaction(pTrans
);
196 NdbSleep_MilliSleep(50);
204 err
= pTrans
->getNdbError();
205 if(err
.status
== NdbError::TemporaryError
){
207 pNdb
->closeTransaction(pTrans
);
208 NdbSleep_MilliSleep(50);
214 if (! fetch_across_commit
&&
215 pTrans
->execute(NdbTransaction::Commit
) != 0) {
216 err
= pTrans
->getNdbError();
219 pNdb
->closeTransaction(pTrans
);
225 if(pTrans
!= 0) pNdb
->closeTransaction(pTrans
);
227 return (err
.code
!= 0 ? err
.code
: NDBT_FAILED
);