Commit f57e0d8e authored by unknown's avatar unknown

WL#1359 NDB: Add table handler and table information available from SQL commands

add a FILES table that allows the user to run SQL queries on the files used
to store their tables.

Currently supports NDB


sql/ha_berkeley.cc:
  Add fill_files_table
sql/ha_blackhole.cc:
  Add fill_files_table
sql/ha_federated.cc:
  Add fill_files_table
sql/ha_heap.cc:
  Add fill_files_table
sql/ha_innodb.cc:
  Add fill_files_table
sql/ha_myisam.cc:
  Add fill_files_table
sql/ha_myisammrg.cc:
  Add fill_files_table
sql/ha_ndbcluster.cc:
  Add fill_files_table and implementation for NDB disk data DATAFILES and UNDOFILES
sql/ha_partition.cc:
  Add fill_files_table
sql/handler.h:
  Add fill_files_table to handlerton
sql/log.cc:
  Add fill_files_table
sql/mysql_priv.h:
  Add schema_table_store_record as a function that handlertons can call to store rows in INFORMATION_SCHEMA.FILES
sql/sql_show.cc:
  implement the INFORMATION_SCHEMA.FILES table.
  
  Eventually this may move to PERFORMANCE_SCHEMA.
  
  It currently exists to allow users to query disk usage for NDB disk data tables.
storage/csv/ha_tina.cc:
  Add fill_files_table
