00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 #include <ndb_opts.h> 00019 #include <NDBT.hpp> 00020 #include <NdbApi.hpp> 00021 #include <NdbSleep.h> 00022 00023 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags); 00024 int desc_logfilegroup(Ndb *myndb, char* name); 00025 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name); 00026 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name); 00027 int desc_tablespace(Ndb *myndb,char* name); 00028 int desc_table(Ndb *myndb,char* name); 00029 00030 NDB_STD_OPTS_VARS; 00031 00032 static const char* _dbname = "TEST_DB"; 00033 static int _unqualified = 0; 00034 static int _partinfo = 0; 00035 static int _retries = 0; 00036 static struct my_option my_long_options[] = 00037 { 00038 NDB_STD_OPTS("ndb_desc"), 00039 { "database", 'd', "Name of database table is in", 00040 (gptr*) &_dbname, (gptr*) &_dbname, 0, 00041 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 00042 { "unqualified", 'u', "Use unqualified table names", 00043 (gptr*) &_unqualified, (gptr*) &_unqualified, 0, 00044 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 00045 { "extra-partition-info", 'p', "Print more info per partition", 00046 (gptr*) &_partinfo, (gptr*) &_partinfo, 0, 00047 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 00048 { "retries", 'r', "Retry every second for # retries", 00049 (gptr*) &_retries, (gptr*) &_retries, 0, 00050 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 00051 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} 00052 }; 00053 static void usage() 00054 { 00055 char desc[] = 00056 "tabname\n"\ 00057 "This program list all properties of table(s) in NDB Cluster.\n"\ 00058 " ex: desc T1 T2 T4\n"; 00059 ndb_std_print_version(); 00060 my_print_help(my_long_options); 00061 my_print_variables(my_long_options); 00062 } 00063 00064 static void print_part_info(Ndb* pNdb, NDBT_Table* pTab); 00065 00066 int main(int argc, char** argv){ 00067 NDB_INIT(argv[0]); 00068 const char *load_default_groups[]= { "mysql_cluster",0 }; 00069 load_defaults("my",load_default_groups,&argc,&argv); 00070 int ho_error; 00071 #ifndef DBUG_OFF 00072 opt_debug= "d:t:O,/tmp/ndb_desc.trace"; 00073 #endif 00074 if ((ho_error=handle_options(&argc, &argv, my_long_options, 00075 ndb_std_get_one_option))) 00076 return NDBT_ProgramExit(NDBT_WRONGARGS); 00077 00078 Ndb_cluster_connection con(opt_connect_str); 00079 if(con.connect(12, 5, 1) != 0) 00080 { 00081 ndbout << "Unable to connect to management server." << endl; 00082 return NDBT_ProgramExit(NDBT_FAILED); 00083 } 00084 if (con.wait_until_ready(30,0) < 0) 00085 { 00086 ndbout << "Cluster nodes not ready in 30 seconds." << endl; 00087 return NDBT_ProgramExit(NDBT_FAILED); 00088 } 00089 00090 Ndb MyNdb(&con, _dbname); 00091 if(MyNdb.init() != 0){ 00092 ERR(MyNdb.getNdbError()); 00093 return NDBT_ProgramExit(NDBT_FAILED); 00094 } 00095 00096 NdbDictionary::Dictionary * dict= MyNdb.getDictionary(); 00097 for(int i= 0; i<argc;i++) 00098 { 00099 if(desc_table(&MyNdb,argv[i])) 00100 ; 00101 else if(desc_tablespace(&MyNdb,argv[i])) 00102 ; 00103 else if(desc_logfilegroup(&MyNdb,argv[i])) 00104 ; 00105 else if(desc_datafile(con, &MyNdb, argv[i])) 00106 ; 00107 else if(desc_undofile(con, &MyNdb, argv[i])) 00108 ; 00109 else 00110 ndbout << "No such object: " << argv[i] << endl << endl; 00111 } 00112 00113 return NDBT_ProgramExit(NDBT_OK); 00114 } 00115 00116 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags) 00117 { 00118 ndbout << "AutoGrow.min_free: " << ags.min_free << endl; 00119 ndbout << "AutoGrow.max_size: " << ags.max_size << endl; 00120 ndbout << "AutoGrow.file_size: " << ags.file_size << endl; 00121 ndbout << "AutoGrow.filename_pattern: " << ags.filename_pattern << endl; 00122 } 00123 00124 int desc_logfilegroup(Ndb *myndb, char* name) 00125 { 00126 NdbDictionary::Dictionary *dict= myndb->getDictionary(); 00127 assert(dict); 00128 NdbDictionary::LogfileGroup lfg= dict->getLogfileGroup(name); 00129 NdbError err= dict->getNdbError(); 00130 if(err.classification!=ndberror_cl_none) 00131 return 0; 00132 00133 ndbout << "Type: LogfileGroup" << endl; 00134 ndbout << "Name: " << lfg.getName() << endl; 00135 ndbout << "UndoBuffer size: " << lfg.getUndoBufferSize() << endl; 00136 ndbout << "Version: " << lfg.getObjectVersion() << endl; 00137 ndbout << "Free Words: " << lfg.getUndoFreeWords() << endl; 00138 00139 desc_AutoGrowSpecification(lfg.getAutoGrowSpecification()); 00140 00141 ndbout << endl; 00142 00143 return 1; 00144 } 00145 00146 int desc_tablespace(Ndb *myndb, char* name) 00147 { 00148 NdbDictionary::Dictionary *dict= myndb->getDictionary(); 00149 assert(dict); 00150 NdbDictionary::Tablespace ts= dict->getTablespace(name); 00151 NdbError err= dict->getNdbError(); 00152 if(err.classification!=ndberror_cl_none) 00153 return 0; 00154 00155 ndbout << "Type: Tablespace" << endl; 00156 ndbout << "Name: " << ts.getName() << endl; 00157 ndbout << "Object Version: " << ts.getObjectVersion() << endl; 00158 ndbout << "Extent Size: " << ts.getExtentSize() << endl; 00159 ndbout << "Default Logfile Group: " << ts.getDefaultLogfileGroup() << endl; 00160 ndbout << endl; 00161 return 1; 00162 } 00163 00164 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name) 00165 { 00166 unsigned id; 00167 NdbDictionary::Dictionary *dict= myndb->getDictionary(); 00168 Ndb_cluster_connection_node_iter iter; 00169 00170 assert(dict); 00171 00172 con.init_get_next_node(iter); 00173 00174 while(id= con.get_next_node(iter)) 00175 { 00176 NdbDictionary::Undofile uf= dict->getUndofile(0, name); 00177 NdbError err= dict->getNdbError(); 00178 if(err.classification!=ndberror_cl_none) 00179 return 0; 00180 00181 ndbout << "Type: Undofile" << endl; 00182 ndbout << "Name: " << name << endl; 00183 ndbout << "Node: " << id << endl; 00184 ndbout << "Path: " << uf.getPath() << endl; 00185 ndbout << "Size: " << uf.getSize() << endl; 00186 00187 ndbout << "Logfile Group: " << uf.getLogfileGroup() << endl; 00188 00195 ndbout << endl; 00196 } 00197 00198 return 1; 00199 } 00200 00201 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name) 00202 { 00203 unsigned id; 00204 NdbDictionary::Dictionary *dict= myndb->getDictionary(); 00205 assert(dict); 00206 Ndb_cluster_connection_node_iter iter; 00207 00208 con.init_get_next_node(iter); 00209 00210 while(id= con.get_next_node(iter)) 00211 { 00212 NdbDictionary::Datafile df= dict->getDatafile(id, name); 00213 NdbError err= dict->getNdbError(); 00214 if(err.classification!=ndberror_cl_none) 00215 return 0; 00216 00217 ndbout << "Type: Datafile" << endl; 00218 ndbout << "Name: " << name << endl; 00219 ndbout << "Node: " << id << endl; 00220 ndbout << "Path: " << df.getPath() << endl; 00221 ndbout << "Size: " << df.getSize() << endl; 00222 ndbout << "Free: " << df.getFree() << endl; 00223 00224 ndbout << "Tablespace: " << df.getTablespace() << endl; 00225 00230 ndbout << endl; 00231 } 00232 00233 return 1; 00234 } 00235 00236 int desc_table(Ndb *myndb, char* name) 00237 { 00238 NdbDictionary::Dictionary * dict= myndb->getDictionary(); 00239 NDBT_Table* pTab; 00240 while ((pTab = (NDBT_Table*)dict->getTable(name)) == NULL && --_retries >= 0) NdbSleep_SecSleep(1); 00241 if (!pTab) 00242 return 0; 00243 00244 ndbout << (* pTab) << endl; 00245 00246 NdbDictionary::Dictionary::List list; 00247 if (dict->listIndexes(list, name) != 0){ 00248 ndbout << name << ": " << dict->getNdbError() << endl; 00249 return NDBT_ProgramExit(NDBT_FAILED); 00250 } 00251 00252 ndbout << "-- Indexes -- " << endl; 00253 ndbout << "PRIMARY KEY("; 00254 unsigned j; 00255 for (j= 0; (int)j < pTab->getNoOfPrimaryKeys(); j++) 00256 { 00257 const NdbDictionary::Column * col= pTab->getColumn(pTab->getPrimaryKey(j)); 00258 ndbout << col->getName(); 00259 if ((int)j < pTab->getNoOfPrimaryKeys()-1) 00260 ndbout << ", "; 00261 } 00262 ndbout << ") - UniqueHashIndex" << endl; 00263 for (j= 0; j < list.count; j++) { 00264 NdbDictionary::Dictionary::List::Element& elt = list.elements[j]; 00265 const NdbDictionary::Index *pIdx = dict->getIndex(elt.name, name); 00266 if (!pIdx){ 00267 ndbout << name << ": " << dict->getNdbError() << endl; 00268 return NDBT_ProgramExit(NDBT_FAILED); 00269 } 00270 00271 ndbout << (*pIdx) << endl; 00272 } 00273 ndbout << endl; 00274 00275 if (_partinfo) 00276 print_part_info(myndb, pTab); 00277 00278 return 1; 00279 } 00280 00281 struct InfoInfo 00282 { 00283 const char * m_title; 00284 NdbRecAttr* m_rec_attr; 00285 const NdbDictionary::Column* m_column; 00286 }; 00287 00288 00289 static 00290 void print_part_info(Ndb* pNdb, NDBT_Table* pTab) 00291 { 00292 InfoInfo g_part_info[] = { 00293 { "Partition", 0, NdbDictionary::Column::FRAGMENT }, 00294 { "Row count", 0, NdbDictionary::Column::ROW_COUNT }, 00295 { "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT }, 00296 { "Frag fixed memory", 0, NdbDictionary::Column::FRAGMENT_FIXED_MEMORY }, 00297 { "Frag varsized memory", 0, NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY }, 00298 { 0, 0, 0 } 00299 }; 00300 00301 ndbout << "-- Per partition info -- " << endl; 00302 00303 NdbConnection* pTrans = pNdb->startTransaction(); 00304 if (pTrans == 0) 00305 return; 00306 00307 do 00308 { 00309 NdbScanOperation* pOp= pTrans->getNdbScanOperation(pTab->getName()); 00310 if (pOp == NULL) 00311 break; 00312 00313 int rs = pOp->readTuples(NdbOperation::LM_CommittedRead); 00314 if (rs != 0) 00315 break; 00316 00317 if (pOp->interpret_exit_last_row() != 0) 00318 break; 00319 00320 Uint32 i = 0; 00321 for(i = 0; g_part_info[i].m_title != 0; i++) 00322 { 00323 if ((g_part_info[i].m_rec_attr = pOp->getValue(g_part_info[i].m_column)) == 0) 00324 break; 00325 } 00326 00327 if (g_part_info[i].m_title != 0) 00328 break; 00329 00330 if (pTrans->execute(NoCommit) != 0) 00331 break; 00332 00333 for (i = 0; g_part_info[i].m_title != 0; i++) 00334 ndbout << g_part_info[i].m_title << "\t"; 00335 ndbout << endl; 00336 00337 while(pOp->nextResult() == 0) 00338 { 00339 for(i = 0; g_part_info[i].m_title != 0; i++) 00340 { 00341 ndbout << *g_part_info[i].m_rec_attr << "\t"; 00342 } 00343 ndbout << endl; 00344 } 00345 } while(0); 00346 00347 pTrans->close(); 00348 }
1.4.7

