From 036ac80ae047493d38b591c56d848af4721da2fd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 19:26:11 +0500 Subject: A fix (bug #2631: mlockall called after dropping root permissions). --- sql/mysqld.cc | 122 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 36 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 670e6a5a63e..06599cf0ea7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -414,6 +414,7 @@ char mysql_real_data_home[FN_REFLEN], max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; char *language_ptr= language; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; +struct passwd *user_info; #ifndef EMBEDDED_LIBRARY bool mysql_embedded=0; #else @@ -1028,27 +1029,26 @@ static void set_ports() } } -/* Change to run as another user if started with --user */ -static void set_user(const char *user) +static struct passwd *check_user(const char *user) { -#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) - struct passwd *ent; +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + struct passwd *user_info; uid_t user_id= geteuid(); - - // don't bother if we aren't superuser + + // Don't bother if we aren't superuser if (user_id) { if (user) { - /* Don't give a warning, if real user is same as given with --user */ - struct passwd *user_info= getpwnam(user); + // Don't give a warning, if real user is same as given with --user + user_info= getpwnam(user); if ((!user_info || user_id != user_info->pw_uid) && - global_system_variables.log_warnings) - fprintf(stderr, - "Warning: One can only use the --user switch if running as root\n"); + global_system_variables.log_warnings) + fprintf(stderr, + "Warning: One can only use the --user switch if running as root\n"); } - return; + return NULL; } if (!user) { @@ -1057,38 +1057,52 @@ static void set_user(const char *user) fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n"); unireg_abort(1); } - return; + return NULL; } if (!strcmp(user,"root")) - return; // Avoid problem with dynamic libraries - - uid_t uid; - if (!(ent = getpwnam(user))) + return NULL; // Avoid problem with dynamic libraries + if (!(user_info= getpwnam(user))) { - // allow a numeric uid to be used + // Allow a numeric uid to be used const char *pos; - for (pos=user; isdigit(*pos); pos++) ; - if (*pos) // Not numeric id - { - fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); - unireg_abort(1); - } - uid=atoi(user); // Use numberic uid + for (pos= user; isdigit(*pos); pos++); + if (*pos) // Not numeric id + goto err; + if (!(user_info= getpwuid(atoi(user)))) + goto err; + else + return user_info; } else { + return user_info; + } + +err: + fprintf(stderr, + "Fatal error: Can't change to run as user '%s'. Please check that the user exists!\n", + user); + unireg_abort(1); + return NULL; +#else + return NULL; +#endif +} + + +static void set_user(const char *user, struct passwd *user_info) +{ +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + DBUG_ASSERT(user_info); #ifdef HAVE_INITGROUPS - initgroups((char*) user,ent->pw_gid); + initgroups((char*) user, user_info->pw_gid); #endif - if (setgid(ent->pw_gid) == -1) - { - sql_perror("setgid"); - unireg_abort(1); - } - uid=ent->pw_uid; + if (setgid(user_info->pw_gid) == -1) + { + sql_perror("setgid"); + unireg_abort(1); } - - if (setuid(uid) == -1) + if (setuid(user_info->pw_uid) == -1) { sql_perror("setuid"); unireg_abort(1); @@ -1096,6 +1110,24 @@ static void set_user(const char *user) #endif } +static void set_effective_user(struct passwd *user_info) +{ +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + DBUG_ASSERT(user_info); + if (setegid(user_info->pw_gid) == -1) + { + sql_perror("setegid"); + unireg_abort(1); + } + if (seteuid(user_info->pw_uid) == -1) + { + sql_perror("seteuid"); + unireg_abort(1); + } +#endif +} + + /* Change root user if started with --chroot */ static void set_root(const char *path) @@ -1171,7 +1203,18 @@ static void server_init(void) unireg_abort(1); } } - set_user(mysqld_user); // Works also with mysqld_user==NULL + + if ((user_info= check_user(mysqld_user))) + { +#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) + if (locked_in_memory && !getuid()) + set_effective_user(user_info); + else + set_user(mysqld_user, user_info); +#else + set_user(mysqld_user, user_info); +#endif + } #ifdef __NT__ /* create named pipe */ @@ -2466,8 +2509,13 @@ You should consider changing lower_case_table_names to 1 or 2", } ha_key_cache(); #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) - if (locked_in_memory && !geteuid()) + if (locked_in_memory && !getuid()) { + if (seteuid(0) == -1) + { // this should never happen + sql_perror("seteuid"); + unireg_abort(1); + } if (mlockall(MCL_CURRENT)) { if (global_system_variables.log_warnings) @@ -2475,6 +2523,8 @@ You should consider changing lower_case_table_names to 1 or 2", } else locked_in_memory=1; + if (user_info) + set_user(mysqld_user, user_info); } #else locked_in_memory=0; -- cgit v1.2.1 From f6b5313ea662575eaa201e5a4947612824ffb09e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Sep 2004 11:27:31 +0200 Subject: union.test: drop table added BitKeeper/etc/ignore: Added support-files/my-innodb-heavy-4G.cnf to the ignore list mysql-test/r/union.result: drop table added mysql-test/t/union.test: drop table added --- .bzrignore | 1 + mysql-test/r/union.result | 1 + mysql-test/t/union.test | 1 + 3 files changed, 3 insertions(+) diff --git a/.bzrignore b/.bzrignore index 8583b7ef437..1d14c09a602 100644 --- a/.bzrignore +++ b/.bzrignore @@ -545,3 +545,4 @@ vio/test-sslserver vio/viotest-ssl scripts/make_win_binary_distribution EXCEPTIONS-CLIENT +support-files/my-innodb-heavy-4G.cnf diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 4b9555c334b..45866cdf495 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -420,6 +420,7 @@ a (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; Wrong usage/placement of 'SQL_CALC_FOUND_ROWS' create temporary table t1 select a from t1 union select a from t2; +drop table t1; create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list select a from t1 union select a from t2 order by t2.a; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c978aef9ce0..2bcd50b11de 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -224,6 +224,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; create temporary table t1 select a from t1 union select a from t2; +drop table t1; --error 1093 create table t1 select a from t1 union select a from t2; --error 1054 -- cgit v1.2.1 From b7269f4ebf6127eca406b1dd14f2078af2df485c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:20:40 +0200 Subject: bug#5389 merge.test fails on qnx - uninitalized variable in myrg_open() myisammrg/myrg_open.c: backport from 4.1 mysql-test/r/union.result: after merge fix mysql-test/t/union.test: after merge fix sql/log.cc: backward compatibility: inhibit severity labels in error log --- myisammrg/myrg_open.c | 28 ++++++++++++++-------------- mysql-test/r/union.result | 1 - mysql-test/t/union.test | 1 - sql/log.cc | 20 +++++++++++++------- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 4c6ffb98ad5..a59ccb7d966 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -34,14 +34,17 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,errpos=0; uint files=0,i,dir_length,length,key_parts; - ulonglong file_offset; + ulonglong file_offset=0; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO *m_info=0; File fd; IO_CACHE file; MI_INFO *isam=0; + uint found_merge_insert_method= 0; DBUG_ENTER("myrg_open"); + LINT_INIT(key_parts); + bzero((char*) &file,sizeof(file)); if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4), O_RDONLY | O_SHARE,MYF(0))) < 0) @@ -69,10 +72,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) continue; /* Skip empty lines */ if (buff[0] == '#') { - if( !strncmp(buff+1,"INSERT_METHOD=",14)) + if (!strncmp(buff+1,"INSERT_METHOD=",14)) { /* Lookup insert method */ int tmp=find_type(buff+15,&merge_insert_method,2); - m_info->merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); + found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); } continue; /* Skip comments */ } @@ -84,8 +87,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) VOID(cleanup_dirname(buff,name_buff)); } if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) - goto err; - if (!m_info) + goto err; + if (!m_info) /* First file */ { key_parts=isam->s->base.key_parts; if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO) + @@ -97,15 +100,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { m_info->open_tables=(MYRG_TABLE *) (m_info+1); m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files); + m_info->tables= files; + files= 0; } - else - { - m_info->open_tables=0; - m_info->rec_per_key_part=0; - } - m_info->tables=files; m_info->reclength=isam->s->base.reclength; - file_offset=files=0; errpos=3; } m_info->open_tables[files].table= isam; @@ -122,14 +120,16 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->del+= isam->state->del; m_info->data_file_length+= isam->state->data_file_length; for (i=0; i < key_parts; i++) - m_info->rec_per_key_part[i]+=isam->s->state.rec_per_key_part[i] / m_info->tables; + m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] / + m_info->tables); } if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO), - MYF(MY_WME|MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL)))) goto err; /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + m_info->merge_insert_method= found_merge_insert_method; if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 79c589774d8..0db18b090bc 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -424,7 +424,6 @@ create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list select a from t1 union select a from t2 order by t2.a; Unknown column 't2.a' in 'ORDER BY' -drop table t1; drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; * diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index e55cb3ea272..eb2d8dd6efa 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -229,7 +229,6 @@ drop table t1; create table t1 select a from t1 union select a from t2; --error 1054 select a from t1 union select a from t2 order by t2.a; -drop table t1; # Drop temporary table drop table t1,t2; # diff --git a/sql/log.cc b/sql/log.cc index 55ef2e72960..151d613f637 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1221,7 +1221,7 @@ bool MYSQL_LOG::write(Log_event* event_info) if (e.write(file)) goto err; } -#if MYSQL_VERSION_ID < 40100 +#if MYSQL_VERSION_ID < 40100 if (thd->variables.convert_set) { Query_log_event e(thd, "SET CHARACTER SET DEFAULT", 25, 0); @@ -1761,15 +1761,21 @@ void print_buffer_to_file(enum loglevel level, const char *buffer) skr=time(NULL); localtime_r(&skr, &tm_tmp); start=&tm_tmp; +#if MYSQL_VERSION_ID > 40100 fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", - start->tm_year % 100, - start->tm_mon+1, - start->tm_mday, - start->tm_hour, - start->tm_min, - start->tm_sec, +#else + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d %s\n", +#endif + start->tm_year % 100, + start->tm_mon+1, + start->tm_mday, + start->tm_hour, + start->tm_min, + start->tm_sec, +#if MYSQL_VERSION_ID > 40100 (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "WARNING" : "INFORMATION"), +#endif buffer); fflush(stderr); -- cgit v1.2.1 From 99aff0ca03051abd29fac55e9aa34237e72b4a71 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:30:16 +0200 Subject: Dependency fix. We observed that doing any change to class THD in sql_class.h resulted in mysqld going crazy (parsing errors, query cache errors in query_cache.test). This is because sql_yacc.cc depends on several .h files but those were not listed in the dependencies of sql_yacc.o. The present patch does fix the issue; but my auto*-expert colleagues may have a better one. sql/Makefile.am: sql_yacc.c includes mysql_priv.h, slave.h etc, so sql_yacc.o does depend on these .h files; so they need to be listed in the dependencies. --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index 0a664a120a5..0fc81a48c63 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -108,7 +108,7 @@ gen_lex_hash.o: gen_lex_hash.cc lex.h sql_yacc.cc: sql_yacc.yy sql_yacc.h: sql_yacc.yy -sql_yacc.o: sql_yacc.cc sql_yacc.h +sql_yacc.o: sql_yacc.cc sql_yacc.h $(noinst_HEADERS) @echo "Note: The following compile may take a long time." @echo "If it fails, re-run configure with --with-low-memory" $(CXXCOMPILE) $(LM_CFLAGS) -c $< -- cgit v1.2.1 From 2ca7ff9da63de8dbc7d6c328cf153f2af84e5255 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:47:26 +0200 Subject: Replacing class Disable_binlog by macros. Patch already approved by Monty. sql/log.cc: removing unneeded class Disable_binlog sql/sql_class.h: removing unneeded class Disable_binlog sql/sql_table.cc: As discussed, class Disable_binlog is removed and replaced by macros. --- sql/log.cc | 16 ---------------- sql/sql_class.h | 21 --------------------- sql/sql_table.cc | 47 ++++++++++++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 56 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 55ef2e72960..a864943edf8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1682,22 +1682,6 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) } -Disable_binlog::Disable_binlog(THD *thd_arg) : - thd(thd_arg), - save_options(thd_arg->options), save_master_access(thd_arg->master_access) -{ - thd_arg->options&= ~OPTION_BIN_LOG; - thd_arg->master_access|= SUPER_ACL; // unneeded in 4.1 -}; - - -Disable_binlog::~Disable_binlog() -{ - thd->options= save_options; - thd->master_access= save_master_access; -} - - /* Check if a string is a valid number diff --git a/sql/sql_class.h b/sql/sql_class.h index 30947041b7d..d362a90b7df 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -638,27 +638,6 @@ public: #define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_SQL 4 -/* - Disables binary logging for one thread, and resets it back to what it was - before being disabled. - Some functions (like the internal mysql_create_table() when it's called by - mysql_alter_table()) must NOT write to the binlog (binlogging is done at the - at a later stage of the command already, and must be, for locking reasons); - so we internally disable it temporarily by creating the Disable_binlog - object and reset the state by destroying the object (don't forget that! or - write code so that the object gets automatically destroyed when leaving a - block, see example in sql_table.cc). -*/ -class Disable_binlog { -private: - THD *thd; - ulong save_options; - ulong save_master_access; -public: - Disable_binlog(THD *thd_arg); - ~Disable_binlog(); -}; - /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 96eebd98ac3..c712167bfc1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -30,6 +30,16 @@ #include #endif +#include "sql_acl.h" // for SUPER_ACL +# define tmp_disable_binlog(A) \ + ulong save_options= (A)->options, save_master_access= (A)->master_access; \ + (A)->options&= ~OPTION_BIN_LOG; \ + (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ + +#define reenable_binlog(A) \ + (A)->options= save_options; \ + (A)->master_access= save_master_access; + extern HASH open_cache; static const char *primary_key_name="PRIMARY"; @@ -840,9 +850,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, MYSQL_LOCK **lock) { TABLE tmp_table; // Used during 'create_field()' - TABLE *table; + TABLE *table= 0; tmp_table.table_name=0; - Disable_binlog disable_binlog(thd); DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -872,23 +881,25 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, extra_fields->push_back(cr_field); } /* create and lock table */ - /* QQ: This should be done atomic ! */ - /* We don't log the statement, it will be logged later */ - if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0)) - DBUG_RETURN(0); + /* QQ: create and open should be done atomic ! */ /* + We don't log the statement, it will be logged later. If this is a HEAP table, the automatic DELETE FROM which is written to the binlog when a HEAP table is opened for the first time since startup, must not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we don't want to delete from it) 2) it would be written before the CREATE - TABLE, which is a wrong order. So we keep binary logging disabled. + TABLE, which is a wrong order. So we keep binary logging disabled when we + open_table(). */ - if (!(table=open_table(thd,db,name,name,(bool*) 0))) + tmp_disable_binlog(thd); + if (!mysql_create_table(thd,db,name,create_info,*extra_fields,*keys,0)) { - quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); - DBUG_RETURN(0); + if (!(table=open_table(thd,db,name,name,(bool*) 0))) + quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); } + reenable_binlog(thd); + if (!table) + DBUG_RETURN(0); table->reginfo.lock_type=TL_WRITE; if (!((*lock)=mysql_lock_tables(thd,&table,1))) { @@ -1925,14 +1936,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, else create_info->data_file_name=create_info->index_file_name=0; { - /* - We don't log the statement, it will be logged later. Using a block so - that disable_binlog is deleted when we leave it in either way. - */ - Disable_binlog disable_binlog(thd); - if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1))) + /* We don't log the statement, it will be logged later. */ + tmp_disable_binlog(thd); + int error= mysql_create_table(thd, new_db, tmp_name, + create_info,create_list,key_list,1); + reenable_binlog(thd); + if (error) DBUG_RETURN(error); } if (table->tmp_table) -- cgit v1.2.1 From 94d95f99128c7a39c7e7df78a913b01f605622ad Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:48:42 +0200 Subject: Bug #5413 mysqlcheck segfaults when user has to few permissions --- client/mysqlcheck.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1c5638f3c52..8764611adf4 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -413,18 +413,18 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (!(mysql_query(sock, "SHOW TABLES") || - (res = mysql_store_result(sock)))) + if (mysql_query(sock, "SHOW TABLES") || + !((res= mysql_store_result(sock)))) return 1; if (opt_all_in_1) { - /* + /* We need table list in form `a`, `b`, `c` that's why we need 4 more chars added to to each table name space is for more readable output in logs and in case of error */ - + char *tables, *end; uint tot_length = 0; -- cgit v1.2.1 From d7e7cead7862bd8d300d7fa982c83bea165a15a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 23:20:33 +0200 Subject: Fix of previous push. sql/sql_table.cc: stupid me. error already exists in the function. Using a local 'int error' resulted in global 'error' not being inited, which probably made next steps (those testing global error) go wrong! --- sql/sql_table.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c712167bfc1..e2e186abb0d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1938,8 +1938,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* We don't log the statement, it will be logged later. */ tmp_disable_binlog(thd); - int error= mysql_create_table(thd, new_db, tmp_name, - create_info,create_list,key_list,1); + error= mysql_create_table(thd, new_db, tmp_name, + create_info,create_list,key_list,1); reenable_binlog(thd); if (error) DBUG_RETURN(error); -- cgit v1.2.1 From 32c030adb91e67f652e9231ce719e2a49f25f1d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 11:40:27 +0300 Subject: Fixed Bug#3645, "PROCEDURE ANALYSE() recommends illegal FLOAT columns". --- sql/sql_analyse.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 3847849d6a7..0723c274a17 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -810,6 +810,13 @@ void field_real::get_opt_type(String *answer, if (min_arg >= 0) answer->append(" UNSIGNED"); } + else if (item->decimals == NOT_FIXED_DEC) + { + if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX) + answer->append("FLOAT", 5); + else + answer->append("DOUBLE", 6); + } else { if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX) -- cgit v1.2.1 From 9c14253ac847654134e09d976c0cee909736357e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 11:15:23 +0200 Subject: A new test for the fix for BUG#4500 ("SET CHARACTER SET replicates incorrectly"). As I cannot be 100% sure that there won't be issues with some of our exotic platforms (who knows if the charset of will play fair?), I'll send an email to the build guys. Well, this holds if bk does not crash on binary chars of this cset. --- mysql-test/r/rpl_set_charset.result | 51 +++++++++++++++++++++++++++++++++++++ mysql-test/t/rpl_set_charset.test | 40 +++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 mysql-test/r/rpl_set_charset.result create mode 100644 mysql-test/t/rpl_set_charset.test diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result new file mode 100644 index 00000000000..b2bfa3678a9 --- /dev/null +++ b/mysql-test/r/rpl_set_charset.result @@ -0,0 +1,51 @@ +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; +drop database if exists mysqltest1; +create database mysqltest1 /*!40100 character set latin2 */; +use mysqltest1; +drop table if exists t1; +create table t1 (a varchar(255) character set latin2, b varchar(4)); +SET CHARACTER SET cp1250_latin2; +INSERT INTO t1 VALUES ('','80'); +INSERT INTO t1 VALUES ('','90'); +INSERT INTO t1 VALUES ('','A0'); +INSERT INTO t1 VALUES ('','B0'); +INSERT INTO t1 VALUES ('','C0'); +INSERT INTO t1 VALUES ('','D0'); +INSERT INTO t1 VALUES ('','E0'); +INSERT INTO t1 VALUES ('','F0'); +select "--- on master ---"; +--- on master --- +--- on master --- +select hex(a),b from t1 order by b; +hex(a) b +A9A6ABAEAC 80 +B9B6BBBEBC 90 +A3A1AAAF A0 +B3B1BAA5B5BF B0 +C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0 +D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 +E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 +show binlog events from 1979; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.001 1979 Query 1 1979 use `mysqltest1`; SET CHARACTER SET DEFAULT +use mysqltest1; +select "--- on slave ---"; +--- on slave --- +--- on slave --- +select hex(a),b from t1 order by b; +hex(a) b +A9A6ABAEAC 80 +B9B6BBBEBC 90 +A3A1AAAF A0 +B3B1BAA5B5BF B0 +C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0 +D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 +E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 +drop table t1; diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test new file mode 100644 index 00000000000..6aa864b1008 --- /dev/null +++ b/mysql-test/t/rpl_set_charset.test @@ -0,0 +1,40 @@ +source include/master-slave.inc; +--disable_warnings +drop database if exists mysqltest1; +# 4.1 bases its conversion on the db's charset, +# while 4.0 uses the part of "SET CHARACTER SET" after "_". +# So for 4.1 we add a clause to CREATE DATABASE. +create database mysqltest1 /*!40100 character set latin2 */; +use mysqltest1; +drop table if exists t1; +--enable_warnings +create table t1 (a varchar(255) character set latin2, b varchar(4)); +SET CHARACTER SET cp1250_latin2; +INSERT INTO t1 VALUES ('','80'); +INSERT INTO t1 VALUES ('','90'); +INSERT INTO t1 VALUES ('','A0'); +INSERT INTO t1 VALUES ('','B0'); +INSERT INTO t1 VALUES ('','C0'); +INSERT INTO t1 VALUES ('','D0'); +INSERT INTO t1 VALUES ('','E0'); +INSERT INTO t1 VALUES ('','F0'); +select "--- on master ---"; +select hex(a),b from t1 order by b; +# It's complicated to verify that the charset is reset to default in +# the binlog after each query, except by checking the binlog. When you +# merge this into 4.1/5.0, the 1979 will have to be changed; all you have +# to do is read the var/log/master-bin.0*01 with mysqlbinlog, verify +# that a SET CHARACTER SET DEFAULT is just after the last INSERT, and +# replace 1979 by its position (the "# at" line above the SET). +show binlog events from 1979; +save_master_pos; +connection slave; +sync_with_master; +use mysqltest1; +select "--- on slave ---"; +select hex(a),b from t1 order by b; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; -- cgit v1.2.1 From c42a054a778f6dc8af4dc2bc470c3467e0b9fd1b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 13:36:27 +0200 Subject: cleanup --- mysql-test/r/rpl_set_charset.result | 1 + mysql-test/t/rpl_set_charset.test | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result index b2bfa3678a9..7297d80865b 100644 --- a/mysql-test/r/rpl_set_charset.result +++ b/mysql-test/r/rpl_set_charset.result @@ -49,3 +49,4 @@ D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 drop table t1; +drop database mysqltest1; diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test index 6aa864b1008..dcfc11bf25e 100644 --- a/mysql-test/t/rpl_set_charset.test +++ b/mysql-test/t/rpl_set_charset.test @@ -38,3 +38,5 @@ drop table t1; save_master_pos; connection slave; sync_with_master; +connection master; +drop database mysqltest1; -- cgit v1.2.1 From 32a86d6b171d883e18a7896ef03ddefdf7070d49 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 13:48:38 +0200 Subject: better fix for bug#5001 --- scripts/mysqld_safe.sh | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 8ad2ee1df4d..b9e7ce21f79 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -322,36 +322,26 @@ do # but should work for the rest of the servers. # The only thing is ps x => redhat 5 gives warnings when using ps -x. # kill -9 is used or the process won't react on the kill. - if test -n "$mysql_tcp_port" - then - numofproces=`ps xa | grep -v "grep" | grep $ledir/$MYSQLD| grep -c "port=$mysql_tcp_port"` - else - numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD` - fi + numofproces=`ps xa | grep -v "grep" | grep "$ledir/$MYSQLD\>" | grep -c "pid-file=$pid_file"` echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log I=1 while test "$I" -le "$numofproces" do - if test -n "$mysql_tcp_port" + PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "pid-file=$pid_file" | sed -n '$p'` + + for T in $PROC + do + break + done + # echo "TEST $I - $T **" + if kill -9 $T then - PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "port=$mysql_tcp_port" | sed -n '$p'` - else - PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | sed -n '$p'` + echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log + else + break fi - - for T in $PROC - do - break - done - # echo "TEST $I - $T **" - if kill -9 $T - then - echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log - else - break - fi - I=`expr $I + 1` + I=`expr $I + 1` done fi echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log @@ -359,3 +349,4 @@ done echo "`date +'%y%m%d %H:%M:%S'` mysqld ended" | tee -a $err_log echo "" | tee -a $err_log + -- cgit v1.2.1