From 40ec012c905be0262ba5c36bbccfa0db0105e31f Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 25 Nov 2009 16:25:01 +0400 Subject: [PATCH 1/7] Backport from 6.0-codebase. WL#3951 - MyISAM: Additional Error Logs for Data Corruption When table corruption is detected, in addition to current error message provide following information: - list of threads (and queries) accessing a table; - thread_id of a thread that detected corruption; - source file name and line number where this corruption was detected; - optional extra information (string). mysql-test/r/myisam_crash_before_flush_keys.result: Adjusted a test case according to WL#3951. mysql-test/t/myisam_crash_before_flush_keys.test: Adjusted a test case according to WL#3951. storage/myisam/CMakeLists.txt: Added mi_extrafunc.h to myisam sources list. storage/myisam/Makefile.am: Added mi_extrafunc.h to myisam headers list. storage/myisam/ha_myisam.cc: Added _mi_report_crashed() function (reports additional information whenever table corruption is detected). storage/myisam/mi_extrafunc.h: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/mi_locking.c: For every call to mi_lock_database(F_[RD|WR|EXTRA_]LCK) - add current thread to the list of threads accessing this table. For every call to mi_lock_database(F_UNLCK) - remove current thread from the list of threads accessing this table. storage/myisam/mi_test1.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/mi_test2.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/mi_test3.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/myisam_ftdump.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/myisamchk.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/myisamdef.h: Extra elements are added to MI_INFO and MYISAM_SHARE structures. MI_INFO is extended with LIST element, that holds a pointer to THD object accessing a table. MYISAM_SHARE is extended with LIST (list of threads accessing a table). Whenever table is marked as crashed, call mi_report_crashed() macro to provide useful information. storage/myisam/myisamlog.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/myisampack.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/rt_test.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisam/sp_test.c: All standalone programs must define their version of _mi_report_crashed() by including mi_extrafunc.h. storage/myisammrg/ha_myisammrg.cc: For each unedrlying table initialize `in_use' variable. --- .../r/myisam_crash_before_flush_keys.result | 2 + .../t/myisam_crash_before_flush_keys.test | 3 ++ storage/myisam/CMakeLists.txt | 3 +- storage/myisam/Makefile.am | 2 +- storage/myisam/ha_myisam.cc | 40 +++++++++++++++++++ storage/myisam/mi_extrafunc.h | 21 ++++++++++ storage/myisam/mi_locking.c | 4 ++ storage/myisam/mi_test1.c | 2 + storage/myisam/mi_test2.c | 2 + storage/myisam/mi_test3.c | 2 + storage/myisam/myisam_ftdump.c | 2 + storage/myisam/myisamchk.c | 2 + storage/myisam/myisamdef.h | 6 +++ storage/myisam/myisamlog.c | 2 + storage/myisam/myisampack.c | 2 +- storage/myisam/rt_test.c | 2 + storage/myisam/sp_test.c | 1 + storage/myisammrg/ha_myisammrg.cc | 3 ++ 18 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 storage/myisam/mi_extrafunc.h diff --git a/mysql-test/r/myisam_crash_before_flush_keys.result b/mysql-test/r/myisam_crash_before_flush_keys.result index d3545ea47d0..43eb1625409 100644 --- a/mysql-test/r/myisam_crash_before_flush_keys.result +++ b/mysql-test/r/myisam_crash_before_flush_keys.result @@ -3,6 +3,8 @@ # # Don't test this under valgrind, memory leaks will occur # Binary must be compiled with debug for crash to occur +call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:"); +call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table"); SET GLOBAL delay_key_write=ALL; CREATE TABLE t1(a INT, b INT, diff --git a/mysql-test/t/myisam_crash_before_flush_keys.test b/mysql-test/t/myisam_crash_before_flush_keys.test index 1860ddd27e3..0b0491098cd 100644 --- a/mysql-test/t/myisam_crash_before_flush_keys.test +++ b/mysql-test/t/myisam_crash_before_flush_keys.test @@ -8,6 +8,9 @@ --echo # Binary must be compiled with debug for crash to occur --source include/have_debug.inc +call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:"); +call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table"); + let $MYSQLD_DATADIR= `select @@datadir`; SET GLOBAL delay_key_write=ALL; CREATE TABLE t1(a INT, diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt index 829d89a798a..9a0aa06e861 100755 --- a/storage/myisam/CMakeLists.txt +++ b/storage/myisam/CMakeLists.txt @@ -26,7 +26,8 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c - rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c) + rt_split.c sort.c sp_key.c ft_eval.h mi_extrafunc.h myisamdef.h + rt_index.h mi_rkey.c) MYSQL_STORAGE_ENGINE(MYISAM) diff --git a/storage/myisam/Makefile.am b/storage/myisam/Makefile.am index 6dd0d2bcbdb..c659d05be40 100644 --- a/storage/myisam/Makefile.am +++ b/storage/myisam/Makefile.am @@ -50,7 +50,7 @@ myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \ fulltext.h ftdefs.h ft_test1.h ft_eval.h \ - ha_myisam.h + ha_myisam.h mi_extrafunc.h mi_test1_DEPENDENCIES= $(LIBRARIES) mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 612d02bbcd3..1dd964f520e 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -539,6 +539,45 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) va_end(args); } + +/** + Report list of threads (and queries) accessing a table, thread_id of a + thread that detected corruption, ource file name and line number where + this corruption was detected, optional extra information (string). + + This function is intended to be used when table corruption is detected. + + @param[in] file MI_INFO object. + @param[in] message Optional error message. + @param[in] sfile Name of source file. + @param[in] sline Line number in source file. + + @return void +*/ + +void _mi_report_crashed(MI_INFO *file, const char *message, + const char *sfile, uint sline) +{ + THD *cur_thd; + LIST *element; + char buf[1024]; + pthread_mutex_lock(&file->s->intern_lock); + if ((cur_thd= (THD*) file->in_use.data)) + sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id, + sfile, sline); + else + sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline); + if (message) + sql_print_error("%s", message); + for (element= file->s->in_use; element; element= list_rest(element)) + { + THD *thd= (THD*) element->data; + sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0) + : "Unknown thread accessing table"); + } + pthread_mutex_unlock(&file->s->intern_lock); +} + } @@ -1894,6 +1933,7 @@ int ha_myisam::delete_table(const char *name) int ha_myisam::external_lock(THD *thd, int lock_type) { + file->in_use.data= thd; return mi_lock_database(file, !table->s->tmp_table ? lock_type : ((lock_type == F_UNLCK) ? F_UNLCK : F_EXTRA_LCK)); diff --git a/storage/myisam/mi_extrafunc.h b/storage/myisam/mi_extrafunc.h new file mode 100644 index 00000000000..4aa28832c6d --- /dev/null +++ b/storage/myisam/mi_extrafunc.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2000-2006 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +void _mi_report_crashed(MI_INFO *file __attribute__((unused)), + const char *message __attribute__((unused)), + const char *sfile __attribute__((unused)), + uint sline __attribute__((unused))) +{ +} diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 8a5866ae763..fd2094caa54 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -45,6 +45,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ++share->w_locks; ++share->tot_locks; info->lock_type= lock_type; + info->s->in_use= list_add(info->s->in_use, &info->in_use); DBUG_RETURN(0); } @@ -136,6 +137,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) } info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); info->lock_type= F_UNLCK; + info->s->in_use= list_delete(info->s->in_use, &info->in_use); break; case F_RDLCK: if (info->lock_type == F_WRLCK) @@ -182,6 +184,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) share->r_locks++; share->tot_locks++; info->lock_type=lock_type; + info->s->in_use= list_add(info->s->in_use, &info->in_use); break; case F_WRLCK: if (info->lock_type == F_RDLCK) @@ -231,6 +234,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) info->invalidator=info->s->invalidator; share->w_locks++; share->tot_locks++; + info->s->in_use= list_add(info->s->in_use, &info->in_use); break; default: break; /* Impossible */ diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index f218bf4e77f..6a938c6e269 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -679,3 +679,5 @@ static void usage() my_print_help(my_long_options); my_print_variables(my_long_options); } + +#include "mi_extrafunc.h" diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 23c58638166..40732db3d4f 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -1055,3 +1055,5 @@ static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff) } return; } + +#include "mi_extrafunc.h" diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index 5bdc33b8518..44f194f5c9b 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -488,6 +488,8 @@ int test_update(MI_INFO *file,int id,int lock_type) return 0; } +#include "mi_extrafunc.h" + #else /* __NETWARE__ */ #include diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c index 63d954242a0..7c14ae37de2 100644 --- a/storage/myisam/myisam_ftdump.c +++ b/storage/myisam/myisam_ftdump.c @@ -274,3 +274,5 @@ static void complain(int val) /* Kinda assert :-) */ exit(1); } } + +#include "mi_extrafunc.h" diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 611fb6325c8..b26f3200504 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1815,3 +1815,5 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...) va_end(args); DBUG_VOID_RETURN; } + +#include "mi_extrafunc.h" diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index b64c7f6bd7f..9866b44ba15 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -165,6 +165,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */ MI_COLUMNDEF *rec; /* Pointer to field information */ MI_PACK pack; /* Data about packed records */ MI_BLOB *blobs; /* Pointer to blobs */ + LIST *in_use; /* List of threads using this table */ char *unique_file_name; /* realpath() of index file */ char *data_file_name, /* Resolved path names from symlinks */ *index_file_name; @@ -242,6 +243,7 @@ struct st_myisam_info { DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */ MEM_ROOT ft_memroot; /* used by the parser */ MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */ + LIST in_use; /* Thread using this table */ char *filename; /* parameter to open filename */ uchar *buff, /* Temp area for key */ *lastkey,*lastkey2; /* Last used search key */ @@ -385,8 +387,10 @@ typedef struct st_mi_sort_param #define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\ mi_int2store(x,boh); } #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) +#define mi_report_crashed(A, B) _mi_report_crashed((A), (B), __FILE__, __LINE__) #define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \ DBUG_PRINT("error", ("Marked table crashed")); \ + mi_report_crashed((x), 0); \ }while(0) #define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \ STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \ @@ -764,6 +768,8 @@ int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); void mi_remap_file(MI_INFO *info, my_off_t size); +void _mi_report_crashed(MI_INFO *file, const char *message, + const char *sfile, uint sline); /* Functions needed by mi_check */ volatile int *killed_ptr(MI_CHECK *param); diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c index fafb5140a5e..47667a52d16 100644 --- a/storage/myisam/myisamlog.c +++ b/storage/myisam/myisamlog.c @@ -845,3 +845,5 @@ static my_bool cmp_filename(struct file_info *file_info, char * name) return 1; return strcmp(file_info->name,name) ? 1 : 0; } + +#include "mi_extrafunc.h" diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 908c32e48d3..f63e8087fd5 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -3201,4 +3201,4 @@ static int fakecmp(my_off_t **count1, my_off_t **count2) } #endif - +#include "mi_extrafunc.h" diff --git a/storage/myisam/rt_test.c b/storage/myisam/rt_test.c index 7d15afd12ef..4a9b61605d9 100644 --- a/storage/myisam/rt_test.c +++ b/storage/myisam/rt_test.c @@ -468,3 +468,5 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) exit(0); } #endif /*HAVE_RTREE_KEYS*/ + +#include "mi_extrafunc.h" diff --git a/storage/myisam/sp_test.c b/storage/myisam/sp_test.c index f572c7ab19b..069f43c320d 100644 --- a/storage/myisam/sp_test.c +++ b/storage/myisam/sp_test.c @@ -562,3 +562,4 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) } #endif /*HAVE_SPATIAL*/ +#include "mi_extrafunc.h" diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 471e2243aac..b28529b08e7 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1009,7 +1009,10 @@ int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) int ha_myisammrg::external_lock(THD *thd, int lock_type) { + MYRG_TABLE *tmp; DBUG_ASSERT(this->file->children_attached); + for (tmp= file->open_tables; tmp != file->end_table; tmp++) + tmp->table->in_use.data= thd; return myrg_lock_database(file,lock_type); } From e86daf9bf299b552d68cb27771b3492ee7a1c9bf Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Thu, 3 Dec 2009 16:16:49 +0530 Subject: [PATCH 2/7] WL#4448 Generalize the handlerton::fill_files_table call with handlerton::fill_is_table The attached patch adds a method handlerton::fill_is_table that can be used instead of having to create specific handlerton::fill_*_table methods. sql/ha_ndbcluster.cc: WL#4448 Generalize the handlerton::fill_files_table call with handlerton::fill_is_table Implemented the method ndbcluster_fill_is_table that uses the supplied table id to switch to the appropriate fill_*_table method. sql/handler.h: WL#4448 Generalize the handlerton::fill_files_table call with handlerton::fill_is_table Moved the enum_schema_table enumeration from table.h to here. contains the declaration for the new method fill_is_tables. sql/sql_show.cc: WL#4448 Generalize the handlerton::fill_files_table call with handlerton::fill_is_table calls the fill_is_table method instead of the fill_files_table method. sql/table.h: WL#4448 Generalize the handlerton::fill_files_table call with handlerton::fill_is_table removed the earlier definition of enum_schema_tables. --- sql/ha_ndbcluster.cc | 35 ++++++++++++++++++++++++++++++++- sql/handler.h | 46 +++++++++++++++++++++++++++++++++++++++++--- sql/sql_show.cc | 5 +++-- sql/table.h | 41 --------------------------------------- 4 files changed, 80 insertions(+), 47 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 83cceb0da76..3bb3c3388e2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -94,6 +94,11 @@ static bool ndbcluster_show_status(handlerton *hton, THD*, static int ndbcluster_alter_tablespace(handlerton *hton, THD* thd, st_alter_tablespace *info); +static int ndbcluster_fill_is_table(handlerton *hton, + THD *thd, + TABLE_LIST *tables, + COND *cond, + enum enum_schema_tables); static int ndbcluster_fill_files_table(handlerton *hton, THD *thd, TABLE_LIST *tables, @@ -7403,7 +7408,7 @@ static int ndbcluster_init(void *p) 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; + h->fill_is_table= ndbcluster_fill_is_table; #ifdef HAVE_NDB_BINLOG ndbcluster_binlog_init_handlerton(); #endif @@ -7539,6 +7544,34 @@ ndbcluster_init_error: DBUG_RETURN(TRUE); } +/** + Used to fill in INFORMATION_SCHEMA* tables. + + @param hton handle to the handlerton structure + @param thd the thread/connection descriptor + @param[in,out] tables the information schema table that is filled up + @param cond used for conditional pushdown to storage engine + @param schema_table_idx the table id that distinguishes the type of table + + @return Operation status + */ +static int ndbcluster_fill_is_table(handlerton *hton, + THD *thd, + TABLE_LIST *tables, + COND *cond, + enum enum_schema_tables schema_table_idx) +{ + int ret= 0; + + if (schema_table_idx == SCH_FILES) + { + ret= ndbcluster_fill_files_table(hton, thd, tables, cond); + } + + return ret; +} + + static int ndbcluster_end(handlerton *hton, ha_panic_function type) { DBUG_ENTER("ndbcluster_end"); diff --git a/sql/handler.h b/sql/handler.h index 05a9e13653c..957729a7bf0 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -515,6 +515,46 @@ class st_alter_tablespace : public Sql_alloc /* The handler for a table type. Will be included in the TABLE structure */ struct TABLE; + +/* + Make sure that the order of schema_tables and enum_schema_tables are the same. +*/ +enum enum_schema_tables +{ + SCH_CHARSETS= 0, + SCH_COLLATIONS, + SCH_COLLATION_CHARACTER_SET_APPLICABILITY, + SCH_COLUMNS, + SCH_COLUMN_PRIVILEGES, + SCH_ENGINES, + SCH_EVENTS, + SCH_FILES, + SCH_GLOBAL_STATUS, + SCH_GLOBAL_VARIABLES, + SCH_KEY_COLUMN_USAGE, + SCH_OPEN_TABLES, + SCH_PARTITIONS, + SCH_PLUGINS, + SCH_PROCESSLIST, + SCH_PROFILES, + SCH_REFERENTIAL_CONSTRAINTS, + SCH_PROCEDURES, + SCH_SCHEMATA, + SCH_SCHEMA_PRIVILEGES, + SCH_SESSION_STATUS, + SCH_SESSION_VARIABLES, + SCH_STATISTICS, + SCH_STATUS, + SCH_TABLES, + SCH_TABLE_CONSTRAINTS, + SCH_TABLE_NAMES, + SCH_TABLE_PRIVILEGES, + SCH_TRIGGERS, + SCH_USER_PRIVILEGES, + SCH_VARIABLES, + SCH_VIEWS +}; + struct TABLE_SHARE; struct st_foreign_key_info; typedef struct st_foreign_key_info FOREIGN_KEY_INFO; @@ -679,9 +719,9 @@ struct handlerton uint (*partition_flags)(); uint (*alter_table_flags)(uint flags); int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info); - int (*fill_files_table)(handlerton *hton, THD *thd, - TABLE_LIST *tables, - class Item *cond); + int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables, + class Item *cond, + enum enum_schema_tables); uint32 flags; /* global handler flags */ /* Those handlerton functions below are properly initialized at handler diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3af0df73079..b6bfac99dd5 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6264,8 +6264,9 @@ static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin, struct run_hton_fill_schema_files_args *args= (run_hton_fill_schema_files_args *) arg; handlerton *hton= plugin_data(plugin, handlerton *); - if(hton->fill_files_table && hton->state == SHOW_OPTION_YES) - hton->fill_files_table(hton, thd, args->tables, args->cond); + if (hton->fill_is_table && hton->state == SHOW_OPTION_YES) + hton->fill_is_table(hton, thd, args->tables, args->cond, + get_schema_table_idx(args->tables->schema_table)); return false; } diff --git a/sql/table.h b/sql/table.h index 76bebd3fdaa..03220487684 100644 --- a/sql/table.h +++ b/sql/table.h @@ -878,47 +878,6 @@ typedef struct st_foreign_key_info List referenced_fields; } FOREIGN_KEY_INFO; -/* - Make sure that the order of schema_tables and enum_schema_tables are the same. -*/ - -enum enum_schema_tables -{ - SCH_CHARSETS= 0, - SCH_COLLATIONS, - SCH_COLLATION_CHARACTER_SET_APPLICABILITY, - SCH_COLUMNS, - SCH_COLUMN_PRIVILEGES, - SCH_ENGINES, - SCH_EVENTS, - SCH_FILES, - SCH_GLOBAL_STATUS, - SCH_GLOBAL_VARIABLES, - SCH_KEY_COLUMN_USAGE, - SCH_OPEN_TABLES, - SCH_PARTITIONS, - SCH_PLUGINS, - SCH_PROCESSLIST, - SCH_PROFILES, - SCH_REFERENTIAL_CONSTRAINTS, - SCH_PROCEDURES, - SCH_SCHEMATA, - SCH_SCHEMA_PRIVILEGES, - SCH_SESSION_STATUS, - SCH_SESSION_VARIABLES, - SCH_STATISTICS, - SCH_STATUS, - SCH_TABLES, - SCH_TABLE_CONSTRAINTS, - SCH_TABLE_NAMES, - SCH_TABLE_PRIVILEGES, - SCH_TRIGGERS, - SCH_USER_PRIVILEGES, - SCH_VARIABLES, - SCH_VIEWS -}; - - #define MY_I_S_MAYBE_NULL 1 #define MY_I_S_UNSIGNED 2 From 21aaf8dded17341805afd72539bc7606ebb0b46a Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Thu, 3 Dec 2009 16:48:02 +0530 Subject: [PATCH 3/7] WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order Introduce a flag that will enable the REPLACE command to work correctly with an underlying storage engine that does not report unique key conflicts in the ascending order. sql/handler.h: WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order Adds the flag that will be set by a SE that does not report unique key conflicts in the ascending order. sql/sql_insert.cc: WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order modifies the function used for a last row replace optimization to check for the HA_DUPLICATE_KEY_NOT_IN_ORDER flag. --- sql/handler.h | 23 +++++++++++++++++++++++ sql/sql_insert.cc | 17 +++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/sql/handler.h b/sql/handler.h index 05a9e13653c..8e8f417739e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -127,6 +127,29 @@ */ #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34) #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) +/* + When a multiple key conflict happens in a REPLACE command mysql + expects the conflicts to be reported in the ascending order of + key names. + + For e.g. + + CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT + NULL, INDEX(c)); + + REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3); + + MySQL expects the conflict with 'a' to be reported before the conflict with + 'b'. + + If the underlying storage engine does not report the conflicting keys in + ascending order, it causes unexpected errors when the REPLACE command is + executed. + + This flag helps the underlying SE to inform the server that the keys are not + ordered. +*/ +#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36) /* Set of all binlog flags. Currently only contain the capabilities diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b1c7c7f647e..988c91e3168 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1322,6 +1322,23 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, static int last_uniq_key(TABLE *table,uint keynr) { + /* + When an underlying storage engine informs that the unique key + conflicts are not reported in the ascending order by setting + the HA_DUPLICATE_KEY_NOT_IN_ORDER flag, we cannot rely on this + information to determine the last key conflict. + + The information about the last key conflict will be used to + do a replace of the new row on the conflicting row, rather + than doing a delete (of old row) + insert (of new row). + + Hence check for this flag and disable replacing the last row + by returning 0 always. Returning 0 will result in doing + a delete + insert always. + */ + if (table->file->ha_table_flags() & HA_DUPLICATE_KEY_NOT_IN_ORDER) + return 0; + while (++keynr < table->s->keys) if (table->key_info[keynr].flags & HA_NOSAME) return 0; From a5aa3b3c919ab53cdcaa657a6446051348371245 Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Thu, 3 Dec 2009 17:18:43 +0530 Subject: [PATCH 4/7] Bug#40814 CSV engine does not parse \X characters when they occur in unquoted fields When a .CSV file for table in the CSV engine contains \X characters as part of unquoted fields, e.g. 2,naraya\nan \n is not interpreted as a new line (it is however interpreted as a newline in a quoted field). The old algorithm copied the entire value for a unquoted field without parsing the \X characters. The new algorithm adds the capability to handle \X characters in the unquoted fields of a .CSV file. mysql-test/r/csv.result: Bug#40814 CSV engine does not parse \X characters when they occur in unquoted fields Contains additional test output corresponding to the new tests added. mysql-test/t/csv.test: Bug#40814 CSV engine does not parse \X characters when they occur in unquoted fields Contains additional tests for testing the behaviour of the CSV storage engine when the fields are not enclosed in quotes and contain \X characters. storage/csv/ha_tina.cc: Bug#40814 CSV engine does not parse \X characters when they occur in unquoted fields Changes the parsing logic of the rows in a CSV file, to parse \X characters that might be present in the unquoted fields. --- mysql-test/r/csv.result | 56 +++++++++++++++++++++++++++++ mysql-test/t/csv.test | 80 +++++++++++++++++++++++++++++++++++++++++ storage/csv/ha_tina.cc | 73 ++++++++++++++++++++++++++++++++----- 3 files changed, 201 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 4b96f5a5ed0..97996b484bb 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5407,4 +5407,60 @@ test.t1 repair status OK select * from t1 limit 1; a drop table t1; +# +# Test for the following cases +# 1) integers and strings enclosed in quotes +# 2) integers and strings not enclosed in quotes +# 3) \X characters with quotes +# 4) \X characters outside quotes +# +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; +# remove the already existing .CSV file if any +# create the .CSV file that contains the hard-coded data used in +# testing +1,"integer sans quotes" +1,string sans quotes +1,quotes"in between" strings +"1",Integer with quote and string with no quote +1,"escape sequence \n \" \\ \r \a within quotes" +1,escape sequence \n \" \\ \r \a without quotes +# select from the table in which the data has been filled in using +# the hard-coded .CSV file +SELECT * FROM t1; +c1 c2 +1 integer sans quotes +1 string sans quotes +1 quotes"in between" strings +1 Integer with quote and string with no quote +1 escape sequence + " \ \a within quotes +1 escape sequence + " \ \a without quotes +DROP TABLE t1; +# Test for the case when a field begins with a quote, but does not end in a +# quote. +# Note: This results in an error. +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; +# remove the already existing .CSV file if any +# create the .CSV file that contains the hard-coded data used in +# testing +1,"string only at the beginning quotes +# select from the table in which the data has been filled in using +# the hard-coded .CSV file +SELECT * FROM t1; +ERROR HY000: Table 't1' is marked as crashed and should be repaired +DROP TABLE t1; +# Test for the case when a field ends with a quote, but does not begin in a +# quote. +# Note: This results in an error. +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; +# remove the already existing .CSV file if any +# create the .CSV file that contains the hard-coded data used in +# testing +1,string with only ending quotes" +# select from the table in which the data has been filled in using +# the hard-coded .CSV file +SELECT * FROM t1; +ERROR HY000: Table 't1' is marked as crashed and should be repaired +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index cdf274190dd..ea949f463c9 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1819,4 +1819,84 @@ repair table t1; select * from t1 limit 1; drop table t1; +# +# Bug #40814 CSV engine does not parse \X characters when they occur in unquoted fields +# + +--echo # +--echo # Test for the following cases +--echo # 1) integers and strings enclosed in quotes +--echo # 2) integers and strings not enclosed in quotes +--echo # 3) \X characters with quotes +--echo # 4) \X characters outside quotes +--echo # + +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; + +--echo # remove the already existing .CSV file if any +--remove_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # create the .CSV file that contains the hard-coded data used in +--echo # testing +--write_file $MYSQLD_DATADIR/test/t1.CSV +1,"integer sans quotes" +1,string sans quotes +1,quotes"in between" strings +"1",Integer with quote and string with no quote +1,"escape sequence \n \" \\ \r \a within quotes" +1,escape sequence \n \" \\ \r \a without quotes +EOF +--cat_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # select from the table in which the data has been filled in using +--echo # the hard-coded .CSV file +SELECT * FROM t1; + +DROP TABLE t1; + +--echo # Test for the case when a field begins with a quote, but does not end in a +--echo # quote. +--echo # Note: This results in an error. + +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; + +--echo # remove the already existing .CSV file if any +--remove_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # create the .CSV file that contains the hard-coded data used in +--echo # testing +--write_file $MYSQLD_DATADIR/test/t1.CSV +1,"string only at the beginning quotes +EOF +--cat_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # select from the table in which the data has been filled in using +--echo # the hard-coded .CSV file +--error ER_CRASHED_ON_USAGE +SELECT * FROM t1; + +DROP TABLE t1; + +--echo # Test for the case when a field ends with a quote, but does not begin in a +--echo # quote. +--echo # Note: This results in an error. + +CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv; + +--echo # remove the already existing .CSV file if any +--remove_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # create the .CSV file that contains the hard-coded data used in +--echo # testing +--write_file $MYSQLD_DATADIR/test/t1.CSV +1,string with only ending quotes" +EOF +--cat_file $MYSQLD_DATADIR/test/t1.CSV + +--echo # select from the table in which the data has been filled in using +--echo # the hard-coded .CSV file +--error ER_CRASHED_ON_USAGE +SELECT * FROM t1; + +DROP TABLE t1; --echo End of 5.1 tests diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 9cc0f1e607b..fac78986563 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -614,6 +614,33 @@ int ha_tina::find_current_row(uchar *buf) memset(buf, 0, table->s->null_bytes); + /* + Parse the line obtained using the following algorithm + + BEGIN + 1) Store the EOL (end of line) for the current row + 2) Until all the fields in the current query have not been + filled + 2.1) If the current character is a quote + 2.1.1) Until EOL has not been reached + a) If end of current field is reached, move + to next field and jump to step 2.3 + b) If current character is a \\ handle + \\n, \\r, \\, \\" + c) else append the current character into the buffer + before checking that EOL has not been reached. + 2.2) If the current character does not begin with a quote + 2.2.1) Until EOL has not been reached + a) If the end of field has been reached move to the + next field and jump to step 2.3 + b) If current character begins with \\ handle + \\n, \\r, \\, \\" + c) else append the current character into the buffer + before checking that EOL has not been reached. + 2.3) Store the current field value and jump to 2) + TERMINATE + */ + for (Field **field=table->field ; *field ; field++) { char curr_char; @@ -622,19 +649,23 @@ int ha_tina::find_current_row(uchar *buf) if (curr_offset >= end_offset) goto err; curr_char= file_buff->get_value(curr_offset); + /* Handle the case where the first character is a quote */ if (curr_char == '"') { - curr_offset++; // Incrementpast the first quote + /* Increment past the first quote */ + curr_offset++; - for(; curr_offset < end_offset; curr_offset++) + /* Loop through the row to extract the values for the current field */ + for ( ; curr_offset < end_offset; curr_offset++) { curr_char= file_buff->get_value(curr_offset); - // Need to convert line feeds! + /* check for end of the current field */ if (curr_char == '"' && (curr_offset == end_offset - 1 || file_buff->get_value(curr_offset + 1) == ',')) { - curr_offset+= 2; // Move past the , and the " + /* Move past the , and the " */ + curr_offset+= 2; break; } if (curr_char == '\\' && curr_offset != (end_offset - 1)) @@ -656,7 +687,7 @@ int ha_tina::find_current_row(uchar *buf) else // ordinary symbol { /* - We are at final symbol and no last quote was found => + If we are at final symbol and no last quote was found => we are working with a damaged file. */ if (curr_offset == end_offset - 1) @@ -667,15 +698,41 @@ int ha_tina::find_current_row(uchar *buf) } else { - for(; curr_offset < end_offset; curr_offset++) + for ( ; curr_offset < end_offset; curr_offset++) { curr_char= file_buff->get_value(curr_offset); + /* Move past the ,*/ if (curr_char == ',') { - curr_offset++; // Skip the , + curr_offset++; break; } - buffer.append(curr_char); + if (curr_char == '\\' && curr_offset != (end_offset - 1)) + { + curr_offset++; + curr_char= file_buff->get_value(curr_offset); + if (curr_char == 'r') + buffer.append('\r'); + else if (curr_char == 'n' ) + buffer.append('\n'); + else if (curr_char == '\\' || curr_char == '"') + buffer.append(curr_char); + else /* This could only happed with an externally created file */ + { + buffer.append('\\'); + buffer.append(curr_char); + } + } + else + { + /* + We are at the final symbol and a quote was found for the + unquoted field => We are working with a damaged field. + */ + if (curr_offset == end_offset - 1 && curr_char == '"') + goto err; + buffer.append(curr_char); + } } } From e8d0168475c73058fa09cd80c23eb5b64d0401cc Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 7 Dec 2009 16:22:51 +0400 Subject: [PATCH 5/7] WL#2511 - Add a new table to the Information Schema for TABLESPACE's Implemented a new INFORMATION_SCHEMA table, which is intended to provide information about tablespaces. mysql-test/r/information_schema.result: Updated test result according to WL#2511. With this WL I_S has new TABLESPACES schema. mysql-test/r/information_schema_db.result: Updated test result according to WL#2511. With this WL I_S has new TABLESPACES schema. mysql-test/r/mysqlshow.result: Updated test result according to WL#2511. With this WL I_S has new TABLESPACES schema. mysql-test/suite/funcs_1/r/is_columns_is.result: Updated test result according to WL#2511. With this WL I_S has new TABLESPACES schema. mysql-test/suite/funcs_1/r/is_tables_is.result: Updated test result according to WL#2511. With this WL I_S has new TABLESPACES schema. sql/handler.h: Added SCH_TABLESPACES to enum_schema_tables. sql/mysql_priv.h: Added human readable definitions for I_S.TABLESPACES field identifiers. sql/sql_show.cc: Added I_S.TABLESPACES schema. The code which handles I_S.FILES is capable to handle I_S.TABLESPACES as well. Thus we reuse this code and let functions/variables have more generic names. --- mysql-test/r/information_schema.result | 10 +++- mysql-test/r/information_schema_db.result | 2 + mysql-test/r/mysqlshow.result | 2 + .../suite/funcs_1/r/is_columns_is.result | 18 ++++++++ .../suite/funcs_1/r/is_tables_is.result | 46 +++++++++++++++++++ sql/handler.h | 1 + sql/mysql_priv.h | 11 +++++ sql/sql_show.cc | 43 +++++++++++++---- 8 files changed, 123 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 04234eb3cc4..ea0f28d123d 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -65,6 +65,7 @@ SESSION_STATUS SESSION_VARIABLES STATISTICS TABLES +TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS @@ -103,6 +104,7 @@ inner join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name TABLES TABLES +TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TRIGGERS TRIGGERS @@ -122,6 +124,7 @@ left join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name TABLES TABLES +TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TRIGGERS TRIGGERS @@ -141,6 +144,7 @@ right join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name TABLES TABLES +TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TRIGGERS TRIGGERS @@ -628,6 +632,7 @@ COLLATIONS SYSTEM VIEW MEMORY show tables from information_schema like "T%"; Tables_in_information_schema (T%) TABLES +TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS @@ -637,6 +642,7 @@ use information_schema; show full tables like "T%"; Tables_in_information_schema (T%) Table_type TABLES SYSTEM VIEW +TABLESPACES SYSTEM VIEW TABLE_CONSTRAINTS SYSTEM VIEW TABLE_PRIVILEGES SYSTEM VIEW TRIGGERS SYSTEM VIEW @@ -649,6 +655,7 @@ use information_schema; show tables like "T%"; Tables_in_information_schema (T%) TABLES +TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS @@ -855,7 +862,7 @@ table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name not like 'ndb%' AND table_name not like 'innodb_%' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 28 +information_schema 29 mysql 22 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row @@ -1317,6 +1324,7 @@ SESSION_STATUS information_schema.SESSION_STATUS 1 SESSION_VARIABLES information_schema.SESSION_VARIABLES 1 STATISTICS information_schema.STATISTICS 1 TABLES information_schema.TABLES 1 +TABLESPACES information_schema.TABLESPACES 1 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 TRIGGERS information_schema.TRIGGERS 1 diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index bed73d9faf7..bb75bdfff60 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -28,6 +28,7 @@ SESSION_STATUS SESSION_VARIABLES STATISTICS TABLES +TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS @@ -36,6 +37,7 @@ VIEWS show tables from INFORMATION_SCHEMA like 'T%'; Tables_in_information_schema (T%) TABLES +TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index 4eb3383952c..1313d573af2 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -102,6 +102,7 @@ Database: information_schema | SESSION_VARIABLES | | STATISTICS | | TABLES | +| TABLESPACES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TRIGGERS | @@ -142,6 +143,7 @@ Database: INFORMATION_SCHEMA | SESSION_VARIABLES | | STATISTICS | | TABLES | +| TABLESPACES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TRIGGERS | diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index e10c775c227..6c11f1d2524 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -252,6 +252,15 @@ def information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 u def information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select def information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +def information_schema TABLESPACES AUTOEXTEND_SIZE 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +def information_schema TABLESPACES ENGINE 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema TABLESPACES EXTENT_SIZE 5 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +def information_schema TABLESPACES LOGFILE_GROUP_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema TABLESPACES MAXIMUM_SIZE 7 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +def information_schema TABLESPACES NODEGROUP_ID 8 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +def information_schema TABLESPACES TABLESPACE_COMMENT 9 NULL YES varchar 2048 6144 NULL NULL utf8 utf8_general_ci varchar(2048) select +def information_schema TABLESPACES TABLESPACE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema TABLESPACES TABLESPACE_TYPE 3 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -607,6 +616,15 @@ NULL information_schema TABLES CHECK_TIME datetime NULL NULL NULL NULL datetime NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) unsigned 3.0000 information_schema TABLES CREATE_OPTIONS varchar 255 765 utf8 utf8_general_ci varchar(255) 3.0000 information_schema TABLES TABLE_COMMENT varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema TABLESPACES TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema TABLESPACES ENGINE varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema TABLESPACES TABLESPACE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema TABLESPACES LOGFILE_GROUP_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +NULL information_schema TABLESPACES EXTENT_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema TABLESPACES AUTOEXTEND_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema TABLESPACES MAXIMUM_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema TABLESPACES NODEGROUP_ID bigint NULL NULL NULL NULL bigint(21) unsigned +3.0000 information_schema TABLESPACES TABLESPACE_COMMENT varchar 2048 6144 utf8 utf8_general_ci varchar(2048) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 552ac560741..13b5218fc2f 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -521,6 +521,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME TABLESPACES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME TABLE_CONSTRAINTS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -1159,6 +1182,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME TABLESPACES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME TABLE_CONSTRAINTS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/sql/handler.h b/sql/handler.h index 957729a7bf0..484d93e527d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -546,6 +546,7 @@ enum enum_schema_tables SCH_STATISTICS, SCH_STATUS, SCH_TABLES, + SCH_TABLESPACES, SCH_TABLE_CONSTRAINTS, SCH_TABLE_NAMES, SCH_TABLE_PRIVILEGES, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6d97bfe3f16..81b85fac1ae 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2458,6 +2458,17 @@ inline void kill_delayed_threads(void) {} #define IS_FILES_CHECKSUM 35 #define IS_FILES_STATUS 36 #define IS_FILES_EXTRA 37 + +#define IS_TABLESPACES_TABLESPACE_NAME 0 +#define IS_TABLESPACES_ENGINE 1 +#define IS_TABLESPACES_TABLESPACE_TYPE 2 +#define IS_TABLESPACES_LOGFILE_GROUP_NAME 3 +#define IS_TABLESPACES_EXTENT_SIZE 4 +#define IS_TABLESPACES_AUTOEXTEND_SIZE 5 +#define IS_TABLESPACES_MAXIMUM_SIZE 6 +#define IS_TABLESPACES_NODEGROUP_ID 7 +#define IS_TABLESPACES_TABLESPACE_COMMENT 8 + void init_fill_schema_files_row(TABLE* table); bool schema_table_store_record(THD *thd, TABLE *table); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b6bfac99dd5..bef367f63d0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6252,17 +6252,17 @@ bool get_schema_tables_result(JOIN *join, DBUG_RETURN(result); } -struct run_hton_fill_schema_files_args +struct run_hton_fill_schema_table_args { TABLE_LIST *tables; COND *cond; }; -static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin, +static my_bool run_hton_fill_schema_table(THD *thd, plugin_ref plugin, void *arg) { - struct run_hton_fill_schema_files_args *args= - (run_hton_fill_schema_files_args *) arg; + struct run_hton_fill_schema_table_args *args= + (run_hton_fill_schema_table_args *) arg; handlerton *hton= plugin_data(plugin, handlerton *); if (hton->fill_is_table && hton->state == SHOW_OPTION_YES) hton->fill_is_table(hton, thd, args->tables, args->cond, @@ -6270,15 +6270,15 @@ static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin, return false; } -int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond) +int hton_fill_schema_table(THD *thd, TABLE_LIST *tables, COND *cond) { - DBUG_ENTER("fill_schema_files"); + DBUG_ENTER("hton_fill_schema_table"); - struct run_hton_fill_schema_files_args args; + struct run_hton_fill_schema_table_args args; args.tables= tables; args.cond= cond; - plugin_foreach(thd, run_hton_fill_schema_files, + plugin_foreach(thd, run_hton_fill_schema_table, MYSQL_STORAGE_ENGINE_PLUGIN, &args); DBUG_RETURN(0); @@ -6860,6 +6860,29 @@ ST_FIELD_INFO referential_constraints_fields_info[]= }; +ST_FIELD_INFO tablespaces_fields_info[]= +{ + {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, + {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLESPACE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, + 0, SKIP_OPEN_TABLE}, + {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, + 0, SKIP_OPEN_TABLE}, + {"EXTENT_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, + MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE}, + {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, + MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE}, + {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, + MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE}, + {"NODEGROUP_ID", 21, MYSQL_TYPE_LONGLONG, 0, + MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE}, + {"TABLESPACE_COMMENT", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, + SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} +}; + + /* Description of ST_FIELD_INFO in table.h @@ -6890,7 +6913,7 @@ ST_SCHEMA_TABLE schema_tables[]= 0, make_old_format, 0, -1, -1, 0, 0}, #endif {"FILES", files_fields_info, create_schema_table, - fill_schema_files, 0, 0, -1, -1, 0, 0}, + hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, {"GLOBAL_STATUS", variables_fields_info, create_schema_table, fill_status, make_old_format, 0, 0, -1, 0, 0}, {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, @@ -6931,6 +6954,8 @@ ST_SCHEMA_TABLE schema_tables[]= {"TABLES", tables_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, OPTIMIZE_I_S_TABLE}, + {"TABLESPACES", tablespaces_fields_info, create_schema_table, + hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, From 6b8cd32eaa0e4bcbe2e5031cbb465f6a6036bc58 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 9 Dec 2009 11:33:28 +0400 Subject: [PATCH 6/7] An addition to backport of WL#3951 - MyISAM: Additional Error Logs for Data Corruption Fixed partition_repair_myisam.test. mysql-test/suite/parts/t/partition_repair_myisam.test: Suppress some extra warnings produced by MyISAM. --- mysql-test/suite/parts/t/partition_repair_myisam.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/parts/t/partition_repair_myisam.test b/mysql-test/suite/parts/t/partition_repair_myisam.test index a7ceb5b7faf..146e52db092 100644 --- a/mysql-test/suite/parts/t/partition_repair_myisam.test +++ b/mysql-test/suite/parts/t/partition_repair_myisam.test @@ -3,6 +3,8 @@ --disable_warnings --disable_query_log drop table if exists t1_will_crash; +call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:"); +call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table"); --enable_query_log --enable_warnings From 9b0e649a2ca37e7ac6a17e12e130b9162687f660 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 10 Dec 2009 13:19:06 +0400 Subject: [PATCH 7/7] After merge fix: pthread_mutext_[un]lock -> mysql_mutex_[un]lock. --- storage/myisam/ha_myisam.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index d0db7e785f3..33678e9677b 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -561,7 +561,7 @@ void _mi_report_crashed(MI_INFO *file, const char *message, THD *cur_thd; LIST *element; char buf[1024]; - pthread_mutex_lock(&file->s->intern_lock); + mysql_mutex_lock(&file->s->intern_lock); if ((cur_thd= (THD*) file->in_use.data)) sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id, sfile, sline); @@ -575,7 +575,7 @@ void _mi_report_crashed(MI_INFO *file, const char *message, sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0) : "Unknown thread accessing table"); } - pthread_mutex_unlock(&file->s->intern_lock); + mysql_mutex_unlock(&file->s->intern_lock); } }