diff options
author | unknown <monty@donna.mysql.com> | 2000-09-12 03:02:33 +0300 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2000-09-12 03:02:33 +0300 |
commit | fe4cccd6a43496395ec52e9043cd4350e5eac69d (patch) | |
tree | 051686baf31e5363765879f2437ada3abea6b71b /sql | |
parent | 1dc6a46936306fbccaf19275e6f9dc4acc1e48a1 (diff) | |
download | mariadb-git-fe4cccd6a43496395ec52e9043cd4350e5eac69d.tar.gz |
Update to new root alloc, OPTIMIZE TABLE and some other changes
Docs/manual.texi:
Added chapter for binary log, updated the changelog, linux section, OPTIMIZE TABLE...
client/mysqladmin.c:
Fixed bug with pid-file handling.
client/mysqldump.c:
Version change
configure.in:
Version change
include/Makefile.am:
Fix for SCO to get sched.h removed.
include/global.h:
Increased MY_NFILE; Added thread_safe_increment
include/my_sys.h:
Better root_alloc
include/mysql.h:
Better root_alloc
include/mysys_err.h:
Fix for PREAD/PWRITE on windows
libmysql/libmysql.c:
Better root_alloc
myisam/mi_locking.c:
Fix for PREAD/PWRITE on windows
myisam/mi_static.c:
Fix for PREAD/PWRITE on windows
mysys/default.c:
Better root_alloc
mysys/errors.c:
Fix for PREAD/PWRITE on windows
mysys/my_alloc.c:
Better root_alloc
mysys/my_create.c:
Fix for PREAD/PWRITE on windows
mysys/my_fopen.c:
Fix for PREAD/PWRITE on windows
mysys/my_open.c:
Fix for PREAD/PWRITE on windows
mysys/my_pread.c:
Fix for PREAD/PWRITE on windows
mysys/tree.c:
Better root_alloc
readline/bind.c:
Removed compiler warning
readline/isearch.c:
Removed compiler warning
scripts/safe_mysqld.sh:
Allow use of MYSQL_UNIX_PORT and MYSQL_TCP_PORT
sql-bench/crash-me.sh:
Version change
sql-bench/limits/mysql-3.23.cfg:
Update to latest MySQL version
sql/filesort.cc:
Added more statistics
sql/ha_berkeley.h:
Fixed bug with ORDER BY
sql/ha_myisam.cc:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/ha_myisam.h:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/handler.cc:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/handler.h:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/item_func.cc:
Fixed comment
sql/item_timefunc.cc:
Fixed possible month bug
sql/mini_client.cc:
Use of new root_alloc
sql/mysql_priv.h:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/mysqld.cc:
Added more statistics
sql/opt_range.cc:
Use of new root_alloc
sql/slave.cc:
Use of new root_alloc
sql/sql_acl.cc:
Use of new root_alloc
sql/sql_class.cc:
Use of new root_alloc
sql/sql_parse.cc:
Use of new root_alloc
sql/sql_select.cc:
Added more statistics
sql/sql_table.cc:
Added OPTIMIZE TABLE and cleaned up the repair code
sql/sql_udf.cc:
Use of new root_alloc
sql/sql_yacc.yy:
Fixed that OPTIMIZE TABLE can take many tables as arguments
sql/table.cc:
Use of new root_alloc
sql/thr_malloc.cc:
Use of new root_alloc
support-files/mysql.server.sh:
Removed usage of AWK
Diffstat (limited to 'sql')
-rw-r--r-- | sql/filesort.cc | 12 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 13 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 128 | ||||
-rw-r--r-- | sql/ha_myisam.h | 5 | ||||
-rw-r--r-- | sql/handler.cc | 14 | ||||
-rw-r--r-- | sql/handler.h | 37 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 2 | ||||
-rw-r--r-- | sql/mini_client.cc | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 12 | ||||
-rw-r--r-- | sql/mysqld.cc | 37 | ||||
-rw-r--r-- | sql/opt_range.cc | 10 | ||||
-rw-r--r-- | sql/slave.cc | 6 | ||||
-rw-r--r-- | sql/sql_acl.cc | 12 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 55 | ||||
-rw-r--r-- | sql/sql_select.cc | 25 | ||||
-rw-r--r-- | sql/sql_table.cc | 255 | ||||
-rw-r--r-- | sql/sql_udf.cc | 6 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 9 | ||||
-rw-r--r-- | sql/table.cc | 6 | ||||
-rw-r--r-- | sql/thr_malloc.cc | 4 |
22 files changed, 312 insertions, 345 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index ae07bec3323..96ce57fc683 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -115,7 +115,15 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, param.ref_length= table[0]->file->ref_length; param.sort_length=sortlength(sortorder,s_length)+ param.ref_length; param.max_rows= max_rows; - + + if (select && select->quick) + { + statistic_increment(filesort_range_count, &LOCK_status); + } + else + { + statistic_increment(filesort_scan_count, &LOCK_status); + } if (select && my_b_inited(&select->file)) { records=special=select->records; /* purecov: deadcode */ @@ -261,6 +269,8 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, } if (error) my_error(ER_FILSORT_ABORT,MYF(ME_ERROR+ME_WAITTANG)); + else + statistic_add(filesort_rows, records, &LOCK_status); #ifdef SKIPP_DBUG_IN_FILESORT DBUG_POP(); /* Ok to DBUG */ diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 9a8872b5df0..adea939bf61 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -66,12 +66,13 @@ class ha_berkeley: public handler public: ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), - int_option_flag(HA_READ_NEXT+HA_READ_PREV+ - HA_KEYPOS_TO_RNDPOS+ HA_READ_ORDER+ HA_LASTKEY_ORDER+ - HA_LONGLONG_KEYS+ HA_NULL_KEY + - HA_BLOB_KEY + - HA_REQUIRE_PRIMARY_KEY + HA_NOT_EXACT_COUNT + - HA_PRIMARY_KEY_IN_READ_INDEX + HA_DROP_BEFORE_CREATE), + int_option_flag(HA_READ_NEXT | HA_READ_PREV | + HA_REC_NOT_IN_SEQ | + HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | + HA_LONGLONG_KEYS | HA_NULL_KEY | + HA_BLOB_KEY | + HA_REQUIRE_PRIMARY_KEY | HA_NOT_EXACT_COUNT | + HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE), last_dup_key((uint) -1) { } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index ca9f58628e1..2c89b5303ac 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -30,10 +30,6 @@ #include "../myisam/myisamdef.h" #endif -#if !defined(HAVE_PREAD) -pthread_mutex_t THR_LOCK_keycache; -#endif - ulong myisam_sort_buffer_size; /***************************************************************************** @@ -228,7 +224,7 @@ int ha_myisam::write_row(byte * buf) int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { - if (!file) return HA_CHECK_INTERNAL_ERROR; + if (!file) return HA_ADMIN_INTERNAL_ERROR; int error ; MI_CHECK param; MYISAM_SHARE* share = file->s; @@ -249,7 +245,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) STATE_CRASHED_ON_REPAIR)) && share->state.open_count == 0) || ((param.testflag & T_FAST) && share->state.open_count == 0))) - return HA_CHECK_ALREADY_CHECKED; + return HA_ADMIN_ALREADY_DONE; error = chk_size(¶m, file); if (!error) @@ -277,17 +273,11 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; pthread_mutex_lock(&share->intern_lock); -#ifndef HAVE_PREAD - pthread_mutex_lock(&THR_LOCK_keycache); // QQ; Has to be removed! -#endif share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | STATE_CRASHED_ON_REPAIR); if (!(table->db_stat & HA_READ_ONLY)) error=update_state_info(¶m,file,UPDATE_TIME | UPDATE_OPEN_COUNT | UPDATE_STAT); -#ifndef HAVE_PREAD - pthread_mutex_unlock(&THR_LOCK_keycache);// QQ; Has to be removed! -#endif pthread_mutex_unlock(&share->intern_lock); info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE | HA_STATUS_CONST); @@ -299,7 +289,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; } - return error ? HA_CHECK_CORRUPT : HA_CHECK_OK; + return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } @@ -309,7 +299,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) two threads may do an analyze at the same time! */ -int ha_myisam::analyze(THD *thd) +int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) { int error=0; MI_CHECK param; @@ -323,62 +313,104 @@ int ha_myisam::analyze(THD *thd) T_DONT_CHECK_CHECKSUM); param.using_global_keycache = 1; - if (share->state.changed & STATE_NOT_ANALYZED) + if (!(share->state.changed & STATE_NOT_ANALYZED)) + return HA_ADMIN_ALREADY_DONE; + + error = chk_key(¶m, file); + if (!error) { - error = chk_key(¶m, file); - if (!error) - { - pthread_mutex_lock(&share->intern_lock); -#ifndef HAVE_PREAD - pthread_mutex_lock(&THR_LOCK_keycache); // QQ; Has to be removed! -#endif - error=update_state_info(¶m,file,UPDATE_STAT); -#ifndef HAVE_PREAD - pthread_mutex_unlock(&THR_LOCK_keycache);// QQ; Has to be removed! -#endif - pthread_mutex_unlock(&share->intern_lock); - } - else if (!mi_is_crashed(file)) - mi_mark_crashed(file); + pthread_mutex_lock(&share->intern_lock); + error=update_state_info(¶m,file,UPDATE_STAT); + pthread_mutex_unlock(&share->intern_lock); } - return error ? HA_CHECK_CORRUPT : HA_CHECK_OK; + else if (!mi_is_crashed(file)) + mi_mark_crashed(file); + return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { - if (!file) return HA_CHECK_INTERNAL_ERROR; + if (!file) return HA_ADMIN_INTERNAL_ERROR; MI_CHECK param; myisamchk_init(¶m); param.thd = thd; param.op_name = (char*) "repair"; - param.testflag = (check_opt->flags | T_SILENT|T_FORCE_CREATE|T_REP_BY_SORT| - T_STATISTICS); + param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE | + T_REP_BY_SORT); if (check_opt->quick) param.opt_rep_quick++; param.sort_buffer_length= check_opt->sort_buffer_size; - return repair(thd,param); + return repair(thd,param,0); +} + +int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) +{ + if (!file) return HA_ADMIN_INTERNAL_ERROR; + MI_CHECK param; + + myisamchk_init(¶m); + param.thd = thd; + param.op_name = (char*) "optimize"; + param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE | + T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX); + param.opt_rep_quick++; + param.sort_buffer_length= check_opt->sort_buffer_size; + return repair(thd,param,1); } -int ha_myisam::repair(THD *thd, MI_CHECK ¶m) +int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) { - int error; + int error=0; + bool optimize_done= !optimize; char fixed_name[FN_REFLEN]; + const char *old_proc_info=thd->proc_info; MYISAM_SHARE* share = file->s; param.table_name = table->table_name; param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; param.thd=thd; - + VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT, 4+ (param.opt_follow_links ? 16 : 0))); - if (mi_test_if_sort_rep(file,file->state->records)) - error = mi_repair_by_sort(¶m, file, fixed_name, param.opt_rep_quick); - else - error= mi_repair(¶m, file, fixed_name, param.opt_rep_quick); + + if (!optimize || file->state->del || + share->state.split != file->state->records) + { + optimize_done=1; + if (mi_test_if_sort_rep(file,file->state->records)) + { + param.testflag|= T_STATISTICS; // We get this for free + thd->proc_info="Repairing by sorting"; + error = mi_repair_by_sort(¶m, file, fixed_name, param.opt_rep_quick); + } + else + { + thd->proc_info="Repairing"; + error= mi_repair(¶m, file, fixed_name, param.opt_rep_quick); + } + } + if (!error) + { + if ((param.testflag & T_SORT_INDEX) && + (share->state.changed & STATE_NOT_SORTED_PAGES)) + { + optimize_done=1; + thd->proc_info="Sorting index"; + error=mi_sort_index(¶m,file,fixed_name); + } + if ((param.testflag & T_STATISTICS) && + (share->state.changed & STATE_NOT_ANALYZED)) + { + optimize_done=1; + thd->proc_info="Analyzing"; + error = chk_key(¶m, file); + } + } + thd->proc_info="saving state"; if (!error) { if (share->state.changed & STATE_CHANGED) @@ -390,7 +422,10 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m) file->save_state=file->s->state.state; if (file->s->base.auto_key) update_auto_increment_key(¶m, file, 1); - error = update_state_info(¶m, file, UPDATE_TIME|UPDATE_STAT); + error = update_state_info(¶m, file, + UPDATE_TIME | + (param.testflag & T_STATISTICS ? + UPDATE_STAT : 0)); info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE | HA_STATUS_CONST); } @@ -407,6 +442,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m) We have to close all instances of this file to ensure that we can do the rename safely and that all threads are using the new version. */ + thd->proc_info="renaming file"; VOID(pthread_mutex_lock(&LOCK_open)); if (close_cached_table(thd,table)) error=1; @@ -421,7 +457,9 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m) VOID(pthread_mutex_unlock(&LOCK_open)); } } - return error ? HA_REPAIR_FAILED : HA_REPAIR_OK; + thd->proc_info=old_proc_info; + return (error ? HA_ADMIN_FAILED : + !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK); } @@ -451,7 +489,7 @@ bool ha_myisam::activate_all_index(THD *thd) param.myf_rw&= ~MY_WAIT_IF_FULL; param.sort_buffer_length= myisam_sort_buffer_size; param.opt_rep_quick++; - error=repair(thd,param) != HA_CHECK_OK; + error=repair(thd,param,0) != HA_ADMIN_OK; thd->proc_info=save_proc_info; } DBUG_RETURN(error); diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index c065c60825d..c8f097e792f 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -30,7 +30,7 @@ class ha_myisam: public handler { MI_INFO *file; uint int_option_flag; - int repair(THD *thd, MI_CHECK ¶m); + int repair(THD *thd, MI_CHECK ¶m, bool optimize); public: ha_myisam(TABLE *table): handler(table), file(0), @@ -93,8 +93,9 @@ class ha_myisam: public handler int rename_table(const char * from, const char * to); int delete_table(const char *name); int check(THD* thd, HA_CHECK_OPT* check_opt); - int analyze(THD* thd); + int analyze(THD* thd,HA_CHECK_OPT* check_opt); int repair(THD* thd, HA_CHECK_OPT* check_opt); + int optimize(THD* thd, HA_CHECK_OPT* check_opt); int dump(THD* thd, int fd); int net_read_dump(NET* net); }; diff --git a/sql/handler.cc b/sql/handler.cc index 17388267fb9..ed4613d754f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -318,7 +318,7 @@ int handler::ha_open(const char *name, int mode, int test_if_locked) if (!error) { if (!alloc_root_inited(&table->mem_root)) // If temporary table - ref=sql_alloc(ALIGN_SIZE(ref_length)*2); + ref=(byte*) sql_alloc(ALIGN_SIZE(ref_length)*2); else ref=(byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2); if (!ref) @@ -334,22 +334,22 @@ int handler::ha_open(const char *name, int mode, int test_if_locked) int handler::check(THD* thd, HA_CHECK_OPT* check_opt) { - return HA_CHECK_NOT_IMPLEMENTED; + return HA_ADMIN_NOT_IMPLEMENTED; } int handler::repair(THD* thd, HA_CHECK_OPT* check_opt) { - return HA_REPAIR_NOT_IMPLEMENTED; + return HA_ADMIN_NOT_IMPLEMENTED; } -int handler::optimize(THD* thd) +int handler::optimize(THD* thd, HA_CHECK_OPT* check_opt) { - return HA_OPTIMIZE_NOT_IMPLEMENTED; + return HA_ADMIN_NOT_IMPLEMENTED; } -int handler::analyze(THD* thd) +int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt) { - return HA_ANALYZE_NOT_IMPLEMENTED; + return HA_ADMIN_NOT_IMPLEMENTED; } /* Read first row from a table */ diff --git a/sql/handler.h b/sql/handler.h index 08bf355b60e..70b05f0c7f7 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -27,26 +27,12 @@ // the following is for checking tables -#define HA_CHECK_ALREADY_CHECKED 1 -#define HA_CHECK_OK 0 -#define HA_CHECK_NOT_IMPLEMENTED -1 -#define HA_CHECK_CORRUPT -2 -#define HA_CHECK_INTERNAL_ERROR -3 - -#define HA_REPAIR_OK 0 -#define HA_REPAIR_NOT_IMPLEMENTED -1 -#define HA_REPAIR_FAILED -2 -#define HA_REPAIR_INTERNAL_ERROR -3 - -#define HA_OPTIMIZE_OK 0 -#define HA_OPTIMIZE_NOT_IMPLEMENTED -1 -#define HA_OPTIMIZE_FAILED -2 -#define HA_OPTIMIZE_INTERNAL_ERROR -3 - -#define HA_ANALYZE_OK 0 -#define HA_ANALYZE_NOT_IMPLEMENTED -1 -#define HA_ANALYZE_FAILED -2 -#define HA_ANALYZE_INTERNAL_ERROR -3 +#define HA_ADMIN_ALREADY_DONE 1 +#define HA_ADMIN_OK 0 +#define HA_ADMIN_NOT_IMPLEMENTED -1 +#define HA_ADMIN_FAILED -2 +#define HA_ADMIN_CORRUPT -3 +#define HA_ADMIN_INTERNAL_ERROR -4 /* Bits in bas_flag to show what database can do */ @@ -156,9 +142,10 @@ typedef struct st_ha_check_opt uint flags; bool quick; bool changed_files; + bool optimize; inline void init() { - flags= 0; quick= 0; + flags= 0; quick= optimize=0; sort_buffer_size = myisam_sort_buffer_size; } } HA_CHECK_OPT; @@ -257,10 +244,10 @@ public: virtual int delete_all_rows(); virtual longlong get_auto_increment(); virtual void update_create_info(HA_CREATE_INFO *create_info) {} - virtual int check(THD* thd, HA_CHECK_OPT* check_opt ); - virtual int repair(THD* thd, HA_CHECK_OPT* check_opt); - virtual int optimize(THD* thd); - virtual int analyze(THD* thd); + virtual int check(THD* thd, HA_CHECK_OPT* check_opt ); + virtual int repair(THD* thd, HA_CHECK_OPT* check_opt); + virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt); + virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt); virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; } virtual void deactivate_non_unique_index(ha_rows rows) {} virtual bool activate_all_index(THD *thd) {return 0;} diff --git a/sql/item_func.cc b/sql/item_func.cc index 65677690ed3..f80d084dc82 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1012,7 +1012,7 @@ longlong Item_func_bit_count::val_int() /**************************************************************************** ** Functions to handle dynamic loadable functions ** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su> -** Rewritten by: Monty. +** Rewritten by monty. ****************************************************************************/ #ifdef HAVE_DLOPEN diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 5b09f58d41e..49bce381901 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -134,7 +134,7 @@ longlong Item_func_month::val_int() String* Item_func_monthname::val_str(String* str) { uint month=(uint) Item_func_month::val_int(); - if (null_value) + if (!month) // This is also true for NULL return (String*) 0; return &month_names[month-1]; } diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 5cd0fe2c680..6ba2de57d2d 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -208,8 +208,9 @@ static void mc_free_old_query(MYSQL *mysql) { DBUG_ENTER("mc_free_old_query"); if (mysql->fields) - free_root(&mysql->field_alloc); - init_alloc_root(&mysql->field_alloc,8192); /* Assume rowlength < 8192 */ + free_root(&mysql->field_alloc,MYF(0)); + else + init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */ mysql->fields=0; mysql->field_count=0; /* For API */ DBUG_VOID_RETURN; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d9719b9bd68..3b5c87fcab2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -34,7 +34,7 @@ typedef ulong key_part_map; /* Used for finding key parts */ #include "mysql_com.h" #include "unireg.h" -void init_sql_alloc(MEM_ROOT *root,uint block_size); +void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size); gptr sql_alloc(unsigned size); gptr sql_calloc(unsigned size); char *sql_strdup(const char *str); @@ -243,9 +243,10 @@ int mysql_check_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); int mysql_repair_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); -int mysql_analyze_table(THD* thd, TABLE_LIST* table_list); -int mysql_optimize_table(THD* thd, TABLE_LIST* table_list); - +int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); /* net_pkg.c */ void send_error(NET *net,uint sql_errno=0, const char *err=0); @@ -434,6 +435,9 @@ extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables, delayed_insert_limit, delayed_queue_size, delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use,delayed_insert_errors; +extern ulong filesort_rows, filesort_range_count, filesort_scan_count; +extern ulong select_range_check_count, select_range_count, select_scan_count; +extern ulong select_full_range_join_count,select_full_join_count; extern uint test_flags,select_errors,mysql_port,ha_open_options; extern ulong thd_startup_options, slow_launch_threads, slow_launch_time; extern time_t start_time; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index af8d66cc046..4d3dc8de519 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -145,7 +145,7 @@ static pthread_t select_thread; static pthread_t flush_thread; // Used when debugging static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, - opt_ansi_mode; + opt_ansi_mode,opt_myisam_log=0; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0; // if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync, and are @@ -205,6 +205,9 @@ ulong query_id=1L,long_query_count,long_query_time,aborted_threads, aborted_connects,delayed_insert_timeout,delayed_insert_limit, delayed_queue_size,delayed_insert_threads,delayed_insert_writes, delayed_rows_in_use,delayed_insert_errors,flush_time; +ulong filesort_rows, filesort_range_count, filesort_scan_count; +ulong select_range_check_count, select_range_count, select_scan_count; +ulong select_full_range_join_count,select_full_join_count; ulong specialflag=0,opened_tables=0,created_tmp_tables=0, created_tmp_disk_tables=0; ulong max_connections,max_insert_delayed_threads,max_used_connections, @@ -579,7 +582,7 @@ void clean_up(void) udf_free(); #endif end_key_cache(); /* This is usually freed automaticly */ - (void) ha_panic(HA_PANIC_CLOSE); /* close all tables */ + (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ #ifdef USE_RAID end_raid(); #endif @@ -1481,6 +1484,8 @@ int main(int argc, char **argv) sql_print_error("Can't init databases"); exit(1); } + if (opt_myisam_log) + (void) mi_log( 1 ); ft_init_stopwords(ft_precompiled_stopwords); /* SerG */ #ifdef __WIN__ @@ -1509,7 +1514,9 @@ int main(int argc, char **argv) { select_thread_in_use=0; (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); +#ifndef __WIN__ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore +#endif exit(1); } if (!opt_noacl) @@ -1643,7 +1650,9 @@ int main(int argc, char **argv) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); } (void) pthread_mutex_unlock(&LOCK_thread_count); +#ifndef __WIN__ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore +#endif my_thread_end(); exit(0); return(0); /* purecov: deadcode */ @@ -2203,7 +2212,7 @@ static struct option long_options[] = { {"log", optional_argument, 0, 'l'}, {"language", required_argument, 0, 'L'}, {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG}, - {"log-bin-index", optional_argument, 0, (int) OPT_BIN_LOG_INDEX}, + {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX}, {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG}, {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG}, {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG}, @@ -2440,9 +2449,17 @@ struct show_var_st status_vars[]= { {"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST}, {"Opened_tables", (char*) &opened_tables, SHOW_LONG}, {"Questions", (char*) 0, SHOW_QUESTION}, + {"Select_full_join", (char*) &select_full_join_count, SHOW_LONG}, + {"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG}, + {"Select_range", (char*) &select_range_count, SHOW_LONG}, + {"Select_range_check", (char*) &select_range_check_count, SHOW_LONG}, + {"Select_scan", (char*) &select_scan_count, SHOW_LONG}, + {"Slave_running", (char*) &slave_running, SHOW_BOOL}, {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_queries", (char*) &long_query_count, SHOW_LONG}, - {"Slave_running", (char*) &slave_running, SHOW_BOOL}, + {"Sort_range", (char*) &filesort_range_count, SHOW_LONG}, + {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, + {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, @@ -2508,7 +2525,7 @@ static void usage(void) --log-bin-index=file File that holds the names for last binary log files\n\ --log-update[=file] Log updates to file.# where # is a unique number\n\ if not given.\n\ - --log-isam[=file] Log all isam changes to file\n\ + --log-isam[=file] Log all MyISAM changes to file\n\ --log-long-format Log some extra information to update log\n\ --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\ --log-slow-queries=[file]\n\ @@ -2583,7 +2600,9 @@ The default values (after parsing the command line arguments) are:\n\n"); printf("datadir: %s\n",mysql_real_data_home); printf("tmpdir: %s\n",mysql_tmpdir); printf("language: %s\n",language); +#ifndef __WIN__ printf("pid file: %s\n",pidfile_name); +#endif if (opt_logname) printf("logfile: %s\n",opt_logname); if (opt_update_logname) @@ -2739,9 +2758,9 @@ static void get_options(int argc,char **argv) thd_startup_options|=OPTION_BIG_TABLES; break; case (int) OPT_ISAM_LOG: + opt_myisam_log=1; if (optarg) - nisam_log_filename=optarg; - (void) nisam_log(1); + myisam_log_filename=optarg; break; case (int) OPT_UPDATE_LOG: opt_update_log=1; @@ -3168,8 +3187,8 @@ static int get_service_parameters() else if ( lstrcmp(szKeyValueName, TEXT("ISAMLogFile")) == 0 ) { CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - COPY_KEY_VALUE( nisam_log_filename ); - (void) nisam_log( 1 ); + COPY_KEY_VALUE( myisam_log_filename ); + opt_myisam_log=1; } else if ( lstrcmp(szKeyValueName, TEXT("LongLogFormat")) == 0 ) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 25ee26dbdbd..0ba5bd0cf8f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -387,7 +387,7 @@ QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc) { if (!no_alloc) { - init_sql_alloc(&alloc,1024); // Allocates everything here + init_sql_alloc(&alloc,1024,0); // Allocates everything here my_pthread_setspecific_ptr(THR_MALLOC,&alloc); } else @@ -400,7 +400,7 @@ QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc) QUICK_SELECT::~QUICK_SELECT() { file->index_end(); - free_root(&alloc); + free_root(&alloc,MYF(0)); } @@ -622,13 +622,13 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, param.keys=0; current_thd->no_errors=1; // Don't warn about NULL - init_sql_alloc(&alloc,2048); + init_sql_alloc(&alloc,2048,0); if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc, sizeof(KEY_PART)* head->key_parts))) { current_thd->no_errors=0; - free_root(&alloc); // Return memory & allocator + free_root(&alloc,MYF(0)); // Return memory & allocator DBUG_RETURN(0); // Can't use range } key_parts= param.key_parts; @@ -720,7 +720,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, } } } - free_root(&alloc); // Return memory & allocator + free_root(&alloc,MYF(0)); // Return memory & allocator my_pthread_setspecific_ptr(THR_MALLOC,old_root); current_thd->no_errors=0; } diff --git a/sql/slave.cc b/sql/slave.cc index 2f4f7c10714..b3486e7b97c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -559,7 +559,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) { Query_log_event* qev = (Query_log_event*)ev; int q_len = qev->q_len; - init_sql_alloc(&thd->mem_root, 8192); + init_sql_alloc(&thd->mem_root, 8192,0); thd->db = (char*)qev->db; if(db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { @@ -604,7 +604,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) thd->db = 0;// prevent db from being freed thd->query = 0; // just to be sure close_thread_tables(thd); - free_root(&thd->mem_root); + free_root(&thd->mem_root,0); if (thd->query_error) { sql_print_error("Slave: error running query '%s' ", @@ -628,7 +628,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) case LOAD_EVENT: { Load_log_event* lev = (Load_log_event*)ev; - init_sql_alloc(&thd->mem_root, 8192); + init_sql_alloc(&thd->mem_root, 8192,0); thd->db = (char*)lev->db; thd->query = 0; thd->query_error = 0; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3315893cbbb..6e1bfb23abe 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -156,7 +156,7 @@ int acl_init(bool dont_read_acl_tables) DBUG_RETURN(1); /* purecov: inspected */ } - init_sql_alloc(&mem,1024); + init_sql_alloc(&mem,1024,0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); VOID(init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) @@ -272,7 +272,7 @@ int acl_init(bool dont_read_acl_tables) void acl_free(bool end) { - free_root(&mem); + free_root(&mem,MYF(0)); delete_dynamic(&acl_hosts); delete_dynamic(&acl_users); delete_dynamic(&acl_dbs); @@ -323,7 +323,7 @@ void acl_reload(void) } else { - free_root(&old_mem); + free_root(&old_mem,MYF(0)); delete_dynamic(&old_acl_hosts); delete_dynamic(&old_acl_users); delete_dynamic(&old_acl_dbs); @@ -1845,7 +1845,7 @@ void grant_free(void) DBUG_ENTER("grant_free"); grant_option = FALSE; hash_free(&hash_tables); - free_root(&memex); + free_root(&memex,MYF(0)); DBUG_VOID_RETURN; } @@ -1863,7 +1863,7 @@ int grant_init (void) grant_option = FALSE; (void) hash_init(&hash_tables,0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); - init_sql_alloc(&memex,1024); + init_sql_alloc(&memex,1024,0); if (!initialized) DBUG_RETURN(0); /* purecov: tested */ @@ -1965,7 +1965,7 @@ void grant_reload(void) else { hash_free(&old_hash_tables); - free_root(&old_mem); + free_root(&old_mem,MYF(0)); } pthread_mutex_unlock(&LOCK_grant); DBUG_VOID_RETURN; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a310ac88421..1c506e969f7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,7 +155,7 @@ THD::~THD() safeFree(user); safeFree(db); safeFree(ip); - free_root(&mem_root); + free_root(&mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) DBUG_VOID_RETURN; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 007e90e7ec0..2e559b54b48 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -394,11 +394,13 @@ pthread_handler_decl(handle_one_connection,arg) thd->proc_info=0; // Remove 'login' thd->version=refresh_version; thd->set_time(); + init_sql_alloc(&thd->mem_root,8192,8192); while (!net->error && net->vio != 0 && !thd->killed) { if (do_command(thd)) break; } + free_root(&thd->mem_root,MYF(0)); if (net->error && net->vio != 0) { sql_print_error(ER(ER_NEW_ABORTING_CONNECTION), @@ -453,13 +455,13 @@ int handle_bootstrap(THD *thd,FILE *file) thd->version=refresh_version; char *buff= (char*) thd->net.buff; + init_sql_alloc(&thd->mem_root,8192,8192); while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); while (length && (isspace(buff[length-1]) || buff[length-1] == ';')) length--; buff[length]=0; - init_sql_alloc(&thd->mem_root,8192); thd->current_tablenr=0; thd->query= thd->memdup(buff,length+1); thd->query_id=query_id++; @@ -469,8 +471,9 @@ int handle_bootstrap(THD *thd,FILE *file) { DBUG_RETURN(-1); } - free_root(&thd->mem_root); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); } + free_root(&thd->mem_root,MYF(0)); DBUG_RETURN(0); } @@ -537,7 +540,6 @@ bool do_command(THD *thd) enum enum_server_command command; DBUG_ENTER("do_command"); - init_sql_alloc(&thd->mem_root,8192); net= &thd->net; thd->current_tablenr=0; @@ -741,7 +743,7 @@ bool do_command(THD *thd) send_eof(net); // This is for 'quit request' close_connection(net); close_thread_tables(thd); // Free before kill - free_root(&thd->mem_root); + free_root(&thd->mem_root,MYF(0)); kill_mysql(); error=TRUE; break; @@ -822,7 +824,7 @@ bool do_command(THD *thd) thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(net_buffer_length); // Reclaim some memory - free_root(&thd->mem_root); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); DBUG_RETURN(error); } @@ -1191,33 +1193,34 @@ mysql_execute_command(void) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ - res = mysql_analyze_table(thd, tables); + res = mysql_analyze_table(thd, tables, &lex->check_opt); break; } + case SQLCOM_OPTIMIZE: { HA_CREATE_INFO create_info; - /* This is now done with ALTER TABLE, but should be done with isamchk */ - if (!tables->db) - tables->db=thd->db; - if (check_access(thd,SELECT_ACL | INSERT_ACL,tables->db, - &tables->grant.privilege)) + if (check_db_used(thd,tables) || + check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL,tables)) - goto error; - - lex->create_list.empty(); - lex->key_list.empty(); - lex->col_list.empty(); - lex->drop_list.empty(); - lex->alter_list.empty(); - bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type=DB_TYPE_DEFAULT; - create_info.row_type=ROW_TYPE_DEFAULT; - res= mysql_alter_table(thd, NullS, NullS, &create_info, - tables, lex->create_list, - lex->key_list, lex->drop_list, lex->alter_list, - 0,DUP_ERROR); + if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) + { + /* Use ALTER TABLE */ + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->drop_list.empty(); + lex->alter_list.empty(); + bzero((char*) &create_info,sizeof(create_info)); + create_info.db_type=DB_TYPE_DEFAULT; + create_info.row_type=ROW_TYPE_DEFAULT; + res= mysql_alter_table(thd, NullS, NullS, &create_info, + tables, lex->create_list, + lex->key_list, lex->drop_list, lex->alter_list, + 0,DUP_ERROR); + } + else + res = mysql_optimize_table(thd, tables, &lex->check_opt); break; } case SQLCOM_UPDATE: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d70dcc82df4..d9d3d90f0d8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2333,10 +2333,35 @@ make_join_readinfo(JOIN *join,uint options) } /* These init changes read_record */ if (tab->use_quick == 2) + { tab->read_first_record= join_init_quick_read_record; + statistic_increment(select_range_check_count, &LOCK_status); + } else { tab->read_first_record= join_init_read_record; + if (i == join->const_tables) + { + if (tab->select && tab->select->quick) + { + statistic_increment(select_range_count, &LOCK_status); + } + else + { + statistic_increment(select_scan_count, &LOCK_status); + } + } + else + { + if (tab->select && tab->select->quick) + { + statistic_increment(select_full_range_join_count, &LOCK_status); + } + else + { + statistic_increment(select_full_join_count, &LOCK_status); + } + } if (tab->select && tab->select->quick && table->used_keys & ((key_map) 1 << tab->select->quick->index)) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ce434fd43d7..a3da4daa9f4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -718,105 +718,19 @@ bool close_cached_table(THD *thd,TABLE *table) } -int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) -{ - TABLE_LIST *table; - List<Item> field_list; - Item* item; - String* packet = &thd->packet; - - DBUG_ENTER("mysql_repair_table"); - - field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Op", 10)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Msg_type", 10)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Msg_text", 255)); - item->maybe_null = 1; - if (send_fields(thd, field_list, 1)) - DBUG_RETURN(-1); - - - for (table = tables; table; table = table->next) - { - char table_name[NAME_LEN*2+2]; - char* db = (table->db) ? table->db : thd->db; - strxmov(table_name,db ? db : "",".",table->name,NullS); - - table->table = open_ltable(thd, table, TL_WRITE); - packet->length(0); - - if (!table->table) - { - const char *err_msg; - net_store_data(packet, table_name); - net_store_data(packet, "repair"); - net_store_data(packet, "error"); - if (!(err_msg=thd->net.last_error)) - err_msg=ER(ER_CHECK_NO_SUCH_TABLE); - net_store_data(packet, err_msg); - thd->net.last_error[0]=0; - if (my_net_write(&thd->net, (char*) thd->packet.ptr(), - packet->length())) - goto err; - continue; - } - - int repair_code = table->table->file->repair(thd, check_opt); - packet->length(0); - net_store_data(packet, table_name); - net_store_data(packet, "repair"); - - switch(repair_code) { - case HA_REPAIR_NOT_IMPLEMENTED: - net_store_data(packet, "error"); - net_store_data(packet, ER(ER_CHECK_NOT_IMPLEMENTED)); - break; - - case HA_REPAIR_OK: - net_store_data(packet, "status"); - net_store_data(packet, "OK"); - break; - - case HA_REPAIR_FAILED: - net_store_data(packet, "status"); - net_store_data(packet, "Not repaired"); - break; - - default: - net_store_data(packet, "Unknown - internal error during repair"); - break; - } - close_thread_tables(thd); - if (my_net_write(&thd->net, (char*) packet->ptr(), - packet->length())) - goto err; - } - - close_thread_tables(thd); - send_eof(&thd->net); - DBUG_RETURN(0); - err: - close_thread_tables(thd); - DBUG_RETURN(-1); -} - -int mysql_optimize_table(THD* thd, TABLE_LIST* tables) -{ - net_printf(&thd->net, ER_PARSE_ERROR, "Sorry; This doesn't work yet", "", - 0); - return 1; -} - -int mysql_analyze_table(THD* thd, TABLE_LIST* tables) +static int mysql_admin_table(THD* thd, TABLE_LIST* tables, + HA_CHECK_OPT* check_opt, + thr_lock_type lock_type, + bool open_for_modify, + const char *operator_name, + int (handler::*operator_func) + (THD *, HA_CHECK_OPT *)) { TABLE_LIST *table; List<Item> field_list; Item* item; String* packet = &thd->packet; - DBUG_ENTER("mysql_analyze_table"); + DBUG_ENTER("mysql_admin_table"); field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); item->maybe_null = 1; @@ -829,21 +743,20 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables) if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); - for (table = tables; table; table = table->next) { char table_name[NAME_LEN*2+2]; char* db = (table->db) ? table->db : thd->db; strxmov(table_name,db ? db : "",".",table->name,NullS); - table->table = open_ltable(thd, table, TL_READ_NO_INSERT); + table->table = open_ltable(thd, table, lock_type); packet->length(0); if (!table->table) { const char *err_msg; net_store_data(packet, table_name); - net_store_data(packet, "analyze"); + net_store_data(packet, operator_name); net_store_data(packet, "error"); if (!(err_msg=thd->net.last_error)) err_msg=ER(ER_CHECK_NO_SUCH_TABLE); @@ -854,126 +767,53 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables) goto err; continue; } - if (table->table->db_stat & HA_READ_ONLY) + if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { net_store_data(packet, table_name); - net_store_data(packet, "analyze"); + net_store_data(packet, operator_name); net_store_data(packet, "error"); net_store_data(packet, ER(ER_OPEN_AS_READONLY)); + close_thread_tables(thd); if (my_net_write(&thd->net, (char*) thd->packet.ptr(), packet->length())) goto err; continue; } - int analyze_code = table->table->file->analyze(thd); + int result_code = (table->table->file->*operator_func)(thd, check_opt); packet->length(0); net_store_data(packet, table_name); - net_store_data(packet, "analyze"); + net_store_data(packet, operator_name); - switch(analyze_code) { - case HA_ANALYZE_NOT_IMPLEMENTED: + switch (result_code) { + case HA_ADMIN_NOT_IMPLEMENTED: net_store_data(packet, "error"); net_store_data(packet, ER(ER_CHECK_NOT_IMPLEMENTED)); break; - case HA_ANALYZE_OK: + case HA_ADMIN_OK: net_store_data(packet, "status"); net_store_data(packet, "OK"); break; - default: - net_store_data(packet, "Unknown - internal error during analyze"); - break; - } - close_thread_tables(thd); - if (my_net_write(&thd->net, (char*) packet->ptr(), - packet->length())) - goto err; - } - - close_thread_tables(thd); - send_eof(&thd->net); - DBUG_RETURN(0); - err: - close_thread_tables(thd); - DBUG_RETURN(-1); -} - -int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) -{ - TABLE_LIST *table; - List<Item> field_list; - Item* item; - String* packet = &thd->packet; - - DBUG_ENTER("mysql_check_table"); - - field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Op", 10)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Msg_type", 10)); - item->maybe_null = 1; - field_list.push_back(item = new Item_empty_string("Msg_text", 255)); - item->maybe_null = 1; - if (send_fields(thd, field_list, 1)) - DBUG_RETURN(-1); - - - for (table = tables; table; table = table->next) - { - char table_name[NAME_LEN*2+2]; - char* db = (table->db) ? table->db : thd->db; - strxmov(table_name,db ? db : "",".",table->name,NullS); - - table->table = open_ltable(thd, table, TL_READ_NO_INSERT); - packet->length(0); - - if (!table->table) - { - const char *err_msg; - net_store_data(packet, table_name); - net_store_data(packet, "check"); - net_store_data(packet, "error"); - if (!(err_msg=thd->net.last_error)) - err_msg=ER(ER_CHECK_NO_SUCH_TABLE); - net_store_data(packet, err_msg); - thd->net.last_error[0]=0; - if (my_net_write(&thd->net, (char*) thd->packet.ptr(), - packet->length())) - goto err; - continue; - } - - int check_code = table->table->file->check(thd, check_opt); - packet->length(0); - net_store_data(packet, table_name); - net_store_data(packet, "check"); - - switch(check_code) { - case HA_CHECK_NOT_IMPLEMENTED: - net_store_data(packet, "error"); - net_store_data(packet, ER(ER_CHECK_NOT_IMPLEMENTED)); - break; - - case HA_CHECK_OK: + case HA_ADMIN_FAILED: net_store_data(packet, "status"); - net_store_data(packet, "OK"); + net_store_data(packet, "Operation failed"); break; - case HA_CHECK_ALREADY_CHECKED: + case HA_ADMIN_ALREADY_DONE: net_store_data(packet, "status"); - net_store_data(packet, "Not checked"); + net_store_data(packet, "Table is already up to date"); break; - case HA_CHECK_CORRUPT: - net_store_data(packet, "status"); + case HA_ADMIN_CORRUPT: + net_store_data(packet, "error"); net_store_data(packet, "Corrupt"); break; - default: - net_store_data(packet, "Unknown - internal error during check"); + default: // Probably HA_ADMIN_INTERNAL_ERROR + net_store_data(packet, "error"); + net_store_data(packet, "Unknown - internal error during operation"); break; } close_thread_tables(thd); @@ -982,15 +822,52 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) goto err; } - close_thread_tables(thd); send_eof(&thd->net); DBUG_RETURN(0); err: - close_thread_tables(thd); + close_thread_tables(thd); // Shouldn't be needed DBUG_RETURN(-1); } +int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +{ + DBUG_ENTER("mysql_repair_table"); + DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, + TL_WRITE, 1, + "repair", + &handler::repair)); +} + +int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +{ + DBUG_ENTER("mysql_optimize_table"); + DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, + TL_WRITE, 1, + "optimize", + &handler::optimize)); +} + + +int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +{ + DBUG_ENTER("mysql_analyze_table"); + DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, + TL_READ_NO_INSERT, 1, + "analyze", + &handler::analyze)); +} + + +int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) +{ + DBUG_ENTER("mysql_check_table"); + DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, + TL_READ_NO_INSERT, 0, + "check", + &handler::check)); +} + int mysql_alter_table(THD *thd,char *new_db, char *new_name, HA_CREATE_INFO *create_info, diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index e5508dafe37..75d796faf5e 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -107,14 +107,14 @@ void udf_init() pthread_mutex_init(&THR_LOCK_udf,NULL); - init_sql_alloc(&mem, 1024); + init_sql_alloc(&mem, 1024,0); THD *new_thd = new THD; if (!new_thd || hash_init(&udf_hash,32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE)) { sql_print_error("Can't allocate memory for udf structures"); hash_free(&udf_hash); - free_root(&mem); + free_root(&mem,MYF(0)); DBUG_VOID_RETURN; } initialized = 1; @@ -208,7 +208,7 @@ void udf_free() dlclose(udf->dlhandle); } hash_free(&udf_hash); - free_root(&mem); + free_root(&mem,MYF(0)); DBUG_VOID_RETURN; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 37aedda10f0..d4fec1289ba 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1104,11 +1104,12 @@ mi_check_types: | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; } analyze: - ANALYZE_SYM table_or_tables table_list + ANALYZE_SYM table_or_tables { Lex->sql_command = SQLCOM_ANALYZE; Lex->check_opt.init(); } + table_list opt_mi_check_type check: CHECK_SYM table_or_tables @@ -1119,12 +1120,12 @@ check: table_list opt_mi_check_type optimize: - OPTIMIZE table_or_tables table_ident + OPTIMIZE table_or_tables { Lex->sql_command = SQLCOM_OPTIMIZE; - if (!add_table_to_list($3, NULL)) - YYABORT; + Lex->check_opt.init(); } + table_list opt_mi_check_type rename: RENAME table_or_tables diff --git a/sql/table.cc b/sql/table.cc index 5917244a4f3..e0270838651 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -69,7 +69,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->db_stat = db_stat; error=1; - init_sql_alloc(&outparam->mem_root,1024); + init_sql_alloc(&outparam->mem_root,1024,0); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root); @@ -550,7 +550,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, my_pthread_setspecific_ptr(THR_MALLOC,old_root); frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG); outparam->file=0; // For easyer errorchecking - free_root(&outparam->mem_root); + free_root(&outparam->mem_root,MYF(0)); my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); } /* openfrm */ @@ -578,7 +578,7 @@ int closefrm(register TABLE *table) delete table->file; table->file=0; /* For easyer errorchecking */ hash_free(&table->name_hash); - free_root(&table->mem_root); + free_root(&table->mem_root,MYF(0)); DBUG_RETURN(error); } diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index e890019553f..deb304443df 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -27,9 +27,9 @@ extern "C" { } } -void init_sql_alloc(MEM_ROOT *mem_root,uint block_size) +void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc) { - init_alloc_root(mem_root,block_size); + init_alloc_root(mem_root, block_size, pre_alloc); mem_root->error_handler=sql_alloc_error_handler; } |