parent 43f6f1b9
......@@ -152,6 +152,7 @@ handlerton berkeley_hton = {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME
};
......
......@@ -60,6 +60,7 @@ handlerton blackhole_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_CAN_RECREATE
};
......
......@@ -397,6 +397,7 @@ handlerton federated_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_ALTER_NOT_SUPPORTED
};
......
......@@ -57,6 +57,7 @@ handlerton heap_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
};
......
......@@ -237,6 +237,7 @@ handlerton innobase_hton = {
innobase_show_status, /* Show status */
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Fill FILES table */
HTON_NO_FLAGS
};
......
......@@ -89,6 +89,7 @@ handlerton myisam_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
};
......
......@@ -67,6 +67,7 @@ handlerton myisammrg_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
};
......
......@@ -63,6 +63,7 @@ static bool ndbcluster_init(void);
static int ndbcluster_end(ha_panic_function flag);
static bool ndbcluster_show_status(THD*,stat_print_fn *,enum ha_stat_type);
static int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info);
static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, COND *cond);
handlerton ndbcluster_hton = {
MYSQL_HANDLERTON_INTERFACE_VERSION,
......@@ -5729,6 +5730,7 @@ static bool ndbcluster_init()
h.alter_tablespace= ndbcluster_alter_tablespace; /* Show status */
h.partition_flags= ndbcluster_partition_flags; /* Partition flags */
h.alter_table_flags=ndbcluster_alter_table_flags; /* Alter table flags */
h.fill_files_table= ndbcluster_fill_files_table;
#ifdef HAVE_NDB_BINLOG
ndbcluster_binlog_init_handlerton();
#endif
......@@ -9473,3 +9475,161 @@ bool ha_ndbcluster::get_no_parts(const char *name, uint *no_parts)
DBUG_RETURN(TRUE);
}
static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, COND *cond)
{
TABLE* table= tables->table;
Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb;
NdbDictionary::Dictionary* dict= ndb->getDictionary();
NdbDictionary::Dictionary::List dflist;
dict->listObjects(dflist,NdbDictionary::Object::Datafile);
for(unsigned i= 0;i < dflist.count;i++)
{
NdbDictionary::Dictionary::List::Element& elt = dflist.elements[i];
Ndb_cluster_connection_node_iter iter;
unsigned id;
g_ndb_cluster_connection->init_get_next_node(iter);
while(id= g_ndb_cluster_connection->get_next_node(iter))
{
NdbDictionary::Datafile df= dict->getDatafile(id, elt.name);
int c=0;
table->field[c++]->set_null(); // FILE_ID
table->field[c++]->store(elt.name,strlen(elt.name),system_charset_info);
table->field[c++]->store("DATAFILE",8,system_charset_info);
table->field[c++]->store(df.getTablespace(),strlen(df.getTablespace()),
system_charset_info);
table->field[c++]->set_null(); // TABLE_CATALOG
table->field[c++]->set_null(); // TABLE_SCHEMA
table->field[c++]->set_null(); // TABLE_NAME
NdbDictionary::Tablespace ts= dict->getTablespace(df.getTablespace());
// LOGFILE_GROUP_NAME
table->field[c++]->store(ts.getDefaultLogfileGroup(),
strlen(ts.getDefaultLogfileGroup()),
system_charset_info);
table->field[c++]->set_null(); // LOGFILE_GROUP_NUMBER
table->field[c++]->store(ndbcluster_hton.name,
strlen(ndbcluster_hton.name),
system_charset_info); // ENGINE
table->field[c++]->set_null(); // FULLTEXT_KEYS
table->field[c++]->set_null(); // DELETED_ROWS
table->field[c++]->set_null(); // UPDATE_COUNT
table->field[c++]->store(df.getFree() / ts.getExtentSize()); // FREE_EXTENTS
table->field[c++]->store(df.getSize() / ts.getExtentSize()); // TOTAL_EXTENTS
table->field[c++]->store(ts.getExtentSize()); // EXTENT_SIZE
table->field[c++]->store(df.getSize()); // INITIAL_SIZE
table->field[c++]->store(df.getSize()); // MAXIMUM_SIZE
table->field[c++]->set_null(); // AUTOEXTEND_SIZE
table->field[c++]->set_null(); // CREATION_TIME
table->field[c++]->set_null(); // LAST_UPDATE_TIME
table->field[c++]->set_null(); // LAST_ACCESS_TIME
table->field[c++]->set_null(); // RECOVER_TIME
table->field[c++]->set_null(); // TRANSACTION_COUNTER
table->field[c++]->store(df.getObjectVersion()); // VERSION
table->field[c++]->store("FIXED",5,system_charset_info); // ROW_FORMAT
table->field[c++]->set_null(); // TABLE_ROWS
table->field[c++]->set_null(); // AVG_ROW_LENGTH
table->field[c++]->set_null(); // DATA_LENGTH
table->field[c++]->set_null(); // MAX_DATA_LENGTH
table->field[c++]->set_null(); // INDEX_LENGTH
table->field[c++]->set_null(); // DATA_FREE
table->field[c++]->set_null(); // CREATE_TIME
table->field[c++]->set_null(); // UPDATE_TIME
table->field[c++]->set_null(); // CHECK_TIME
table->field[c++]->set_null(); // CHECKSUM
table->field[c++]->store("NORMAL",6, system_charset_info);
char extra[30];
int len= snprintf(extra,sizeof(extra),"CLUSTER_NODE=%u",id);
table->field[c]->store(extra,len,system_charset_info);
schema_table_store_record(thd, table);
}
}
dict->listObjects(dflist,NdbDictionary::Object::Undofile);
for(unsigned i= 0;i < dflist.count;i++)
{
NdbDictionary::Dictionary::List::Element& elt = dflist.elements[i];
Ndb_cluster_connection_node_iter iter;
unsigned id;
g_ndb_cluster_connection->init_get_next_node(iter);
while(id= g_ndb_cluster_connection->get_next_node(iter))
{
NdbDictionary::Undofile uf= dict->getUndofile(id, elt.name);
int c=0;
table->field[c++]->set_null(); // FILE_ID
table->field[c++]->store(elt.name,strlen(elt.name),system_charset_info);
table->field[c++]->store("UNDO LOG",8,system_charset_info);
table->field[c++]->set_null(); // TABLESPACE NAME
table->field[c++]->set_null(); // TABLE_CATALOG
table->field[c++]->set_null(); // TABLE_SCHEMA
table->field[c++]->set_null(); // TABLE_NAME
NdbDictionary::LogfileGroup lfg=
dict->getLogfileGroup(uf.getLogfileGroup());
// LOGFILE_GROUP_NAME
table->field[c++]->store(uf.getLogfileGroup(),
strlen(uf.getLogfileGroup()),
system_charset_info);
table->field[c++]->store(uf.getLogfileGroupId()); // LOGFILE_GROUP_NUMBER
table->field[c++]->store(ndbcluster_hton.name,
strlen(ndbcluster_hton.name),
system_charset_info); // ENGINE
table->field[c++]->set_null(); // FULLTEXT_KEYS
table->field[c++]->set_null(); // DELETED_ROWS
table->field[c++]->set_null(); // UPDATE_COUNT
table->field[c++]->store(lfg.getUndoFreeWords()); // FREE_EXTENTS
table->field[c++]->store(lfg.getUndoBufferSize()); // TOTAL_EXTENTS
table->field[c++]->store(4); // EXTENT_SIZE
table->field[c++]->store(uf.getSize()); // INITIAL_SIZE
table->field[c++]->store(uf.getSize()); // MAXIMUM_SIZE
table->field[c++]->set_null(); // AUTOEXTEND_SIZE
table->field[c++]->set_null(); // CREATION_TIME
table->field[c++]->set_null(); // LAST_UPDATE_TIME
table->field[c++]->set_null(); // LAST_ACCESS_TIME
table->field[c++]->set_null(); // RECOVER_TIME
table->field[c++]->set_null(); // TRANSACTION_COUNTER
table->field[c++]->store(uf.getObjectVersion()); // VERSION
table->field[c++]->set_null(); // ROW FORMAT
table->field[c++]->set_null(); // TABLE_ROWS
table->field[c++]->set_null(); // AVG_ROW_LENGTH
table->field[c++]->set_null(); // DATA_LENGTH
table->field[c++]->set_null(); // MAX_DATA_LENGTH
table->field[c++]->set_null(); // INDEX_LENGTH
table->field[c++]->set_null(); // DATA_FREE
table->field[c++]->set_null(); // CREATE_TIME
table->field[c++]->set_null(); // UPDATE_TIME
table->field[c++]->set_null(); // CHECK_TIME
table->field[c++]->set_null(); // CHECKSUM
table->field[c++]->store("NORMAL",6, system_charset_info);
char extra[30];
int len= snprintf(extra,sizeof(extra),"CLUSTER_NODE=%u",id);
table->field[c]->store(extra,len,system_charset_info);
schema_table_store_record(thd, table);
}
}
}
......@@ -101,6 +101,7 @@ handlerton partition_hton = {
partition_flags, /* Partition flags */
alter_table_flags, /* Partition flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
};
......
......@@ -571,6 +571,9 @@ typedef struct
uint (*partition_flags)();
uint (*alter_table_flags)(uint flags);
int (*alter_tablespace)(THD *thd, st_alter_tablespace *ts_info);
int (*fill_files_table)(THD *thd,
struct st_table_list *tables,
class Item *cond);
uint32 flags; /* global handler flags */
/*
Handlerton functions are not set in the different storage
......
......@@ -101,6 +101,7 @@ handlerton binlog_hton = {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
};
......
......@@ -1757,5 +1757,8 @@ inline void kill_delayed_threads(void) {}
#define check_stack_overrun(A, B, C) 0
#endif
/* Used by handlers to store things in schema tables */
bool schema_table_store_record(THD *thd, TABLE *table);
#endif /* MYSQL_SERVER */
#endif /* MYSQL_CLIENT */
......@@ -41,9 +41,6 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names, NULL};
#endif
static bool schema_table_store_record(THD *thd, TABLE *table);
/***************************************************************************
** List all table types supported
***************************************************************************/
......@@ -1877,7 +1874,7 @@ typedef struct st_index_field_values
1 error
*/
static bool schema_table_store_record(THD *thd, TABLE *table)
bool schema_table_store_record(THD *thd, TABLE *table)
{
int error;
if ((error= table->file->ha_write_row(table->record[0])))
......@@ -4292,6 +4289,38 @@ bool get_schema_tables_result(JOIN *join)
DBUG_RETURN(result);
}
struct run_hton_fill_schema_files_args
{
TABLE_LIST *tables;
COND *cond;
};
static my_bool run_hton_fill_schema_files(THD *thd, st_plugin_int *plugin,
void *arg)
{
struct run_hton_fill_schema_files_args *args=
(run_hton_fill_schema_files_args *) arg;
handlerton *hton= (handlerton *) plugin->plugin->info;
if(hton->fill_files_table)
hton->fill_files_table(thd, args->tables, args->cond);
return false;
}
int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond)
{
int i;
TABLE *table= tables->table;
DBUG_ENTER("fill_schema_logfile_groups");
struct run_hton_fill_schema_files_args args;
args.tables= tables;
args.cond= cond;
plugin_foreach(thd, run_hton_fill_schema_files,
MYSQL_STORAGE_ENGINE_PLUGIN, &args);
DBUG_RETURN(0);
}
ST_FIELD_INFO schema_fields_info[]=
{
......@@ -4633,6 +4662,48 @@ ST_FIELD_INFO plugin_fields_info[]=
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
};
ST_FIELD_INFO files_fields_info[]=
{
{"FILE_ID", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"FILE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0},
{"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"TABLE_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"LOGFILE_GROUP_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"FULLTEXT_KEYS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"DELETED_ROWS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"UPDATE_COUNT", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"FREE_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"EXTENT_SIZE", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"INITIAL_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
{"MAXIMUM_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
{"AUTOEXTEND_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
{"CREATION_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
{"LAST_UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
{"LAST_ACCESS_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
{"RECOVER_TIME", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
{"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
{"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
{"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
{"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
{"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
{"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
{"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
{"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
{"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
{"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
{"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
{"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0},
{"EXTRA", 255, MYSQL_TYPE_STRING, 0, 0, 0},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
};
/*
Description of ST_FIELD_INFO in table.h
......@@ -4655,6 +4726,8 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_schema_column_privileges, 0, 0, -1, -1, 0},
{"ENGINES", engines_fields_info, create_schema_table,
fill_schema_engines, make_old_format, 0, -1, -1, 0},
{"FILES", files_fields_info, create_schema_table,
fill_schema_files, 0, 0, -1, -1, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
......
......@@ -91,6 +91,7 @@ handlerton tina_hton= {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES Table */
HTON_CAN_RECREATE
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment