From 5c3d5e28afd91f03351452ff6bf26b5c0aab0e21 Mon Sep 17 00:00:00 2001 From: "stewart@mysql.com" <> Date: Sat, 28 Jan 2006 16:16:23 +1300 Subject: [PATCH] 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 | 1 + sql/ha_blackhole.cc | 1 + sql/ha_federated.cc | 1 + sql/ha_heap.cc | 1 + sql/ha_innodb.cc | 1 + sql/ha_myisam.cc | 1 + sql/ha_myisammrg.cc | 1 + sql/ha_ndbcluster.cc | 160 +++++++++++++++++++++++++++++++++++++++++ sql/ha_partition.cc | 1 + sql/handler.h | 3 + sql/log.cc | 1 + sql/mysql_priv.h | 3 + sql/sql_show.cc | 81 +++++++++++++++++++-- storage/csv/ha_tina.cc | 1 + 14 files changed, 253 insertions(+), 4 deletions(-) diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index e9168487cf4..6866b50fd19 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -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 }; diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 71b4ef3c9dc..42c785e2003 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -60,6 +60,7 @@ handlerton blackhole_hton= { NULL, /* Partition flags */ NULL, /* Alter table flags */ NULL, /* Alter Tablespace */ + NULL, /* Fill FILES table */ HTON_CAN_RECREATE }; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index af8dfb9a111..a4282e5013c 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -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 }; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 2fe4bc7aeb5..c520a4e88d4 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -57,6 +57,7 @@ handlerton heap_hton= { NULL, /* Partition flags */ NULL, /* Alter table flags */ NULL, /* Alter Tablespace */ + NULL, /* Fill Files Table */ HTON_CAN_RECREATE }; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 9aee8a63508..eaf52a9ca09 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -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 }; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 06a9acf9761..2e785f13ea3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -89,6 +89,7 @@ handlerton myisam_hton= { NULL, /* Partition flags */ NULL, /* Alter table flags */ NULL, /* Alter Tablespace */ + NULL, /* Fill Files Table */ HTON_CAN_RECREATE }; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 36de3dc64e0..cc40ca0b92b 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -67,6 +67,7 @@ handlerton myisammrg_hton= { NULL, /* Partition flags */ NULL, /* Alter table flags */ NULL, /* Alter Tablespace */ + NULL, /* Fill Files Table */ HTON_CAN_RECREATE }; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 16b37ede164..6e547ca9f86 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -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 @@ end: 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); + } + } +} diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 84e9c779c7d..1cd682f938c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -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 }; diff --git a/sql/handler.h b/sql/handler.h index 43495b46cce..b21199ac9eb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -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 diff --git a/sql/log.cc b/sql/log.cc index b2f7eb582a7..f919127e774 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -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 }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 589ca1349c1..29faefcabda 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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 */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 672f7fe8abe..82c4af25764 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -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, diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 98d28fea93d..17c842f43e0 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -91,6 +91,7 @@ handlerton tina_hton= { NULL, /* Partition flags */ NULL, /* Alter table flags */ NULL, /* Alter Tablespace */ + NULL, /* Fill FILES Table */ HTON_CAN_RECREATE };