From 9d36f27bb021a3496e3b08c91f62a27daaad7664 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Apr 2001 23:47:11 +0300 Subject: Added test for PTHREAD_YIELD Removed test of default master parameter Don't lock locked tables in REPAIR Changed optimzation for SELECT * from table,table ORDER BY keypart LIMIT BitKeeper/deleted/.del-have_default_master.inc~a54c86e65a6c4af: Delete: mysql-test/include/have_default_master.inc BitKeeper/deleted/.del-have_default_master.require~1465255ffdaf82f: Delete: mysql-test/r/have_default_master.require Docs/manual.texi: Changelog for 3.23.38 acconfig.h: Added test for PTHREAD_YIELD acinclude.m4: Added test for PTHREAD_YIELD configure.in: Added test for PTHREAD_YIELD innobase/os/os0thread.c: Added test for PTHREAD_YIELD mysql-test/r/lock.result: Added test of lock bug mysql-test/t/lock.test: Added test of lock bug mysql-test/t/rpl000014.test: Removed test of default master parameter mysql-test/t/rpl000015.test: Removed test of default master parameter mysql-test/t/rpl000016.test: Removed test of default master parameter sql/ha_myisam.cc: Don't lock locked tables in REPAIR sql/sql_select.cc: Changed optimzation for SELECT * from table,table ORDER BY keypart LIMIT --- sql/ha_myisam.cc | 6 ++++-- sql/sql_select.cc | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 1a205e54b9d..b6cfc2c3612 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -533,7 +533,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT, 4+ (param.opt_follow_links ? 16 : 0))); - if (mi_lock_database(file,F_WRLCK)) + // Don't lock tables if we have used LOCK TABLE + if (!thd->locked_tables && mi_lock_database(file,F_WRLCK)) { mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno); DBUG_RETURN(HA_ADMIN_FAILED); @@ -615,7 +616,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) update_state_info(¶m, file, 0); } thd->proc_info=old_proc_info; - mi_lock_database(file,F_UNLCK); + if (!thd->locked_tables) + mi_lock_database(file,F_UNLCK); DBUG_RETURN(error ? HA_ADMIN_FAILED : !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e726a9969ca..77cf20f813a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -528,9 +528,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (order && (join.const_tables == join.tables || test_if_skip_sort_order(&join.join_tab[join.const_tables], order, - (having || group || - join.const_tables != join.tables - 1) ? - HA_POS_ERROR : thd->select_limit))) + (group ? HA_POS_ERROR : thd->select_limit)))) order=0; select_describe(&join,need_tmp, (order != 0 && -- cgit v1.2.1 From e69d8fb32a97cd7269f01ecc60b74f710e4a7c6b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Apr 2001 20:41:19 +0300 Subject: Fix for BDB and LOCK TABLES BitKeeper/deleted/.del-ib_config.h.in~9e57db8504e55b7: Delete: innobase/ib_config.h.in BitKeeper/deleted/.del-ib_config.h~7539e26ffc614439: Delete: innobase/ib_config.h Docs/manual.texi: Changelog myisam/mi_locking.c: Cleanup mysql-test/r/bdb.result: Test for LOCK TABLES mysql-test/r/innodb.result: Test for LOCK TABLES mysql-test/t/bdb.test: Test for LOCK TABLES mysql-test/t/innodb.test: Test for LOCK TABLES sql-bench/test-insert.sh: Allow loop to be small sql/ha_berkeley.cc: Fixed bug when using LOCK TABLES with BDB sql/ha_berkeley.h: Fixed bug when using LOCK TABLES with BDB sql/handler.h: Fixed bug when using LOCK TABLES with BDB sql/sql_base.cc: Fixed bug when using LOCK TABLES with BDB sql/sql_parse.cc: UNLOCK TABLES ends transaction sql/sql_select.cc: Fix to not call index_end() twice --- sql/ha_berkeley.cc | 26 ++++++++++++++++++++++++-- sql/ha_berkeley.h | 1 + sql/handler.h | 2 ++ sql/sql_base.cc | 22 ++++++++++++++++++++-- sql/sql_parse.cc | 1 + sql/sql_select.cc | 6 ++++-- 6 files changed, 52 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 9dbd7b6c998..4b4894ebcd5 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -41,10 +41,9 @@ from the updated tables. Testing of: - - LOCK TABLES - Mark tables that participate in a transaction so that they are not closed during the transaction. We need to test what happens if - MySQL closes a table that is updated by a not commit transaction. + MySQL closes a table that is updated by a not commited transaction. */ @@ -1701,12 +1700,35 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) DBUG_PRINT("trans",("commiting non-updating transaction")); error=txn_commit((DB_TXN*) thd->transaction.stmt.bdb_tid,0); thd->transaction.stmt.bdb_tid=0; + transaction=0; } } } DBUG_RETURN(error); } + +/* + When using LOCK TABLE's external_lock is only called when the actual + TABLE LOCK is done. + Under LOCK TABLES, each used tables will force a call to start_stmt. +*/ + +int ha_berkeley::start_stmt(THD *thd) +{ + int error=0; + DBUG_ENTER("ha_berkeley::start_stmt"); + if (!thd->transaction.stmt.bdb_tid) + { + error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, + (DB_TXN**) &thd->transaction.stmt.bdb_tid, + 0); + transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; + } + DBUG_RETURN(error); +} + + /* The idea with handler::store_lock() is the following: diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 9724d128b1f..9e657d72da1 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -136,6 +136,7 @@ class ha_berkeley: public handler int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); + int start_stmt(THD *thd); void position(byte *record); int analyze(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd, HA_CHECK_OPT* check_opt); diff --git a/sql/handler.h b/sql/handler.h index 638529ab882..c7df6e2a915 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -265,6 +265,7 @@ public: virtual int extra(enum ha_extra_function operation)=0; virtual int reset()=0; virtual int external_lock(THD *thd, int lock_type)=0; + virtual int start_stmt(THD *thd) {return 0;} virtual int delete_all_rows(); virtual longlong get_auto_increment(); virtual void update_create_info(HA_CREATE_INFO *create_info) {} @@ -344,6 +345,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, bool update_create_info); int ha_delete_table(enum db_type db_type, const char *path); void ha_key_cache(void); +int ha_start_stmt(THD *thd); int ha_commit_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans); int ha_autocommit_or_rollback(THD *thd, int error); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 49c858b7a16..134449fd20a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1399,6 +1399,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) &refresh)) && refresh) ; if (table) { + int error; table_list->table=table; table->grant= table_list->grant; if (thd->locked_tables) @@ -1410,7 +1411,12 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), MYF(0),table_list->name); - DBUG_RETURN(0); + table=0; + } + else if ((error=table->file->start_stmt(thd))) + { + table->file->print_error(error,MYF(0)); + table=0; } thd->proc_info=0; DBUG_RETURN(table); @@ -1437,10 +1443,10 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables) int lock_tables(THD *thd,TABLE_LIST *tables) { + TABLE_LIST *table; if (tables && !thd->locked_tables) { uint count=0; - TABLE_LIST *table; for (table = tables ; table ; table=table->next) count++; TABLE **start,**ptr; @@ -1451,6 +1457,18 @@ int lock_tables(THD *thd,TABLE_LIST *tables) if (!(thd->lock=mysql_lock_tables(thd,start,count))) return -1; /* purecov: inspected */ } + else + { + for (table = tables ; table ; table=table->next) + { + int error; + if ((error=table->table->file->start_stmt(thd))) + { + table->table->file->print_error(error,MYF(0)); + return -1; + } + } + } return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5ed17d76dff..f0cc3f9c42a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1830,6 +1830,7 @@ mysql_execute_command(void) { thd->lock=thd->locked_tables; thd->locked_tables=0; // Will be automaticly closed + end_active_trans(thd); } if (thd->global_read_lock) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 77cf20f813a..00a41a851b5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2525,7 +2525,6 @@ join_free(JOIN *join) delete tab->select; delete tab->quick; x_free(tab->cache.buff); - end_read_record(&tab->read_record); if (tab->table) { if (tab->table->key_read) @@ -2533,8 +2532,11 @@ join_free(JOIN *join) tab->table->key_read=0; tab->table->file->extra(HA_EXTRA_NO_KEYREAD); } - tab->table->file->index_end(); + /* Don't free index if we are using read_record */ + if (!tab->read_record.table) + tab->table->file->index_end(); } + end_read_record(&tab->read_record); } join->table=0; } -- cgit v1.2.1 From 4a7af05c7fdd23d5ec194531b6fdb5dcfb113868 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Apr 2001 15:18:46 +0300 Subject: Portability fixes BitKeeper/deleted/.del-compile-ia64-O0-sgicc~a4e0732013d6b602: Delete: BUILD/compile-ia64-O0-sgicc BitKeeper/deleted/.del-compile-ia64-O0~3a41dfebefc817d1: Delete: BUILD/compile-ia64-O0 BitKeeper/deleted/.del-compile-ia64-O2-sgicc~6ff796ecac337849: Delete: BUILD/compile-ia64-O2-sgicc BitKeeper/deleted/.del-compile-ia64-O2~87d13594c3599830: Delete: BUILD/compile-ia64-O2 BitKeeper/deleted/.del-compile-ia64-O6~c34e6b943b12c468: Delete: BUILD/compile-ia64-O6 Docs/manual.texi: Cleanup mysql-test/r/rpl000014.result: Change port number for comparison mysql-test/r/rpl000015.result: Change port number for comparison mysql-test/r/rpl000016.result: Change port number for comparison mysql-test/t/rpl000014.test: Change port number for comparison mysql-test/t/rpl000015.test: Change port number for comparison mysql-test/t/rpl000016.test: Change port number for comparison sql-bench/Results/ATIS-mysql-NT_4.0: New test results sql-bench/Results/RUN-mysql-NT_4.0: New test results sql-bench/Results/alter-table-mysql-NT_4.0: New test results sql-bench/Results/big-tables-mysql-NT_4.0: New test results sql-bench/Results/connect-mysql-NT_4.0: New test results sql-bench/Results/create-mysql-NT_4.0: New test results sql-bench/Results/insert-mysql-NT_4.0: New test results sql-bench/Results/select-mysql-NT_4.0: New test results sql-bench/Results/wisconsin-mysql-NT_4.0: New test results sql/slave.cc: Removed not used variable --- sql/slave.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 0220f574112..aded6d558fc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1191,7 +1191,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) pthread_cond_broadcast(&COND_slave_start); pthread_mutex_unlock(&LOCK_slave); - int error = 1; + // int error = 1; bool retried_once = 0; ulonglong last_failed_pos = 0; @@ -1369,7 +1369,7 @@ the slave thread with \"mysqladmin start-slave\". We stopped at log \ } } - error = 0; + // error = 0; err: // print the current replication position sql_print_error("Slave thread exiting, replication stopped in log '%s' at \ -- cgit v1.2.1 From 4c5dd2f27801294f716567995c0d6e625670a9a7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Apr 2001 17:14:53 +0300 Subject: Fixed that database name is shown for CHECK TABLE BitKeeper/etc/ignore: Added client/mysqlcheck to the ignore list Docs/manual.texi: Changelog --- sql/ha_myisam.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index b6cfc2c3612..6409ec5d019 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -50,10 +50,12 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, { THD* thd = (THD*)param->thd; String* packet = &thd->packet; - packet->length(0); + uint length; char msgbuf[MI_MAX_MSG_BUF]; - msgbuf[0] = 0; + char name[NAME_LEN*2+2]; + packet->length(0); + msgbuf[0] = 0; // healthy paranoia ? my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia @@ -70,9 +72,12 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME)); return; } - net_store_data(packet, param->table_name); + length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) - + name); + net_store_data(packet, name, length); net_store_data(packet, param->op_name); net_store_data(packet, msg_type); + net_store_data(packet, msgbuf); if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length())) fprintf(stderr, @@ -245,6 +250,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) myisamchk_init(¶m); param.thd = thd; param.op_name = (char*)"check"; + param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = check_opt->flags | T_CHECK | T_SILENT; @@ -332,6 +338,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) myisamchk_init(¶m); param.thd = thd; param.op_name = (char*) "analyze"; + param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag=(T_FAST | T_CHECK | T_SILENT | T_STATISTICS | T_DONT_CHECK_CHECKSUM); @@ -384,6 +391,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) myisamchk_init(¶m); param.thd = thd; param.op_name = (char*)"restore"; + param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; mi_check_print_error(¶m,errmsg, errno ); @@ -438,6 +446,7 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) myisamchk_init(¶m); param.thd = thd; param.op_name = (char*)"backup"; + param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; mi_check_print_error(¶m,errmsg, errno ); @@ -524,6 +533,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) ha_rows rows= file->state->records; DBUG_ENTER("ha_myisam::repair"); + param.db_name = table->table_cache_key; param.table_name = table->table_name; param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; -- cgit v1.2.1 From 94ab8e9c4c1ac68a119feee041b29b0fb81ed350 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Apr 2001 03:03:08 +0300 Subject: Fixed portability problems in mysqlcheck Docs/manual.texi: Updated TODO client/mysqlcheck.c: Fixed portability problems mysql-test/r/backup.result: Fixed output after format change for BACKUP TABLE sql/ha_berkeley.cc: Added missing variable sql/opt_range.cc: Small optimization when calculating key blocks --- sql/ha_berkeley.cc | 1 + sql/opt_range.cc | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 4b4894ebcd5..32af39e4a0d 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -571,6 +571,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) transaction=0; cursor=0; key_read=0; + block_size=8192; // Berkeley DB block size share->fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD); get_status(); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 98be3639a06..b95b97d670f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -697,7 +697,9 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, ** and that all key blocks are half full (normally things are ** much better) */ - uint keys_per_block= head->file->block_size/2/head->key_info[param.real_keynr[idx]].key_length+1; + uint keys_per_block= head->file->block_size/2/ + (head->key_info[param.real_keynr[idx]].key_length+ + head->file->ref_length) + 1; found_read_time=((double) (found_records+keys_per_block-1)/ (double) keys_per_block); } -- cgit v1.2.1 From 0574441192273bd210232919eb72f2fc7eb153b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Apr 2001 17:12:59 +0300 Subject: Fixed probelm with count(*) and normal functions when no matchin rows. Changed 'lib' to 'master-data' Fix for slow slaves Docs/manual.texi: Changelog include/mysql.h: Fixes for Cygwin libmysql/libmysql.c: Fixes for Cygwin mysql-test/Makefile.am: Include missing test files mysql-test/include/master-slave.inc: Fixes for slow slaves mysql-test/install_test_db.sh: Change 'lib' to 'master-data' mysql-test/mysql-test-run.sh: Change 'lib' to 'master-data' mysql-test/r/group_by.result: Test case for count(*) problem mysql-test/t/group_by.test: Test case for count(*) problem mysql-test/t/rpl000018-master.sh: Change 'lib' to 'master-data' sql/sql_select.cc: Fix for count(*) problem --- sql/sql_select.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 00a41a851b5..63d08b6be5b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4643,7 +4643,11 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), else { if (!join->first_record) + { + /* No matching rows for group function */ clear_tables(join); + copy_fields(&join->tmp_table_param); + } if (join->having && join->having->val_int() == 0) error= -1; // Didn't satisfy having else @@ -4875,7 +4879,11 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (idx < (int) join->send_group_parts) { if (!join->first_record) + { + /* No matching rows for group function */ clear_tables(join); + copy_fields(&join->tmp_table_param); + } copy_sum_funcs(join->sum_funcs); if (!join->having || join->having->val_int()) { @@ -4899,7 +4907,6 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } if (idx < (int) join->send_group_parts) { - copy_fields(&join->tmp_table_param); copy_funcs(join->tmp_table_param.funcs); init_sum_functions(join->sum_funcs); if (join->procedure) -- cgit v1.2.1 From 4f8d308200f158d502cc36922c4600e47c40d23b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Apr 2001 12:11:01 +0300 Subject: Fix for release Docs/manual.texi: new links scripts/make_binary_distribution.sh: Added missing files sql/sql_select.cc: Added accidently removed line --- sql/sql_select.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 63d08b6be5b..a418af81187 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4907,6 +4907,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } if (idx < (int) join->send_group_parts) { + copy_fields(&join->tmp_table_param); copy_funcs(join->tmp_table_param.funcs); init_sum_functions(join->sum_funcs); if (join->procedure) -- cgit v1.2.1 From dc394cb9b5f0fafd55c2398d929fc1229b452f76 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Apr 2001 17:39:26 -0600 Subject: fixed redundant repetition of use db in mysqlbinlog added support for virtual master ( replicating from a directory with binlogs) test case for backup/restore with virtual master client/mysqltest.c: fix to accomodate for new test case mysql-test/mysql-test-run.sh: do not automagically start slave sql/log.cc: support for virtual master sql/log_event.cc: fix for mysqlbinlog sql/log_event.h: fix for mysqlbinlog sql/mysqlbinlog.cc: fix for mysqlbinlog sql/slave.cc: virtual master sql/slave.h: virtual master sql/sql_class.h: clean-up/fixes for virtual master sql/sql_repl.cc: cleanup/fixes for virtual master sql/sql_repl.h: virtual master --- sql/log.cc | 48 ++++++++++++------ sql/log_event.cc | 32 +++++++++--- sql/log_event.h | 14 ++--- sql/mysqlbinlog.cc | 6 ++- sql/slave.cc | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++--- sql/slave.h | 15 +++++- sql/sql_class.h | 3 ++ sql/sql_repl.cc | 13 +++-- sql/sql_repl.h | 3 ++ 9 files changed, 236 insertions(+), 44 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index 9601d162d28..3e8be76aacb 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -103,7 +103,7 @@ MYSQL_LOG::~MYSQL_LOG() void MYSQL_LOG::set_index_file_name(const char* index_file_name) { if (index_file_name) - fn_format(this->index_file_name,index_file_name,mysql_data_home,"-index", + fn_format(this->index_file_name,index_file_name,mysql_data_home,".index", 4); else this->index_file_name[0] = 0; @@ -129,6 +129,32 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) return 0; } +bool MYSQL_LOG::open_index( int options) +{ + return (index_file < 0 && + (index_file = my_open(index_file_name, options | O_BINARY , + MYF(MY_WME))) < 0); +} + +void MYSQL_LOG::init(enum_log_type log_type_arg) +{ + log_type = log_type_arg; + if (!inited) + { + inited=1; + (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); + (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); + } +} + +void MYSQL_LOG::close_index() +{ + if(index_file >= 0) + { + my_close(index_file, MYF(0)); + index_file = -1; + } +} void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name) @@ -137,17 +163,11 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, char buff[512]; File file= -1; bool do_magic; - - if (!inited) - { - inited=1; - (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); - if (log_type_arg == LOG_BIN && *fn_ext(log_name)) + + if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name)) no_rotate = 1; - } + init(log_type_arg); - log_type=log_type_arg; if (!(name=my_strdup(log_name,MYF(MY_WME)))) goto err; if (new_name) @@ -208,10 +228,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, clean up if failed */ if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) || - (index_file < 0 && - (index_file = my_open(index_file_name, - O_APPEND | O_BINARY | O_RDWR | O_CREAT, - MYF(MY_WME))) < 0)) + open_index(O_APPEND | O_RDWR | O_CREAT)) goto err; Start_log_event s; bool error; @@ -224,8 +241,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, pthread_mutex_unlock(&LOCK_index); if (error) { - my_close(index_file,MYF(0)); - index_file= -1; + close_index(); goto err; } } diff --git a/sql/log_event.cc b/sql/log_event.cc index d643952c5b0..5fc5f7f0e62 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -280,7 +280,7 @@ void Log_event::print_timestamp(FILE* file, time_t* ts) } -void Start_log_event::print(FILE* file, bool short_form) +void Start_log_event::print(FILE* file, bool short_form, char* last_db) { if (short_form) return; @@ -293,7 +293,7 @@ void Start_log_event::print(FILE* file, bool short_form) fflush(file); } -void Stop_log_event::print(FILE* file, bool short_form) +void Stop_log_event::print(FILE* file, bool short_form, char* last_db) { if (short_form) return; @@ -303,7 +303,7 @@ void Stop_log_event::print(FILE* file, bool short_form) fflush(file); } -void Rotate_log_event::print(FILE* file, bool short_form) +void Rotate_log_event::print(FILE* file, bool short_form, char* last_db) { if (short_form) return; @@ -441,7 +441,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len): *((char*)query+q_len) = 0; } -void Query_log_event::print(FILE* file, bool short_form) +void Query_log_event::print(FILE* file, bool short_form, char* last_db) { char buff[40],*end; // Enough for SET TIMESTAMP if (!short_form) @@ -451,7 +451,15 @@ void Query_log_event::print(FILE* file, bool short_form) (ulong) thread_id, (ulong) exec_time, error_code); } - if (db && db[0]) + bool same_db = 0; + + if(db && last_db) + { + if(!(same_db = !memcmp(last_db, db, db_len))) + memcpy(last_db, db, db_len + 1); + } + + if (db && db[0] && !same_db) fprintf(file, "use %s;\n", db); end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10); *end++=';'; @@ -507,7 +515,7 @@ int Intvar_log_event::write_data(IO_CACHE* file) return my_b_write(file, (byte*) buf, sizeof(buf)); } -void Intvar_log_event::print(FILE* file, bool short_form) +void Intvar_log_event::print(FILE* file, bool short_form, char* last_db) { char llbuff[22]; if(!short_form) @@ -625,7 +633,7 @@ void Load_log_event::copy_log_event(const char *buf, ulong data_len) } -void Load_log_event::print(FILE* file, bool short_form) +void Load_log_event::print(FILE* file, bool short_form, char* last_db) { if (!short_form) { @@ -634,7 +642,15 @@ void Load_log_event::print(FILE* file, bool short_form) thread_id, exec_time); } - if(db && db[0]) + bool same_db = 0; + + if(db && last_db) + { + if(!(same_db = !memcmp(last_db, db, db_len))) + memcpy(last_db, db, db_len + 1); + } + + if(db && db[0] && !same_db) fprintf(file, "use %s;\n", db); fprintf(file, "LOAD DATA INFILE '%s' ", fname); diff --git a/sql/log_event.h b/sql/log_event.h index 0f4945bae3c..41f847e8d92 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -100,7 +100,7 @@ public: virtual ~Log_event() {} virtual int get_data_size() { return 0;} - virtual void print(FILE* file, bool short_form = 0) = 0; + virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0; void print_timestamp(FILE* file, time_t *ts = 0); void print_header(FILE* file); @@ -169,7 +169,7 @@ public: ; } - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; #define DUMPFILE_FLAG 0x1 @@ -312,7 +312,7 @@ public: ; } - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; extern char server_version[SERVER_VERSION_LENGTH]; @@ -350,7 +350,7 @@ public: // sizeof(binlog_version) + sizeof(server_version) sizeof(created) return 2 + sizeof(server_version) + 4; } - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; class Intvar_log_event: public Log_event @@ -369,7 +369,7 @@ public: int write_data(IO_CACHE* file); - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; class Stop_log_event: public Log_event @@ -388,7 +388,7 @@ public: } ~Stop_log_event() {} Log_event_type get_type_code() { return STOP_EVENT;} - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; class Rotate_log_event: public Log_event @@ -416,7 +416,7 @@ public: int get_data_size() { return ident_len;} int write_data(IO_CACHE* file); - void print(FILE* file, bool short_form = 0); + void print(FILE* file, bool short_form = 0, char* last_db = 0); }; #endif diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc index 49daa04ffff..1ad6a430710 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -290,6 +290,7 @@ static void dump_remote_table(NET* net, const char* db, const char* table) static void dump_remote_log_entries(const char* logname) { char buf[128]; + char last_db[FN_REFLEN+1] = ""; uint len; NET* net = &mysql->net; if(!position) position = 4; // protect the innocent from spam @@ -323,7 +324,7 @@ Unfortunately, no sweepstakes today, adjusted position to 4\n"); len - 1); if(ev) { - ev->print(stdout, short_form); + ev->print(stdout, short_form, last_db); if(ev->get_type_code() == LOAD_EVENT) dump_remote_file(net, ((Load_log_event*)ev)->fname); delete ev; @@ -338,6 +339,7 @@ static void dump_local_log_entries(const char* logname) File fd = -1; IO_CACHE cache,*file= &cache; ulonglong rec_count = 0; + char last_db[FN_REFLEN+1] = ""; if (logname && logname[0] != '-') { @@ -397,7 +399,7 @@ Could not read entry at offset %s : Error in log format or read error", if (!short_form) printf("# at %s\n",llstr(old_off,llbuff)); - ev->print(stdout, short_form); + ev->print(stdout, short_form, last_db); } rec_count++; delete ev; diff --git a/sql/slave.cc b/sql/slave.cc index aded6d558fc..1ca8324e204 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -20,6 +20,7 @@ #include #include "mini_client.h" #include "slave.h" +#include "sql_repl.h" #include #include @@ -441,6 +442,101 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi) return error; } +void MASTER_INFO::close_virtual_master() +{ + vm_binlog.close_index(); + end_io_cache(&vm_cache); + if(vm_fd >= 0) + { + my_close(vm_fd, MYF(0)); + vm_fd = -1; + } +} + +int MASTER_INFO::setup_virtual_master() +{ + vm_binlog.init(LOG_BIN); + vm_binlog.set_index_file_name(host); + if(vm_binlog.open_index(O_RDONLY)) + { + sql_print_error("virtual master: could not open index file '%s': \ + (%d)", host, my_errno); + return 1; + } + + if(vm_binlog.find_first_log(&vm_linfo,log_file_name)) + { + sql_print_error("virtual master: could not find first log"); + return 1; + } + + if(open_log()) + return 1; + + return 0; +} + +int MASTER_INFO::open_log() +{ + const char* errmsg = "Unknown error"; + if(vm_fd >= 0) + { + end_io_cache(&vm_cache); + my_close(vm_fd, MYF(0)); + } + + // if backup-up logs have relative paths, assume they are relative to + // the directory that has the log index, not cwd + char logname_buf[FN_REFLEN+1], *logname; + if(vm_linfo.log_file_name[0] == FN_LIBCHAR) + logname = vm_linfo.log_file_name; + else + { + char* end = strnmov(logname_buf, host, + sizeof(logname_buf)); + for(; *end != FN_LIBCHAR; --end); // we will always find it, first + // char of host is always FN_LIBCHAR for virtual master + + strncpy(end + 1, vm_linfo.log_file_name, + sizeof(logname_buf) - (end - logname_buf)); + logname = logname_buf; + } + + if((vm_fd = open_binlog(&vm_cache, logname, &errmsg)) < 0) + { + sql_print_error("virtual master: error opening binlog '%s': %s", + vm_linfo.log_file_name, errmsg); + return 1; + } + + strncpy(log_file_name, vm_linfo.log_file_name, sizeof(log_file_name)); + return 0; +} + +uint MASTER_INFO::read_event() +{ + for(;!(vm_ev = Log_event::read_log_event(&vm_cache, 0));) + { + if(!vm_cache.error) // eof - try next log + { + switch(vm_binlog.find_next_log(&vm_linfo)) + { + case LOG_INFO_EOF: + return 0; + case 0: + if(open_log()) + return packet_error; + continue; + default: + sql_print_error("virtual master: could not read next log"); + return packet_error; + } + } + } + + return vm_ev->get_data_size() + LOG_EVENT_HEADER_LEN; +} + void end_master_info(MASTER_INFO* mi) { if(mi->fd >= 0) @@ -450,6 +546,8 @@ void end_master_info(MASTER_INFO* mi) mi->fd = -1; } mi->inited = 0; + if(mi->virtual_master) + mi->close_virtual_master(); } int init_master_info(MASTER_INFO* mi) @@ -545,6 +643,7 @@ int init_master_info(MASTER_INFO* mi) } mi->inited = 1; + mi->virtual_master = (mi->host[0] == FN_LIBCHAR); // now change the cache from READ to WRITE - must do this // before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1); @@ -742,6 +841,9 @@ static int safe_sleep(THD* thd, int sec) static int request_dump(MYSQL* mysql, MASTER_INFO* mi) { + if(mi->virtual_master) + return 0; + char buf[FN_REFLEN + 10]; int len; int binlog_flags = 0; // for now @@ -795,6 +897,9 @@ command"); static uint read_event(MYSQL* mysql, MASTER_INFO *mi) { + if(mi->virtual_master) + return mi->read_event(); + uint len = packet_error; // for convinience lets think we start by // being in the interrupted state :-) @@ -860,16 +965,18 @@ point. If you are sure that your master is ok, run this query manually on the\ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) { - Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1, - event_len); + Log_event * ev = (mi->virtual_master) ? mi->vm_ev : + Log_event::read_log_event((const char*)net->read_pos + 1, + event_len) ; char llbuff[22]; if (ev) { int type_code = ev->get_type_code(); - if (ev->server_id == ::server_id || slave_skip_counter) + if ((!mi->virtual_master && ev->server_id == ::server_id) + || slave_skip_counter) { - if(type_code == LOAD_EVENT) + if(type_code == LOAD_EVENT && !mi->virtual_master) skip_load_data_infile(net); mi->inc_pos(event_len); @@ -971,6 +1078,14 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) case LOAD_EVENT: { + if(mi->virtual_master) + { + delete ev; + sql_print_error("LOAD DATA INFILE does not yet work with virtual \ +master. Perform in manually, then restart slave with SET SQL_SKIP_COUNTER=1;\ +SLAVE START"); + return 1; + } Load_log_event* lev = (Load_log_event*)ev; init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)lev->db); @@ -993,7 +1108,8 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) // the table will be opened in mysql_load if(table_rules_on && !tables_ok(thd, &tables)) { - skip_load_data_infile(net); + if(!mi->virtual_master) + skip_load_data_infile(net); } else { @@ -1057,7 +1173,8 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) { // we will just ask the master to send us /dev/null if we do not // want to load the data :-) - skip_load_data_infile(net); + if(!mi->virtual_master) + skip_load_data_infile(net); } thd->net.vio = 0; @@ -1293,9 +1410,21 @@ try again, log '%s' at postion %s", RPL_LOG_NAME, sql_print_error("Slave thread killed while reading event"); goto err; } + + if(!event_len && glob_mi.virtual_master) + { + sql_print_error("Virtual master replication finished"); + goto err; + } if (event_len == packet_error) { + if(glob_mi.virtual_master) + { + sql_print_error("Virtual master replication encountered \ +error while reading event, replication terminated"); + goto err; + } thd->proc_info = "Waiting to reconnect after a failed read"; if(mysql->net.vio) vio_close(mysql->net.vio); @@ -1403,6 +1532,8 @@ position %s", static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { + if(mi->virtual_master) + return mi->setup_virtual_master(); int slave_was_killed; #ifndef DBUG_OFF events_till_disconnect = disconnect_slave_event_count; @@ -1432,6 +1563,9 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { + if(mi->virtual_master) + return mi->setup_virtual_master(); + int slave_was_killed; char llbuff[22]; diff --git a/sql/slave.h b/sql/slave.h index 311368a4b82..d04c0c13c23 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -16,8 +16,14 @@ typedef struct st_master_info pthread_mutex_t lock; pthread_cond_t cond; bool inited; + bool virtual_master; // for replay of binlogs from a directory + MYSQL_LOG vm_binlog; + LOG_INFO vm_linfo; + IO_CACHE vm_cache; + int vm_fd; + Log_event* vm_ev; - st_master_info():pending(0),fd(-1),inited(0) + st_master_info():pending(0),fd(-1),inited(0),virtual_master(0),vm_fd(-1) { host[0] = 0; user[0] = 0; password[0] = 0; pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST); @@ -28,6 +34,8 @@ typedef struct st_master_info { pthread_mutex_destroy(&lock); pthread_cond_destroy(&cond); + if(virtual_master) + close_virtual_master(); } inline void inc_pending(ulonglong val) { @@ -51,6 +59,11 @@ typedef struct st_master_info } int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos); + int setup_virtual_master(); + void close_virtual_master(); + uint read_event(); + int open_log(); + } MASTER_INFO; typedef struct st_table_rule_ent diff --git a/sql/sql_class.h b/sql/sql_class.h index 297b6acbad5..f7dc799113e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -71,9 +71,12 @@ public: ~MYSQL_LOG(); pthread_mutex_t* get_log_lock() { return &LOCK_log; } void set_index_file_name(const char* index_file_name = 0); + void init(enum_log_type log_type_arg); void open(const char *log_name,enum_log_type log_type, const char *new_name=0); void new_file(void); + bool open_index(int options); + void close_index(); bool write(THD *thd, enum enum_server_command command,const char *format,...); bool write(THD *thd, const char *query, uint query_length, time_t query_start=0); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 05e64670df5..ed41bf53692 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -132,7 +132,7 @@ static int send_file(THD *thd) } -static File open_log(IO_CACHE *log, const char *log_file_name, +File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg) { File file; @@ -294,7 +294,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) goto err; } - if ((file=open_log(&log, log_file_name, &errmsg)) < 0) + if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0) goto err; if(pos < 4) @@ -483,7 +483,7 @@ sweepstakes if you report the bug"; // fake Rotate_log event just in case it did not make it to the log // otherwise the slave make get confused about the offset - if ((file=open_log(&log, log_file_name, &errmsg)) < 0 || + if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 || fake_rotate_event(net, packet, log_file_name, &errmsg)) goto err; @@ -694,7 +694,12 @@ int change_master(THD* thd) glob_mi.pos = lex_mi->pos; if(lex_mi->host) - strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host)); + { + if(glob_mi.virtual_master) + glob_mi.close_virtual_master(); + strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host)); + glob_mi.virtual_master = (glob_mi.host[0] == FN_LIBCHAR); + } if(lex_mi->user) strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user)); if(lex_mi->password) diff --git a/sql/sql_repl.h b/sql/sql_repl.h index f8a67f51aa2..68f2b4ba6c4 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -9,6 +9,9 @@ extern uint32 server_id; extern bool server_id_supplied; extern I_List binlog_do_db, binlog_ignore_db; +File open_binlog(IO_CACHE *log, const char *log_file_name, + const char **errmsg); + int start_slave(THD* thd = 0, bool net_report = 1); int stop_slave(THD* thd = 0, bool net_report = 1); int change_master(THD* thd); -- cgit v1.2.1 From d909ccb6dc7805616e299cc2014af50e0540fd53 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Apr 2001 14:44:35 +0300 Subject: ha_innobase.cc Changed the error code HA_ERR_KEY_NOT_FOUND to HA_ERR_END_OF_INDEX in index_first to eliminate an error message sql/ha_innobase.cc: Changed the error code HA_ERR_KEY_NOT_FOUND to HA_ERR_END_OF_INDEX in index_first to eliminate an error message --- sql/ha_innobase.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index f263f693103..72857fc953f 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -1868,7 +1868,7 @@ corresponding row to buf. */ int ha_innobase::index_first( /*=====================*/ - /* out: 0, HA_ERR_KEY_NOT_FOUND, + /* out: 0, HA_ERR_END_OF_FILE, or error code */ mysql_byte* buf) /* in/out: buffer for the row */ { @@ -1879,6 +1879,12 @@ ha_innobase::index_first( error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY); + /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ + + if (error == HA_ERR_KEY_NOT_FOUND) { + error = HA_ERR_END_OF_FILE; + } + DBUG_RETURN(error); } @@ -1899,7 +1905,7 @@ ha_innobase::index_last( error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY); - /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ + /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ if (error == HA_ERR_KEY_NOT_FOUND) { error = HA_ERR_END_OF_FILE; -- cgit v1.2.1 From 97907ee8d723a9143734655151153e2c6243ab28 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Apr 2001 22:44:27 +0300 Subject: Portability fixes for Ia64 and Sgi compiler DROP DATABASE in mysqladmin asks for confirmation (again) Added examined_rows to slow query log SHOW CREATE for TEMPORARY table BitKeeper/deleted/.del-shw000001.result~8b20b03d8319b9a5: Delete: mysql-test/r/shw000001.result BitKeeper/deleted/.del-shw000001.test~770d96a2c1c65b20: Delete: mysql-test/t/shw000001.test Docs/manual.texi: Added information about InnoDB and TEMPORARY tables acinclude.m4: Portability fixes client/errmsg.c: merge with libmysqd/errmsg.c client/mysqladmin.c: DROP DATABASE asks for confirmation (again) client/mysqltest.c: Portability fixes configure.in: Portability fixes for SGI compiler on Ia64 extra/resolve_stack_dump.c: Portability fixes include/global.h: Portability fixes isam/_dbug.c: Portability fixes mysql-test/mysql-test-run.sh: Portability fixes mysql-test/r/show_check.result: New test for SHOW CREATE mysql-test/t/show_check.test: New test for SHOW CREATE scripts/make_binary_distribution.sh: Added missing files sql/filesort.cc: Added examined_rows to slow query log sql/log.cc: Added examined_rows to slow query log sql/mysql_priv.h: Added examined_rows to slow query log sql/mysqlbinlog.cc: Fixed core dump when using wrong option sql/mysqld.cc: Removed not used argument sql/sql_base.cc: Fixed name problem with SHOW CREATE for TEMPORARY table sql/sql_class.h: Added examined_rows to slow query log sql/sql_parse.cc: Added examined_rows to slow query log sql/sql_select.cc: Added examined_rows to slow query log sql/sql_select.h: Added examined_rows to slow query log sql/sql_show.cc: Fixed SHOW CREATE for TEMPORARY table sql/sql_table.cc: Added examined_rows to slow query log --- sql/filesort.cc | 10 +++++++--- sql/log.cc | 7 ++++--- sql/mysql_priv.h | 3 ++- sql/mysqlbinlog.cc | 1 + sql/mysqld.cc | 2 +- sql/sql_base.cc | 5 +++-- sql/sql_class.h | 2 +- sql/sql_parse.cc | 2 +- sql/sql_select.cc | 15 +++++++++++---- sql/sql_select.h | 3 ++- sql/sql_show.cc | 5 ++++- sql/sql_table.cc | 4 +++- 12 files changed, 40 insertions(+), 19 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index e116e2b68e6..610fe2e966f 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -49,7 +49,7 @@ typedef struct st_sort_param { uint sort_length; /* Length of sortarg */ uint keys; /* Max antal nycklar / buffert */ uint ref_length; /* Length of record ref. */ - ha_rows max_rows; + ha_rows max_rows,examined_rows; TABLE *sort_form; /* For quicker make_sortkey */ SORT_FIELD *local_sortorder; SORT_FIELD *end; @@ -91,7 +91,8 @@ static uint sortlength(SORT_FIELD *sortorder,uint length); open a new file is opened */ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, - SQL_SELECT *select, ha_rows special, ha_rows max_rows) + SQL_SELECT *select, ha_rows special, ha_rows max_rows, + ha_rows *examined_rows) { int error; uint memavl,old_memavl,maxbuffer,skr; @@ -113,6 +114,7 @@ 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; + param.examined_rows=0; if (select && select->quick) { @@ -259,7 +261,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, my_error(ER_FILSORT_ABORT,MYF(ME_ERROR+ME_WAITTANG)); else statistic_add(filesort_rows, records, &LOCK_status); - + *examined_rows= param.examined_rows; #ifdef SKIPP_DBUG_IN_FILESORT DBUG_POP(); /* Ok to DBUG */ #endif @@ -367,6 +369,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, file->rnd_end(); DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ } + if (error == 0) + param->examined_rows++; if (error == 0 && (!select || select->skipp_record() == 0)) { if (idx == param->keys) diff --git a/sql/log.cc b/sql/log.cc index 9601d162d28..4ae9fa79d5b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -825,11 +825,12 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, { /* For slow query log */ if (my_b_printf(&log_file, - "# Time: %lu Lock_time: %lu Rows_sent: %lu\n", + "# Time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n", (ulong) (current_time - query_start), (ulong) (thd->time_after_lock - query_start), - (ulong) thd->sent_row_count) == (uint) -1) - tmp_errno=errno; + (ulong) thd->sent_row_count, + (ulong) thd->examined_row_count) == (uint) -1) + tmp_errno=errno; } if (thd->db && strcmp(thd->db,db)) { // Database changed diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 78e9db5652f..9c134183fdd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -602,7 +602,8 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, int use_record_cache, bool print_errors); void end_read_record(READ_RECORD *info); ha_rows filesort(TABLE **form,struct st_sort_field *sortorder, uint s_length, - SQL_SELECT *select, ha_rows special,ha_rows max_rows); + SQL_SELECT *select, ha_rows special,ha_rows max_rows, + ha_rows *examined_rows); void change_double_for_sort(double nr,byte *to); int get_quick_record(SQL_SELECT *select); int calc_weekday(long daynr,bool sunday_first_day_of_week); diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc index 49daa04ffff..60989615390 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -58,6 +58,7 @@ static struct option long_options[] = {"table", required_argument, 0, 't'}, {"user", required_argument, 0, 'u'}, {"version", no_argument, 0, 'V'}, + {0, 0, 0, 0} }; void sql_print_error(const char *format,...); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 48484aa168c..931a21c9191 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1388,7 +1388,7 @@ static void *signal_hand(void *arg __attribute__((unused))) if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR); if (pthread_create(&tmp,&connection_attrib, kill_server_thread, - (void*) sig)) + (void*) 0)) sql_print_error("Error: Can't create thread to kill server"); #else kill_server((void*) sig); // MIT THREAD has a alarm thread diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 134449fd20a..afff01e9a16 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1508,8 +1508,9 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked tmp_table->tmp_table = 1; tmp_table->table_cache_key=(char*) (tmp_table+1); - tmp_table->key_length= (uint) (strmov(strmov(tmp_table->table_cache_key,db) - +1, table_name) + tmp_table->key_length= (uint) (strmov((tmp_table->real_name= + strmov(tmp_table->table_cache_key,db) + +1), table_name) - tmp_table->table_cache_key)+1; int4store(tmp_table->table_cache_key + tmp_table->key_length, thd->slave_proxy_id); diff --git a/sql/sql_class.h b/sql/sql_class.h index 297b6acbad5..cb08b8a9df4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -265,7 +265,7 @@ public: #endif ulonglong next_insert_id,last_insert_id,current_insert_id; ha_rows select_limit,offset_limit,default_select_limit,cuted_fields, - max_join_size,sent_row_count; + max_join_size, sent_row_count, examined_row_count; table_map used_tables; ulong query_id,version, inactive_timeout,options,thread_id; ulong gemini_spin_retries; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f0cc3f9c42a..7a94dc32997 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2266,7 +2266,7 @@ mysql_init_query(THD *thd) thd->lex.table_list.next= (byte**) &thd->lex.table_list.first; thd->fatal_error=0; // Safety thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0; - thd->sent_row_count=0; + thd->sent_row_count=thd->examined_row_count=0; DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a418af81187..be1444c52e4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -265,7 +265,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, join.join_tab=0; join.tmp_table_param.copy_field=0; join.sum_funcs=0; - join.send_records=join.found_records=0; + join.send_records=join.found_records=join.examined_rows=0; join.tmp_table_param.end_write_records= HA_POS_ERROR; join.first_record=join.sort_and_group=0; join.select_options=select_options; @@ -784,6 +784,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, error=do_select(&join,&fields,NULL,procedure); err: + thd->examined_row_count=join.examined_rows; thd->proc_info="end"; join.lock=0; // It's faster to unlock later join_free(&join); @@ -867,6 +868,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, table->reginfo.not_exists_optimize=0; bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->keys); all_table_map|= table->map; + s->join=join; if ((s->on_expr=tables->on_expr)) { // table->maybe_null=table->outer_join=1; // Mark for send fields @@ -2219,6 +2221,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join_tab->ref.key = -1; join_tab->not_used_in_distinct=0; join_tab->read_first_record= join_init_read_record; + join_tab->join=join; bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); tmp_table->status=0; tmp_table->null_row=0; @@ -3915,8 +3918,8 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error, table->file=0; *table =new_table; table->file->change_table_ptr(table); - - thd->proc_info=save_proc_info; + thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ? + "Copying to tmp table on disk" : save_proc_info); DBUG_RETURN(0); err: @@ -4096,6 +4099,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) bool not_used_in_distinct=join_tab->not_used_in_distinct; ha_rows found_records=join->found_records; READ_RECORD *info= &join_tab->read_record; + join->examined_rows++; do { @@ -4483,6 +4487,7 @@ join_init_read_next_with_key(READ_RECORD *info) return 0; } + static int join_init_read_last_with_key(JOIN_TAB *tab) { @@ -5204,6 +5209,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) { SORT_FIELD *sortorder; uint length; + ha_rows examined_rows; TABLE *table=tab->table; SQL_SELECT *select=tab->select; DBUG_ENTER("create_sort_index"); @@ -5242,12 +5248,13 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) } } table->found_records=filesort(&table,sortorder,length, - select, 0L, select_limit); + select, 0L, select_limit, &examined_rows); delete select; // filesort did select tab->select=0; tab->select_cond=0; tab->type=JT_ALL; // Read with normal read_record tab->read_first_record= join_init_read_record; + tab->join->examined_rows+=examined_rows; if (table->key_read) // Restore if we used indexes { table->key_read=0; diff --git a/sql/sql_select.h b/sql/sql_select.h index 2f7454e4059..bb97a10128f 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -102,6 +102,7 @@ typedef struct st_join_table { bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; TABLE_REF ref; JOIN_CACHE cache; + JOIN *join; } JOIN_TAB; @@ -151,7 +152,7 @@ class JOIN { uint send_group_parts; bool sort_and_group,first_record,full_join,group, no_field_update; table_map const_table_map,outer_join; - ha_rows send_records,found_records; + ha_rows send_records,found_records,examined_rows,row_limit; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; double best_read; List *fields; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 38c068d35c3..39ddb79e9de 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -781,7 +781,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) List field_list; char tmp[MAX_FIELD_WIDTH]; String type(tmp, sizeof(tmp)); - packet->append("CREATE TABLE ", 13); + if (table->tmp_table) + packet->append("CREATE TEMPORARY TABLE ", 23); + else + packet->append("CREATE TABLE ", 13); append_identifier(thd,packet,table->real_name); packet->append(" (\n", 3); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 77aaf1edae4..78721c3e8f9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1633,6 +1633,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, TABLE_LIST tables; List fields; List all_fields; + ha_rows examined_rows; DBUG_ENTER("copy_data_between_tables"); if (!(copy= new Copy_field[to->fields])) @@ -1668,7 +1669,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (setup_order(thd, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || (from->found_records = filesort(&from, sortorder, length, - (SQL_SELECT *) 0, 0L, HA_POS_ERROR)) + (SQL_SELECT *) 0, 0L, HA_POS_ERROR, + &examined_rows)) == HA_POS_ERROR) goto err; }; -- cgit v1.2.1 From bc564fd0bc26ecaa54b0d6c6cbb5c293cfd59c1e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Apr 2001 15:20:59 -0600 Subject: fixed bug in mysqlbinlog --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 5fc5f7f0e62..17499db4684 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -455,7 +455,7 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) if(db && last_db) { - if(!(same_db = !memcmp(last_db, db, db_len))) + if(!(same_db = !memcmp(last_db, db, db_len + 1))) memcpy(last_db, db, db_len + 1); } @@ -646,7 +646,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db) if(db && last_db) { - if(!(same_db = !memcmp(last_db, db, db_len))) + if(!(same_db = !memcmp(last_db, db, db_len + 1))) memcpy(last_db, db, db_len + 1); } -- cgit v1.2.1 From b74fd76c270820f75e95a004b3a776d2ecda7e1e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Apr 2001 01:12:51 +0300 Subject: Added a new option --result-file to mysqlbinlog. sql/mysqlbinlog.cc: Added option -r. --- sql/mysqlbinlog.cc | 66 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'sql') diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc index 05ff166cd49..f0a9692cc2d 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -38,6 +38,7 @@ ulong mysqld_net_retry_count = 10L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; uint test_flags = 0; +FILE *result_file; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; @@ -46,19 +47,19 @@ static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; static struct option long_options[] = { #ifndef DBUG_OFF - {"debug", optional_argument, 0, '#'}, + {"debug", optional_argument, 0, '#'}, #endif - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"offset", required_argument, 0, 'o'}, - {"password", required_argument, 0, 'p'}, - {"port", required_argument, 0, 'P'}, - {"position", required_argument, 0, 'j'}, - {"short-form", no_argument, 0, 's'}, - {"table", required_argument, 0, 't'}, - {"user", required_argument, 0, 'u'}, - {"version", no_argument, 0, 'V'}, - {0, 0, 0, 0} + {"help", no_argument, 0, '?'}, + {"host", required_argument, 0, 'h'}, + {"offset", required_argument, 0, 'o'}, + {"password", required_argument, 0, 'p'}, + {"port", required_argument, 0, 'P'}, + {"position", required_argument, 0, 'j'}, + {"result-file", required_argument, 0, 'r'}, + {"short-form", no_argument, 0, 's'}, + {"table", required_argument, 0, 't'}, + {"user", required_argument, 0, 'u'}, + {"version", no_argument, 0, 'V'}, }; void sql_print_error(const char *format,...); @@ -107,7 +108,7 @@ static void die(const char* fmt, ...) static void print_version() { - printf("%s Ver 1.2 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver 1.3 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); } @@ -134,6 +135,7 @@ the mysql command line client\n\n"); -P, --port=port Use port to connect to the remove server\n\ -u, --user=username Connect to the remove server as username\n\ -p, --password=password Password to connect to remote server\n\ +-r, --result-file=file Direct output to a given file\n\ -j, --position=N Start reading the binlog at position N\n\ -t, --table=name Get raw table dump using COM_TABLE_DUMB\n\ -V, --version Print version and exit.\n\ @@ -164,17 +166,18 @@ static void dump_remote_file(NET* net, const char* fname) die("Failed reading a packet during the dump of %s ", fname); if(!short_form) - (void)my_fwrite(stdout, (byte*) net->read_pos, packet_len, MYF(0)); + (void)my_fwrite(result_file, (byte*) net->read_pos, packet_len,MYF(0)); } - fflush(stdout); + fflush(result_file); } static int parse_args(int *argc, char*** argv) { int c, opt_index = 0; - while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:t:?V", long_options, + result_file = stdout; + while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:r:t:?V", long_options, &opt_index)) != EOF) { switch(c) @@ -211,6 +214,11 @@ static int parse_args(int *argc, char*** argv) pass = my_strdup(optarg, MYF(0)); break; + case 'r': + if (!(result_file = my_fopen(optarg, O_WRONLY | O_BINARY, MYF(MY_WME)))) + exit(1); + break; + case 'u': use_remote = 1; user = my_strdup(optarg, MYF(0)); @@ -277,14 +285,14 @@ static void dump_remote_table(NET* net, const char* db, const char* table) die("Error sending the table dump command"); for(;;) - { - uint packet_len = my_net_read(net); - if(packet_len == 0) break; // end of file - if(packet_len == packet_error) - die("Error reading packet in table dump"); - my_fwrite(stdout, (byte*)net->read_pos, packet_len, MYF(MY_WME)); - fflush(stdout); - } + { + uint packet_len = my_net_read(net); + if(packet_len == 0) break; // end of file + if(packet_len == packet_error) + die("Error reading packet in table dump"); + my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME)); + fflush(result_file); + } } @@ -325,7 +333,7 @@ Unfortunately, no sweepstakes today, adjusted position to 4\n"); len - 1); if(ev) { - ev->print(stdout, short_form, last_db); + ev->print(result_file, short_form, last_db); if(ev->get_type_code() == LOAD_EVENT) dump_remote_file(net, ((Load_log_event*)ev)->fname); delete ev; @@ -352,7 +360,7 @@ static void dump_local_log_entries(const char* logname) } else { - if (init_io_cache(file, fileno(stdout), 0, READ_CACHE, (my_off_t) 0, + if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) exit(1); if (position) @@ -398,9 +406,9 @@ Could not read entry at offset %s : Error in log format or read error", if (rec_count >= offset) { if (!short_form) - printf("# at %s\n",llstr(old_off,llbuff)); + fprintf(result_file, "# at %s\n",llstr(old_off,llbuff)); - ev->print(stdout, short_form, last_db); + ev->print(result_file, short_form, last_db); } rec_count++; delete ev; @@ -448,6 +456,8 @@ int main(int argc, char** argv) dump_log_entries(*(argv++)); } } + if (result_file != stdout) + my_fclose(result_file, MYF(0)); if (use_remote) mc_mysql_close(mysql); return 0; -- cgit v1.2.1 From eaa2350748beea0aa28bef227e62f4f00377247c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Apr 2001 16:07:40 +0300 Subject: Cleanup sql/log_event.cc: cleanup sql/mysqld.cc: Portability fix for AIX 4.2 Fix for services on Windows --- sql/log_event.cc | 2 +- sql/mysqld.cc | 34 ++++++++++++++++++++++++++-------- sql/sql_select.cc | 3 +-- 3 files changed, 28 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 5fc5f7f0e62..0cfdb2b3df7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -694,7 +694,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db) } if((int)skip_lines > 0) - fprintf(file, " IGNORE %d LINES ", skip_lines); + fprintf(file, " IGNORE %ld LINES ", (long) skip_lines); if (num_fields) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 931a21c9191..3d42f59ff93 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -92,6 +92,11 @@ int deny_severity = LOG_WARNING; typedef fp_except fp_except_t; #endif +#ifdef _AIX41 +extern "C" int initgroups(const char *,int); +#endif + + /* We can't handle floating point expections with threads, so disable this on freebsd */ @@ -144,7 +149,7 @@ static pthread_cond_t COND_handler_count; static uint handler_count; #endif #ifdef __WIN__ -static bool opt_console=0; +static bool opt_console=0,start_mode=0; #endif #ifdef HAVE_BERKELEY_DB @@ -1945,12 +1950,24 @@ The server will not act as a slave."); sql_print_error("After lock_thread_count"); #endif #else - // remove the event, because it will not be valid anymore - Service.SetShutdownEvent(0); - if(hEventShutdown) CloseHandle(hEventShutdown); - // if it was started as service on NT try to stop the service - if(Service.IsNT()) - Service.Stop(); + if (Service.IsNT()) + { + if(start_mode) + { + if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) + Service.Stop(); + } + else + { + Service.SetShutdownEvent(0); + if(hEventShutdown) CloseHandle(hEventShutdown); + } + } + else + { + Service.SetShutdownEvent(0); + if(hEventShutdown) CloseHandle(hEventShutdown); + } #endif /* Wait until cleanup is done */ @@ -2003,6 +2020,7 @@ int main(int argc, char **argv) else if (argc == 1) // No arguments; start as a service { // init service + start_mode = 1; long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service); return 0; } @@ -2477,7 +2495,7 @@ enum options { OPT_GEMINI_SKIP, OPT_INNODB_SKIP, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, - OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, + OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC }; static struct option long_options[] = { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index be1444c52e4..aad84cfd1b9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -210,7 +210,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, { if (item->with_sum_func) flag|=1; - else if (!item->const_item()) + else if (!(flag & 2) && !item->const_item()) flag|=2; } if (flag == 3) @@ -871,7 +871,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, s->join=join; if ((s->on_expr=tables->on_expr)) { - // table->maybe_null=table->outer_join=1; // Mark for send fields if (!table->file->records) { // Empty table s->key_dependent=s->dependent=0; -- cgit v1.2.1 From 6c127155953165ab3999dcd198de6ec8871059e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 May 2001 23:39:05 +0300 Subject: Fixed a bug with SELECT DISTINCT and HAVING Docs/manual.texi: Update AIX information support-files/Makefile.am: Removed mysql-max spec --- sql/sql_select.cc | 136 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 53 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aad84cfd1b9..5e2b42cc4c3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -36,7 +36,8 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, DYNAMIC_ARRAY *keyuse,List &ftfuncs); -static bool update_ref_and_keys(DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, +static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, + JOIN_TAB *join_tab, uint tables,COND *conds,table_map table_map, List &ftfuncs); static int sort_keyuse(KEYUSE *a,KEYUSE *b); @@ -106,12 +107,14 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, ha_rows select_limit); static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit); -static int remove_duplicates(JOIN *join,TABLE *entry,List &fields); +static bool fix_having(JOIN *join, Item **having); +static int remove_duplicates(JOIN *join,TABLE *entry,List &fields, + Item *having); static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, - ulong offset); + ulong offset,Item *having); static int remove_dup_with_hash_index(THD *thd, TABLE *table, uint field_count, Field **first_field, - ulong key_length); + ulong key_length,Item *having); static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count); static ulong used_blob_length(CACHE_FIELD **ptr); static bool store_record_in_cache(JOIN_CACHE *cache); @@ -717,8 +720,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (select_distinct && ! group) { thd->proc_info="Removing duplicates"; - if (remove_duplicates(&join,tmp_table,fields)) - goto err; /* purecov: inspected */ + if (having) + having->update_used_tables(); + if (remove_duplicates(&join,tmp_table,fields, having)) + goto err; /* purecov: inspected */ + having=0; select_distinct=0; } tmp_table->reginfo.lock_type=TL_UNLOCK; @@ -749,28 +755,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, /* If we have already done the group, add HAVING to sorted table */ if (having && ! group && ! join.sort_and_group) { - having->update_used_tables(); // Some tables may have been const - JOIN_TAB *table=&join.join_tab[join.const_tables]; - table_map used_tables= join.const_table_map | table->table->map; - - Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables); - if (sort_table_cond) - { - if (!table->select) - if (!(table->select=new SQL_SELECT)) - goto err; - if (!table->select->cond) - table->select->cond=sort_table_cond; - else // This should never happen - if (!(table->select->cond=new Item_cond_and(table->select->cond, - sort_table_cond))) - goto err; - table->select_cond=table->select->cond; - DBUG_EXECUTE("where",print_where(table->select->cond, - "select and having");); - having=make_cond_for_table(having,~ (table_map) 0,~used_tables); - DBUG_EXECUTE("where",print_where(conds,"having after sort");); - } + if (fix_having(&join,&having)) + goto err; } if (create_sort_index(&join.join_tab[join.const_tables], group ? group : order, @@ -941,7 +927,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, } if (conds || outer_join) - if (update_ref_and_keys(keyuse_array,stat,join->tables, + if (update_ref_and_keys(join->thd,keyuse_array,stat,join->tables, conds,~outer_join,ftfuncs)) DBUG_RETURN(1); @@ -1442,8 +1428,9 @@ sort_keyuse(KEYUSE *a,KEYUSE *b) */ static bool -update_ref_and_keys(DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,uint tables, - COND *cond, table_map normal_tables,List &ftfuncs) +update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, + uint tables, COND *cond, table_map normal_tables, + List &ftfuncs) { uint and_level,i,found_eq_constant; @@ -1451,8 +1438,7 @@ update_ref_and_keys(DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,uint tables, KEY_FIELD *key_fields,*end; if (!(key_fields=(KEY_FIELD*) - my_malloc(sizeof(key_fields[0])* - (current_thd->cond_count+1)*2,MYF(0)))) + thd->alloc((sizeof(key_fields[0])*thd->cond_count+1)*2))) return TRUE; /* purecov: inspected */ and_level=0; end=key_fields; if (cond) @@ -1466,14 +1452,10 @@ update_ref_and_keys(DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,uint tables, } } if (init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) - { - my_free((gptr) key_fields,MYF(0)); return TRUE; - } /* fill keyuse with found key parts */ for (KEY_FIELD *field=key_fields ; field != end ; field++) add_key_part(keyuse,field); - my_free((gptr) key_fields,MYF(0)); } if (ftfuncs.elements) @@ -1894,7 +1876,7 @@ cache_record_length(JOIN *join,uint idx) { uint length; JOIN_TAB **pos,**end; - THD *thd=current_thd; + THD *thd=join->thd; length=0; for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ; @@ -2076,7 +2058,7 @@ get_best_combination(JOIN *join) } else { - THD *thd=current_thd; + THD *thd=join->thd; for (i=0 ; i < keyparts ; keyuse++,i++) { while (keyuse->keypart != i || @@ -4433,7 +4415,8 @@ join_init_read_record(JOIN_TAB *tab) { if (tab->select && tab->select->quick) tab->select->quick->reset(); - init_read_record(&tab->read_record,current_thd, tab->table, tab->select,1,1); + init_read_record(&tab->read_record, tab->join->thd, tab->table, + tab->select,1,1); return (*tab->read_record.read_record)(&tab->read_record); } @@ -5265,6 +5248,38 @@ err: } +/* +** Add the HAVING criteria to table->select +*/ + +static bool fix_having(JOIN *join, Item **having) +{ + (*having)->update_used_tables(); // Some tables may have been const + JOIN_TAB *table=&join->join_tab[join->const_tables]; + table_map used_tables= join->const_table_map | table->table->map; + + Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables); + if (sort_table_cond) + { + if (!table->select) + if (!(table->select=new SQL_SELECT)) + return 1; + if (!table->select->cond) + table->select->cond=sort_table_cond; + else // This should never happen + if (!(table->select->cond=new Item_cond_and(table->select->cond, + sort_table_cond))) + return 1; + table->select_cond=table->select->cond; + DBUG_EXECUTE("where",print_where(table->select_cond, + "select and having");); + *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables); + DBUG_EXECUTE("where",print_where(*having,"having after make_cond");); + } + return 0; +} + + /***************************************************************************** ** Remove duplicates from tmp table ** This should be recoded to add a uniuqe index to the table and remove @@ -5305,7 +5320,7 @@ static void free_blobs(Field **ptr) static int -remove_duplicates(JOIN *join, TABLE *entry,List &fields) +remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) { int error; ulong reclength,offset; @@ -5342,9 +5357,10 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields) sortbuff_size))) error=remove_dup_with_hash_index(join->thd, entry, field_count, first_field, - reclength); + reclength, having); else - error=remove_dup_with_compare(join->thd, entry, first_field, offset); + error=remove_dup_with_compare(join->thd, entry, first_field, offset, + having); free_blobs(first_field); DBUG_RETURN(error); @@ -5352,19 +5368,19 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields) static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, - ulong offset) + ulong offset, Item *having) { handler *file=table->file; - char *org_record,*new_record; + char *org_record,*new_record, *record; int error; ulong reclength=table->reclength-offset; DBUG_ENTER("remove_dup_with_compare"); - org_record=(char*) table->record[0]+offset; + org_record=(char*) (record=table->record[0])+offset; new_record=(char*) table->record[1]+offset; file->rnd_init(); - error=file->rnd_next(table->record[0]); + error=file->rnd_next(record); for (;;) { if (thd->killed) @@ -5381,6 +5397,12 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, break; goto err; } + if (having && !having->val_int()) + { + if ((error=file->delete_row(record))) + goto err; + continue; + } if (copy_blobs(first_field)) { my_error(ER_OUT_OF_SORTMEMORY,MYF(0)); @@ -5393,7 +5415,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, bool found=0; for (;;) { - if ((error=file->rnd_next(table->record[0]))) + if ((error=file->rnd_next(record))) { if (error == HA_ERR_RECORD_DELETED) continue; @@ -5403,19 +5425,19 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (compare_record(table, first_field) == 0) { - if ((error=file->delete_row(table->record[0]))) + if ((error=file->delete_row(record))) goto err; } else if (!found) { found=1; - file->position(table->record[0]); // Remember position + file->position(record); // Remember position } } if (!found) break; // End of file /* Restart search on next row */ - error=file->restart_rnd_next(table->record[0],file->ref); + error=file->restart_rnd_next(record,file->ref); } file->extra(HA_EXTRA_NO_CACHE); @@ -5436,7 +5458,8 @@ err: static int remove_dup_with_hash_index(THD *thd, TABLE *table, uint field_count, Field **first_field, - ulong key_length) + ulong key_length, + Item *having) { byte *key_buffer, *key_pos, *record=table->record[0]; int error; @@ -5484,6 +5507,12 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, break; goto err; } + if (having && !having->val_int()) + { + if ((error=file->delete_row(record))) + goto err; + continue; + } /* copy fields to key buffer */ field_length=field_lengths; @@ -5499,7 +5528,8 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, if ((error=file->delete_row(record))) goto err; } - (void) hash_insert(&hash, key_pos-key_length); + else + (void) hash_insert(&hash, key_pos-key_length); key_pos+=extra_length; } my_free((char*) key_buffer,MYF(0)); -- cgit v1.2.1 From 0f716142902ea3209a57eae9fa18ca7de28a3da8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 May 2001 08:46:58 +0300 Subject: Fixed bug from last commit Docs/manual.texi: Changelog --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5e2b42cc4c3..398a2ddeec9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1438,7 +1438,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, KEY_FIELD *key_fields,*end; if (!(key_fields=(KEY_FIELD*) - thd->alloc((sizeof(key_fields[0])*thd->cond_count+1)*2))) + thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2))) return TRUE; /* purecov: inspected */ and_level=0; end=key_fields; if (cond) -- cgit v1.2.1 From 5461e6717c588b3c566c7edb4cd1b0d662e1a92c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 May 2001 14:41:03 +0300 Subject: sql_yacc.yy changed ...IN SHARE MODE to ...LOCK IN SHARE MODE to resolve a parsing bug after a WHERE clause sql/sql_yacc.yy: changed ...IN SHARE MODE to ...LOCK IN SHARE MODE to resolve a parsing bug after a WHERE clause --- sql/sql_yacc.yy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1196d279e5c..cb89dc04c15 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1270,7 +1270,7 @@ select_lock_type: /* empty */ | FOR_SYM UPDATE_SYM { Lex->lock_option= TL_WRITE; } - | IN_SYM SHARE_SYM MODE_SYM + | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; } select_item_list: -- cgit v1.2.1 From 70f585cbd689a2418a572097f0cf090b049cc4e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 May 2001 11:46:49 -0600 Subject: reversed virtual master BitKeeper/deleted/.del-binlog-backup-restore.test~d5b0b9bd83738a9f: Delete: mysql-test/t/binlog-backup-restore.test BitKeeper/deleted/.del-binlog-backup-restore.result~605de78abda64d27: Delete: mysql-test/r/binlog-backup-restore.result --- sql/slave.cc | 146 +++-------------------------------------------------------- sql/slave.h | 15 +----- 2 files changed, 7 insertions(+), 154 deletions(-) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 1ca8324e204..aded6d558fc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -20,7 +20,6 @@ #include #include "mini_client.h" #include "slave.h" -#include "sql_repl.h" #include #include @@ -442,101 +441,6 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi) return error; } -void MASTER_INFO::close_virtual_master() -{ - vm_binlog.close_index(); - end_io_cache(&vm_cache); - if(vm_fd >= 0) - { - my_close(vm_fd, MYF(0)); - vm_fd = -1; - } -} - -int MASTER_INFO::setup_virtual_master() -{ - vm_binlog.init(LOG_BIN); - vm_binlog.set_index_file_name(host); - if(vm_binlog.open_index(O_RDONLY)) - { - sql_print_error("virtual master: could not open index file '%s': \ - (%d)", host, my_errno); - return 1; - } - - if(vm_binlog.find_first_log(&vm_linfo,log_file_name)) - { - sql_print_error("virtual master: could not find first log"); - return 1; - } - - if(open_log()) - return 1; - - return 0; -} - -int MASTER_INFO::open_log() -{ - const char* errmsg = "Unknown error"; - if(vm_fd >= 0) - { - end_io_cache(&vm_cache); - my_close(vm_fd, MYF(0)); - } - - // if backup-up logs have relative paths, assume they are relative to - // the directory that has the log index, not cwd - char logname_buf[FN_REFLEN+1], *logname; - if(vm_linfo.log_file_name[0] == FN_LIBCHAR) - logname = vm_linfo.log_file_name; - else - { - char* end = strnmov(logname_buf, host, - sizeof(logname_buf)); - for(; *end != FN_LIBCHAR; --end); // we will always find it, first - // char of host is always FN_LIBCHAR for virtual master - - strncpy(end + 1, vm_linfo.log_file_name, - sizeof(logname_buf) - (end - logname_buf)); - logname = logname_buf; - } - - if((vm_fd = open_binlog(&vm_cache, logname, &errmsg)) < 0) - { - sql_print_error("virtual master: error opening binlog '%s': %s", - vm_linfo.log_file_name, errmsg); - return 1; - } - - strncpy(log_file_name, vm_linfo.log_file_name, sizeof(log_file_name)); - return 0; -} - -uint MASTER_INFO::read_event() -{ - for(;!(vm_ev = Log_event::read_log_event(&vm_cache, 0));) - { - if(!vm_cache.error) // eof - try next log - { - switch(vm_binlog.find_next_log(&vm_linfo)) - { - case LOG_INFO_EOF: - return 0; - case 0: - if(open_log()) - return packet_error; - continue; - default: - sql_print_error("virtual master: could not read next log"); - return packet_error; - } - } - } - - return vm_ev->get_data_size() + LOG_EVENT_HEADER_LEN; -} - void end_master_info(MASTER_INFO* mi) { if(mi->fd >= 0) @@ -546,8 +450,6 @@ void end_master_info(MASTER_INFO* mi) mi->fd = -1; } mi->inited = 0; - if(mi->virtual_master) - mi->close_virtual_master(); } int init_master_info(MASTER_INFO* mi) @@ -643,7 +545,6 @@ int init_master_info(MASTER_INFO* mi) } mi->inited = 1; - mi->virtual_master = (mi->host[0] == FN_LIBCHAR); // now change the cache from READ to WRITE - must do this // before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1); @@ -841,9 +742,6 @@ static int safe_sleep(THD* thd, int sec) static int request_dump(MYSQL* mysql, MASTER_INFO* mi) { - if(mi->virtual_master) - return 0; - char buf[FN_REFLEN + 10]; int len; int binlog_flags = 0; // for now @@ -897,9 +795,6 @@ command"); static uint read_event(MYSQL* mysql, MASTER_INFO *mi) { - if(mi->virtual_master) - return mi->read_event(); - uint len = packet_error; // for convinience lets think we start by // being in the interrupted state :-) @@ -965,18 +860,16 @@ point. If you are sure that your master is ok, run this query manually on the\ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) { - Log_event * ev = (mi->virtual_master) ? mi->vm_ev : - Log_event::read_log_event((const char*)net->read_pos + 1, - event_len) ; + Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1, + event_len); char llbuff[22]; if (ev) { int type_code = ev->get_type_code(); - if ((!mi->virtual_master && ev->server_id == ::server_id) - || slave_skip_counter) + if (ev->server_id == ::server_id || slave_skip_counter) { - if(type_code == LOAD_EVENT && !mi->virtual_master) + if(type_code == LOAD_EVENT) skip_load_data_infile(net); mi->inc_pos(event_len); @@ -1078,14 +971,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) case LOAD_EVENT: { - if(mi->virtual_master) - { - delete ev; - sql_print_error("LOAD DATA INFILE does not yet work with virtual \ -master. Perform in manually, then restart slave with SET SQL_SKIP_COUNTER=1;\ -SLAVE START"); - return 1; - } Load_log_event* lev = (Load_log_event*)ev; init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)lev->db); @@ -1108,8 +993,7 @@ SLAVE START"); // the table will be opened in mysql_load if(table_rules_on && !tables_ok(thd, &tables)) { - if(!mi->virtual_master) - skip_load_data_infile(net); + skip_load_data_infile(net); } else { @@ -1173,8 +1057,7 @@ SLAVE START"); { // we will just ask the master to send us /dev/null if we do not // want to load the data :-) - if(!mi->virtual_master) - skip_load_data_infile(net); + skip_load_data_infile(net); } thd->net.vio = 0; @@ -1410,21 +1293,9 @@ try again, log '%s' at postion %s", RPL_LOG_NAME, sql_print_error("Slave thread killed while reading event"); goto err; } - - if(!event_len && glob_mi.virtual_master) - { - sql_print_error("Virtual master replication finished"); - goto err; - } if (event_len == packet_error) { - if(glob_mi.virtual_master) - { - sql_print_error("Virtual master replication encountered \ -error while reading event, replication terminated"); - goto err; - } thd->proc_info = "Waiting to reconnect after a failed read"; if(mysql->net.vio) vio_close(mysql->net.vio); @@ -1532,8 +1403,6 @@ position %s", static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { - if(mi->virtual_master) - return mi->setup_virtual_master(); int slave_was_killed; #ifndef DBUG_OFF events_till_disconnect = disconnect_slave_event_count; @@ -1563,9 +1432,6 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { - if(mi->virtual_master) - return mi->setup_virtual_master(); - int slave_was_killed; char llbuff[22]; diff --git a/sql/slave.h b/sql/slave.h index d04c0c13c23..311368a4b82 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -16,14 +16,8 @@ typedef struct st_master_info pthread_mutex_t lock; pthread_cond_t cond; bool inited; - bool virtual_master; // for replay of binlogs from a directory - MYSQL_LOG vm_binlog; - LOG_INFO vm_linfo; - IO_CACHE vm_cache; - int vm_fd; - Log_event* vm_ev; - st_master_info():pending(0),fd(-1),inited(0),virtual_master(0),vm_fd(-1) + st_master_info():pending(0),fd(-1),inited(0) { host[0] = 0; user[0] = 0; password[0] = 0; pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST); @@ -34,8 +28,6 @@ typedef struct st_master_info { pthread_mutex_destroy(&lock); pthread_cond_destroy(&cond); - if(virtual_master) - close_virtual_master(); } inline void inc_pending(ulonglong val) { @@ -59,11 +51,6 @@ typedef struct st_master_info } int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos); - int setup_virtual_master(); - void close_virtual_master(); - uint read_event(); - int open_log(); - } MASTER_INFO; typedef struct st_table_rule_ent -- cgit v1.2.1 From 9167c803120d616191aee7aa5d9d620683b2a857 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 May 2001 16:01:13 -0600 Subject: Docs/manual.texi fixed bug sql/sql_repl.cc undid virtual master change Docs/manual.texi: fixed bug sql/sql_repl.cc: undid virtual master change --- sql/sql_repl.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ed41bf53692..e5039d118be 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -695,10 +695,7 @@ int change_master(THD* thd) if(lex_mi->host) { - if(glob_mi.virtual_master) - glob_mi.close_virtual_master(); strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host)); - glob_mi.virtual_master = (glob_mi.host[0] == FN_LIBCHAR); } if(lex_mi->user) strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user)); -- cgit v1.2.1 From d6ad4beed345b96dd45b4c731cd53f22cc5ef65d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 May 2001 17:27:35 -0600 Subject: better error message in replication when packet is too large sql/mini_client.cc: pass along ER_NET_PACKET_TOO_LARGE sql/slave.cc: better error message when the packet is too large in slave thread --- sql/mini_client.cc | 10 ++++++++-- sql/slave.cc | 12 +++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/mini_client.cc b/sql/mini_client.cc index fa1b9da38a8..38180c0c6c8 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -330,8 +330,14 @@ mc_net_safe_read(MYSQL *mysql) if(errno != EINTR) { mc_end_server(mysql); - net->last_errno=CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + if(net->last_errno != ER_NET_PACKET_TOO_LARGE) + { + net->last_errno=CR_SERVER_LOST; + strmov(net->last_error,ER(net->last_errno)); + } + else + strmov(net->last_error, "Packet too large - increase \ +max_allowed_packet on this server"); } return(packet_error); } diff --git a/sql/slave.cc b/sql/slave.cc index aded6d558fc..6b9c376a625 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1293,9 +1293,19 @@ try again, log '%s' at postion %s", RPL_LOG_NAME, sql_print_error("Slave thread killed while reading event"); goto err; } - + + if (event_len == packet_error) { + if(mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE) + { + sql_print_error("Log entry on master is longer than \ +max_allowed_packet on slave. Slave thread will be aborted. If the entry is \ +really supposed to be that long, restart the server with a higher value of \ +max_allowed_packet. The current value is %ld", max_allowed_packet); + goto err; + } + thd->proc_info = "Waiting to reconnect after a failed read"; if(mysql->net.vio) vio_close(mysql->net.vio); -- cgit v1.2.1 From 62bff11cb46c059b1fcb2aeba5e65ec99e7d3448 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 5 May 2001 09:41:47 +0300 Subject: Added LOAD DATA CONCURRENT Docs/manual.texi: Update information about REPAIR and optimize scripts/mysqlhotcopy.sh: Changed Alpha -> Beta sql/sql_yacc.yy: A --- sql/lex.h | 1 + sql/sql_yacc.yy | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/lex.h b/sql/lex.h index 6c83cb34366..d5df5ed5511 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -88,6 +88,7 @@ static SYMBOL symbols[] = { { "COMMIT", SYM(COMMIT_SYM),0,0}, { "COMMITTED", SYM(COMMITTED_SYM),0,0}, { "COMPRESSED", SYM(COMPRESSED_SYM),0,0}, + { "CONCURRENT", SYM(CONCURRENT),0,0}, { "CONSTRAINT", SYM(CONSTRAINT),0,0}, { "CREATE", SYM(CREATE),0,0}, { "CROSS", SYM(CROSS),0,0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1196d279e5c..3caa956ebea 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -145,6 +145,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token COMMITTED_SYM %token COLUMNS %token COLUMN_SYM +%token CONCURRENT %token CONSTRAINT %token DATABASES %token DATA_SYM @@ -2339,7 +2340,7 @@ use: USE_SYM ident /* import, export of files */ -load: LOAD DATA_SYM opt_low_priority opt_local INFILE TEXT_STRING +load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING { Lex->sql_command= SQLCOM_LOAD; Lex->local_file= $4; @@ -2366,6 +2367,12 @@ opt_local: /* empty */ { $$=0;} | LOCAL_SYM { $$=1;} +load_data_lock: + /* empty */ { Lex->lock_option= current_thd->update_lock_default; } + | CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + + opt_duplicate: /* empty */ { Lex->duplicates=DUP_ERROR; } | REPLACE { Lex->duplicates=DUP_REPLACE; } @@ -2523,6 +2530,7 @@ keyword: | COMMIT_SYM {} | COMMITTED_SYM {} | COMPRESSED_SYM {} + | CONCURRENT {} | DATA_SYM {} | DATETIME {} | DATE_SYM {} -- cgit v1.2.1 From 0fece375f2ae4bb173357609b46924a997113593 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 May 2001 23:02:36 +0300 Subject: Applied patches for BDB tables Fixes to InnoDB to compile on Windows Fix for temporary InnoDB tables Fixed bug in REPLACE() Fixed sub char keys for InnoDB Docs/manual.texi: Changelog + update of table types bdb/include/log.h: Patch from Sleepycat bdb/log/log.c: Patch from Sleepycat bdb/log/log_rec.c: Patch from Sleepycat client/mysqladmin.c: Cleanup innobase/include/univ.i: Fix for compilation on Windows innobase/os/os0file.c: cleanup innobase/pars/pars0grm.y: Fix for compilation on Windows mysql-test/r/innodb.result: New test case mysql-test/t/innodb.test: New test case sql/ha_innobase.cc: cleanup sql/ha_innobase.h: Fix for prefix keys sql/handler.h: Fix for temporary Innodb tables sql/item_strfunc.cc: Fixed bug in REPLACE() sql/lock.cc: Fix for temporary Innodb tables sql/mysqld.cc: Added --skip-stack-trace sql/share/english/errmsg.txt: Better error messages sql/sql_base.cc: Fix for temporary Innodb tables sql/sql_select.cc: Fix for temporary Innodb tables sql/sql_table.cc: Fixed sub char keys for InnoDB sql/table.h: Fix for temporary Innodb tables --- sql/ha_innobase.cc | 2 +- sql/ha_innobase.h | 4 ++-- sql/handler.h | 1 + sql/item_strfunc.cc | 10 +++++++--- sql/lock.cc | 4 ++-- sql/mysqld.cc | 19 +++++++++++++------ sql/share/english/errmsg.txt | 2 +- sql/sql_base.cc | 8 ++++---- sql/sql_select.cc | 2 +- sql/sql_table.cc | 35 +++++++++++++++++++---------------- sql/table.h | 5 ++++- 11 files changed, 55 insertions(+), 37 deletions(-) (limited to 'sql') diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 72857fc953f..8af9de0eaba 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -449,7 +449,7 @@ innobase_init(void) if (!innobase_data_file_path) { fprintf(stderr, - "Can't initialize InnoDB as 'innobase_data_file_path' is not set\n"); + "Can't initialize InnoDB as 'innodb_data_file_path' is not set\n"); innodb_skip=1; DBUG_RETURN(FALSE); // Continue without innobase } diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index e85d73bdae5..429e47523dd 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -83,14 +83,14 @@ class ha_innobase: public handler HA_NO_WRITE_DELAYED | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | - HA_NOT_READ_AFTER_KEY), + HA_NOT_READ_AFTER_KEY | HA_NO_PREFIX_CHAR_KEYS), last_dup_key((uint) -1), start_of_scan(0) { } ~ha_innobase() {} - const char* table_type() const { return("Innobase");} + const char* table_type() const { return("InnoDB");} const char** bas_ext() const; ulong option_flag() const { return int_option_flag; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/handler.h b/sql/handler.h index c7df6e2a915..076bf783f80 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -73,6 +73,7 @@ #define HA_NOT_READ_AFTER_KEY (HA_DROP_BEFORE_CREATE*2) #define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2) #define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2) +#define HA_NO_PREFIX_CHAR_KEYS (HA_NO_TEMP_TABLES*2) /* Parameters for open() (in register form->filestat) */ /* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */ diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 82dcb0268b4..80f72c30e57 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -393,12 +393,14 @@ void Item_func_reverse::fix_length_and_dec() String *Item_func_replace::val_str(String *str) { String *res,*res2,*res3; - int offset=0; + int offset; uint from_length,to_length; bool alloced=0; #ifdef USE_MB const char *ptr,*end,*strend,*search,*search_end; register uint32 l; + bool binary_str = (args[0]->binary || args[1]->binary || + !use_mb(default_charset_info)); #endif null_value=0; @@ -415,7 +417,8 @@ String *Item_func_replace::val_str(String *str) if ((offset=res->strstr(*res2)) < 0) return res; #else - if (!use_mb(default_charset_info) && (offset=res->strstr(*res2)) < 0) + offset=0; + if (binary_str && (offset=res->strstr(*res2)) < 0) return res; #endif if (!(res3=args[2]->val_str(&tmp_value2))) @@ -424,7 +427,7 @@ String *Item_func_replace::val_str(String *str) to_length= res3->length(); #ifdef USE_MB - if (use_mb(default_charset_info)) + if (!binary_str) { search=res2->ptr(); search_end=search+from_length; @@ -449,6 +452,7 @@ redo: res=copy_if_not_alloced(str,res,res->length()+to_length); } res->replace((uint) offset,from_length,*res3); + offset+=(int) to_length; goto redo; } skipp: diff --git a/sql/lock.cc b/sql/lock.cc index 915f1831245..23f81c9c164 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -346,7 +346,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=0; for (i=tables=lock_count=0 ; i < count ; i++) { - if (!table_ptr[i]->tmp_table) + if (table_ptr[i]->tmp_table != TMP_TABLE) { tables+=table_ptr[i]->file->lock_count(); lock_count++; @@ -366,7 +366,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, for (i=0 ; i < count ; i++) { TABLE *table; - if ((table=table_ptr[i])->tmp_table) + if ((table=table_ptr[i])->tmp_table == TMP_TABLE) continue; *to++=table; enum thr_lock_type lock_type= table->reginfo.lock_type; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3d42f59ff93..7c4b88d0170 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1222,7 +1222,8 @@ stack trace and/or the core file to produce a readable backtrace that may\n\ help in finding out why mysqld died.\n",sig); #if defined(HAVE_LINUXTHREADS) #ifdef __i386__ - trace_stack(); + if (!(test_flags & TEST_NO_STACKTRACE)) + trace_stack(); fflush(stderr); #endif /* __i386__ */ if (test_flags & TEST_CORE_ON_SIGNAL) @@ -1253,7 +1254,7 @@ static void init_signals(void) struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); - if (!(test_flags & TEST_NO_STACKTRACE)) + if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) { sa.sa_handler=handle_segfault; sigaction(SIGSEGV, &sa, NULL); @@ -2495,7 +2496,8 @@ enum options { OPT_GEMINI_SKIP, OPT_INNODB_SKIP, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, - OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC + OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, + OPT_SKIP_STACK_TRACE }; static struct option long_options[] = { @@ -2617,11 +2619,12 @@ static struct option long_options[] = { {"skip-locking", no_argument, 0, (int) OPT_SKIP_LOCK}, {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE}, {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE}, + {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING}, {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW}, {"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC}, {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB}, {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START}, - {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING}, + {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE}, {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, #include "sslopt-longopts.h" @@ -3047,15 +3050,16 @@ static void usage(void) Don't use concurrent insert with MyISAM\n\ --skip-delay-key-write\n\ Ignore the delay_key_write option for all tables\n\ + --skip-host-cache Don't cache host names\n\ --skip-locking Don't use system locking. To use isamchk one has\n\ to shut down the server.\n\ --skip-name-resolve Don't resolve hostnames.\n\ All hostnames are IP's or 'localhost'\n\ --skip-networking Don't allow connection with TCP/IP.\n\ - --skip-new Don't use new, possible wrong routines.\n\ - --skip-host-cache Don't cache host names\n"); + --skip-new Don't use new, possible wrong routines.\n"); /* We have to break the string here because of VC++ limits */ puts("\ + --skip-stack-trace Don't print a stack trace on failure\n\ --skip-show-database Don't allow 'SHOW DATABASE' commands\n\ --skip-thread-priority\n\ Don't give threads different priorities.\n\ @@ -3501,6 +3505,9 @@ static void get_options(int argc,char **argv) case (int) OPT_WANT_CORE: test_flags |= TEST_CORE_ON_SIGNAL; break; + case (int) OPT_SKIP_STACK_TRACE: + test_flags|=TEST_NO_STACKTRACE; + break; case (int) OPT_BIND_ADDRESS: if (optarg && isdigit(optarg[0])) { diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 74139b30a85..ff29fffe958 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -90,7 +90,7 @@ "File '%-.80s' already exists", "Records: %ld Deleted: %ld Skipped: %ld Warnings: %ld", "Records: %ld Duplicates: %ld", -"Incorrect sub part key. The used key part isn't a string or the used length is longer than the key part", +"Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys", "You can't delete all columns with ALTER TABLE. Use DROP TABLE instead", "Can't DROP '%-.64s'. Check that column/key exists", "Records: %ld Duplicates: %ld Warnings: %ld", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index afff01e9a16..3c81723b61f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1495,8 +1495,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, DBUG_RETURN(0); /* purecov: inspected */ if (openfrm(path, table_name, - (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | - HA_TRY_READ_ONLY), + (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX), READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, ha_open_options, tmp_table)) @@ -1505,8 +1504,9 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, } tmp_table->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL - tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked - tmp_table->tmp_table = 1; + tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked + tmp_table->tmp_table = (tmp_table->file->has_transactions() ? + TRANSACTIONAL_TMP_TABLE : TMP_TABLE); tmp_table->table_cache_key=(char*) (tmp_table+1); tmp_table->key_length= (uint) (strmov((tmp_table->real_name= strmov(tmp_table->table_cache_key,db) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 398a2ddeec9..95a87e06f2b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3358,7 +3358,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->blob_ptr_size=mi_portable_sizeof_char_ptr; table->map=1; - table->tmp_table=1; + table->tmp_table= TMP_TABLE; table->db_low_byte_first=1; // True for HEAP and MyISAM table->temp_pool_slot = temp_pool_slot; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 78721c3e8f9..ad39b91a5ca 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -479,12 +479,16 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } } else if (column->length > length || - (f_is_packed(sql_field->pack_flag) && column->length != length)) + ((f_is_packed(sql_field->pack_flag) || + ((file->option_flag() & HA_NO_PREFIX_CHAR_KEYS) && + (key_info->flags & HA_NOSAME))) && + column->length != length)) { my_error(ER_WRONG_SUB_KEY,MYF(0)); DBUG_RETURN(-1); } - length=column->length; + if (!(file->option_flag() & HA_NO_PREFIX_CHAR_KEYS)) + length=column->length; } else if (length == 0) { @@ -1426,21 +1430,20 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info, create_list,key_list,1,1))) // no logging DBUG_RETURN(error); + + if (table->tmp_table) + new_table=open_table(thd,new_db,tmp_name,tmp_name,0); + else { - if (table->tmp_table) - new_table=open_table(thd,new_db,tmp_name,tmp_name,0); - else - { - char path[FN_REFLEN]; - (void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,tmp_name); - fn_format(path,path,"","",4); - new_table=open_temporary_table(thd, path, new_db, tmp_name,0); - } - if (!new_table) - { - VOID(quick_rm_table(new_db_type,new_db,tmp_name)); - goto err; - } + char path[FN_REFLEN]; + (void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,tmp_name); + fn_format(path,path,"","",4); + new_table=open_temporary_table(thd, path, new_db, tmp_name,0); + } + if (!new_table) + { + VOID(quick_rm_table(new_db_type,new_db,tmp_name)); + goto err; } save_time_stamp=new_table->time_stamp; diff --git a/sql/table.h b/sql/table.h index a3b361742c5..b627a158556 100644 --- a/sql/table.h +++ b/sql/table.h @@ -41,6 +41,8 @@ typedef struct st_grant_info uint want_privilege; } GRANT_INFO; +enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2}; + /* Table cache entry struct */ class Field_timestamp; @@ -83,10 +85,11 @@ struct st_table { uint blob_ptr_size; /* 4 or 8 */ uint next_number_key_offset; int current_lock; /* Type of lock on table */ + enum tmp_table_type tmp_table; my_bool copy_blobs; /* copy_blobs when storing */ my_bool null_row; /* All columns are null */ my_bool maybe_null,outer_join; /* Used with OUTER JOIN */ - my_bool distinct,tmp_table,const_table; + my_bool distinct,const_table; my_bool key_read; my_bool crypted; my_bool db_low_byte_first; /* Portable row format */ -- cgit v1.2.1 From 68ebea2d6f84c15aac8ccd24995830719878c31d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 May 2001 22:22:04 -0600 Subject: stack trace updates: limited support on Alpha - in general case, even with frame pointer, stack trace on alpha is impossible without looking at the symbol table frame pointer does get saved on the stack, but you have no idea where and where the return address is saved. So the best we can do without the symbol table is look for magic opcodes and try to guess how big each frame is and where the return address was hidden from the instruction parameters. In practice, we can usually go up 3-4 frames before we hit some nasty frame that the current code cannot figure out. This is actually not too bad, especially when we already have the query Also cleaned up messages, print more variables, tell the user of how much memory mysqld could potentially use, and warn of what can happen with default STACK_SIZE and a lot of connections if coredump happens when there are more than 200 connections. sql/mysqld.cc: stack trace updates --- sql/mysqld.cc | 203 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 174 insertions(+), 29 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3d42f59ff93..96afd647022 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1111,9 +1111,12 @@ static void start_signal_handler(void) #ifdef HAVE_LINUXTHREADS static sig_handler write_core(int sig); -#ifdef __i386__ -#define SIGRETURN_FRAME_COUNT 1 -#define PTR_SANE(p) ((char*)p >= heap_start && (char*)p <= heap_end) +#if defined (__i386__) || defined(__alpha__) +#define LINUX_STACK_TRACE +#endif + +#ifdef LINUX_STACK_TRACE +#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) extern char* __bss_start; static char* heap_start, *heap_end; @@ -1133,32 +1136,90 @@ inline __volatile__ void print_str(const char* name, fputc(*val++, stderr); fputc('\n', stderr); } +#endif + + +#ifdef LINUX_STACK_TRACE +#define SIGRETURN_FRAME_COUNT 1 + +#ifdef __alpha__ +// The only way to backtrace without a symbol table on alpha +// to find stq fp,N(sp), and the first byte +// of the instruction opcode will give us the value of N. From this +// we can find where the old value of fp is stored + +#define MAX_INSTR_IN_FUNC 10000 + +inline uchar** find_prev_fp(uint32* pc, uchar** fp) +{ + int i; + for(i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + uchar* p = (uchar*)pc; + if(p[2] == 222 && p[3] == 35) + { + return (uchar**)((uchar*)fp - *(short int*)p); + } + } + return 0; +} + +inline uint32* find_prev_pc(uint32* pc, uchar** fp) +{ + int i; + for(i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + char* p = (char*)pc; + if(p[1] == 0 && p[2] == 94 && p[3] == -73) + { + uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); + return prev_pc; + } + } + return 0; +} + +#endif inline __volatile__ void trace_stack() { uchar **stack_bottom; - uchar** ebp; - LINT_INIT(ebp); + uchar** fp; + LINT_INIT(fp); LINT_INIT(stack_bottom); fprintf(stderr, "Attempting backtrace. You can use the following information to find out\n\ -where mysqld died. If you see no messages after this, something went\n\ +where mysqld died. If you see no messages after this, something went\n\ terribly wrong...\n"); THD* thd = current_thd; uint frame_count = 0; +#ifdef __i386__ __asm __volatile__ ("movl %%ebp,%0" - :"=r"(ebp) - :"r"(ebp)); - if (!ebp) + :"=r"(fp) + :"r"(fp)); + if (!fp) { fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\ -fomit-frame-pointer? Aborting backtrace!\n"); return; } +#endif +#ifdef __alpha__ + __asm __volatile__ ("mov $15,%0" + :"=r"(fp) + :"r"(fp)); + if (!fp) + { + fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\ +-fomit-frame-pointer? Aborting backtrace!\n"); + return; + } +#endif + if (!thd) { - fprintf(stderr, "Cannot determine thread, ebp=%p, backtrace may not be correct.\n", ebp); + fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp); /* Assume that the stack starts at the previous even 65K */ ulong tmp= min(0x10000,thread_stack); stack_bottom= (uchar**) (((ulong) &stack_bottom + tmp) & @@ -1166,33 +1227,77 @@ terribly wrong...\n"); } else stack_bottom = (uchar**) thd->thread_stack; - if (ebp > stack_bottom || ebp < stack_bottom - thread_stack) + if (fp > stack_bottom || fp < stack_bottom - thread_stack) { - fprintf(stderr, - "Bogus stack limit or frame pointer, aborting backtrace.\n"); + fprintf(stderr, "Bogus stack limit or frame pointer,\ + fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n", + fp, stack_bottom, thread_stack); return; } fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n"); +#ifdef __alpha__ + fprintf(stderr, "Warning: Alpha stacks are difficult -\ + will be taking some wild guesses, stack trace may be incorrect or \ + terminate abruptly\n"); + // On Alpha, we need to get pc + uint32* pc; + __asm __volatile__ ("bsr %0, do_next; do_next: " + :"=r"(pc) + :"r"(pc)); +#endif - while (ebp < stack_bottom) + while (fp < stack_bottom) { - uchar** new_ebp = (uchar**)*ebp; +#ifdef __i386__ + uchar** new_fp = (uchar**)*fp; fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ? - *(ebp+17) : *(ebp+1)); - if (new_ebp <= ebp ) + *(fp+17) : *(fp+1)); +#endif +#ifdef __alpha__ + uchar** new_fp = find_prev_fp(pc, fp); + if(frame_count == SIGRETURN_FRAME_COUNT - 1) + { + new_fp += 90; + } + + if(fp && pc) + { + pc = find_prev_pc(pc, fp); + if(pc) + fprintf(stderr, "%p\n", pc); + else + { + fprintf(stderr, "Not smart enough to deal with the rest\ + of this stack\n"); + goto print_glob_vars; + } + } + else + { + fprintf(stderr, "Not smart enough to deal with the rest of \ + this stack\n"); + goto print_glob_vars; + } +#endif + if (new_fp <= fp ) { - fprintf(stderr, "\ -New value of ebp failed sanity check, terminating backtrace!\n"); - return; + fprintf(stderr, "New value of fp=%p failed sanity check,\ + terminating stack trace!\n", new_fp); + goto print_glob_vars; } - ebp = new_ebp; + fp = new_fp; ++frame_count; } - fprintf(stderr, "Stack trace successful, trying to get some variables.\n\ + fprintf(stderr, "Stack trace seems successful - bottom reached\n"); + + print_glob_vars: + fprintf(stderr, "Please read http://www.mysql.com/doc/U/s/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\ +stack trace is much more helpful in diagnosing the problem, so please do \n\ +resolve it\n"); + fprintf(stderr, "Trying to get some variables.\n\ Some pointers may be invalid and cause the dump to abort...\n"); - heap_start = __bss_start; heap_end = (char*)sbrk(0); print_str("thd->query", thd->query, 1024); fprintf(stderr, "thd->thread_id = %ld\n", thd->thread_id); @@ -1206,6 +1311,10 @@ test case for the crash, and send it to bugs@lists.mysql.com\n"); #endif #endif +#ifdef HAVE_LINUXTHREADS +#define UNSAFE_DEFAULT_LINUX_THREADS 200 +#endif + static sig_handler handle_segfault(int sig) { // strictly speaking, one needs a mutex here @@ -1213,18 +1322,49 @@ static sig_handler handle_segfault(int sig) // so not having the mutex is not as bad as possibly using a buggy // mutex - so we keep things simple if (segfaulted) - return; + { + fprintf(stderr, "Fatal signal %d while backtracing\n", sig); + exit(1); + } + segfaulted = 1; fprintf(stderr,"\ mysqld got signal %d;\n\ -The manual section 'Debugging a MySQL server' tells you how to use a\n\ -stack trace and/or the core file to produce a readable backtrace that may\n\ -help in finding out why mysqld died.\n",sig); +This could be because you hit a bug. It is also possible that \n\ +this binary or one of the libraries it was linked agaist is \n\ +corrupt, improperly built, or misconfigured. This error can also be\n\ +caused by malfunctioning hardware.", sig); + fprintf(stderr, "We will try our best to scrape up some info\n\ +that will hopefully help diagnose the problem, but since we have already\n\ +crashed, something is definitely wrong and this may fail\n"); + fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size); + fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size); + fprintf(stderr, "sort_buffer=%ld\n", sortbuff_size); + fprintf(stderr, "max_used_connections=%ld\n", max_used_connections); + fprintf(stderr, "max_connections=%ld\n", max_connections); + fprintf(stderr, "threads_connected=%d\n", thread_count); + fprintf(stderr, "It is possible that mysqld could use up to \n\ +key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\ +bytes of memory\n", (keybuff_size + (my_default_record_cache_size + + sortbuff_size) * max_connections)/ 1024); + fprintf(stderr, "Hope that's ok, if not, decrease some variables in the\n\ +equation\n"); + #if defined(HAVE_LINUXTHREADS) -#ifdef __i386__ + + if(sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) + { + fprintf(stderr, "You seem to be running 32-bit Linux and\n\ + have %d concurrent connections. If you have not\n\ +changed STACK_SIZE in LinuxThreads and build the binary yourself,\n\ +LinuxThreads is quite likely to steal a part of global heap for a \n\ +thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n", + thread_count); + } +#ifdef LINUX_STACK_TRACE trace_stack(); fflush(stderr); -#endif /* __i386__ */ +#endif /* LINUX_STACK_TRACE */ if (test_flags & TEST_CORE_ON_SIGNAL) write_core(sig); #endif /* HAVE_LINUXTHREADS */ @@ -1253,6 +1393,11 @@ static void init_signals(void) struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); + +#ifdef LINUX_STACK_TRACE + heap_start = (char*)&__bss_start; +#endif + if (!(test_flags & TEST_NO_STACKTRACE)) { sa.sa_handler=handle_segfault; -- cgit v1.2.1 From b59b5f4b6ec6bd5b0eb8cee832b6d4f51fa646fc Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 May 2001 22:42:49 -0600 Subject: sql/mysqld.cc put back the things that the merge removed sql/mysqld.cc: put back the things that the merge removed --- sql/mysqld.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d51d7b590da..1db105c28f8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1362,7 +1362,8 @@ thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n", thread_count); } #ifdef LINUX_STACK_TRACE - trace_stack(); + if(!(test_flags & TEST_NO_STACKTRACE)) + trace_stack(); fflush(stderr); #endif /* LINUX_STACK_TRACE */ if (test_flags & TEST_CORE_ON_SIGNAL) @@ -1398,7 +1399,7 @@ static void init_signals(void) heap_start = (char*)&__bss_start; #endif - if (!(test_flags & TEST_NO_STACKTRACE)) + if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) { sa.sa_handler=handle_segfault; sigaction(SIGSEGV, &sa, NULL); -- cgit v1.2.1