From a35ba0ea0ce87b54c65d451a50d7821ac0f92d4a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Nov 2003 22:08:45 +0100 Subject: [PATCH 1/7] obligatory update checksum on repair, if it is obligatory verified on check. --- myisam/mi_check.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index a4ae7b25dbb..466defe8fbc 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1153,6 +1153,9 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + if (!param->using_global_keycache) VOID(init_key_cache(param->use_buffers)); @@ -1820,6 +1823,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + bzero((char*)&sort_info,sizeof(sort_info)); bzero((char *)&sort_param, sizeof(sort_param)); if (!(sort_info.key_block= @@ -2189,6 +2195,9 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + bzero((char*)&sort_info,sizeof(sort_info)); if (!(sort_info.key_block= alloc_key_blocks(param, From 069ec78c803516363e91c550624032d1b622dec9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Nov 2003 17:37:15 +0100 Subject: [PATCH 2/7] Item_uint::save_in_field() added to take into account bigint->decimal case BitKeeper/etc/ignore: Added sql/udf_example.so to the ignore list --- .bzrignore | 1 + mysql-test/r/bigint.result | 8 ++++++++ mysql-test/t/bigint.test | 12 ++++++++++++ sql/item.cc | 13 +++++++++++++ sql/item.h | 3 ++- 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index 3dcf46841d9..12cdf99cbc9 100644 --- a/.bzrignore +++ b/.bzrignore @@ -540,3 +540,4 @@ libmysql/vio_priv.h libmysql_r/vio_priv.h hardcopy.0 scripts/make_sharedlib_distribution +sql/udf_example.so diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index d7d811dc5f3..2b595c2b83d 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -67,3 +67,11 @@ select * from t1 limit 9999999999; id a 9999999999 1 drop table t1; +CREATE TABLE t1 ( quantity decimal(60,0)); +insert into t1 values (10000000000000000000); +insert into t1 values ('10000000000000000000'); +select * from t1; +quantity +10000000000000000000 +10000000000000000000 +drop table t1; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index c5691a760c7..a7cc068ec46 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -46,3 +46,15 @@ insert into t1 values (null,1); select * from t1; select * from t1 limit 9999999999; drop table t1; + +# +# Item_uint::save_to_field() +# BUG#1845 +# + +CREATE TABLE t1 ( quantity decimal(60,0)); +insert into t1 values (10000000000000000000); +insert into t1 values ('10000000000000000000'); +select * from t1; +drop table t1; + diff --git a/sql/item.cc b/sql/item.cc index 0e9085180cd..65eb7f1befd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -548,6 +548,19 @@ bool Item_string::save_in_field(Field *field, bool no_conversions) return 0; } +bool Item_uint::save_in_field(Field *field, bool no_conversions) +{ + longlong nr=val_int(); + if (null_value) + return set_field_to_null(field); + field->set_notnull(); + if (nr < 0) + field->store(ulonglong2double(nr)); + else + field->store(nr); + return 0; +} + bool Item_int::save_in_field(Field *field, bool no_conversions) { longlong nr=val_int(); diff --git a/sql/item.h b/sql/item.h index 25650e85434..d23a061eedb 100644 --- a/sql/item.h +++ b/sql/item.h @@ -232,13 +232,14 @@ public: String *val_str(String*); void make_field(Send_field *field); Item *new_item() { return new Item_uint(name,max_length); } + bool save_in_field(Field *field, bool no_conversions); bool fix_fields(THD *thd,struct st_table_list *table_list) { unsigned_flag= 1; return 0; } void print(String *str); - unsigned int size_of() { return sizeof(*this);} + unsigned int size_of() { return sizeof(*this);} }; From 80649ee8746aab02a198285248668cb49ce70f33 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Nov 2003 17:31:17 +0100 Subject: [PATCH 3/7] Fix for BUG#1870 "CHANGE MASTER makes SQL thread restart from coordinates of I/O thread". So, in CHANGE MASTER: when it seems reasonable that the user did not want to discontinue its replication (i.e. when he is not specifying host or port or master_log_file or master_log_pos; this will be documented), set the coordinates of the I/O thread to those of the SQL thread. This way, the SQL thread will see no discontinuity in the relay log (i.e. will skip no events), because the I/O thread will fill the brand new relay log with the events which are just after the position where the SQL thread had stopped (before CHANGE MASTER was issued). And a new test for this bug. mysql-test/r/rpl_loaddata.result: Now, after CHANGE MASTER the coordinates of the I/O thread are the last ones of the SQL thread, so result update. sql/sql_repl.cc: Fix for BUG#1870 "CHANGE MASTER makes SQL thread restart from coordinates of I/O thread". So, in CHANGE MASTER: when it seems reasonable that the user did not want to discontinue its replication (i.e. when he is not specifying host or port or master_log_file or master_log_pos; this will be documented), set the coordinates of the I/O thread to those of the SQL thread. This way, the SQL thread will see no discontinuity in the relay log (i.e. will skip no events), because the I/O thread will fill the brand new relay log with the events which are just after the position where the SQL thread had stopped (before CHANGE MASTER was issued). --- mysql-test/r/rpl_change_master.result | 32 +++++++++++++++++ mysql-test/r/rpl_loaddata.result | 2 +- mysql-test/t/rpl_change_master.test | 26 ++++++++++++++ sql/sql_repl.cc | 49 ++++++++++++++++++++++++--- 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/rpl_change_master.result create mode 100644 mysql-test/t/rpl_change_master.test diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result new file mode 100644 index 00000000000..be2aec616b0 --- /dev/null +++ b/mysql-test/r/rpl_change_master.result @@ -0,0 +1,32 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +select get_lock("a",5); +get_lock("a",5) +1 +create table t1(n int); +insert into t1 values(1+get_lock("a",10)*0); +insert into t1 values(2); +stop slave; +select * from t1; +n +1 +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 273 slave-relay-bin.002 255 master-bin.001 No No 0 0 214 314 +change master to master_user='root'; +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 214 slave-relay-bin.001 4 master-bin.001 No No 0 0 214 4 +select release_lock("a"); +release_lock("a") +1 +start slave; +select * from t1; +n +1 +2 +drop table t1; diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index 8b910d0d183..268e383ce69 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -43,7 +43,7 @@ change master to master_user='test'; change master to master_user='root'; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 1442 slave-relay-bin.001 4 master-bin.001 No No 0 0 1442 4 +127.0.0.1 root MASTER_PORT 1 master-bin.001 1419 slave-relay-bin.001 4 master-bin.001 No No 0 0 1419 4 set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test new file mode 100644 index 00000000000..61de22fe57b --- /dev/null +++ b/mysql-test/t/rpl_change_master.test @@ -0,0 +1,26 @@ +source include/master-slave.inc; + +connection slave; +select get_lock("a",5); +connection master; +create table t1(n int); +insert into t1 values(1+get_lock("a",10)*0); +insert into t1 values(2); +save_master_pos; +connection slave; +sleep 3; # can't sync_with_master as we should be blocked +stop slave; +select * from t1; +show slave status; +change master to master_user='root'; +show slave status; +# Will restart from after the values(2), which is bug +select release_lock("a"); +start slave; +sync_with_master; +select * from t1; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 10581431c72..c95cdc1b04e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -853,8 +853,8 @@ void kill_zombie_dump_threads(uint32 slave_server_id) int change_master(THD* thd, MASTER_INFO* mi) { int thread_mask; - const char* errmsg=0; - bool need_relay_log_purge=1; + const char* errmsg= 0; + bool need_relay_log_purge= 1; DBUG_ENTER("change_master"); lock_slave_threads(mi); @@ -928,6 +928,36 @@ int change_master(THD* thd, MASTER_INFO* mi) mi->rli.relay_log_pos=lex_mi->relay_log_pos; } + /* + If user did specify neither host nor port nor any log name nor any log + pos, i.e. he specified only user/password/master_connect_retry, he probably + wants replication to resume from where it had left, i.e. from the + coordinates of the **SQL** thread (imagine the case where the I/O is ahead + of the SQL; restarting from the coordinates of the I/O would lose some + events which is probably unwanted when you are just doing minor changes + like changing master_connect_retry). + A side-effect is that if only the I/O thread was started, this thread may + restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a + much more unlikely situation than the one we are fixing here). + Note: coordinates of the SQL thread must be read here, before the + 'if (need_relay_log_purge)' block which resets them. + */ + if (!lex_mi->host && !lex_mi->port && + !lex_mi->log_file_name && !lex_mi->pos && + need_relay_log_purge) + { + /* + Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is + not initialized), so we use a max(). + What happens to mi->rli.master_log_pos during the initialization stages + of replication is not 100% clear, so we guard against problems using + max(). + */ + mi->master_log_pos = max(BIN_LOG_HEADER_SIZE, mi->rli.master_log_pos); + strmake(mi->master_log_name,mi->rli.master_log_name, + sizeof(mi->master_log_name)-1); + } + flush_master_info(mi); if (need_relay_log_purge) { @@ -959,10 +989,21 @@ int change_master(THD* thd, MASTER_INFO* mi) } } DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); - /* If changing RELAY_LOG_FILE or RELAY_LOG_POS, this will be nonsense: */ + + /* + Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block, + so restore them to good values. If we left them to ''/0, that would work; + but that would fail in the case of 2 successive CHANGE MASTER (without a + START SLAVE in between): because first one would set the coords in mi to + the good values of those in rli, the set those in rli to ''/0, then + second CHANGE MASTER would set the coords in mi to those of rli, i.e. to + ''/0: we have lost all copies of the original good coordinates. + That's why we always save good coords in rli. + */ mi->rli.master_log_pos = mi->master_log_pos; strmake(mi->rli.master_log_name,mi->master_log_name, - sizeof(mi->rli.master_log_name)-1); + sizeof(mi->rli.master_log_name)-1); + if (!mi->rli.master_log_name[0]) // uninitialized case mi->rli.master_log_pos=0; From a36145a8f2ba164bffe513c887697548b38955df Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Nov 2003 22:06:47 +0100 Subject: [PATCH 4/7] Bug#1826, HANDLER+ALTER TABLE=crash (unfortunately, it cannot be tested in mysql-test suite) more user variable tests mysql-test/r/user_var.result: more user variable tests (just to have this behaviour written down somewhere) mysql-test/t/user_var.test: more user variable tests (just to have this behaviour written down somewhere) sql/sql_handler.cc: Bug#1826, HANDLER+ALTER TABLE=crash (unfortunately, it cannot be tested in mysql-test suite) --- mysql-test/r/user_var.result | 19 +++++++++++++++++++ mysql-test/t/user_var.test | 11 +++++++++++ sql/sql_handler.cc | 13 +++++++++++++ 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d7c41d5dbc4..3e83438b273 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -97,3 +97,22 @@ drop table t1; select @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b, @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b; @a:=10 @b:=2 @a>@b @a:="10" @b:="2" @a>@b @a:=10 @b:=2 @a>@b @a:="10" @b:="2" @a>@b 10 2 1 10 2 1 10 2 1 10 2 1 +create table t1 (i int not null); +insert t1 values (1),(2),(2),(3),(3),(3); +select @a:=0; +@a:=0 +0 +select @a, @a:=@a+count(*), count(*), @a from t1 group by i; +@a @a:=@a+count(*) count(*) @a +0 1 1 0 +0 2 2 0 +0 3 3 0 +select @a:=0; +@a:=0 +0 +select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; +@a+0 @a:=@a+0+count(*) count(*) @a+0 +0 1 1 0 +1 3 2 0 +3 6 3 0 +drop table t1; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 56528405a2a..9cb5d5e1eb0 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -53,3 +53,14 @@ drop table t1; # just for fun :) select @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b, @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b; + +# +# bug#1739 +# Item_func_set_user_var sets update_query_id, Item_func_get_user_var checks it +# +create table t1 (i int not null); +insert t1 values (1),(2),(2),(3),(3),(3); +select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i; +select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; +drop table t1; + diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index dd8dfb31163..208545a435b 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -285,7 +285,20 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, { if (!memcmp(table->table_cache_key, db, dblen) && !my_strcasecmp((is_alias ? table->table_name : table->real_name),table_name)) + { + if (table->version != refresh_version) + { + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } + VOID(pthread_mutex_unlock(&LOCK_open)); + continue; + } break; + } ptr=&(table->next); } return ptr; From c9b59bccb3da2ac065c3aaa883b8d6c0792f7a17 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Nov 2003 16:38:01 +0100 Subject: [PATCH 5/7] - removed some undefined non-weak symbols in libmysqlclient_r by setting LIBS to include @openss_libs@ (BUG#1652) --- libmysql_r/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am index e01fc7634a1..ae091d86a88 100644 --- a/libmysql_r/Makefile.am +++ b/libmysql_r/Makefile.am @@ -19,7 +19,7 @@ target = libmysqlclient_r.la target_defs = -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -## LIBS = @LIBS@ +LIBS = @LIBS@ @openssl_libs@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \ -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes) From 8fcd7311790f548cff66d40ef24b5bc02d61a6e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Nov 2003 23:07:31 +0100 Subject: [PATCH 6/7] minor fixups: more verbose on "no memory" errors - report requested size, avoid flushing rec buffer to a file that is closed and deleted already (on got_error=1) --- myisam/mi_check.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 466defe8fbc..7108fdcba9e 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1368,6 +1368,7 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks, MYF(MY_WME))); + info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */ } mi_mark_crashed_on_repair(info); } @@ -2852,8 +2853,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) if (!(to=mi_alloc_rec_buff(info,block_info.rec_len, &(sort_param->rec_buff)))) { - mi_check_print_error(param,"Not enough memory for blob at %s", - llstr(sort_param->start_recpos,llbuff)); + mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)", + llstr(sort_param->start_recpos,llbuff), block_info.rec_len); DBUG_RETURN(1); } } From cd878c2c8a4a639b2a7147ecf00ce791e15faa42 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Nov 2003 21:21:56 +0300 Subject: [PATCH 7/7] added comments to simple_order, simple_group, no_order, skip_sort_order --- sql/sql_select.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 740b0470fdc..7f8dfd219d0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -208,8 +208,21 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, { TABLE *tmp_table; int error, tmp_error; - bool need_tmp,hidden_group_fields; - bool simple_order,simple_group,no_order, skip_sort_order; + bool need_tmp; + bool hidden_group_fields; + /* + simple_xxxxx is set if ORDER/GROUP BY doesn't include any references + to other tables than the first non-constant table in the JOIN. + It's also set if ORDER/GROUP BY is empty. + */ + bool simple_order, simple_group; + /* + Is set only in case if we have a GROUP BY clause + and no ORDER BY after constant elimination of 'order'. + */ + bool no_order; + /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ + bool skip_sort_order; ha_rows select_limit; Item::cond_result cond_value; SQL_SELECT *select;