MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
desc.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <ndb_global.h>
19 #include <ndb_opts.h>
20 #include <NDBT.hpp>
21 #include <NdbApi.hpp>
22 #include <NdbSleep.h>
23 
24 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags);
25 int desc_logfilegroup(Ndb *myndb, char* name);
26 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name);
27 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name);
28 int desc_tablespace(Ndb *myndb,char* name);
29 int desc_table(Ndb *myndb,char* name);
30 int desc_hashmap(Ndb_cluster_connection &con, Ndb *myndb, char* name);
31 
32 static const char* _dbname = "TEST_DB";
33 static int _unqualified = 0;
34 static int _partinfo = 0;
35 static int _blobinfo = 0;
36 static int _nodeinfo = 0;
37 
38 const char *load_default_groups[]= { "mysql_cluster",0 };
39 
40 static int _retries = 0;
41 
42 static struct my_option my_long_options[] =
43 {
44  NDB_STD_OPTS("ndb_desc"),
45  { "database", 'd', "Name of database table is in",
46  (uchar**) &_dbname, (uchar**) &_dbname, 0,
47  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
48  { "unqualified", 'u', "Use unqualified table names",
49  (uchar**) &_unqualified, (uchar**) &_unqualified, 0,
50  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
51  { "extra-partition-info", 'p', "Print more info per partition",
52  (uchar**) &_partinfo, (uchar**) &_partinfo, 0,
53  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
54  { "retries", 'r', "Retry every second for # retries",
55  (uchar**) &_retries, (uchar**) &_retries, 0,
56  GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
57  { "blob-info", 'b', "Show information for hidden blob tables (requires -p)",
58  (uchar**) &_blobinfo, (uchar**) &_blobinfo, 0,
59  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
60  { "extra-node-info", 'n', "Print node info for partitions (requires -p)",
61  (uchar**) &_nodeinfo, (uchar**) &_nodeinfo, 0,
62  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
63  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
64 };
65 
66 static void short_usage_sub(void)
67 {
68  ndb_short_usage_sub(NULL);
69 }
70 
71 static void usage()
72 {
73  ndb_usage(short_usage_sub, load_default_groups, my_long_options);
74 }
75 
76 static void print_part_info(Ndb* pNdb, NDBT_Table* pTab);
77 
78 int main(int argc, char** argv){
79  NDB_INIT(argv[0]);
80 
81  ndb_opt_set_usage_funcs(short_usage_sub, usage);
82  load_defaults("my",load_default_groups,&argc,&argv);
83  int ho_error;
84 #ifndef DBUG_OFF
85  opt_debug= "d:t:O,/tmp/ndb_desc.trace";
86 #endif
87  if ((ho_error=handle_options(&argc, &argv, my_long_options,
88  ndb_std_get_one_option)))
89  return NDBT_ProgramExit(NDBT_WRONGARGS);
90 
91  Ndb_cluster_connection con(opt_ndb_connectstring, opt_ndb_nodeid);
92  con.set_name("ndb_desc");
93  if(con.connect(12, 5, 1) != 0)
94  {
95  ndbout << "Unable to connect to management server." << endl;
96  return NDBT_ProgramExit(NDBT_FAILED);
97  }
98  if (con.wait_until_ready(30,0) < 0)
99  {
100  ndbout << "Cluster nodes not ready in 30 seconds." << endl;
101  return NDBT_ProgramExit(NDBT_FAILED);
102  }
103 
104  Ndb MyNdb(&con, _dbname);
105  if(MyNdb.init() != 0){
106  ERR(MyNdb.getNdbError());
107  return NDBT_ProgramExit(NDBT_FAILED);
108  }
109 
110  for(int i= 0; i<argc;i++)
111  {
112  if(desc_table(&MyNdb,argv[i]))
113  ;
114  else if(desc_tablespace(&MyNdb,argv[i]))
115  ;
116  else if(desc_logfilegroup(&MyNdb,argv[i]))
117  ;
118  else if(desc_datafile(con, &MyNdb, argv[i]))
119  ;
120  else if(desc_undofile(con, &MyNdb, argv[i]))
121  ;
122  else if (desc_hashmap(con, &MyNdb, argv[i]))
123  ;
124  else
125  ndbout << "No such object: " << argv[i] << endl << endl;
126  }
127 
128  return NDBT_ProgramExit(NDBT_OK);
129 }
130 
131 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags)
132 {
133  ndbout << "AutoGrow.min_free: " << ags.min_free << endl;
134  ndbout << "AutoGrow.max_size: " << ags.max_size << endl;
135  ndbout << "AutoGrow.file_size: " << ags.file_size << endl;
136  ndbout << "AutoGrow.filename_pattern: " << ags.filename_pattern << endl;
137 }
138 
139 int desc_logfilegroup(Ndb *myndb, char* name)
140 {
142  assert(dict);
143  NdbDictionary::LogfileGroup lfg= dict->getLogfileGroup(name);
144  NdbError err= dict->getNdbError();
145  if( (int) err.classification != (int) ndberror_cl_none)
146  return 0;
147 
148  ndbout << "Type: LogfileGroup" << endl;
149  ndbout << "Name: " << lfg.getName() << endl;
150  ndbout << "UndoBuffer size: " << lfg.getUndoBufferSize() << endl;
151  ndbout << "Version: " << lfg.getObjectVersion() << endl;
152  ndbout << "Free Words: " << lfg.getUndoFreeWords() << endl;
153 
154  desc_AutoGrowSpecification(lfg.getAutoGrowSpecification());
155 
156  ndbout << endl;
157 
158  return 1;
159 }
160 
161 int desc_tablespace(Ndb *myndb, char* name)
162 {
164  assert(dict);
165  NdbDictionary::Tablespace ts= dict->getTablespace(name);
166  NdbError err= dict->getNdbError();
167  if ((int) err.classification != (int) ndberror_cl_none)
168  return 0;
169 
170  ndbout << "Type: Tablespace" << endl;
171  ndbout << "Name: " << ts.getName() << endl;
172  ndbout << "Object Version: " << ts.getObjectVersion() << endl;
173  ndbout << "Extent Size: " << ts.getExtentSize() << endl;
174  ndbout << "Default Logfile Group: " << ts.getDefaultLogfileGroup() << endl;
175  ndbout << endl;
176  return 1;
177 }
178 
179 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name)
180 {
181  unsigned id;
184 
185  assert(dict);
186 
187  con.init_get_next_node(iter);
188 
189  while ((id= con.get_next_node(iter)))
190  {
191  NdbDictionary::Undofile uf= dict->getUndofile(0, name);
192  NdbError err= dict->getNdbError();
193  if ((int) err.classification != (int) ndberror_cl_none)
194  return 0;
195 
196  ndbout << "Type: Undofile" << endl;
197  ndbout << "Name: " << name << endl;
198  ndbout << "Node: " << id << endl;
199  ndbout << "Path: " << uf.getPath() << endl;
200  ndbout << "Size: " << uf.getSize() << endl;
201 
202  ndbout << "Logfile Group: " << uf.getLogfileGroup() << endl;
203 
210  ndbout << endl;
211  }
212 
213  return 1;
214 }
215 
216 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name)
217 {
218  unsigned id;
220  assert(dict);
222 
223  con.init_get_next_node(iter);
224 
225  while ((id= con.get_next_node(iter)))
226  {
227  NdbDictionary::Datafile df= dict->getDatafile(id, name);
228  NdbError err= dict->getNdbError();
229  if ((int) err.classification != (int) ndberror_cl_none)
230  return 0;
231 
232  ndbout << "Type: Datafile" << endl;
233  ndbout << "Name: " << name << endl;
234  ndbout << "Node: " << id << endl;
235  ndbout << "Path: " << df.getPath() << endl;
236  ndbout << "Size: " << df.getSize() << endl;
237  ndbout << "Free: " << df.getFree() << endl;
238 
239  ndbout << "Tablespace: " << df.getTablespace() << endl;
240 
245  ndbout << endl;
246  }
247 
248  return 1;
249 }
250 
251 int desc_table(Ndb *myndb, char* name)
252 {
253  NdbDictionary::Dictionary * dict= myndb->getDictionary();
254  NDBT_Table* pTab;
255  while ((pTab = (NDBT_Table*)dict->getTable(name)) == NULL && --_retries >= 0) NdbSleep_SecSleep(1);
256  if (!pTab)
257  return 0;
258 
259  ndbout << (* pTab) << endl;
260 
262  if (dict->listIndexes(list, name) != 0){
263  ndbout << name << ": " << dict->getNdbError() << endl;
264  return NDBT_ProgramExit(NDBT_FAILED);
265  }
266 
267  ndbout << "-- Indexes -- " << endl;
268  ndbout << "PRIMARY KEY(";
269  unsigned j;
270  for (j= 0; (int)j < pTab->getNoOfPrimaryKeys(); j++)
271  {
272  const NdbDictionary::Column * col= pTab->getColumn(pTab->getPrimaryKey(j));
273  ndbout << col->getName();
274  if ((int)j < pTab->getNoOfPrimaryKeys()-1)
275  ndbout << ", ";
276  }
277  ndbout << ") - UniqueHashIndex" << endl;
278  for (j= 0; j < list.count; j++) {
280  const NdbDictionary::Index *pIdx = dict->getIndex(elt.name, name);
281  if (!pIdx){
282  ndbout << name << ": " << dict->getNdbError() << endl;
283  return NDBT_ProgramExit(NDBT_FAILED);
284  }
285 
286  ndbout << (*pIdx) << endl;
287  }
288  ndbout << endl;
289 
290  if (_partinfo)
291  {
292  print_part_info(myndb, pTab);
293  ndbout << endl;
294  if (_blobinfo)
295  {
296  int noOfAttributes = pTab->getNoOfColumns();
297  for (int i = 0; i < noOfAttributes; i++)
298  {
299  const NdbDictionary::Column* column = pTab->getColumn(i);
300  if ((column->getType() == NdbDictionary::Column::Blob) ||
301  (column->getType() == NdbDictionary::Column::Text))
302  {
303  print_part_info(myndb, (NDBT_Table*) column->getBlobTable());
304  ndbout << endl;
305  }
306  }
307  }
308  }
309 
310  return 1;
311 }
312 
313 struct InfoInfo
314 {
315  const char * m_title;
316  NdbRecAttr* m_rec_attr;
317  const NdbDictionary::Column* m_column;
318 };
319 
320 
321 static
322 void print_part_info(Ndb* pNdb, NDBT_Table* pTab)
323 {
324  InfoInfo g_part_info[] = {
325  { "Partition", 0, NdbDictionary::Column::FRAGMENT },
326  { "Row count", 0, NdbDictionary::Column::ROW_COUNT },
327  { "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT },
328  { "Frag fixed memory", 0, NdbDictionary::Column::FRAGMENT_FIXED_MEMORY },
329  { "Frag varsized memory", 0, NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY },
330  { "Extent_space", 0, NdbDictionary::Column::FRAGMENT_EXTENT_SPACE },
331  { "Free extent_space", 0, NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE },
332 
333  { 0, 0, 0 }
334  };
335  const Uint32 FragmentIdOffset = 0;
336 
337  ndbout << "-- Per partition info";
338 
339  if (_blobinfo && _partinfo)
340  ndbout << " for " << pTab->getName();
341 
342  ndbout << " -- " << endl;
343 
344  const Uint32 codeWords= 1;
345  Uint32 codeSpace[ codeWords ];
346  NdbInterpretedCode code(NULL, // Table is irrelevant
347  &codeSpace[0],
348  codeWords);
349  if ((code.interpret_exit_last_row() != 0) ||
350  (code.finalise() != 0))
351  {
352  return;
353  }
354 
355  NdbConnection* pTrans = pNdb->startTransaction();
356  if (pTrans == 0)
357  return;
358 
359  do
360  {
361  NdbScanOperation* pOp= pTrans->getNdbScanOperation(pTab->getName());
362  if (pOp == NULL)
363  break;
364 
366  if (rs != 0)
367  break;
368 
369  if (pOp->setInterpretedCode(&code) != 0)
370  break;
371 
372  Uint32 i = 0;
373  for(i = 0; g_part_info[i].m_title != 0; i++)
374  {
375  if ((g_part_info[i].m_rec_attr = pOp->getValue(g_part_info[i].m_column)) == 0)
376  break;
377  }
378 
379  if (g_part_info[i].m_title != 0)
380  break;
381 
382  if (pTrans->execute(NoCommit) != 0)
383  break;
384 
385  for (i = 0; g_part_info[i].m_title != 0; i++)
386  ndbout << g_part_info[i].m_title << "\t";
387 
388  if (_nodeinfo)
389  {
390  ndbout << "Nodes\t";
391  }
392 
393  ndbout << endl;
394 
395  while(pOp->nextResult() == 0)
396  {
397  for(i = 0; g_part_info[i].m_title != 0; i++)
398  {
399  NdbRecAttr &r= *g_part_info[i].m_rec_attr;
400  unsigned long long val;
401  switch (r.getType()) {
403  val= r.u_64_value();
404  break;
406  val= r.u_32_value();
407  break;
408  default:
409  abort();
410  }
411  if (val != 0)
412  printf("%-*.llu\t", (int)strlen(g_part_info[i].m_title), val);
413  else
414  printf("0%*.s\t", (int)strlen(g_part_info[i].m_title), "");
415  }
416 
417  if (_nodeinfo)
418  {
419  Uint32 partId = g_part_info[ FragmentIdOffset ].m_rec_attr -> u_32_value();
420 
421  const Uint32 MaxReplicas = 4;
422  Uint32 nodeIds[ MaxReplicas ];
423  Uint32 nodeCnt = pTab->getFragmentNodes(partId, &nodeIds[0], MaxReplicas);
424 
425  if (nodeCnt)
426  {
427  for (Uint32 n = 0; n < nodeCnt; n++)
428  {
429  if (n > 0)
430  printf(",");
431  printf("%u", nodeIds[n]);
432  }
433  printf("\t");
434  }
435  else
436  {
437  printf("-\t");
438  }
439  }
440 
441  printf("\n");
442  }
443  } while(0);
444  pTrans->close();
445 }
446 
447 int desc_hashmap(Ndb_cluster_connection &con, Ndb *myndb, char* name)
448 {
450  assert(dict);
451 
453  if (dict->getHashMap(hm, name) == 0)
454  {
455  Uint32 len = hm.getMapLen();
456  Uint32 * tmp = new Uint32[len];
457  hm.getMapValues(tmp, len);
458  for (Uint32 i = 0; i<len; i++)
459  {
460  printf("%.2u ", tmp[i]);
461  if (((i+1) % 25) == 0)
462  printf("\n");
463  }
464  if (((len + 1) % 25) != 0)
465  printf("\n");
466  delete [] tmp;
467  return 1;
468  }
469  return 0;
470 }