From 16e96aac54e72e6a2e1305292747a6e47da0e449 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Nov 2006 15:13:48 +0400 Subject: [PATCH 01/29] bug #22634 (partitioned tables with DATA DIRECTORY option corrupts table) In fact the problem is inside the ARCHIVE engine. It stores real datapath inside the ARM file, but doesn't implement specific ha_archive::rename_table function. As the ALTER TABLE statement first creates the table with the temporary name and then renames it to the normal one, we get the temporary name saved in ARM what leads to "can't open file" error. Code modified to store only path in the ARM, without filename. storage/archive/ha_archive.cc: now we store only path in the ARM file, not the full filename, then we add the tablename as a filename after reading the metafile. --- storage/archive/ha_archive.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index b7673fc96ea..8204c7622e4 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -470,7 +470,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, Since we now possibly no real_path, we will use it instead if it exists. */ if (*share->real_path) - fn_format(share->data_file_name, share->real_path, "", ARZ, + fn_format(share->data_file_name, table_name, share->real_path, ARZ, MY_REPLACE_EXT|MY_UNPACK_FILENAME); VOID(my_hash_insert(&archive_open_tables, (byte*) share)); thr_lock_init(&share->lock); @@ -698,9 +698,13 @@ int ha_archive::create(const char *name, TABLE *table_arg, goto error; } + /* + We reuse name_buff since it is available. + */ write_meta_file(create_file, 0, stats.auto_increment_value, 0, - (char *)create_info->data_file_name, - FALSE); + (create_info->data_file_name && + dirname_part(name_buff, (char*)create_info->data_file_name)) + ? name_buff : 0, FALSE); my_close(create_file,MYF(0)); /* From e8b32b2b01e28926867d12ca3c0f8dc33690db5b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Dec 2006 21:49:26 +0400 Subject: [PATCH 02/29] bug #20835 (Subqueries: literal string with =any fails) We create Item_cache_* object for each operand for each left operand of a subquery predicate. We also create Item_func_conv_charset for each string constant that needs charset conversion. So here we have Item_cache wrapped into Item_func_conv_charset. When Item_func_conv_charset wraps an constant Item it gets it's value in constructor. The problem is that Item_cache is ready to be used only at execution time, which is too late. The fix makes Item_cache wrapping constant to get ready at fix_fields() time. mysql-test/r/subselect.result: test result mysql-test/t/subselect.test: test case sql/item_cmpfunc.cc: now Item_optimizer::fix_left will store constant arguments in cache on fix_fields() stage --- mysql-test/r/subselect.result | 6 ++++++ mysql-test/t/subselect.test | 8 ++++++++ sql/item_cmpfunc.cc | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index a4c666dd876..ee057695cd1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3592,3 +3592,9 @@ FROM t1) t; COUNT(*) 3000 DROP TABLE t1,t2; +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +s1 +a +DROP TABLE t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1cfbc85128a..989f958a5af 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2496,3 +2496,11 @@ SELECT SQL_NO_CACHE COUNT(*) FROM t1) t; DROP TABLE t1,t2; + +# +# Bug#20835 (literal string with =any values) +# +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 02e94d31f02..8d4b58f05a1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -797,7 +797,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } From fa115a0f2cb76106471bb3da0deae805cced557e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Dec 2006 21:45:57 +0400 Subject: [PATCH 03/29] bug #22372 (LOAD DATA crashes the table with the geometry field) The problem is that the GEOMETRY NOT NULL can't automatically set any value as a default one. We always tried to complete LOAD DATA command even if there's not enough data in file. That doesn't work for GEOMETRY NOT NULL. Now Field_*::reset() returns an error sign and it's checked in mysql_load() mysql-test/r/gis.result: test result mysql-test/t/gis.test: testcase sql/field.cc: reset() now returns error sign sql/field.h: Field_*::reset() now returns error sign if the field can't be reset sql/sql_load.cc: check if field can't be reset and return error if it's so --- mysql-test/r/gis.result | 6 +++ mysql-test/t/gis.test | 11 +++- sql/field.cc | 3 +- sql/field.h | 113 ++++++++++++++++++++++------------------ sql/sql_load.cc | 14 ++++- 5 files changed, 92 insertions(+), 55 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index f7066e7edca..ce2b5deadbd 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -671,3 +671,9 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def asbinary(g) 252 8192 0 Y 128 0 63 asbinary(g) drop table t1; +create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); +alter table t1 disable keys; +load data infile '../../std_data/bad_gis_data.dat' into table t1; +ERROR 01000: Data truncated; NULL supplied to NOT NULL column 'b' at row 1 +alter table t1 enable keys; +drop table t1; diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index b66b97c2c41..1ae4f0ae62f 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -363,11 +363,18 @@ drop table t1; select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); -# End of 4.1 tests - --enable_metadata create table t1 (g GEOMETRY); select * from t1; select asbinary(g) from t1; --disable_metadata drop table t1; + +create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); +alter table t1 disable keys; +--error 1263 +load data infile '../../std_data/bad_gis_data.dat' into table t1; +alter table t1 enable keys; +drop table t1; + +# End of 4.1 tests diff --git a/sql/field.cc b/sql/field.cc index 757c62cccd1..e88b8b313e2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1137,10 +1137,11 @@ void Field_null::sql_type(String &res) const This is an number stored as a pre-space (or pre-zero) string ****************************************************************************/ -void +int Field_decimal::reset(void) { Field_decimal::store("0",1,&my_charset_bin); + return 0; } void Field_decimal::overflow(bool negative) diff --git a/sql/field.h b/sql/field.h index 79fb7ff76d1..e4991ba1961 100644 --- a/sql/field.h +++ b/sql/field.h @@ -126,7 +126,7 @@ public: bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } - virtual void reset(void) { bzero(ptr,pack_length()); } + virtual int reset(void) { bzero(ptr,pack_length()); return 0; } virtual void reset_fields() {} virtual void set_default() { @@ -387,10 +387,10 @@ public: enum_field_types type() const { return FIELD_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } - void reset(void); - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); + int reset(void); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -418,10 +418,10 @@ public: enum_field_types type() const { return FIELD_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { ptr[0]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -454,10 +454,10 @@ public: enum_field_types type() const { return FIELD_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { ptr[0]=ptr[1]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -488,7 +488,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -521,10 +521,10 @@ public: enum_field_types type() const { return FIELD_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); bool send_binary(Protocol *protocol); @@ -559,10 +559,14 @@ public: enum_field_types type() const { return FIELD_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) + { + ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; + return 0; + } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -594,10 +598,10 @@ public: {} enum_field_types type() const { return FIELD_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { bzero(ptr,sizeof(float)); } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { bzero(ptr,sizeof(float)); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -628,10 +632,10 @@ public: {} enum_field_types type() const { return FIELD_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { bzero(ptr,sizeof(double)); } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { bzero(ptr,sizeof(double)); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -658,9 +662,9 @@ public: enum_field_types type() const { return FIELD_TYPE_NULL;} int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } - int store(double nr) { null[0]=1; return 0; } - int store(longlong nr) { null[0]=1; return 0; } - void reset(void) {} + int store(double nr) { null[0]=1; return 0; } + int store(longlong nr) { null[0]=1; return 0; } + int reset(void) { return 0; } double val_real(void) { return 0.0;} longlong val_int(void) { return 0;} String *val_str(String *value,String *value2) @@ -687,7 +691,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -763,10 +767,10 @@ public: enum_field_types type() const { return FIELD_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -795,7 +799,7 @@ public: int store(double nr); int store(longlong nr); void store_time(TIME *ltime,timestamp_type type); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -826,10 +830,10 @@ public: enum_field_types type() const { return FIELD_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -867,7 +871,11 @@ public: int store(double nr); int store(longlong nr); void store_time(TIME *ltime,timestamp_type type); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } + int reset(void) + { + ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; + return 0; + } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -905,9 +913,13 @@ public: enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } bool zero_pack() const { return 0; } - void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(longlong nr); + int reset(void) + { + charset()->cset->fill(charset(),ptr,field_length,' '); + return 0; + } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(longlong nr); int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); @@ -948,7 +960,7 @@ public: enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } bool zero_pack() const { return 0; } - void reset(void) { bzero(ptr,field_length+2); } + int reset(void) { bzero(ptr,field_length+2); return 0; } uint32 pack_length() const { return (uint32) field_length+2; } uint32 key_length() const { return (uint32) field_length; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -1017,7 +1029,7 @@ public: { return (uint32) (((ulonglong) 1 << (packlength*8)) -1); } - void reset(void) { bzero(ptr, packlength+sizeof(char*)); } + int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; } void reset_fields() { bzero((char*) &value,sizeof(value)); } void store_length(uint32 number); inline uint32 get_length(uint row_offset=0) @@ -1093,6 +1105,7 @@ public: int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr) { return 1; } int store(longlong nr) { return 1; } + int reset(void) { return !maybe_null(); } void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type); void set_key_image(char *buff,uint length, CHARSET_INFO *cs); @@ -1123,7 +1136,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); - void reset() { bzero(ptr,packlength); } + int reset() { bzero(ptr,packlength); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 48862506729..5710f9c4c97 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -527,7 +527,12 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, (enclosed_length && length == 4 && !memcmp(pos,"NULL",4)) || (length == 1 && read_info.found_null)) { - field->reset(); + if (field->reset()) + { + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name, + thd->row_count); + DBUG_RETURN(1); + } field->set_null(); if (!field->maybe_null()) { @@ -560,7 +565,12 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, for (; sql_field ; sql_field=(Item_field*) it++) { sql_field->field->set_null(); - sql_field->field->reset(); + if (sql_field->field->reset()) + { + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),sql_field->field->field_name, + thd->row_count); + DBUG_RETURN(1); + } thd->cuted_fields++; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_TOO_FEW_RECORDS, From 63fce3a24e33407d58a17ec2946caa08e6c1b537 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Dec 2006 21:47:29 +0400 Subject: [PATCH 04/29] bug #22372 datafile added to be used in gis.test mysql-test/std_data/bad_gis_data.dat: New BitKeeper file ``mysql-test/std_data/bad_gis_data.dat'' --- mysql-test/std_data/bad_gis_data.dat | 1 + 1 file changed, 1 insertion(+) create mode 100644 mysql-test/std_data/bad_gis_data.dat diff --git a/mysql-test/std_data/bad_gis_data.dat b/mysql-test/std_data/bad_gis_data.dat new file mode 100644 index 00000000000..257cc5642cb --- /dev/null +++ b/mysql-test/std_data/bad_gis_data.dat @@ -0,0 +1 @@ +foo From 7341315d7404d1a79d9fad85d8b0aad6855b88b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Dec 2006 09:11:56 +0400 Subject: [PATCH 05/29] merging mysql-test/r/gis.result: result fixed sql/field.cc: Field_*::reset() now returns int sql/sql_load.cc: merging fix --- mysql-test/r/gis.result | 32 ++++++++++++++++---------------- sql/field.cc | 3 ++- sql/sql_load.cc | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index c4c073f047a..92386535119 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -673,6 +673,22 @@ POINT(10 10) select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) POINT(10 10) +create table t1 (g GEOMETRY); +select * from t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 g g 255 4294967295 0 Y 144 0 63 +g +select asbinary(g) from t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def asbinary(g) 252 8192 0 Y 128 0 63 +asbinary(g) +drop table t1; +create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); +alter table t1 disable keys; +load data infile '../../std_data/bad_gis_data.dat' into table t1; +ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1 +alter table t1 enable keys; +drop table t1; create table t1 (s1 geometry not null,s2 char(100)); create trigger t1_bu before update on t1 for each row set new.s1 = null; insert into t1 values (null,null); @@ -696,22 +712,6 @@ alter table t1 add primary key pti(pt); ERROR 42000: BLOB/TEXT column 'pt' used in key specification without a key length alter table t1 add primary key pti(pt(20)); drop table t1; -create table t1 (g GEOMETRY); -select * from t1; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def test t1 t1 g g 255 4294967295 0 Y 144 0 63 -g -select asbinary(g) from t1; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def asbinary(g) 252 8192 0 Y 128 0 63 -asbinary(g) -drop table t1; -create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); -alter table t1 disable keys; -load data infile '../../std_data/bad_gis_data.dat' into table t1; -ERROR 01000: Data truncated; NULL supplied to NOT NULL column 'b' at row 1 -alter table t1 enable keys; -drop table t1; create table t1 select GeomFromText('point(1 1)'); desc t1; Field Type Null Key Default Extra diff --git a/sql/field.cc b/sql/field.cc index f1896344349..590246c51b2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2218,9 +2218,10 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg, } -void Field_new_decimal::reset(void) +int Field_new_decimal::reset(void) { store_value(&decimal_zero); + return 0; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 093e88bf82f..018db006276 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -753,7 +753,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, Field *field= ((Item_field *)item)->field; if (field->reset()) { - my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),sql_field->field->field_name, + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name, thd->row_count); DBUG_RETURN(1); } From e7efe2a9e2c0caac67580a6869658c379d33f7da Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Dec 2006 13:38:16 +0400 Subject: [PATCH 06/29] merging --- mysql-test/r/gis.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 047cc56e275..5ef06688ee6 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -680,13 +680,13 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63 g select asbinary(g) from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def asbinary(g) 252 8192 0 Y 128 0 63 +def asbinary(g) 252 16777216 0 Y 128 0 63 asbinary(g) drop table t1; create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); alter table t1 disable keys; load data infile '../../std_data/bad_gis_data.dat' into table t1; -ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1 +ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'b' at row 1 alter table t1 enable keys; drop table t1; create table t1 (s1 geometry not null,s2 char(100)); From e8be5f6d50cf87ca36f77c08a6ab76688aca411d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Dec 2006 15:22:43 +0400 Subject: [PATCH 07/29] merging fix mysql-test/r/gis.result: result fixed mysql-test/t/gis.test: path to datafile fixed --- mysql-test/r/gis.result | 2 +- mysql-test/t/gis.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 92386535119..870e160e563 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -685,7 +685,7 @@ asbinary(g) drop table t1; create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); alter table t1 disable keys; -load data infile '../../std_data/bad_gis_data.dat' into table t1; +load data infile '../std_data_ln/bad_gis_data.dat' into table t1; ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1 alter table t1 enable keys; drop table t1; diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index a9840c9b3b4..95fdf642b94 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -385,7 +385,7 @@ drop table t1; create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); alter table t1 disable keys; --error 1263 -load data infile '../../std_data/bad_gis_data.dat' into table t1; +load data infile '../std_data_ln/bad_gis_data.dat' into table t1; alter table t1 enable keys; drop table t1; From c29d22c96dd972c890cce5fc3a27138c50a4ce37 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Dec 2006 15:02:32 +0100 Subject: [PATCH 08/29] BUG#24780 use --sysconfdir in scripts scripts/Makefile.am: pass --sysconfdir to scripts scripts/mysqlaccess.sh: use --sysconfdir instead of hardcoded /etc scripts/mysqld_multi.sh: use --sysconfdir instead of hardcoded /etc --- scripts/Makefile.am | 1 + scripts/mysqlaccess.sh | 6 +++--- scripts/mysqld_multi.sh | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 30ba75c551d..0f8e80b4efa 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -111,6 +111,7 @@ SUFFIXES = .sh -e 's!@''pkglibdir''@!$(pkglibdir)!g' \ -e 's!@''pkgincludedir''@!$(pkgincludedir)!g' \ -e 's!@''pkgdatadir''@!$(pkgdatadir)!g' \ + -e 's!@''sysconfdir''@!$(sysconfdir)!g' \ -e 's!@''CC''@!@CC@!'\ -e 's!@''CXX''@!@CXX@!'\ -e 's!@''GXX''@!@GXX@!'\ diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh index 654b43a8a99..22e9d121f9a 100644 --- a/scripts/mysqlaccess.sh +++ b/scripts/mysqlaccess.sh @@ -462,8 +462,8 @@ MySQLaccess::Report::Print_Header(); if (-f "./$script_conf") { require "./$script_conf"; } - elsif (-f "/etc/$script_conf") { - require "/etc/$script_conf"; + elsif (-f "@sysconfdir@/$script_conf") { + require "@sysconfdir@/$script_conf"; } # **************************** @@ -929,7 +929,7 @@ sub MergeConfigFile { # ================================= sub MergeConfigFiles { my ($name,$pass,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwuid $<; - MergeConfigFile("/etc/my.cnf"); + MergeConfigFile("@sysconfdir@/my.cnf"); MergeConfigFile("$dir/.my.cnf"); } diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 4a6f380494f..ce778c03206 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -429,9 +429,9 @@ sub find_groups } else { - if (-f "/etc/my.cnf" && -r "/etc/my.cnf") + if (-f "@sysconfdir@/my.cnf" && -r "@sysconfdir@/my.cnf") { - open(MY_CNF, ") && close(MY_CNF); + open(MY_CNF, "<@sysconfdir@/my.cnf") && (@tmp=) && close(MY_CNF); } for ($i = 0; ($line = shift @tmp); $i++) { @@ -658,7 +658,7 @@ sub example # (as per Linux/Unix standard). You may even replace the # /etc/init.d/mysql.server script with it. # -# Before using, you must create a my.cnf file either in /etc/my.cnf +# Before using, you must create a my.cnf file either in @sysconfdir@/my.cnf # or /root/.my.cnf and add the [mysqld_multi] and [mysqld#] groups. # # The script can be found from support-files/mysqld_multi.server.sh From 60b3a86ad4b8b3ba3a0626191d106a20f0b2e871 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Dec 2006 16:06:29 +0100 Subject: [PATCH 09/29] do not autorelease build ids when a child of mysql-test-run.pl dies mysql-test/lib/mtr_unique.pl: do not autorelease build ids when a child dies --- mysql-test/lib/mtr_unique.pl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/mtr_unique.pl b/mysql-test/lib/mtr_unique.pl index a8fb320c773..3adc8413576 100644 --- a/mysql-test/lib/mtr_unique.pl +++ b/mysql-test/lib/mtr_unique.pl @@ -10,10 +10,16 @@ use Fcntl ':flock'; # Requested IDs are stored in a hash and released upon END. # my %mtr_unique_assigned_ids = (); +my $mtr_unique_pid; +BEGIN { + $mtr_unique_pid = $$ unless defined $mtr_unique_pid; +} END { - while(my ($id,$file) = each(%mtr_unique_assigned_ids)) { - print "Autoreleasing $file:$id\n"; - mtr_release_unique_id($file, $id); + if($mtr_unique_pid == $$) { + while(my ($id,$file) = each(%mtr_unique_assigned_ids)) { + print "Autoreleasing $file:$id\n"; + mtr_release_unique_id($file, $id); + } } } From 12ac165c2f856ca8e8bf10a85b60722c9cbade64 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Dec 2006 10:23:03 +0100 Subject: [PATCH 10/29] BUG#24896 mysql_upgrade -p fix client/mysql_upgrade.c: BUG#24896 mysql_upgrade core dumps on RHEL3 using 5.0.30 commerical binaries --- client/mysql_upgrade.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 520d87b5ed7..309b532051c 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -142,6 +142,7 @@ void set_extra_default(int id, const struct my_option *opt) case 'f': /* --force is ours */ case 'u': /* --user passed on cmdline */ case 'T': /* --debug-info is not accepted by mysqlcheck */ + case 'p': /* --password may change yet */ /* so, do nothing */ break; default: @@ -173,7 +174,7 @@ void set_extra_default(int id, const struct my_option *opt) d->id= id; d->name= opt->name; d->n_len= strlen(opt->name); - if (opt->arg_type != NO_ARG) + if (opt->arg_type != NO_ARG && opt->value) switch (opt->var_type & GET_TYPE_MASK) { case GET_BOOL: if (*((int *)opt->value)) @@ -319,6 +320,15 @@ static int create_defaults_file(const char *path, const char *forced_path) } dynstr_set(&buf, "\n[client]"); + if (opt_password) + { + if (dynstr_append_mem(&buf, "\npassword=", 10) + || dynstr_append_mem(&buf, opt_password, strlen(opt_password))) + { + ret = 1; + goto error; + } + } while (extra_defaults) { int len; From e322b0983d7ed21d715440fc19a14a05fe38ad7c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Dec 2006 10:36:52 +0100 Subject: [PATCH 11/29] BUG#24902 --- mysql-test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index aa5c2106e8b..61c523f1aed 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -108,7 +108,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data - $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup50 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51 From f67380eb6aca63927bebe5fafc7ec0db6e58d914 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Dec 2006 13:55:40 +0100 Subject: [PATCH 12/29] BUG#24902 in 5.0 mysql-test/Makefile.am: BUG#24902 --- mysql-test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 72998d786b9..eff2ae740f5 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -98,7 +98,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data - $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib From c6e421bc451e92db86980acc495bfdddd3058d0f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Dec 2006 15:47:02 +0100 Subject: [PATCH 13/29] BUG#24896 magnus' suggestion --- client/mysql_upgrade.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 309b532051c..0f3f307a26d 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -322,8 +322,8 @@ static int create_defaults_file(const char *path, const char *forced_path) dynstr_set(&buf, "\n[client]"); if (opt_password) { - if (dynstr_append_mem(&buf, "\npassword=", 10) - || dynstr_append_mem(&buf, opt_password, strlen(opt_password))) + if (dynstr_append(&buf, "\npassword=") + || dynstr_append(&buf, opt_password)) { ret = 1; goto error; From 007357e7cda5efb3fdd12ad37b069a0f5c35daf4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Dec 2006 22:30:32 +0100 Subject: [PATCH 14/29] support-files/mysql.spec.sh The Docs team has two new manpages for the "server" RPM: "my_print_defaults" and "mysql_tzinfo_to_sql". support-files/mysql.spec.sh: The Docs team has two new manpages for the "server" RPM: "my_print_defaults" and "mysql_tzinfo_to_sql". --- support-files/mysql.spec.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b14ffd24894..083b89d9275 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -549,6 +549,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1* %doc %attr(644, root, man) %{_mandir}/man1/isamchk.1* %doc %attr(644, root, man) %{_mandir}/man1/isamlog.1* +%doc %attr(644, root, man) %{_mandir}/man1/my_print_defaults.1* %doc %attr(644, root, man) %{_mandir}/man1/myisam_ftdump.1* %doc %attr(644, root, man) %{_mandir}/man1/myisamchk.1* %doc %attr(644, root, man) %{_mandir}/man1/myisamlog.1* @@ -560,6 +561,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysql_tzinfo_to_sql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* %doc %attr(644, root, man) %{_mandir}/man1/pack_isam.1* %doc %attr(644, root, man) %{_mandir}/man1/perror.1* @@ -724,6 +726,11 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Thu Dec 14 2006 Joerg Bruehe + +- Include the new man pages for "my_print_defaults" and "mysql_tzinfo_to_sql" + in the server RPM. + * Thu Nov 16 2006 Joerg Bruehe - Explicitly note that the "MySQL-shared" RPMs (as built by MySQL AB) From 13eeee6f3f3f84026d67a01115ef77d676bf7aff Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Dec 2006 22:41:26 +0100 Subject: [PATCH 15/29] support-files/mysql.spec.sh The "mysqlmanager" man page got moved from section 1 to 8. support-files/mysql.spec.sh: The "mysqlmanager" man page got moved from section 1 to 8. --- support-files/mysql.spec.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1c5baddf74a..1bf983cb02c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -588,7 +588,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.8* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_tzinfo_to_sql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* @@ -759,6 +759,7 @@ fi - Include the new man pages for "my_print_defaults" and "mysql_tzinfo_to_sql" in the server RPM. +- The "mysqlmanager" man page got moved from section 1 to 8. * Thu Nov 16 2006 Joerg Bruehe From 6dd079a6c1450a8e0407e3160792e9d54ddd2c84 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Dec 2006 13:18:16 +0100 Subject: [PATCH 16/29] Raise version number after cloning 5.0.32 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index f6a6eedac70..5657cb1be93 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.32) +AM_INIT_AUTOMAKE(mysql, 5.0.34) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From ef8c57f988b5b8e1029cd2c36379e995eef9e46a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Dec 2006 17:45:17 +0100 Subject: [PATCH 17/29] minor fixup support-files/mysql.spec.sh: fixup --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1bf983cb02c..8a633f0d53a 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -588,7 +588,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.8* +%doc %attr(644, root, man) %{_mandir}/man8/mysqlmanager.8* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_tzinfo_to_sql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* From 36c7c608bf0ea1c016f25bb0ca743528e139b9fa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Dec 2006 17:57:31 +0100 Subject: [PATCH 18/29] also include data files for varbinary test in binary distribution --- scripts/make_binary_distribution.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index a6a2f1e3b49..9469cca875d 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -243,6 +243,7 @@ $CP mysql-test/include/*.inc $BASE/mysql-test/include $CP mysql-test/include/*.test $BASE/mysql-test/include $CP mysql-test/t/*.def $BASE/mysql-test/t $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ + mysql-test/std_data/*.MYD mysql-test/std_data/*.MYI \ mysql-test/std_data/*.pem mysql-test/std_data/Moscow_leap \ mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \ mysql-test/std_data/*.cnf \ From 134b83d0a0094cc3a71dbd0a20f118f5a9f10573 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Dec 2006 11:51:45 +0100 Subject: [PATCH 19/29] support-files/mysql.spec.sh Fix the move of "mysqlmanager" to section 8: Directory name was wrong. support-files/mysql.spec.sh: Fix the move of "mysqlmanager" to section 8: Directory name was wrong. --- support-files/mysql.spec.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1bf983cb02c..59369f0de35 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -588,7 +588,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.8* +%doc %attr(644, root, man) %{_mandir}/man8/mysqlmanager.8* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_tzinfo_to_sql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* @@ -755,6 +755,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Dec 18 2006 Joerg Bruehe + +- Fix the move of "mysqlmanager" to section 8: Directory name was wrong. + * Thu Dec 14 2006 Joerg Bruehe - Include the new man pages for "my_print_defaults" and "mysql_tzinfo_to_sql" From e55c9a7ab57ef0a8aeac0bb36ad8f585a52e5432 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Dec 2006 13:44:21 +0100 Subject: [PATCH 20/29] Use a temporary directory for sockets if the socket path becomes too long. --- mysql-test/mysql-test-run.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5002f778da5..397adb9e157 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -58,6 +58,7 @@ $Devel::Trace::TRACE= 0; # Don't trace boring init stuff use File::Path; use File::Basename; use File::Copy; +use File::Temp qw / tempdir /; use Cwd; use Getopt::Long; use Sys::Hostname; @@ -1030,6 +1031,11 @@ sub command_line_setup () { my $sockdir = $opt_tmpdir; $sockdir =~ s|/+$||; + # On some operating systems, there is a limit to the length of a + # UNIX domain socket's path far below PATH_MAX, so try to avoid long + # socket path names. + $sockdir = tempdir(CLEANUP => 1) if ( length($sockdir) > 80 ); + # Put this into a hash, will be a C struct $master->[0]= From 306f42701cdbf0801c710f3c0fe0e74c521455fc Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Dec 2006 18:41:38 -0700 Subject: [PATCH 21/29] This ChangeSet must be null-merged to 5.1. Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Bugs fixed: - Bug #21468: InnoDB crash during recovery with corrupted data pages: XA bug? - Bug #24299: Identifiers in foreign keys cannot contain U+0160, U+0360, ..., U+FF60 - Bug #24386: Performance degradation caused by instrumentation in mutex_struct - Bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect time fields innobase/dict/dict0dict.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1030: branches/5.0: Replace isspace() with a wrapper ib_isspace(), because on Win32 isspace(0xa0) appears to hold. (Bug #24299) innobase/include/sync0rw.h: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/include/sync0sync.h: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/include/sync0sync.ic: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/log/log0recv.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1076: branches/5.0: Remove the unintentionally committed change to univ.i in r1075. Fix assertion failure sync0sync.c line 1239 (the latter ut_error in sync_thread_reset_level()) in crash recovery when UNIV_SYNC_DEBUG is enabled. Revision r1079: branches/5.0: recv_recovery_from_checkpoint_finish(): Add 1 sec delay before switching on the sync order checks in crash recovery, so that file I/O threads have time to suspend themselves. innobase/srv/srv0start.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1075: branches/5.0: Fix assertion failure sync0sync.c line 1239 (the latter ut_error in sync_thread_reset_level()) in crash recovery when UNIV_SYNC_DEBUG is enabled. Revision r1077: branches/5.0: innobase_start_or_create_for_mysql(): Remove unnecessary delay now that we moved the setting sync_order_checks_on=TRUE to log0recv.c, to the start of the rollback phase in crash recovery. innobase/sync/sync0rw.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/sync/sync0sync.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) innobase/trx/trx0roll.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1067: branches/5.0: trx_rollback_for_mysql(), trx_commit_for_mysql(): Protect the creation of trx_dummy_sess with kernel_mutex. This error was introduced in r1046 and r1050. Revision r1050: branches/5.0: trx_rollback_for_mysql(): Fix the comment introduced in r1046. trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared transaction in XA recovery, just in case our code would need the session object also in that case (does not seem to need it right now). Revision r1048: branches/5.0: trx_rollback_for_mysql(): Do not set trx->sess back to NULL. This bug was introduced in r1046. Revision r1046: branches/5.0: trx_rollback_for_mysql(): Ensure that trx->sess is non-NULL when calling trx_general_rollback_for_mysql(). This removes a segmentation fault when rolling back a prepared transaction in XA recovery. (Bug #21468) innobase/trx/trx0trx.c: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1067: branches/5.0: trx_rollback_for_mysql(), trx_commit_for_mysql(): Protect the creation of trx_dummy_sess with kernel_mutex. This error was introduced in r1046 and r1050. Revision r1050: branches/5.0: trx_rollback_for_mysql(): Fix the comment introduced in r1046. trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared transaction in XA recovery, just in case our code would need the session object also in that case (does not seem to need it right now). sql/ha_innodb.cc: Applied innodb-5.0-ss1040 and innodb-5.0-ss1099 snapshots. Revision r1040: branches/5.0: Port r1039 from trunk: Port r1034 from branches/zip: Remove some instrumentation and reduce the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386) Revision r1099: branches/5.0: Merge revision 1098 from trunk: Fix bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect time fields --- innobase/dict/dict0dict.c | 29 +++++++++++---------- innobase/include/sync0rw.h | 14 +++++++--- innobase/include/sync0sync.h | 32 ++++++++++++++--------- innobase/include/sync0sync.ic | 4 +-- innobase/log/log0recv.c | 10 ++++++++ innobase/srv/srv0start.c | 11 -------- innobase/sync/sync0rw.c | 14 +++++----- innobase/sync/sync0sync.c | 32 +++++++++++++---------- innobase/trx/trx0roll.c | 22 ++++++++++++++-- innobase/trx/trx0trx.c | 18 +++++++++++++ sql/ha_innodb.cc | 48 +++++++++++++++++++++-------------- 11 files changed, 152 insertions(+), 82 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index fffe851bc52..ba03e1f5e41 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -27,6 +27,9 @@ Created 1/8/1996 Heikki Tuuri #include "que0que.h" #include "rem0cmp.h" +/* Implement isspace() in a locale-independent way. (Bug #24299) */ +#define ib_isspace(c) strchr(" \v\f\t\r\n", c) + dict_sys_t* dict_sys = NULL; /* the dictionary system */ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve @@ -2406,7 +2409,7 @@ dict_accept( *success = FALSE; - while (isspace(*ptr)) { + while (ib_isspace(*ptr)) { ptr++; } @@ -2451,7 +2454,7 @@ dict_scan_id( *id = NULL; - while (isspace(*ptr)) { + while (ib_isspace(*ptr)) { ptr++; } @@ -2482,7 +2485,7 @@ dict_scan_id( len++; } } else { - while (!isspace(*ptr) && *ptr != '(' && *ptr != ')' + while (!ib_isspace(*ptr) && *ptr != '(' && *ptr != ')' && (accept_also_dot || *ptr != '.') && *ptr != ',' && *ptr != '\0') { @@ -2512,12 +2515,12 @@ dict_scan_id( if (heap && !quote) { /* EMS MySQL Manager sometimes adds characters 0xA0 (in latin1, a 'non-breakable space') to the end of a table name. - But isspace(0xA0) is not true, which confuses our foreign key - parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2 - and 0xA0 are at the end of the string. + After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2 + and 0xA0 are at the end of the string, and ib_isspace() + does not work for multi-byte UTF-8 characters. - TODO: we should lex the string using thd->charset_info, and - my_isspace(). Only after that, convert id names to UTF-8. */ + In MySQL 5.1 we lex the string using thd->charset_info, and + my_isspace(). This workaround is not needed there. */ b = (byte*)(*id); id_len = strlen((char*) b); @@ -3006,11 +3009,11 @@ loop: ut_a(success); - if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') { + if (!ib_isspace(*ptr) && *ptr != '"' && *ptr != '`') { goto loop; } - while (isspace(*ptr)) { + while (ib_isspace(*ptr)) { ptr++; } @@ -3052,7 +3055,7 @@ loop: goto loop; } - if (!isspace(*ptr)) { + if (!ib_isspace(*ptr)) { goto loop; } @@ -3140,7 +3143,7 @@ col_loop1: } ptr = dict_accept(ptr, "REFERENCES", &success); - if (!success || !isspace(*ptr)) { + if (!success || !ib_isspace(*ptr)) { dict_foreign_report_syntax_err(name, start_of_latest_foreign, ptr); return(DB_CANNOT_ADD_CONSTRAINT); @@ -3527,7 +3530,7 @@ loop: ptr = dict_accept(ptr, "DROP", &success); - if (!isspace(*ptr)) { + if (!ib_isspace(*ptr)) { goto loop; } diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 741f9500612..4cd26ba1921 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -61,8 +61,12 @@ Creates, or rather, initializes an rw-lock object in a specified memory location (which must be appropriately aligned). The rw-lock is initialized to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free is necessary only if the memory block containing it is freed. */ -#define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__, #L) - +#ifdef UNIV_DEBUG +# define rw_lock_create(L) rw_lock_create_func((L), #L, __FILE__, __LINE__) +#else /* UNIV_DEBUG */ +# define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__) +#endif /* UNIV_DEBUG */ + /*=====================*/ /********************************************************************** Creates, or rather, initializes an rw-lock object in a specified memory @@ -74,9 +78,11 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name); /* in: mutex name */ + ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing the rw-lock is freed. Removes an rw-lock object from the global list. The diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 9893921c5d2..769c2a98244 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -39,7 +39,11 @@ location (which must be appropriately aligned). The mutex is initialized in the reset state. Explicit freeing of the mutex with mutex_free is necessary only if the memory block containing it is freed. */ -#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__, #M) +#ifdef UNIV_DEBUG +# define mutex_create(M) mutex_create_func((M), #M, __FILE__, __LINE__) +#else +# define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__) +#endif /*===================*/ /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory @@ -51,9 +55,11 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name); /* in: mutex name */ + ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing the mutex is freed. Removes a mutex object from the mutex list. The mutex @@ -479,15 +485,17 @@ struct mutex_struct { ulint cline; /* Line where created */ ulint magic_n; #ifndef UNIV_HOTBACKUP - ulong count_using; /* count of times mutex used */ - ulong count_spin_loop; /* count of spin loops */ - ulong count_spin_rounds; /* count of spin rounds */ - ulong count_os_wait; /* count of os_wait */ - ulong count_os_yield; /* count of os_wait */ - ulonglong lspent_time; /* mutex os_wait timer msec */ - ulonglong lmax_spent_time; /* mutex os_wait timer msec */ - const char* cmutex_name;/* mutex name */ - ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */ + ulong count_os_wait; /* count of os_wait */ +# ifdef UNIV_DEBUG + ulong count_using; /* count of times mutex used */ + ulong count_spin_loop; /* count of spin loops */ + ulong count_spin_rounds; /* count of spin rounds */ + ulong count_os_yield; /* count of os_wait */ + ulonglong lspent_time; /* mutex os_wait timer msec */ + ulonglong lmax_spent_time; /* mutex os_wait timer msec */ + const char* cmutex_name;/* mutex name */ + ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */ +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ }; diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index b3fde61db5e..a32a82d6e8b 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -250,9 +250,9 @@ mutex_enter_func( /* Note that we do not peek at the value of lock_word before trying the atomic test_and_set; we could peek, and possibly save time. */ -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_using++; -#endif /* UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ if (!mutex_test_and_set(mutex)) { diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 113d237b535..c1ceb9791f2 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -33,6 +33,7 @@ Created 9/20/1997 Heikki Tuuri #include "btr0cur.h" #include "dict0boot.h" #include "fil0fil.h" +#include "sync0sync.h" #ifdef UNIV_HOTBACKUP /* This is set to FALSE if the backup was originally taken with the @@ -2969,6 +2970,15 @@ recv_recovery_from_checkpoint_finish(void) #ifndef UNIV_LOG_DEBUG recv_sys_free(); #endif + +#ifdef UNIV_SYNC_DEBUG + /* Wait for a while so that created threads have time to suspend + themselves before we switch the latching order checks on */ + os_thread_sleep(1000000); + + /* Switch latching order checks on in sync0sync.c */ + sync_order_checks_on = TRUE; +#endif if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { /* Rollback the uncommitted transactions which have no user session */ diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index b41dcbe44cd..5f8707a661c 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1554,17 +1554,6 @@ innobase_start_or_create_for_mysql(void) srv_was_started = TRUE; srv_is_being_started = FALSE; -#ifdef UNIV_DEBUG - /* Wait a while so that the created threads have time to suspend - themselves before we switch sync debugging on; otherwise a thread may - execute mutex_enter() before the checks are on, and mutex_exit() after - the checks are on, which will cause an assertion failure in sync - debug. */ - - os_thread_sleep(3000000); -#endif - sync_order_checks_on = TRUE; - if (trx_doublewrite == NULL) { /* Create the doublewrite buffer to a new tablespace */ diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 050de73db9e..629331d6049 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -89,9 +89,11 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name) /* in: mutex name */ + ulint cline) /* in: file line where created */ { /* If this is the very first time a synchronization object is created, then the following call initializes @@ -102,10 +104,10 @@ rw_lock_create_func( lock->mutex.cfile_name = cfile_name; lock->mutex.cline = cline; -#ifndef UNIV_HOTBACKUP - lock->mutex.cmutex_name = cmutex_name; - lock->mutex.mutex_type = 1; -#endif /* !UNIV_HOTBACKUP */ +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP + lock->mutex.cmutex_name = cmutex_name; + lock->mutex.mutex_type = 1; +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ rw_lock_set_waiters(lock, 0); rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 95bf83dce79..25b7a5588d9 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -202,9 +202,11 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name) /* in: mutex name */ + ulint cline) /* in: file line where created */ { #if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) mutex_reset_lock_word(mutex); @@ -223,6 +225,8 @@ mutex_create_func( mutex->cfile_name = cfile_name; mutex->cline = cline; #ifndef UNIV_HOTBACKUP + mutex->count_os_wait = 0; +# ifdef UNIV_DEBUG mutex->cmutex_name= cmutex_name; mutex->count_using= 0; mutex->mutex_type= 0; @@ -230,8 +234,8 @@ mutex_create_func( mutex->lmax_spent_time= 0; mutex->count_spin_loop= 0; mutex->count_spin_rounds= 0; - mutex->count_os_wait= 0; mutex->count_os_yield= 0; +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ /* Check that lock_word is aligned; this is important on Intel */ @@ -378,13 +382,13 @@ mutex_spin_wait( { ulint index; /* index of the reserved wait cell */ ulint i; /* spin round count */ -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */ ulint ltime_diff; ulint sec; ulint ms; uint timer_started = 0; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ ut_ad(mutex); mutex_loop: @@ -398,10 +402,10 @@ mutex_loop: memory word. */ spin_loop: -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex_spin_wait_count++; mutex->count_spin_loop++; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) { @@ -415,7 +419,7 @@ spin_loop: if (i == SYNC_SPIN_ROUNDS) { -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_os_yield++; if (timed_mutexes == 1 && timer_started==0) { @@ -423,7 +427,7 @@ spin_loop: lstart_time= (ib_longlong)sec * 1000000 + ms; timer_started = 1; } -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ os_thread_yield(); } @@ -436,9 +440,9 @@ spin_loop: mutex_spin_round_count += i; -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_spin_rounds += i; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ if (mutex_test_and_set(mutex) == 0) { @@ -522,6 +526,7 @@ Now there is no risk of infinite wait on the event. */ #ifndef UNIV_HOTBACKUP mutex->count_os_wait++; +# ifdef UNIV_DEBUG /* !!!!! Sometimes os_wait can be called without os_thread_yield */ @@ -532,13 +537,14 @@ Now there is no risk of infinite wait on the event. */ lstart_time= (ib_longlong)sec * 1000000 + ms; timer_started = 1; } +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ sync_array_wait_event(sync_primary_wait_array, index); goto mutex_loop; finish_timing: -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP if (timed_mutexes == 1 && timer_started==1) { ut_usectime(&sec, &ms); @@ -551,7 +557,7 @@ finish_timing: mutex->lmax_spent_time= ltime_diff; } } -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ return; } diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index fdfb7428129..bf8b9fd1939 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -129,9 +129,27 @@ trx_rollback_for_mysql( } trx->op_info = "rollback"; - - err = trx_general_rollback_for_mysql(trx, FALSE, NULL); + /* If we are doing the XA recovery of prepared transactions, then + the transaction object does not have an InnoDB session object, and we + set a dummy session that we use for all MySQL transactions. */ + + mutex_enter(&kernel_mutex); + + if (trx->sess == NULL) { + /* Open a dummy session */ + + if (!trx_dummy_sess) { + trx_dummy_sess = sess_open(); + } + + trx->sess = trx_dummy_sess; + } + + mutex_exit(&kernel_mutex); + + err = trx_general_rollback_for_mysql(trx, FALSE, NULL); + trx->op_info = ""; return(err); diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 2637b28ef90..4dc826e5947 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1601,7 +1601,25 @@ trx_commit_for_mysql( ut_a(trx); trx->op_info = "committing"; + + /* If we are doing the XA recovery of prepared transactions, then + the transaction object does not have an InnoDB session object, and we + set the dummy session that we use for all MySQL transactions. */ + mutex_enter(&kernel_mutex); + + if (trx->sess == NULL) { + /* Open a dummy session */ + + if (!trx_dummy_sess) { + trx_dummy_sess = sess_open(); + } + + trx->sess = trx_dummy_sess; + } + + mutex_exit(&kernel_mutex); + trx_start_if_not_started(trx); mutex_enter(&kernel_mutex); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e9ccc0ccede..617712d72bb 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5309,19 +5309,11 @@ ha_innobase::info( prebuilt->trx->op_info = (char*) "returning various info to MySQL"; - - if (ib_table->space != 0) { - my_snprintf(path, sizeof(path), "%s/%s%s", - mysql_data_home, ib_table->name, - ".ibd"); - unpack_filename(path,path); - } else { - my_snprintf(path, sizeof(path), "%s/%s%s", + my_snprintf(path, sizeof(path), "%s/%s%s", mysql_data_home, ib_table->name, reg_ext); - unpack_filename(path,path); - } + unpack_filename(path,path); /* Note that we do not know the access time of the table, nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ @@ -6378,14 +6370,17 @@ innodb_mutex_show_status( Protocol *protocol= thd->protocol; List field_list; mutex_t* mutex; +#ifdef UNIV_DEBUG ulint rw_lock_count= 0; ulint rw_lock_count_spin_loop= 0; ulint rw_lock_count_spin_rounds= 0; ulint rw_lock_count_os_wait= 0; ulint rw_lock_count_os_yield= 0; ulonglong rw_lock_wait_time= 0; +#endif /* UNIV_DEBUG */ DBUG_ENTER("innodb_mutex_show_status"); +#ifdef UNIV_DEBUG field_list.push_back(new Item_empty_string("Mutex", FN_REFLEN)); field_list.push_back(new Item_empty_string("Module", FN_REFLEN)); field_list.push_back(new Item_uint("Count", 21)); @@ -6394,19 +6389,23 @@ innodb_mutex_show_status( field_list.push_back(new Item_uint("OS_waits", 21)); field_list.push_back(new Item_uint("OS_yields", 21)); field_list.push_back(new Item_uint("OS_waits_time", 21)); +#else /* UNIV_DEBUG */ + field_list.push_back(new Item_empty_string("File", FN_REFLEN)); + field_list.push_back(new Item_uint("Line", 21)); + field_list.push_back(new Item_uint("OS_waits", 21)); +#endif /* UNIV_DEBUG */ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_enter(&mutex_list_mutex); -#endif + mutex_enter_noninline(&mutex_list_mutex); mutex = UT_LIST_GET_FIRST(mutex_list); while ( mutex != NULL ) { +#ifdef UNIV_DEBUG if (mutex->mutex_type != 1) { if (mutex->count_using > 0) @@ -6423,9 +6422,7 @@ innodb_mutex_show_status( if (protocol->write()) { -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_exit(&mutex_list_mutex); -#endif + mutex_exit_noninline(&mutex_list_mutex); DBUG_RETURN(1); } } @@ -6439,10 +6436,25 @@ innodb_mutex_show_status( rw_lock_count_os_yield += mutex->count_os_yield; rw_lock_wait_time += mutex->lspent_time; } +#else /* UNIV_DEBUG */ + protocol->prepare_for_resend(); + protocol->store(mutex->cfile_name, system_charset_info); + protocol->store((ulonglong)mutex->cline); + protocol->store((ulonglong)mutex->count_os_wait); + + if (protocol->write()) + { + mutex_exit_noninline(&mutex_list_mutex); + DBUG_RETURN(1); + } +#endif /* UNIV_DEBUG */ mutex = UT_LIST_GET_NEXT(list, mutex); } + mutex_exit_noninline(&mutex_list_mutex); + +#ifdef UNIV_DEBUG protocol->prepare_for_resend(); protocol->store("rw_lock_mutexes", system_charset_info); protocol->store("", system_charset_info); @@ -6457,10 +6469,8 @@ innodb_mutex_show_status( { DBUG_RETURN(1); } +#endif /* UNIV_DEBUG */ -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_exit(&mutex_list_mutex); -#endif send_eof(thd); DBUG_RETURN(FALSE); } From 2eeeb9b4d390b438e0c3eac7143255dc10e979ca Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Dec 2006 15:10:15 +0100 Subject: [PATCH 22/29] remove hard-coded socket paths from some tests mysql-test/t/grant_cache.test: replace hard-coded socket paths with variable containing the appropriate path mysql-test/t/myisam.test: replace hard-coded socket paths with variable containing the appropriate path mysql-test/t/query_cache_notembedded.test: replace hard-coded socket paths with variable containing the appropriate path mysql-test/t/rpl000015.test: replace hard-coded socket paths with variable containing the appropriate path mysql-test/t/rpl000017.test: replace hard-coded socket paths with variable containing the appropriate path mysql-test/t/rpl_rotate_logs.test: replace hard-coded socket paths with variable containing the appropriate path --- mysql-test/t/grant_cache.test | 14 +++++++------- mysql-test/t/myisam.test | 2 +- mysql-test/t/query_cache_notembedded.test | 4 ++-- mysql-test/t/rpl000015.test | 4 ++-- mysql-test/t/rpl000017.test | 4 ++-- mysql-test/t/rpl_rotate_logs.test | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test index 703ad5d8004..7e17a03ec21 100644 --- a/mysql-test/t/grant_cache.test +++ b/mysql-test/t/grant_cache.test @@ -14,7 +14,7 @@ set GLOBAL query_cache_size=1355776; reset query cache; flush status; -connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; show grants for current_user; show grants; @@ -29,7 +29,7 @@ insert into mysqltest.t2 values (3,3,3); create table test.t1 (a char (10)); insert into test.t1 values ("test.t1"); select * from t1; -connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,master.sock); +connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection root2; # put queries in cache select * from t1; @@ -47,7 +47,7 @@ grant SELECT on test.t1 to mysqltest_2@localhost; grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; # The following queries should be fetched from cache -connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,master.sock); +connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user1; show grants for current_user(); show status like "Qcache_queries_in_cache"; @@ -72,12 +72,12 @@ show status like "Qcache_hits"; show status like "Qcache_not_cached"; # Don't use '' as user because it will pick Unix login -connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,master.sock); +connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,$MASTER_MYSOCK); connection unkuser; show grants for current_user(); # The following queries should be fetched from cache -connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,master.sock); +connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user2; select "user2"; select * from t1; @@ -92,7 +92,7 @@ show status like "Qcache_hits"; show status like "Qcache_not_cached"; # The following queries should not be fetched from cache -connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,master.sock); +connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user3; select "user3"; --replace_result 127.0.0.1 localhost @@ -113,7 +113,7 @@ show status like "Qcache_hits"; show status like "Qcache_not_cached"; # Connect without a database -connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,master.sock); +connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK); connection user4; select "user4"; show grants; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 745e3a2e377..c3269084c6f 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -495,7 +495,7 @@ insert into t1 values (1),(2),(3),(4),(5),(6); insert into t2 values (1,1),(2,1); lock tables t1 read local, t2 read local; select straight_join * from t1,t2 force index (primary) where t1.a=t2.a; -connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); insert into t2 values(2,0); disconnect root; connection default; diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index fd4785ffe95..20baf3450e2 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -81,12 +81,12 @@ drop table t1, t2, t3, t11, t21; # # do not use QC if tables locked (BUG#12385) # -connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE = MyISAM; LOCK TABLE t1 READ LOCAL; -connect (root2,localhost,root,,test,$MASTER_MYPORT,master.sock); +connect (root2,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root2; INSERT INTO t1 VALUES (), (), (); connection root; diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index 4e329fc87ea..a23a4b0ba5f 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock); -connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock); +connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); +connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); connection master; reset master; show master status; diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test index 7b4e6bf4d3a..ea3aba8fb75 100644 --- a/mysql-test/t/rpl000017.test +++ b/mysql-test/t/rpl000017.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock); -connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock); +connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); +connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); connection master; reset master; grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab'; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index 891582a167c..8d751e43958 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -9,11 +9,11 @@ # changes # - Test creating a duplicate key error and recover from it -connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock); +connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); --disable_warnings drop table if exists t1, t2, t3, t4; --enable_warnings -connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock); +connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); system cat /dev/null > var/slave-data/master.info; system chmod 000 var/slave-data/master.info; connection slave; From f8920dd59f87f488435f7f60939ed63e0a4b6b52 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Dec 2006 15:54:12 -0700 Subject: [PATCH 23/29] Bug #24947: REPEAT function returns NULL when passed a field as the count parameter Handling of large signed/unsigned values was not consistent, so some string functions could return bogus results. The current fix is to simply patch up the val_str() methods for those string items. It would be good clean this code up in general, to make similar problems much harder to make. This is left as an exercise for the reader. mysql-test/r/func_str.result: Update test results for bug #24947 mysql-test/t/func_str.test: Add test case for bug #24947 sql/item_strfunc.cc: Adjust some string function Items' val_str() methods to handle large signed/unsigned arguments properly --- mysql-test/r/func_str.result | 12 +++++++++++ mysql-test/t/func_str.test | 8 +++++++ sql/item_strfunc.cc | 41 ++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 14c61a2dd93..b5a9d4de105 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1916,4 +1916,16 @@ CHAR(0xff,0x8f USING utf8) IS NULL Warnings: Error 1300 Invalid utf8 character string: 'FF8F' SET SQL_MODE=@orig_sql_mode; +select substring('abc', cast(2 as unsigned int)); +substring('abc', cast(2 as unsigned int)) +bc +select repeat('a', cast(2 as unsigned int)); +repeat('a', cast(2 as unsigned int)) +aa +select rpad('abc', cast(5 as unsigned integer), 'x'); +rpad('abc', cast(5 as unsigned integer), 'x') +abcxx +select lpad('abc', cast(5 as unsigned integer), 'x'); +lpad('abc', cast(5 as unsigned integer), 'x') +xxabc End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index af4f8b9a9d2..a55b633b91e 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -991,5 +991,13 @@ SELECT CHAR(0xff,0x8f USING utf8) IS NULL; SET SQL_MODE=@orig_sql_mode; +# +# Bug #24947: problem with some string function with unsigned int parameters +# + +select substring('abc', cast(2 as unsigned int)); +select repeat('a', cast(2 as unsigned int)); +select rpad('abc', cast(5 as unsigned integer), 'x'); +select lpad('abc', cast(5 as unsigned integer), 'x'); --echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0b48a00012a..afc2edb06dd 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1166,7 +1166,8 @@ String *Item_func_substr::val_str(String *str) /* if "unsigned_flag" is set, we have a *huge* positive number. */ /* Assumes that the maximum length of a String is < INT_MAX32. */ - if ((args[1]->unsigned_flag) || (start < INT_MIN32) || (start > INT_MAX32)) + if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) || + (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32))) return &my_empty_string; start= ((start < 0) ? res->numchars() + start : start - 1); @@ -2227,25 +2228,23 @@ String *Item_func_repeat::val_str(String *str) uint length,tot_length; char *to; /* must be longlong to avoid truncation */ - longlong tmp_count= args[1]->val_int(); - long count= (long) tmp_count; + longlong count= args[1]->val_int(); String *res= args[0]->val_str(str); - /* Assumes that the maximum length of a String is < INT_MAX32. */ - /* Bounds check on count: If this is triggered, we will error. */ - if ((tmp_count > INT_MAX32) || args[1]->unsigned_flag) - count= INT_MAX32; - if (args[0]->null_value || args[1]->null_value) goto err; // string and/or delim are null null_value= 0; - if ((tmp_count <= 0) && !args[1]->unsigned_flag) // For nicer SQL code + if ((count <= 0) && !args[1]->unsigned_flag) // For nicer SQL code return &my_empty_string; + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Bounds check on count: If this is triggered, we will error. */ + if ((ulonglong) count > INT_MAX32) + count= INT_MAX32; if (count == 1) // To avoid reallocs return res; length=res->length(); // Safe length check - if (length > current_thd->variables.max_allowed_packet/count) + if (length > current_thd->variables.max_allowed_packet / (uint) count) { push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_ALLOWED_PACKET_OVERFLOWED, @@ -2319,15 +2318,14 @@ String *Item_func_rpad::val_str(String *str) String *res= args[0]->val_str(str); String *rpad= args[2]->val_str(&rpad_str); - /* Assumes that the maximum length of a String is < INT_MAX32. */ - /* Set here so that rest of code sees out-of-bound value as such. */ - if ((count > INT_MAX32) || args[1]->unsigned_flag) - count= INT_MAX32; - - if (!res || args[1]->null_value || !rpad || count < 0) + if (!res || args[1]->null_value || !rpad || + ((count < 0) && !args[1]->unsigned_flag)) goto err; null_value=0; - + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if ((ulonglong) count > INT_MAX32) + count= INT_MAX32; if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos((int) count)); // Shorten result if longer @@ -2421,14 +2419,15 @@ String *Item_func_lpad::val_str(String *str) String *res= args[0]->val_str(&tmp_value); String *pad= args[2]->val_str(&lpad_str); + if (!res || args[1]->null_value || !pad || + ((count < 0) && !args[1]->unsigned_flag)) + goto err; + null_value=0; /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if ((count > INT_MAX32) || args[1]->unsigned_flag) + if ((ulonglong) count > INT_MAX32) count= INT_MAX32; - if (!res || args[1]->null_value || !pad || count < 0) - goto err; - null_value=0; res_char_length= res->numchars(); if (count <= res_char_length) From 47b0a0b08904e900e6b034e32ad124139c9dcb93 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Dec 2006 16:57:51 -0700 Subject: [PATCH 24/29] Added innodb_rollback_on_timeout option to restore the 4.1 InnoDB timeout behavior (Bug #24200) mysql-test/t/innodb_mysql-master.opt: Set --innodb-lock-wait-timeout=2, since test for bug #24200 times out. This *could* cause random test failures if some long-running transaction concurrency is being tested. However, such a test really should go in innodb-big or some other test file. --- innobase/include/row0mysql.h | 2 + innobase/row/row0mysql.c | 11 +++++- .../include/innodb_rollback_on_timeout.inc | 37 +++++++++++++++++++ mysql-test/r/innodb_mysql.result | 36 ++++++++++++++++++ mysql-test/r/innodb_timeout_rollback.result | 35 ++++++++++++++++++ mysql-test/t/innodb_mysql-master.opt | 1 + mysql-test/t/innodb_mysql.test | 2 + .../t/innodb_timeout_rollback-master.opt | 1 + mysql-test/t/innodb_timeout_rollback.test | 5 +++ sql/ha_innodb.cc | 7 ++++ sql/ha_innodb.h | 1 + sql/mysqld.cc | 7 +++- sql/set_var.cc | 1 + 13 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/innodb_rollback_on_timeout.inc create mode 100644 mysql-test/r/innodb_timeout_rollback.result create mode 100644 mysql-test/t/innodb_mysql-master.opt create mode 100644 mysql-test/t/innodb_timeout_rollback-master.opt create mode 100644 mysql-test/t/innodb_timeout_rollback.test diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 7d8740db044..9e28fabe491 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -19,6 +19,8 @@ Created 9/17/2000 Heikki Tuuri #include "btr0pcur.h" #include "trx0types.h" +extern ibool row_rollback_on_timeout; + typedef struct row_prebuilt_struct row_prebuilt_t; /*********************************************************************** diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index efbb93ba9f5..4bc5f39359c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -35,6 +35,9 @@ Created 9/17/2000 Heikki Tuuri /* A dummy variable used to fool the compiler */ ibool row_mysql_identically_false = FALSE; +/* Provide optional 4.x backwards compatibility for 5.0 and above */ +ibool row_rollback_on_timeout = FALSE; + /* List of tables we should drop in background. ALTER TABLE in MySQL requires that the table handler can drop the table in background when there are no queries to it any more. Protected by the kernel mutex. */ @@ -514,7 +517,9 @@ handle_new_error: return(TRUE); } else if (err == DB_DEADLOCK - || err == DB_LOCK_TABLE_FULL) { + || err == DB_LOCK_TABLE_FULL + || (err == DB_LOCK_WAIT_TIMEOUT + && row_rollback_on_timeout)) { /* Roll back the whole transaction; this resolution was added to version 3.23.43 */ @@ -522,6 +527,10 @@ handle_new_error: } else if (err == DB_OUT_OF_FILE_SPACE || err == DB_LOCK_WAIT_TIMEOUT) { + + ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT + && row_rollback_on_timeout)); + if (savept) { /* Roll back the latest, possibly incomplete insertion or update */ diff --git a/mysql-test/include/innodb_rollback_on_timeout.inc b/mysql-test/include/innodb_rollback_on_timeout.inc new file mode 100644 index 00000000000..73c7374c79e --- /dev/null +++ b/mysql-test/include/innodb_rollback_on_timeout.inc @@ -0,0 +1,37 @@ +# +# Bug #24200: Provide backwards compatibility mode for 4.x "rollback on +# transaction timeout" +# +show variables like 'innodb_rollback_on_timeout'; +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con2; +begin work; +insert into t1 values (2); +select * from t1; + +connection con1; +begin work; +insert into t1 values (5); +select * from t1; +# Lock wait timeout set to 2 seconds in -master.opt; this +# statement will time out; in 5.0.13+, it will not roll back transaction. +--error ER_LOCK_WAIT_TIMEOUT +insert into t1 values (2); +# On 5.0.13+, this should give ==> 1, 5 +select * from t1; +commit; + +connection con2; +select * from t1; +commit; + +connection default; +select * from t1; +drop table t1; +disconnect con1; +disconnect con2; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 012f9492d8d..f150af4b6c2 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -383,4 +383,40 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort DROP TABLE t1; +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout OFF +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +5 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +5 +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/innodb_timeout_rollback.result b/mysql-test/r/innodb_timeout_rollback.result new file mode 100644 index 00000000000..b25a2bbd815 --- /dev/null +++ b/mysql-test/r/innodb_timeout_rollback.result @@ -0,0 +1,35 @@ +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout ON +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt new file mode 100644 index 00000000000..205c733455d --- /dev/null +++ b/mysql-test/t/innodb_mysql-master.opt @@ -0,0 +1 @@ +--innodb-lock-wait-timeout=2 diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 06cfe71ef11..45a2ede091b 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -384,4 +384,6 @@ EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; DROP TABLE t1; +--source include/innodb_rollback_on_timeout.inc + --echo End of 5.0 tests diff --git a/mysql-test/t/innodb_timeout_rollback-master.opt b/mysql-test/t/innodb_timeout_rollback-master.opt new file mode 100644 index 00000000000..50921bb4df0 --- /dev/null +++ b/mysql-test/t/innodb_timeout_rollback-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=2 --innodb_rollback_on_timeout diff --git a/mysql-test/t/innodb_timeout_rollback.test b/mysql-test/t/innodb_timeout_rollback.test new file mode 100644 index 00000000000..99890971064 --- /dev/null +++ b/mysql-test/t/innodb_timeout_rollback.test @@ -0,0 +1,5 @@ +-- source include/have_innodb.inc + +--source include/innodb_rollback_on_timeout.inc + +--echo End of 5.0 tests diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 9f367313fb0..456fd27d9d9 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -173,6 +173,7 @@ my_bool innobase_use_large_pages = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_file_per_table = FALSE; my_bool innobase_locks_unsafe_for_binlog = FALSE; +my_bool innobase_rollback_on_timeout = FALSE; my_bool innobase_create_status_file = FALSE; static char *internal_innobase_data_file_path = NULL; @@ -467,6 +468,10 @@ convert_error_code_to_mysql( latest SQL statement in a lock wait timeout. Previously, we rolled back the whole transaction. */ + if (thd && row_rollback_on_timeout) { + ha_rollback(thd); + } + return(HA_ERR_LOCK_WAIT_TIMEOUT); } else if (error == (int) DB_NO_REFERENCED_ROW) { @@ -1380,6 +1385,8 @@ innobase_init(void) os_use_large_pages = (ibool) innobase_use_large_pages; os_large_page_size = (ulint) innobase_large_page_size; + row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout; + srv_file_per_table = (ibool) innobase_file_per_table; srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 95d7a9437ad..60bc0e9c7cf 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -216,6 +216,7 @@ extern my_bool innobase_log_archive, innobase_use_large_pages, innobase_use_native_aio, innobase_file_per_table, innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout, innobase_create_status_file; extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before calling innobase_end() if you want diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9411ba2ef12..5890a2af21d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4692,7 +4692,8 @@ enum options_mysqld OPT_LOG_SLOW_ADMIN_STATEMENTS, OPT_TABLE_LOCK_WAIT_TIMEOUT, OPT_PORT_OPEN_TIMEOUT, - OPT_MERGE + OPT_MERGE, + OPT_INNODB_ROLLBACK_ON_TIMEOUT }; @@ -4968,6 +4969,10 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, + {"innodb_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT, + "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)", + (gptr*) &innobase_rollback_on_timeout, (gptr*) &innobase_rollback_on_timeout, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_status_file", OPT_INNODB_STATUS_FILE, "Enable SHOW INNODB STATUS output in the innodb_status. file", (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, diff --git a/sql/set_var.cc b/sql/set_var.cc index 23afef742a6..5bbab6224ef 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -904,6 +904,7 @@ struct show_var_st init_vars[]= { {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS}, {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG}, {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG }, + {"innodb_rollback_on_timeout", (char*) &innobase_rollback_on_timeout, SHOW_MY_BOOL}, {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS}, {sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS}, {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, From fe3672d28570eb552786cb3c5c179f205ed73324 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Dec 2006 17:42:26 -0700 Subject: [PATCH 25/29] Alternative decimal2double implementation using an algorithm more similar to my_strtod() (and maybe even a bit faster due to less floating point divisions). This should at least partially fix Bug #23260 for DECIMALs with a moderate number of total digits. --- strings/decimal.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/strings/decimal.c b/strings/decimal.c index 6b7a2266194..bdc3b1eef42 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -138,6 +138,12 @@ static const dec1 frac_max[DIG_PER_DEC1-1]={ 900000000, 990000000, 999000000, 999900000, 999990000, 999999000, 999999900, 999999990 }; +static double scaler10[]= { + 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 +}; +static double scaler1[]= { + 1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 +}; #ifdef HAVE_purify #define sanity(d) DBUG_ASSERT((d)->len > 0) @@ -946,15 +952,27 @@ fatal_error: int decimal2double(decimal_t *from, double *to) { - double x=0, t=DIG_BASE; - int intg, frac; - dec1 *buf=from->buf; + double result= 0.0; + int i, exp= 0; + dec1 *buf= from->buf; + + for (i= from->intg; i > 0; i-= DIG_PER_DEC1) + result= result * DIG_BASE + *buf++; + + for (i= from->frac; i > 0; i-= DIG_PER_DEC1) { + result= result * DIG_BASE + *buf++; + exp+= DIG_PER_DEC1; + } + + DBUG_PRINT("info", ("interm.: %f %d %f", result, exp, + scaler10[exp / 10] * scaler1[exp % 10])); + + result/= scaler10[exp / 10] * scaler1[exp % 10]; + + *to= from->sign ? -result : result; + + DBUG_PRINT("info", ("result: %f (%lx)", *to, *to)); - for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) - x=x*DIG_BASE + *buf++; - for (frac=from->frac; frac > 0; frac-=DIG_PER_DEC1, t*=DIG_BASE) - x+=*buf++/t; - *to=from->sign ? -x : x; return E_DEC_OK; } From 29aae170443d7bbc6dff1b6dd868ed7ea719eec3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Dec 2006 20:17:33 -0700 Subject: [PATCH 26/29] Remove warnings by casting cmd-line-utils/readline/histfile.c: Remove warning (compare signed & unsigned) sql/udf_example.c: Remove warning (cast integer to pointer of different size) strings/decimal.c: Remove warning (%lx format, double arg) --- cmd-line-utils/readline/histfile.c | 3 ++- sql/udf_example.c | 2 +- strings/decimal.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index a7d6a68098e..f1822b105a4 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -334,7 +334,8 @@ history_truncate_file (fname, lines) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ - if (file_size != finfo.st_size || file_size + 1 < file_size) + if ((long long) file_size != (long long) finfo.st_size || + file_size + 1 < file_size) { close (file); #if defined (EFBIG) diff --git a/sql/udf_example.c b/sql/udf_example.c index bbab47e253d..f938cc9c1d3 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -1087,7 +1087,7 @@ my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message) strmov(message, "IS_CONST accepts only one argument"); return 1; } - initid->ptr= (char*)((args->args[0] != NULL) ? 1 : 0); + initid->ptr= (char*)((args->args[0] != NULL) ? 1UL : 0); return 0; } diff --git a/strings/decimal.c b/strings/decimal.c index bdc3b1eef42..f6ac4717a32 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -971,7 +971,7 @@ int decimal2double(decimal_t *from, double *to) *to= from->sign ? -result : result; - DBUG_PRINT("info", ("result: %f (%lx)", *to, *to)); + DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to)); return E_DEC_OK; } From 14d05efc913143e998b1e032e16ee66b2f03611c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Dec 2006 10:54:41 +0100 Subject: [PATCH 27/29] Disable test "im_deamon_life_cycle", Bug#24425, see note: [19 Dec 23:17] Trudy Pelzer --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 53b73363c22..3ee1130760e 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,6 +10,7 @@ # ############################################################################## +im_deamon_life_cycle : Bug#24425 see note: [19 Dec 23:17] Trudy Pelzer ndb_load : Bug#17233 user_limits : Bug#23921 random failure of user_limits.test flush2 : Bug#24805 Pushbuild can't handle test with --disable-log-bin From b8550ca15a961b522c3197afb465b8998a966722 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Dec 2006 11:13:16 +0100 Subject: [PATCH 28/29] Fix silly typos in the disabling of "im_daemon_life_cycle" (bug#24415). --- mysql-test/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 3ee1130760e..3213bd4eb5b 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,7 +10,7 @@ # ############################################################################## -im_deamon_life_cycle : Bug#24425 see note: [19 Dec 23:17] Trudy Pelzer +im_daemon_life_cycle : Bug#24415 see note: [19 Dec 23:17] Trudy Pelzer ndb_load : Bug#17233 user_limits : Bug#23921 random failure of user_limits.test flush2 : Bug#24805 Pushbuild can't handle test with --disable-log-bin From 8b855aecad88b3a653827d5a12e511b74c3fd413 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Dec 2006 17:11:47 -0700 Subject: [PATCH 29/29] Post-merge fix (related to bug 24200 changes) sql/mysqld.cc: Post-merge fix sql/set_var.cc: Post-merge fix --- sql/mysqld.cc | 4 +++- sql/set_var.cc | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1764c1975de..d6031504799 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -391,6 +391,7 @@ extern my_bool innobase_log_archive, innobase_use_large_pages, innobase_use_native_aio, innobase_file_per_table, innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout, innobase_create_status_file; extern "C" { extern ulong srv_max_buf_pool_modified_pct; @@ -8154,7 +8155,8 @@ my_bool innobase_log_archive, innobase_use_doublewrite, innobase_use_checksums, innobase_file_per_table, - innobase_locks_unsafe_for_binlog; + innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout; extern "C" { ulong srv_max_buf_pool_modified_pct; diff --git a/sql/set_var.cc b/sql/set_var.cc index 728aefd6428..64d46b1fc30 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -78,7 +78,8 @@ extern my_bool innobase_log_archive, innobase_use_doublewrite, innobase_use_checksums, innobase_file_per_table, - innobase_locks_unsafe_for_binlog; + innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout; extern "C" { extern ulong srv_max_buf_pool_modified_pct;