From da3a1c815689d81bd0ef720202536d7180825435 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 28 Aug 2012 13:51:01 +0400 Subject: [PATCH 1/8] Fix bugs in BatchedKeyAccess that show up when working with a storage engine in HA_MRR_NO_ASSOCIATION mode. (there is no testcase because we don't ship any such engines currently) --- sql/sql_join_cache.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index d49be2e446c..5c803f85c49 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -3875,8 +3875,9 @@ int JOIN_TAB_SCAN_MRR::next() If a record in in an incremental cache contains no fields then the association for the last record in cache will be equal to cache->end_pos */ - DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) && - (uchar *) (*ptr) <= cache->end_pos); + DBUG_ASSERT((!(mrr_mode & HA_MRR_NO_ASSOCIATION))? + (cache->buff <= (uchar *) (*ptr) && + (uchar *) (*ptr) <= cache->end_pos): TRUE); if (join_tab->table->vfield) update_virtual_fields(join->thd, join_tab->table); } @@ -4542,7 +4543,7 @@ bool JOIN_CACHE_BKAH::prepare_look_for_matches(bool skip_last) { last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0; if (no_association && - (curr_matching_chain= get_matching_chain_by_join_key())) + !(curr_matching_chain= get_matching_chain_by_join_key())) return 1; last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain); return 0; From 95ee3fbf306d28ba315992ea4af458a4fcfb081b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Aug 2012 11:35:42 +0300 Subject: [PATCH 2/8] MDEV-492: fixed incorrect error check. --- mysql-test/r/errors.result | 8 ++++++++ mysql-test/t/errors.test | 9 +++++++++ sql/sql_update.cc | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index e52bdcf336c..62c9a86a46c 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -69,3 +69,11 @@ ERROR 42S22: Unknown column '' in 'VALUES() function' INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE b=(SELECT VALUES(a)+2 FROM t1); DROP TABLE t1, t2; +# +# MDEV-492: incorrect error check before sending OK in mysql_update +# +CREATE TABLE t1 (a CHAR(3), b BLOB); +UPDATE t1 SET a = 'new' +WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; +ERROR 22007: Illegal value used as argument of dynamic column function +drop table t1; diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index b426d9fd5b0..b6aeee63677 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -85,3 +85,12 @@ INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE b=(SELECT VALUES(a)+2 FROM t1); DROP TABLE t1, t2; + +--echo # +--echo # MDEV-492: incorrect error check before sending OK in mysql_update +--echo # +CREATE TABLE t1 (a CHAR(3), b BLOB); +--error ER_DYN_COL_DATA +UPDATE t1 SET a = 'new' +WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; +drop table t1; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4f816e5f032..7d6eb62f57d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -359,7 +359,7 @@ int mysql_update(THD *thd, table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); select= make_select(table, 0, 0, conds, 0, &error); - if (error || !limit || + if (error || !limit || thd->is_error() || (select && select->check_quick(thd, safe_update, limit))) { delete select; From a44331ab3407488368c9984258ce4c3160872816 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 29 Aug 2012 10:59:51 +0200 Subject: [PATCH 3/8] MDEV-456 An out-of-range datetime value (with a 5-digit year) can be created and cause troubles fix Item_func_add_time::get_date() to generate valid dates. Move the validity check inside get_date_from_daynr() instead of relying on callers (5 that had it, and 2 that did not, but should've) --- mysql-test/r/datetime_456.result | 8 ++++ mysql-test/t/datetime_456.test | 8 ++++ sql/item_timefunc.cc | 35 ++++++++------- sql/mysql_priv.h | 2 +- sql/time.cc | 75 +++++++++++++++----------------- 5 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 mysql-test/r/datetime_456.result create mode 100644 mysql-test/t/datetime_456.test diff --git a/mysql-test/r/datetime_456.result b/mysql-test/r/datetime_456.result new file mode 100644 index 00000000000..ba020a250b7 --- /dev/null +++ b/mysql-test/r/datetime_456.result @@ -0,0 +1,8 @@ +create table t1 (d datetime); +insert t1 values (addtime('9999-12-31 23:59:59', '00:00:01')), +(from_days(3652499)); +select * from t1; +d +NULL +NULL +drop table t1; diff --git a/mysql-test/t/datetime_456.test b/mysql-test/t/datetime_456.test new file mode 100644 index 00000000000..0c187959d52 --- /dev/null +++ b/mysql-test/t/datetime_456.test @@ -0,0 +1,8 @@ +# +# MDEV-456 An out-of-range datetime value (with a 5-digit year) can be created and cause troubles +# +create table t1 (d datetime); +insert t1 values (addtime('9999-12-31 23:59:59', '00:00:01')), + (from_days(3652499)); +select * from t1; +drop table t1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index eec8dde080c..2cd8b3215c4 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -341,9 +341,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, { uint days; days= calc_daynr(l_time->year,1,1) + yearday - 1; - if (days <= 0 || days > MAX_DAY_NUMBER) + if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day)) goto err; - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (week_number >= 0 && weekday) @@ -388,9 +387,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, (weekday - 1); } - if (days <= 0 || days > MAX_DAY_NUMBER) + if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day)) goto err; - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || @@ -1385,13 +1383,16 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date) if ((null_value=args[0]->null_value)) return 1; bzero(ltime, sizeof(MYSQL_TIME)); - get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); - if ((null_value= ((fuzzy_date & TIME_NO_ZERO_DATE) && ltime->year == 0))) - return TRUE; + if (get_date_from_daynr((long) value, <ime->year, <ime->month, + <ime->day)) + return (null_value= 1); + + if ((fuzzy_date & TIME_NO_ZERO_DATE) && ltime->year == 0) + return (null_value= 1); ltime->time_type= MYSQL_TIMESTAMP_DATE; - return 0; + return (null_value= 0); } @@ -2388,14 +2389,12 @@ bool Item_func_makedate::get_date(MYSQL_TIME *ltime, uint fuzzy_date) year= year_2000_handling(year); days= calc_daynr(year,1,1) + daynr - 1; - /* Day number from year 0 to 9999-12-31 */ - if (days >= 0 && days <= MAX_DAY_NUMBER) - { - bzero(ltime, sizeof(*ltime)); - ltime->time_type= MYSQL_TIMESTAMP_DATE; - get_date_from_daynr(days, <ime->year, <ime->month, <ime->day); - return (null_value= 0); - } + if (get_date_from_daynr(days, <ime->year, <ime->month, <ime->day)) + goto err; + ltime->time_type= MYSQL_TIMESTAMP_DATE; + ltime->neg= 0; + ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; + return (null_value= 0); err: return (null_value= 1); @@ -2489,8 +2488,8 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date) if (!is_time) { - get_date_from_daynr(days,<ime->year,<ime->month,<ime->day); - if (!ltime->day) + if (get_date_from_daynr(days,<ime->year,<ime->month,<ime->day) || + !ltime->day) return (null_value= 1); return (null_value= 0); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 605d9353cae..14810fc7119 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2445,7 +2445,7 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size); int set_zone(int nr,int min_zone,int max_zone); ulong convert_period_to_month(ulong period); ulong convert_month_to_period(ulong month); -void get_date_from_daynr(long daynr,uint *year, uint *month, +bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error); bool str_to_time_with_warn(const char *str,uint length,MYSQL_TIME *l_time, diff --git a/sql/time.cc b/sql/time.cc index 778f8b8f313..21ecc3f8050 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -24,9 +24,9 @@ #include - /* Some functions to calculate dates */ +#define MAX_DAY_NUMBER 3652424L -#ifndef TESTTIME + /* Some functions to calculate dates */ /* Name description of interval names used in statements. @@ -146,46 +146,42 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) /* Change a daynr to year, month and day */ /* Daynr 0 is returned as date 00.00.00 */ -void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month, +bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month, uint *ret_day) { uint year,temp,leap_day,day_of_year,days_in_year; uchar *month_pos; DBUG_ENTER("get_date_from_daynr"); - if (daynr <= 365L || daynr >= 3652500) - { /* Fix if wrong daynr */ - *ret_year= *ret_month = *ret_day =0; - } - else + if (daynr < 365 || daynr > MAX_DAY_NUMBER) + DBUG_RETURN(1); + + year= (uint) (daynr*100 / 36525L); + temp=(((year-1)/100+1)*3)/4; + day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp; + while (day_of_year > (days_in_year= calc_days_in_year(year))) { - year= (uint) (daynr*100 / 36525L); - temp=(((year-1)/100+1)*3)/4; - day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp; - while (day_of_year > (days_in_year= calc_days_in_year(year))) - { - day_of_year-=days_in_year; - (year)++; - } - leap_day=0; - if (days_in_year == 366) - { - if (day_of_year > 31+28) - { - day_of_year--; - if (day_of_year == 31+28) - leap_day=1; /* Handle leapyears leapday */ - } - } - *ret_month=1; - for (month_pos= days_in_month ; - day_of_year > (uint) *month_pos ; - day_of_year-= *(month_pos++), (*ret_month)++) - ; - *ret_year=year; - *ret_day=day_of_year+leap_day; + day_of_year-=days_in_year; + (year)++; } - DBUG_VOID_RETURN; + leap_day=0; + if (days_in_year == 366) + { + if (day_of_year > 31+28) + { + day_of_year--; + if (day_of_year == 31+28) + leap_day=1; /* Handle leapyears leapday */ + } + } + *ret_month=1; + for (month_pos= days_in_month ; + day_of_year > (uint) *month_pos ; + day_of_year-= *(month_pos++), (*ret_month)++) + ; + *ret_year=year; + *ret_day=day_of_year+leap_day; + DBUG_RETURN(0); } /* Functions to handle periods */ @@ -805,7 +801,6 @@ void make_truncated_value_warning(THD *thd, /* Daynumber from year 0 to 9999-12-31 */ -#define MAX_DAY_NUMBER 3652424L #define COMBINE(X) \ (((((X)->day * 24LL + (X)->hour) * 60LL + \ (X)->minute) * 60LL + (X)->second)*1000000LL + \ @@ -872,19 +867,18 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, daynr= usec; /* Day number from year 0 to 9999-12-31 */ - if ((ulonglong) daynr > MAX_DAY_NUMBER) + if (get_date_from_daynr((long) daynr, <ime->year, <ime->month, + <ime->day)) goto invalid_date; - get_date_from_daynr((long) daynr, <ime->year, <ime->month, - <ime->day); break; } case INTERVAL_WEEK: period= (calc_daynr(ltime->year,ltime->month,ltime->day) + sign * (long) interval.day); /* Daynumber from year 0 to 9999-12-31 */ - if ((ulong) period > MAX_DAY_NUMBER) + if (get_date_from_daynr((long) period,<ime->year,<ime->month, + <ime->day)) goto invalid_date; - get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day); break; case INTERVAL_YEAR: ltime->year+= sign * (long) interval.year; @@ -1034,4 +1028,3 @@ int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b) return 0; } -#endif From 3444e8e9254070f836488dae12b5c825cc9c563f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 29 Aug 2012 17:55:59 +0200 Subject: [PATCH 4/8] MDEV-454 Addition of a time interval reduces the resulting value 1. Field_newdate::get_date should refuse to return a date with zeros when TIME_NO_ZERO_IN_DATE is set, not when TIME_FUZZY_DATE is unset 2. Item_func_to_days and Item_date_add_interval can only work with valid dates, no zeros allowed. --- mysql-test/r/adddate_454.result | 10 ++++++++++ mysql-test/t/adddate_454.test | 9 +++++++++ sql/field.cc | 2 +- sql/item_timefunc.cc | 4 ++-- 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/adddate_454.result create mode 100644 mysql-test/t/adddate_454.test diff --git a/mysql-test/r/adddate_454.result b/mysql-test/r/adddate_454.result new file mode 100644 index 00000000000..0993cdce32c --- /dev/null +++ b/mysql-test/r/adddate_454.result @@ -0,0 +1,10 @@ +create table t1 (d date); +insert into t1 values ('2012-00-00'); +select * from t1; +d +2012-00-00 +update t1 set d = adddate(d, interval 1 day); +select * from t1; +d +NULL +drop table t1; diff --git a/mysql-test/t/adddate_454.test b/mysql-test/t/adddate_454.test new file mode 100644 index 00000000000..1d69cdc9558 --- /dev/null +++ b/mysql-test/t/adddate_454.test @@ -0,0 +1,9 @@ +# +# MDEV-454 Addition of a time interval reduces the resulting value +# +create table t1 (d date); +insert into t1 values ('2012-00-00'); +select * from t1; +update t1 set d = adddate(d, interval 1 day); +select * from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index cf5b6cf2ff9..9b0f6a7dfcd 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5789,7 +5789,7 @@ bool Field_newdate::get_date(MYSQL_TIME *ltime,uint fuzzydate) if (!tmp) return fuzzydate & TIME_NO_ZERO_DATE; if (!ltime->month || !ltime->day) - return !(fuzzydate & TIME_FUZZY_DATE); + return fuzzydate & TIME_NO_ZERO_IN_DATE; return 0; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2cd8b3215c4..bdad96f12ef 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -751,7 +751,7 @@ longlong Item_func_to_days::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day); } @@ -1932,7 +1932,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { INTERVAL interval; - if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE) || + if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE | TIME_NO_ZERO_IN_DATE) || get_interval_value(args[1], int_type, &value, &interval)) return (null_value=1); From 2de4f09a75ad878753bb090a4c04291113d7a0c0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 29 Aug 2012 18:36:57 +0200 Subject: [PATCH 5/8] MDEV-438 Microseconds: Precision is ignored in CURRENT_TIMESTAMP(N) when it is given as a default column value The syntax for specifying precision in the DEFAULT clause is unintentional and unsupported. Don't allow it anymore. --- sql/sql_yacc.yy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0f013bfb566..b1772536639 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5453,9 +5453,9 @@ attribute: NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; } | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; } | DEFAULT now_or_signed_literal { Lex->default_value=$2; } - | ON UPDATE_SYM NOW_SYM opt_time_precision + | ON UPDATE_SYM NOW_SYM optional_braces { - Item *item= new (YYTHD->mem_root) Item_func_now_local($4); + Item *item= new (YYTHD->mem_root) Item_func_now_local(6); if (item == NULL) MYSQL_YYABORT; Lex->on_update_value= item; @@ -5525,9 +5525,9 @@ attribute: ; now_or_signed_literal: - NOW_SYM opt_time_precision + NOW_SYM optional_braces { - $$= new (YYTHD->mem_root) Item_func_now_local($2); + $$= new (YYTHD->mem_root) Item_func_now_local(6); if ($$ == NULL) MYSQL_YYABORT; } From 0536c506ff7c3ed261abc3d02fb787bfdd228abb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 30 Aug 2012 09:05:27 +0200 Subject: [PATCH 6/8] MDEV-437 Microseconds: In time functions precision is calculated modulo 256 store the precision in uint, not uint8 --- mysql-test/r/func_time.result | 2 ++ mysql-test/t/func_time.test | 2 ++ sql/item.h | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index b3e2a01e2e3..2df0c691083 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1897,3 +1897,5 @@ cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)) select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010'); microsecond('12:00:00.123456') microsecond('2009-12-31 23:59:59.000010') 123456 10 +select now(258); +ERROR 42000: Too big precision 258 specified for 'now'. Maximum is 6. diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 07e6473bfdf..c3d1d74ec50 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1142,3 +1142,5 @@ select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetim select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010'); +--error ER_TOO_BIG_PRECISION +select now(258); diff --git a/sql/item.h b/sql/item.h index ab5243a3d0a..055225a79d7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -582,8 +582,8 @@ public: calls. */ uint name_length; /* Length of name */ + uint decimals; int8 marker; - uint8 decimals; bool maybe_null; /* If item may be null */ bool in_rollup; /* If used in GROUP BY list of a query with ROLLUP */ From 10802c4d9046fd54bf1a27cb7611c182ecde93fb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Aug 2012 10:53:49 +0200 Subject: [PATCH 7/8] MDEV-381: fdatasync() does not correctly flush growing binlog file. When we append data to the binlog file, we use fdatasync() to ensure the data gets to disk so that crash recovery can work. Unfortunately there seems to be a bug in ext3/ext4 on linux, so that fdatasync() does not correctly sync all data when the size of a file is increased. This causes crash recovery to not work correctly (it loses transactions from the binlog). As a work-around, use fsync() for the binlog, not fdatasync(). Since we are increasing the file size, (correct) fdatasync() will most likely not be faster than fsync() on any file system, and fsync() does work correctly on ext3/ext4. This avoids the need to try to detect if we are running on buggy ext3/ext4. --- include/my_sys.h | 1 + mysys/my_sync.c | 18 ++++++++++++++++-- sql/log.cc | 10 +++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index db22f55f492..ebe643abce5 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -70,6 +70,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */ #define MY_SYNC 4096 /* my_copy(): sync dst file */ #define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */ +#define MY_SYNC_FILESIZE 65536 /* my_sync(): safe sync when file is extended */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ diff --git a/mysys/my_sync.c b/mysys/my_sync.c index d8973244620..33033ff1045 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -39,6 +39,13 @@ ulong my_sync_count; /* Count number of sync calls */ (which is correct behaviour, if we know that the other thread synced the file before closing) + MY_SYNC_FILESIZE is useful when syncing a file after it has been extended. + On Linux, fdatasync() on ext3/ext4 file systems does not properly flush + to disk the inode data required to preserve the added data across a crash + (this looks to be a bug). But when a file is extended, inode data will most + likely need flushing in any case, so passing MY_SYNC_FILESIZE as flags + is not likely to be any slower, and will be crash safe on Linux ext3/ext4. + RETURN 0 ok -1 error @@ -67,8 +74,12 @@ int my_sync(File fd, myf my_flags) DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back")); #endif #if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC - res= fdatasync(fd); -#elif defined(HAVE_FSYNC) + if (!(my_flags & MY_SYNC_FILESIZE)) + res= fdatasync(fd); + else + { +#endif +#if defined(HAVE_FSYNC) res= fsync(fd); if (res == -1 && errno == ENOLCK) res= 0; /* Result Bug in Old FreeBSD */ @@ -77,6 +88,9 @@ int my_sync(File fd, myf my_flags) #else #error Cannot find a way to sync a file, durability in danger res= 0; /* No sync (strange OS) */ +#endif +#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC + } #endif } while (res == -1 && errno == EINTR); diff --git a/sql/log.cc b/sql/log.cc index ddb12457fcd..05e8a66ed04 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2838,7 +2838,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, bytes_written+= description_event_for_queue->data_written; } if (flush_io_cache(&log_file) || - my_sync(log_file.file, MYF(MY_WME))) + my_sync(log_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; pthread_mutex_lock(&LOCK_commit_ordered); strmake(last_commit_pos_file, log_file_name, @@ -2864,7 +2864,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, strlen(log_file_name)) || my_b_write(&index_file, (uchar*) "\n", 1) || flush_io_cache(&index_file) || - my_sync(index_file.file, MYF(MY_WME))) + my_sync(index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; #ifdef HAVE_REPLICATION @@ -2956,7 +2956,7 @@ static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset) } /* The following will either truncate the file or fill the end with \n' */ if (my_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) || - my_sync(file, MYF(MY_WME))) + my_sync(file, MYF(MY_WME|MY_SYNC_FILESIZE))) goto err; /* Reset data in old index cache */ @@ -3549,7 +3549,7 @@ int MYSQL_BIN_LOG::sync_purge_index_file() DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file"); if ((error= flush_io_cache(&purge_index_file)) || - (error= my_sync(purge_index_file.file, MYF(MY_WME)))) + (error= my_sync(purge_index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE)))) DBUG_RETURN(error); DBUG_RETURN(error); @@ -4139,7 +4139,7 @@ bool MYSQL_BIN_LOG::flush_and_sync() if (++sync_binlog_counter >= sync_binlog_period && sync_binlog_period) { sync_binlog_counter= 0; - err=my_sync(fd, MYF(MY_WME)); + err=my_sync(fd, MYF(MY_WME|MY_SYNC_FILESIZE)); #ifndef DBUG_OFF if (opt_binlog_dbug_fsync_sleep > 0) my_sleep(opt_binlog_dbug_fsync_sleep); From 51e14492e9410718056b0c6d9d4dabd4a96e8070 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 31 Aug 2012 12:01:52 +0200 Subject: [PATCH 8/8] compilation warning --- sql/item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index f10c491853e..e125e57d2fc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -454,8 +454,8 @@ Item::Item(THD *thd, Item *item): orig_name(item->orig_name), max_length(item->max_length), name_length(item->name_length), - marker(item->marker), decimals(item->decimals), + marker(item->marker), maybe_null(item->maybe_null), in_rollup(item->in_rollup), null_value(item->null_value),