mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / tools / delete_all.cpp
blob9bf51b9000f341abb5d613373070ed02fb8253f8
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>
17 #include <ndb_opts.h>
19 #include <NdbOut.hpp>
20 #include <NdbApi.hpp>
21 #include <NdbSleep.h>
22 #include <NDBT.hpp>
24 static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
25 bool fetch_across_commit, int parallelism=240);
27 NDB_STD_OPTS_VARS;
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}
52 static void usage()
54 #ifdef NOT_USED
55 char desc[] =
56 "tabname\n"\
57 "This program will delete all records in the specified table using scan delete.\n";
58 #endif
59 ndb_std_print_version();
60 print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
61 puts("");
62 my_print_help(my_long_options);
63 my_print_variables(my_long_options);
66 int main(int argc, char** argv){
67 NDB_INIT(argv[0]);
68 load_defaults("my",load_default_groups,&argc,&argv);
69 int ho_error;
70 #ifndef DBUG_OFF
71 opt_debug= "d:t:O,/tmp/ndb_delete_all.trace";
72 #endif
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
97 int res = NDBT_OK;
98 for(int i = 0; i<argc; i++){
99 const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, argv[i]);
100 if(pTab == NULL){
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)";
107 ndbout << " ...";
108 if(clear_table(&MyNdb, pTab, ! _transactional) == NDBT_FAILED){
109 res = 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
121 // them one by one
122 int retryAttempt = 0;
123 const int retryMax = 10;
124 int deletedRows = 0;
125 int check;
126 NdbTransaction *pTrans;
127 NdbScanOperation *pOp;
128 NdbError err;
130 int par = parallelism;
131 while (true){
132 restart:
133 if (retryAttempt++ >= retryMax){
134 g_info << "ERROR: has retried this operation " << retryAttempt
135 << " times, failing!" << endl;
136 return NDBT_FAILED;
139 pTrans = pNdb->startTransaction();
140 if (pTrans == NULL) {
141 err = pNdb->getNdbError();
142 if (err.status == NdbError::TemporaryError){
143 ERR(err);
144 NdbSleep_MilliSleep(50);
145 continue;
147 goto failed;
150 pOp = pTrans->getNdbScanOperation(pTab->getName());
151 if (pOp == NULL) {
152 goto failed;
155 int flags = 0;
156 flags |= _tupscan ? NdbScanOperation::SF_TupScan : 0;
157 flags |= _diskscan ? NdbScanOperation::SF_DiskScan : 0;
158 if( pOp->readTuples(NdbOperation::LM_Exclusive,
159 flags, par) ) {
160 goto failed;
163 if(pTrans->execute(NdbTransaction::NoCommit) != 0){
164 err = pTrans->getNdbError();
165 if(err.status == NdbError::TemporaryError){
166 ERR(err);
167 pNdb->closeTransaction(pTrans);
168 NdbSleep_MilliSleep(50);
169 continue;
171 goto failed;
174 while((check = pOp->nextResult(true)) == 0){
175 do {
176 if (pOp->deleteCurrentTuple() != 0){
177 goto failed;
179 deletedRows++;
180 } while((check = pOp->nextResult(false)) == 0);
182 if(check != -1){
183 if (fetch_across_commit) {
184 check = pTrans->execute(NdbTransaction::Commit);
185 pTrans->restart(); // new tx id
186 } else {
187 check = pTrans->execute(NdbTransaction::NoCommit);
191 err = pTrans->getNdbError();
192 if(check == -1){
193 if(err.status == NdbError::TemporaryError){
194 ERR(err);
195 pNdb->closeTransaction(pTrans);
196 NdbSleep_MilliSleep(50);
197 par = 1;
198 goto restart;
200 goto failed;
203 if(check == -1){
204 err = pTrans->getNdbError();
205 if(err.status == NdbError::TemporaryError){
206 ERR(err);
207 pNdb->closeTransaction(pTrans);
208 NdbSleep_MilliSleep(50);
209 par = 1;
210 goto restart;
212 goto failed;
214 if (! fetch_across_commit &&
215 pTrans->execute(NdbTransaction::Commit) != 0) {
216 err = pTrans->getNdbError();
217 goto failed;
219 pNdb->closeTransaction(pTrans);
220 return NDBT_OK;
222 return NDBT_FAILED;
224 failed:
225 if(pTrans != 0) pNdb->closeTransaction(pTrans);
226 ERR(err);
227 return (err.code != 0 ? err.code : NDBT_FAILED);