summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-04-14 10:04:07 +0200
committerSergei Golubchik <sergii@pisem.net>2013-04-14 10:04:07 +0200
commitf57ecb7786177e0af3b1e3ec94302720b2e0f967 (patch)
treefcbed357c5bcdb373830413086d4f58ff9ba2998
parent9bfbe7fbce86eab5a8a5de7e401772f058872716 (diff)
parentd364e64ae28c5588ea0ad013738a8dfe18412292 (diff)
downloadmariadb-git-f57ecb7786177e0af3b1e3ec94302720b2e0f967.tar.gz
5.5 merge
-rw-r--r--client/mysqlbinlog.cc167
-rw-r--r--include/my_global.h3
-rw-r--r--include/mysql_com.h18
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--mysql-test/include/have_debug_sync.inc6
-rw-r--r--mysql-test/r/fulltext_derived_4316.result8
-rw-r--r--mysql-test/r/quick_select_4161.result31
-rw-r--r--mysql-test/r/subselect_sj.result10
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result10
-rw-r--r--mysql-test/r/windows.result2
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result21
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result21
-rw-r--r--mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test22
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test22
-rw-r--r--mysql-test/t/fulltext_derived_4316.test14
-rw-r--r--mysql-test/t/quick_select_4161.test53
-rw-r--r--mysql-test/t/subselect_sj.test9
-rw-r--r--mysys/default.c2
-rw-r--r--plugin/qc_info/qc_info.cc12
-rw-r--r--sql-common/client.c2
-rw-r--r--sql/item_func.cc29
-rw-r--r--sql/log.cc2
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/multi_range_read.cc2
-rw-r--r--sql/mysqld.cc44
-rw-r--r--sql/opt_range.cc26
-rw-r--r--sql/opt_range.h6
-rw-r--r--sql/opt_subselect.cc6
-rw-r--r--sql/opt_sum.cc2
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_select.cc7
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sys_vars.cc4
-rw-r--r--sql/table.cc4
-rw-r--r--storage/csv/ha_tina.cc6
-rw-r--r--storage/federatedx/ha_federatedx.cc2
-rw-r--r--storage/innobase/fil/fil0fil.c22
-rw-r--r--storage/innobase/handler/ha_innodb.cc50
-rw-r--r--storage/innobase/include/srv0srv.h5
-rw-r--r--storage/innobase/os/os0file.c72
-rw-r--r--storage/innobase/srv/srv0srv.c4
-rw-r--r--storage/innobase/sync/sync0sync.c4
-rw-r--r--storage/maria/ma_bitmap.c11
-rw-r--r--storage/maria/ma_blockrec.c2
-rw-r--r--storage/maria/ma_test3.c2
-rw-r--r--storage/xtradb/fil/fil0fil.c22
-rw-r--r--storage/xtradb/handler/ha_innodb.cc50
-rw-r--r--storage/xtradb/include/srv0srv.h5
-rw-r--r--storage/xtradb/os/os0file.c72
-rw-r--r--storage/xtradb/srv/srv0srv.c4
-rw-r--r--storage/xtradb/sync/sync0sync.c4
-rw-r--r--strings/ctype-utf8.c8
-rw-r--r--strings/decimal.c2
-rw-r--r--tests/mysql_client_test.c9
56 files changed, 767 insertions, 177 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index c8c989753f4..c099459f61e 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -818,6 +818,88 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file,
}
+static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
+{
+ /*
+ These events must be printed in base64 format, if printed.
+ base64 format requires a FD event to be safe, so if no FD
+ event has been printed, we give an error. Except if user
+ passed --short-form, because --short-form disables printing
+ row events.
+ */
+ if (!print_event_info->printed_fd_event && !short_form &&
+ opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
+ {
+ const char* type_str= ev->get_type_str();
+ if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
+ error("--base64-output=never specified, but binlog contains a "
+ "%s event which must be printed in base64.",
+ type_str);
+ else
+ error("malformed binlog: it does not contain any "
+ "Format_description_log_event. I now found a %s event, which "
+ "is not safe to process without a "
+ "Format_description_log_event.",
+ type_str);
+ return 1;
+ }
+ ev->print(result_file, print_event_info);
+ return print_event_info->head_cache.error == -1;
+}
+
+
+static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
+ ulong table_id, bool is_stmt_end)
+{
+ Table_map_log_event *ignored_map=
+ print_event_info->m_table_map_ignored.get_table(table_id);
+ bool skip_event= (ignored_map != NULL);
+
+ /*
+ end of statement check:
+ i) destroy/free ignored maps
+ ii) if skip event, flush cache now
+ */
+ if (is_stmt_end)
+ {
+ /*
+ Now is safe to clear ignored map (clear_tables will also
+ delete original table map events stored in the map).
+ */
+ if (print_event_info->m_table_map_ignored.count() > 0)
+ print_event_info->m_table_map_ignored.clear_tables();
+
+ /*
+ If there is a kept Annotate event and all corresponding
+ rbr-events were filtered away, the Annotate event was not
+ freed and it is just the time to do it.
+ */
+ free_annotate_event();
+
+ /*
+ One needs to take into account an event that gets
+ filtered but was last event in the statement. If this is
+ the case, previous rows events that were written into
+ IO_CACHEs still need to be copied from cache to
+ result_file (as it would happen in ev->print(...) if
+ event was not skipped).
+ */
+ if (skip_event)
+ {
+ if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
+ return 1;
+ }
+ }
+
+ /* skip the event check */
+ if (skip_event)
+ return 0;
+
+ return print_base64(print_event_info, ev);
+}
+
+
/**
Print the given event, and either delete it or delegate the deletion
to someone else.
@@ -1130,86 +1212,29 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
error("Could not rewrite database name");
goto err;
}
+ if (print_base64(print_event_info, ev))
+ goto err;
+ break;
}
case WRITE_ROWS_EVENT:
case DELETE_ROWS_EVENT:
case UPDATE_ROWS_EVENT:
+ {
+ Rows_log_event *e= (Rows_log_event*) ev;
+ if (print_row_event(print_event_info, ev, e->get_table_id(),
+ e->get_flags(Rows_log_event::STMT_END_F)))
+ goto err;
+ break;
+ }
case PRE_GA_WRITE_ROWS_EVENT:
case PRE_GA_DELETE_ROWS_EVENT:
case PRE_GA_UPDATE_ROWS_EVENT:
{
- if (ev_type != TABLE_MAP_EVENT)
- {
- Rows_log_event *e= (Rows_log_event*) ev;
- Table_map_log_event *ignored_map=
- print_event_info->m_table_map_ignored.get_table(e->get_table_id());
- bool skip_event= (ignored_map != NULL);
-
- /*
- end of statement check:
- i) destroy/free ignored maps
- ii) if skip event, flush cache now
- */
- if (e->get_flags(Rows_log_event::STMT_END_F))
- {
- /*
- Now is safe to clear ignored map (clear_tables will also
- delete original table map events stored in the map).
- */
- if (print_event_info->m_table_map_ignored.count() > 0)
- print_event_info->m_table_map_ignored.clear_tables();
-
- /*
- If there is a kept Annotate event and all corresponding
- rbr-events were filtered away, the Annotate event was not
- freed and it is just the time to do it.
- */
- free_annotate_event();
-
- /*
- One needs to take into account an event that gets
- filtered but was last event in the statement. If this is
- the case, previous rows events that were written into
- IO_CACHEs still need to be copied from cache to
- result_file (as it would happen in ev->print(...) if
- event was not skipped).
- */
- if (skip_event)
- {
- if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
- copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
- goto err;
- }
- }
-
- /* skip the event check */
- if (skip_event)
- goto end;
- }
- /*
- These events must be printed in base64 format, if printed.
- base64 format requires a FD event to be safe, so if no FD
- event has been printed, we give an error. Except if user
- passed --short-form, because --short-form disables printing
- row events.
- */
- if (!print_event_info->printed_fd_event && !short_form &&
- opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
- {
- const char* type_str= ev->get_type_str();
- if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
- error("--base64-output=never specified, but binlog contains a "
- "%s event which must be printed in base64.",
- type_str);
- else
- error("malformed binlog: it does not contain any "
- "Format_description_log_event. I now found a %s event, which "
- "is not safe to process without a "
- "Format_description_log_event.",
- type_str);
+ Old_rows_log_event *e= (Old_rows_log_event*) ev;
+ if (print_row_event(print_event_info, ev, e->get_table_id(),
+ e->get_flags(Old_rows_log_event::STMT_END_F)))
goto err;
- }
- /* FALL THROUGH */
+ break;
}
default:
print_skip_replication_statement(print_event_info, ev);
diff --git a/include/my_global.h b/include/my_global.h
index 859c06c6818..30e8909ed13 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -393,7 +393,8 @@ C_MODE_END
#define compile_time_assert(X) \
do \
{ \
- typedef char compile_time_assert[(X) ? 1 : -1]; \
+ typedef char compile_time_assert[(X) ? 1 : -1] \
+ __attribute__((unused)); \
} while(0)
#endif
diff --git a/include/mysql_com.h b/include/mysql_com.h
index e9a24fd767d..be1d727c15a 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -34,6 +34,24 @@
#define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1)
#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH)
+/*
+ MDEV-4088
+
+ MySQL (and MariaDB 5.x before the fix) was using the first character of the
+ server version string (as sent in the first handshake protocol packet) to
+ decide on the replication event formats. And for 10.x the first character
+ is "1", which the slave thought comes from some ancient 1.x version
+ (ignoring the fact that the first ever MySQL version was 3.x).
+
+ To support replication to these old clients, we fake the version in the
+ first handshake protocol packet to start from "5.5.5-" (for example,
+ it might be "5.5.5-10.0.1-MariaDB-debug-log".
+
+ On the client side we remove this fake version prefix to restore the
+ correct server version. The version "5.5.5" did not support
+ pluggable authentication, so any version starting from "5.5.5-" and
+ claiming to support pluggable auth, must be using this fake prefix.
+*/
#ifdef EMBEDDED_LIBRARY
#define RPL_VERSION_HACK ""
#else
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 5332003885d..5e798674c2d 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -440,7 +440,7 @@ static MYSQL_RES * emb_store_result(MYSQL *mysql)
int emb_read_change_user_result(MYSQL *mysql)
{
mysql->net.read_pos= (uchar*)""; // fake an OK packet
- return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */;
+ return mysql_errno(mysql) ? (int)packet_error : 1 /* length of the OK packet */;
}
MYSQL_METHODS embedded_methods=
diff --git a/mysql-test/include/have_debug_sync.inc b/mysql-test/include/have_debug_sync.inc
index 8efec7dad95..dbe6dfddd26 100644
--- a/mysql-test/include/have_debug_sync.inc
+++ b/mysql-test/include/have_debug_sync.inc
@@ -1,4 +1,4 @@
-if (`SELECT COUNT(*) = 0 FROM information_schema.session_variables WHERE
- variable_name = 'debug_sync' AND variable_value LIKE 'ON %'`) {
- --skip Needs debug_sync enabled
+if (`select count(*) = 0 from information_schema.session_variables where variable_name = 'debug_sync' and variable_value like 'on %'`)
+{
+ skip debug_sync is not available;
}
diff --git a/mysql-test/r/fulltext_derived_4316.result b/mysql-test/r/fulltext_derived_4316.result
new file mode 100644
index 00000000000..141202c9842
--- /dev/null
+++ b/mysql-test/r/fulltext_derived_4316.result
@@ -0,0 +1,8 @@
+create table t1 (ft text) engine=myisam;
+insert into t1 values ('test1'),('test2');
+select distinct match(ft) against("test1" in boolean mode) from
+(select distinct ft from t1) as t;
+match(ft) against("test1" in boolean mode)
+1
+0
+drop table t1;
diff --git a/mysql-test/r/quick_select_4161.result b/mysql-test/r/quick_select_4161.result
new file mode 100644
index 00000000000..862be6055ce
--- /dev/null
+++ b/mysql-test/r/quick_select_4161.result
@@ -0,0 +1,31 @@
+CREATE TABLE t1 (
+event_date date DEFAULT '0000-00-00' NOT NULL,
+type int(11) DEFAULT '0' NOT NULL,
+event_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (event_date,type,event_id)
+);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
+set debug_sync='inside_make_join_statistics signal killme wait_for done';
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+set debug_sync='now wait_for killme';
+kill %connection%;
+set debug_sync='now signal done';
+Got one of the listed errors
+drop table t1;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index a4e4922474e..92c626eca61 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -2783,6 +2783,16 @@ a b
deallocate prepare stmt;
drop table t1,t2;
#
+# MDEV-4335: Unexpected results when selecting on information_schema
+#
+CREATE TABLE t1 (db VARCHAR(64) DEFAULT NULL);
+INSERT INTO t1 VALUES ('mysql'),('information_schema');
+SELECT * FROM t1 WHERE db IN (SELECT `SCHEMA_NAME` FROM information_schema.SCHEMATA);
+db
+mysql
+information_schema
+DROP TABLE t1;
+#
# MySQL Bug#13340270: assertion table->sort.record_pointers == __null
#
CREATE TABLE t1 (
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 4e67c1cc01c..04a54c9a371 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -2797,6 +2797,16 @@ a b
deallocate prepare stmt;
drop table t1,t2;
#
+# MDEV-4335: Unexpected results when selecting on information_schema
+#
+CREATE TABLE t1 (db VARCHAR(64) DEFAULT NULL);
+INSERT INTO t1 VALUES ('mysql'),('information_schema');
+SELECT * FROM t1 WHERE db IN (SELECT `SCHEMA_NAME` FROM information_schema.SCHEMATA);
+db
+information_schema
+mysql
+DROP TABLE t1;
+#
# MySQL Bug#13340270: assertion table->sort.record_pointers == __null
#
CREATE TABLE t1 (
diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result
index dc624a07f4f..d0cdd858d4a 100644
--- a/mysql-test/r/windows.result
+++ b/mysql-test/r/windows.result
@@ -16,7 +16,7 @@ CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (1,1);
EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
DROP TABLE t1;
CREATE DATABASE `TESTDB`;
diff --git a/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result b/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result
new file mode 100644
index 00000000000..fa6379fbe1c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result
@@ -0,0 +1,21 @@
+select @@global.innodb_use_atomic_writes;
+@@global.innodb_use_atomic_writes
+0
+select @@session.innodb_use_atomic_writes;
+ERROR HY000: Variable 'innodb_use_atomic_writes' is a GLOBAL variable
+show global variables like 'innodb_use_atomic_writes';
+Variable_name Value
+innodb_use_atomic_writes OFF
+show session variables like 'innodb_use_atomic_writes';
+Variable_name Value
+innodb_use_atomic_writes OFF
+select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_USE_ATOMIC_WRITES OFF
+select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_USE_ATOMIC_WRITES OFF
+set global innodb_use_atomic_writes=1;
+ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable
+set session innodb_use_atomic_writes=1;
+ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result b/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result
new file mode 100644
index 00000000000..7ea55fba0a4
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result
@@ -0,0 +1,21 @@
+select @@global.innodb_use_fallocate;
+@@global.innodb_use_fallocate
+1
+select @@session.innodb_use_fallocate;
+ERROR HY000: Variable 'innodb_use_fallocate' is a GLOBAL variable
+show global variables like 'innodb_use_fallocate';
+Variable_name Value
+innodb_use_fallocate ON
+show session variables like 'innodb_use_fallocate';
+Variable_name Value
+innodb_use_fallocate ON
+select * from information_schema.global_variables where variable_name='innodb_use_fallocate';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_USE_FALLOCATE ON
+select * from information_schema.session_variables where variable_name='innodb_use_fallocate';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_USE_FALLOCATE ON
+set global innodb_use_fallocate=1;
+ERROR HY000: Variable 'innodb_use_fallocate' is a read only variable
+set session innodb_use_fallocate=1;
+ERROR HY000: Variable 'innodb_use_fallocate' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result
index 9f630e8bb00..bb7492ee7ef 100644
--- a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result
+++ b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result
@@ -1,7 +1,7 @@
SET @start_value = @@global.max_binlog_cache_size;
SELECT @start_value;
@start_value
-4294963200
+18446744073709547520
'#--------------------FN_DYNVARS_072_01------------------------#'
SET @@global.max_binlog_cache_size = 5000;
Warnings:
@@ -9,7 +9,7 @@ Warning 1292 Truncated incorrect max_binlog_cache_size value: '5000'
SET @@global.max_binlog_cache_size = DEFAULT;
SELECT @@global.max_binlog_cache_size;
@@global.max_binlog_cache_size
-4294963200
+18446744073709547520
'#---------------------FN_DYNVARS_072_02-------------------------#'
SET @@global.max_binlog_cache_size = @start_value;
SELECT @@global.max_binlog_cache_size = 4294967295;
@@ -149,4 +149,4 @@ ERROR 42S22: Unknown column 'max_binlog_cache_size' in 'field list'
SET @@global.max_binlog_cache_size = @start_value;
SELECT @@global.max_binlog_cache_size;
@@global.max_binlog_cache_size
-4294963200
+18446744073709547520
diff --git a/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result
index 14407672aa3..0b2db8eef69 100644
--- a/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result
+++ b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result
@@ -1,7 +1,7 @@
SET @start_value = @@global.max_binlog_stmt_cache_size;
SELECT @start_value;
@start_value
-4294963200
+18446744073709547520
'#--------------------FN_DYNVARS_072_01------------------------#'
SET @@global.max_binlog_stmt_cache_size = 5000;
Warnings:
@@ -9,7 +9,7 @@ Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '5000'
SET @@global.max_binlog_stmt_cache_size = DEFAULT;
SELECT @@global.max_binlog_stmt_cache_size;
@@global.max_binlog_stmt_cache_size
-4294963200
+18446744073709547520
'#---------------------FN_DYNVARS_072_02-------------------------#'
SET @@global.max_binlog_stmt_cache_size = @start_value;
SELECT @@global.max_binlog_stmt_cache_size = 4294967295;
@@ -149,4 +149,4 @@ ERROR 42S22: Unknown column 'max_binlog_stmt_cache_size' in 'field list'
SET @@global.max_binlog_stmt_cache_size = @start_value;
SELECT @@global.max_binlog_stmt_cache_size;
@@global.max_binlog_stmt_cache_size
-4294963200
+18446744073709547520
diff --git a/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test b/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test
new file mode 100644
index 00000000000..e14f618ee6b
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test
@@ -0,0 +1,22 @@
+--source include/have_innodb.inc
+# bool readonly
+
+#
+# show values;
+#
+select @@global.innodb_use_atomic_writes;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_use_atomic_writes;
+show global variables like 'innodb_use_atomic_writes';
+show session variables like 'innodb_use_atomic_writes';
+select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes';
+select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes';
+
+#
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global innodb_use_atomic_writes=1;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session innodb_use_atomic_writes=1;
+
diff --git a/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test b/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test
new file mode 100644
index 00000000000..655893be98e
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test
@@ -0,0 +1,22 @@
+--source include/have_innodb.inc
+# bool readonly
+
+#
+# show values;
+#
+select @@global.innodb_use_fallocate;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_use_fallocate;
+show global variables like 'innodb_use_fallocate';
+show session variables like 'innodb_use_fallocate';
+select * from information_schema.global_variables where variable_name='innodb_use_fallocate';
+select * from information_schema.session_variables where variable_name='innodb_use_fallocate';
+
+#
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global innodb_use_fallocate=1;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session innodb_use_fallocate=1;
+
diff --git a/mysql-test/t/fulltext_derived_4316.test b/mysql-test/t/fulltext_derived_4316.test
new file mode 100644
index 00000000000..ecf4a0e7722
--- /dev/null
+++ b/mysql-test/t/fulltext_derived_4316.test
@@ -0,0 +1,14 @@
+#
+# MATCH on the derived tables
+#
+
+#
+# MDEV-4316 MariaDB server crash with signal 11
+#
+
+create table t1 (ft text) engine=myisam;
+insert into t1 values ('test1'),('test2');
+select distinct match(ft) against("test1" in boolean mode) from
+ (select distinct ft from t1) as t;
+drop table t1;
+
diff --git a/mysql-test/t/quick_select_4161.test b/mysql-test/t/quick_select_4161.test
new file mode 100644
index 00000000000..1e746754b41
--- /dev/null
+++ b/mysql-test/t/quick_select_4161.test
@@ -0,0 +1,53 @@
+#
+# MDEV-4161 Assertion `status_var.memory_used == 0' fails in virtual THD::~THD()
+#
+--source include/have_debug_sync.inc
+
+CREATE TABLE t1 (
+ event_date date DEFAULT '0000-00-00' NOT NULL,
+ type int(11) DEFAULT '0' NOT NULL,
+ event_id int(11) DEFAULT '0' NOT NULL,
+ PRIMARY KEY (event_date,type,event_id)
+);
+
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
+
+connect (killee, localhost, root);
+
+let $id=`select connection_id()`;
+
+set debug_sync='inside_make_join_statistics signal killme wait_for done';
+send select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+
+connection default;
+set debug_sync='now wait_for killme';
+--replace_result $id %connection%
+eval kill $id;
+set debug_sync='now signal done';
+
+connection killee;
+--error 1053,1927,2006,2013
+reap;
+
+connection default;
+disconnect killee;
+
+drop table t1;
+
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index efbd2b00f24..e2abb8040b3 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2482,6 +2482,15 @@ deallocate prepare stmt;
drop table t1,t2;
--echo #
+--echo # MDEV-4335: Unexpected results when selecting on information_schema
+--echo #
+CREATE TABLE t1 (db VARCHAR(64) DEFAULT NULL);
+INSERT INTO t1 VALUES ('mysql'),('information_schema');
+SELECT * FROM t1 WHERE db IN (SELECT `SCHEMA_NAME` FROM information_schema.SCHEMATA);
+DROP TABLE t1;
+
+
+--echo #
--echo # MySQL Bug#13340270: assertion table->sort.record_pointers == __null
--echo #
diff --git a/mysys/default.c b/mysys/default.c
index 9e23eb6b261..70738e11d4b 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -814,7 +814,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
continue;
/* Configuration File Directives */
- if ((*ptr == '!'))
+ if (*ptr == '!')
{
if (recursion_level >= max_recursion_level)
{
diff --git a/plugin/qc_info/qc_info.cc b/plugin/qc_info/qc_info.cc
index e20b4dac5ea..af13b6edf93 100644
--- a/plugin/qc_info/qc_info.cc
+++ b/plugin/qc_info/qc_info.cc
@@ -62,12 +62,12 @@ bool schema_table_store_record(THD *thd, TABLE *table);
/* ST_FIELD_INFO is defined in table.h */
static ST_FIELD_INFO qc_info_fields[]=
{
- {"STATEMENT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
- {"STATEMENT_TEXT", MAX_STATEMENT_TEXT_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0},
- {"RESULT_BLOCKS_COUNT", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, 0},
- {"RESULT_BLOCKS_SIZE", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, 0},
- {"RESULT_BLOCKS_SIZE_USED", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, 0},
- {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+ {"STATEMENT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
+ {"STATEMENT_TEXT", MAX_STATEMENT_TEXT_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, 0},
+ {"RESULT_BLOCKS_COUNT", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, 0, 0},
+ {"RESULT_BLOCKS_SIZE", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, 0, 0},
+ {"RESULT_BLOCKS_SIZE_USED", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
};
static int qc_info_fill_table(THD *thd, TABLE_LIST *tables,
diff --git a/sql-common/client.c b/sql-common/client.c
index e48cdac369e..2d83f2ef215 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -3416,7 +3416,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
- /* remove the rpl hack from the version string */
+ /* remove the rpl hack from the version string, see RPL_VERSION_HACK comment */
if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH &&
strncmp(mysql->server_version, RPL_VERSION_HACK,
sizeof(RPL_VERSION_HACK) - 1) == 0)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 31bf11284b5..878d041c76d 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -5940,15 +5940,12 @@ void Item_func_match::init_search(bool no_order)
{
DBUG_ENTER("Item_func_match::init_search");
+ if (!table->file->get_table()) // the handler isn't opened yet
+ DBUG_VOID_RETURN;
+
/* Check if init_search() has been called before */
if (ft_handler)
{
- /*
- We should reset ft_handler as it is cleaned up
- on destruction of FT_SELECT object
- (necessary in case of re-execution of subquery).
- TODO: FT_SELECT should not clean up ft_handler.
- */
if (join_key)
table->file->ft_handler= ft_handler;
DBUG_VOID_RETURN;
@@ -5957,10 +5954,10 @@ void Item_func_match::init_search(bool no_order)
if (key == NO_SUCH_KEY)
{
List<Item> fields;
- fields.push_back(new Item_string(" ",1, cmp_collation.collation));
- for (uint i=1; i < arg_count; i++)
+ fields.push_back(new Item_string(" ", 1, cmp_collation.collation));
+ for (uint i= 1; i < arg_count; i++)
fields.push_back(args[i]);
- concat_ws=new Item_func_concat_ws(fields);
+ concat_ws= new Item_func_concat_ws(fields);
/*
Above function used only to get value and do not need fix_fields for it:
Item_string - basic constant
@@ -5972,10 +5969,10 @@ void Item_func_match::init_search(bool no_order)
if (master)
{
- join_key=master->join_key=join_key|master->join_key;
+ join_key= master->join_key= join_key | master->join_key;
master->init_search(no_order);
- ft_handler=master->ft_handler;
- join_key=master->join_key;
+ ft_handler= master->ft_handler;
+ join_key= master->join_key;
DBUG_VOID_RETURN;
}
@@ -5985,7 +5982,7 @@ void Item_func_match::init_search(bool no_order)
if (!(ft_tmp=key_item()->val_str(&value)))
{
ft_tmp= &value;
- value.set("",0,cmp_collation.collation);
+ value.set("", 0, cmp_collation.collation);
}
if (ft_tmp->charset() != cmp_collation.collation)
@@ -5998,7 +5995,11 @@ void Item_func_match::init_search(bool no_order)
if (join_key && !no_order)
flags|=FT_SORTED;
- ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
+
+ if (key != NO_SUCH_KEY)
+ thd_proc_info(table->in_use, "FULLTEXT initialization");
+
+ ft_handler= table->file->ft_init_ext(flags, key, ft_tmp);
if (join_key)
table->file->ft_handler=ft_handler;
diff --git a/sql/log.cc b/sql/log.cc
index 5ddfab6f805..f81630a181d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2288,7 +2288,7 @@ static int find_uniq_filename(char *name)
my_dirend(dir_info);
/* check if reached the maximum possible extension number */
- if ((max_found == MAX_LOG_UNIQUE_FN_EXT))
+ if (max_found == MAX_LOG_UNIQUE_FN_EXT)
{
sql_print_error("Log filename extension number exhausted: %06lu. \
Please fix this by archiving old logs and \
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 6c637be19fa..529f702f8a9 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1370,7 +1370,7 @@ failed my_b_read"));
Log_event *res= 0;
#ifndef max_allowed_packet
THD *thd=current_thd;
- uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0;
+ uint max_allowed_packet= thd ? slave_max_allowed_packet:~(uint)0;
#endif
if (data_len > max_allowed_packet)
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index b9f49a83b4b..e3719600dff 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -1648,7 +1648,7 @@ int DsMrr_impl::dsmrr_explain_info(uint mrr_mode, char *str, size_t size)
uint used_str_len= strlen(used_str);
uint copy_len= min(used_str_len, size);
- memcpy(str, used_str, size);
+ memcpy(str, used_str, copy_len);
return copy_len;
}
return 0;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3f569e31d08..e36302e9055 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2184,8 +2184,28 @@ static my_socket activate_tcp_port(uint port)
for (a= ai; a != NULL; a= a->ai_next)
{
ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
- if (ip_sock != INVALID_SOCKET)
+
+ char ip_addr[INET6_ADDRSTRLEN];
+
+ if (vio_get_normalized_ip_string(a->ai_addr, a->ai_addrlen,
+ ip_addr, sizeof (ip_addr)))
+ {
+ ip_addr[0]= 0;
+ }
+
+ if (ip_sock == INVALID_SOCKET)
+ {
+ sql_print_error("Failed to create a socket for %s '%s': errno: %d.",
+ (a->ai_family == AF_INET) ? "IPv4" : "IPv6",
+ (const char *) ip_addr,
+ (int) socket_errno);
+ }
+ else
+ {
+ sql_print_information("Server socket created on IP: '%s'.",
+ (const char *) ip_addr);
break;
+ }
}
if (ip_sock == INVALID_SOCKET)
@@ -7801,28 +7821,6 @@ mysqld_get_one_option(int optid,
case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL;
break;
- case (int) OPT_BIND_ADDRESS:
- {
- struct addrinfo *res_lst, hints;
-
- bzero(&hints, sizeof(struct addrinfo));
- hints.ai_socktype= SOCK_STREAM;
- hints.ai_protocol= IPPROTO_TCP;
-
- if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
- {
- sql_print_error("Can't start server: cannot resolve hostname!");
- return 1;
- }
-
- if (res_lst->ai_next)
- {
- sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
- return 1;
- }
- freeaddrinfo(res_lst);
- }
- break;
case OPT_CONSOLE:
if (opt_console)
opt_error_log= 0; // Force logs to stdout
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 8b07e022ad3..955250905e8 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -132,7 +132,12 @@
static int sel_cmp(Field *f,uchar *a,uchar *b,uint8 a_flag,uint8 b_flag);
-static uchar is_null_string[2]= {1,0};
+/*
+ this should be long enough so that any memcmp with a string that
+ starts from '\0' won't cross is_null_string boundaries, even
+ if the memcmp is optimized to compare 4- 8- or 16- bytes at once
+*/
+static uchar is_null_string[20]= {1,0};
class RANGE_OPT_PARAM;
/*
@@ -2000,7 +2005,7 @@ int QUICK_ROR_INTERSECT_SELECT::init()
1 error
*/
-int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
+int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc)
{
handler *save_file= file, *org_file;
my_bool org_key_read;
@@ -2028,7 +2033,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
DBUG_RETURN(0);
}
- if (!(file= head->file->clone(head->s->normalized_path.str, thd->mem_root)))
+ if (!(file= head->file->clone(head->s->normalized_path.str, alloc)))
{
/*
Manually set the error flag. Note: there seems to be quite a few
@@ -2129,7 +2134,8 @@ failure:
0 OK
other error code
*/
-int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
+int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler,
+ MEM_ROOT *alloc)
{
List_iterator_fast<QUICK_SELECT_WITH_RECORD> quick_it(quick_selects);
QUICK_SELECT_WITH_RECORD *cur;
@@ -2146,7 +2152,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
There is no use of this->file. Use it for the first of merged range
selects.
*/
- int error= quick->init_ror_merged_scan(TRUE);
+ int error= quick->init_ror_merged_scan(TRUE, alloc);
if (error)
DBUG_RETURN(error);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
@@ -2158,7 +2164,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
const MY_BITMAP * const save_read_set= quick->head->read_set;
const MY_BITMAP * const save_write_set= quick->head->write_set;
#endif
- if (quick->init_ror_merged_scan(FALSE))
+ if (quick->init_ror_merged_scan(FALSE, alloc))
DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
@@ -2192,7 +2198,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
int QUICK_ROR_INTERSECT_SELECT::reset()
{
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset");
- if (!scans_inited && init_ror_merged_scan(TRUE))
+ if (!scans_inited && init_ror_merged_scan(TRUE, &alloc))
DBUG_RETURN(1);
scans_inited= TRUE;
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
@@ -2329,7 +2335,7 @@ int QUICK_ROR_UNION_SELECT::reset()
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++))
{
- if (quick->init_ror_merged_scan(FALSE))
+ if (quick->init_ror_merged_scan(FALSE, &alloc))
DBUG_RETURN(1);
}
scans_inited= TRUE;
@@ -7373,8 +7379,10 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
DBUG_RETURN(tree);
}
/* Here when simple cond */
- if (cond->const_item() && !cond->is_expensive())
+ if (cond->const_item())
{
+ if (cond->is_expensive())
+ DBUG_RETURN(0);
/*
During the cond->val_int() evaluation we can come across a subselect
item which may allocate memory on the thd->mem_root and assumes
diff --git a/sql/opt_range.h b/sql/opt_range.h
index c59b2a7eb02..fff6e414ad9 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -323,7 +323,7 @@ public:
0 Ok
other Error
*/
- virtual int init_ror_merged_scan(bool reuse_handler)
+ virtual int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc)
{ DBUG_ASSERT(0); return 1; }
/*
@@ -473,7 +473,7 @@ public:
uchar *cur_prefix);
bool reverse_sorted() { return 0; }
bool unique_key_range();
- int init_ror_merged_scan(bool reuse_handler);
+ int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc);
void save_last_pos()
{ file->position(record); }
int get_type() { return QS_TYPE_RANGE; }
@@ -722,7 +722,7 @@ public:
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
- int init_ror_merged_scan(bool reuse_handler);
+ int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc);
bool push_quick_back(MEM_ROOT *alloc, QUICK_RANGE_SELECT *quick_sel_range);
class QUICK_SELECT_WITH_RECORD : public Sql_alloc
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 710c04ba063..b720a0d0c92 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1513,6 +1513,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/
parent_lex->leaf_tables.concat(&subq_lex->leaf_tables);
+ if (subq_lex->options & OPTION_SCHEMA_TABLE)
+ parent_lex->options |= OPTION_SCHEMA_TABLE;
+
/*
Same as above for next_local chain
(a theory: a next_local chain always starts with ::leaf_tables
@@ -1730,6 +1733,9 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
*/
parent_lex->leaf_tables.push_back(jtbm);
+ if (subq_pred->unit->first_select()->options & OPTION_SCHEMA_TABLE)
+ parent_lex->options |= OPTION_SCHEMA_TABLE;
+
/*
Same as above for TABLE_LIST::next_local chain
(a theory: a next_local chain always starts with ::leaf_tables
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index fa3a07b72c5..069fe6452e8 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -84,7 +84,7 @@ static ulonglong get_exact_record_count(List<TABLE_LIST> &tables)
while ((tl= ti++))
{
ha_rows tmp= tl->table->file->records();
- if ((tmp == HA_POS_ERROR))
+ if (tmp == HA_POS_ERROR)
return ULONGLONG_MAX;
count*= tmp;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 72a9e69b042..39dad6f075c 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -9343,7 +9343,6 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list));
Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
- thd_proc_info(thd, "FULLTEXT initialization");
while ((ifm=li++))
ifm->init_search(no_order);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 41e09482e8e..abefbc42255 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3848,6 +3848,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
DBUG_RETURN(TRUE);
join->join_tab=stat;
+ join->top_join_tab_count= table_count;
join->map2table=stat_ref;
join->table= table_vector;
join->const_tables=const_count;
@@ -3895,6 +3896,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
if (join->choose_subquery_plan(all_table_map & ~join->const_table_map))
goto error;
+ DEBUG_SYNC(join->thd, "inside_make_join_statistics");
+
/* Generate an execution plan from the found optimal join order. */
DBUG_RETURN(join->thd->check_killed() || get_best_combination(join));
@@ -10587,6 +10590,10 @@ bool JOIN_TAB::preread_init()
dbug_serve_apcs(join->thd, 1);
);
+ /* init ftfuns for just initialized derived table */
+ if (table->fulltext_searched)
+ init_ftfuncs(join->thd, join->select_lex, test(join->order));
+
return FALSE;
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ac71837def4..2717fdb325f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -7451,20 +7451,20 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
break;
case MYSQL_TYPE_DATE:
if (!(item=new Item_return_date_time(fields_info->field_name,
- MAX_DATE_WIDTH,
+ strlen(fields_info->field_name),
fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIME:
if (!(item=new Item_return_date_time(fields_info->field_name,
- MAX_TIME_FULL_WIDTH,
+ strlen(fields_info->field_name),
fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
if (!(item=new Item_return_date_time(fields_info->field_name,
- MAX_DATETIME_WIDTH,
+ strlen(fields_info->field_name),
fields_info->field_type)))
DBUG_RETURN(0);
break;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 6a7466d6cf1..8da30535c4a 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1092,7 +1092,7 @@ static Sys_var_ulonglong Sys_max_binlog_cache_size(
"Sets the total size of the transactional cache",
GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(IO_SIZE, ULONGLONG_MAX),
- DEFAULT((UINT_MAX/IO_SIZE)*IO_SIZE),
+ DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE),
BLOCK_SIZE(IO_SIZE));
static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size(
@@ -1100,7 +1100,7 @@ static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size(
"Sets the total size of the statement cache",
GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(IO_SIZE, ULONGLONG_MAX),
- DEFAULT((UINT_MAX/IO_SIZE)*IO_SIZE),
+ DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE),
BLOCK_SIZE(IO_SIZE));
static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type)
diff --git a/sql/table.cc b/sql/table.cc
index faa087cbaa4..422ae238a72 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3454,9 +3454,9 @@ bool check_column_name(const char *name)
}
#else
last_char_is_space= *name==' ';
-#endif
- if (*name == NAMES_SEP_CHAR)
+ if (*name == '\377')
return 1;
+#endif
name++;
name_length++;
}
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index ab2e2c118f8..c51e2b9c968 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -1426,9 +1426,9 @@ int ha_tina::rnd_end()
DBUG_RETURN(-1);
/* Open the file again */
- if (((data_file= mysql_file_open(csv_key_file_data,
- share->data_file_name,
- O_RDONLY, MYF(MY_WME))) == -1))
+ if ((data_file= mysql_file_open(csv_key_file_data,
+ share->data_file_name,
+ O_RDONLY, MYF(MY_WME))) == -1)
DBUG_RETURN(my_errno ? my_errno : -1);
/*
As we reopened the data file, increase share->data_file_version
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 2f84cdf5c45..d760fcf082f 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -766,7 +766,7 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share,
user:@hostname:port/db/table
Then password is a null string, so set to NULL
*/
- if ((share->password[0] == '\0'))
+ if (share->password[0] == '\0')
share->password= NULL;
}
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 2f875663039..c3a206fb009 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -4023,6 +4023,24 @@ fil_extend_space_to_desired_size(
start_page_no = space->size;
file_start_page_no = space->size - node->size;
+#ifdef HAVE_POSIX_FALLOCATE
+ if (srv_use_posix_fallocate) {
+ offset_high = size_after_extend * page_size / (4ULL*1024*1024*1024);
+ offset_low = size_after_extend * page_size % (4ULL*1024*1024*1024);
+
+ mutex_exit(&fil_system->mutex);
+ success = os_file_set_size(node->name, node->handle,
+ offset_low, offset_high);
+ mutex_enter(&fil_system->mutex);
+ if (success) {
+ node->size += (size_after_extend - start_page_no);
+ space->size += (size_after_extend - start_page_no);
+ os_has_said_disk_full = FALSE;
+ }
+ goto complete_io;
+ }
+#endif
+
/* Extend at most 64 pages at a time */
buf_size = ut_min(64, size_after_extend - start_page_no) * page_size;
buf2 = mem_alloc(buf_size + page_size);
@@ -4075,6 +4093,10 @@ fil_extend_space_to_desired_size(
mem_free(buf2);
+#ifdef HAVE_POSIX_FALLOCATE
+complete_io:
+#endif
+
fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
*actual_size = space->size;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index d8f3b739d4d..328f81036c9 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -164,6 +164,8 @@ static my_bool innobase_file_format_check = TRUE;
static my_bool innobase_log_archive = FALSE;
static char* innobase_log_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
+static my_bool innobase_use_atomic_writes = FALSE;
+static my_bool innobase_use_fallocate = TRUE;
static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
@@ -2489,6 +2491,38 @@ innobase_change_buffering_inited_ok:
innobase_commit_concurrency_init_default();
+#ifdef HAVE_POSIX_FALLOCATE
+ srv_use_posix_fallocate = (ibool) innobase_use_fallocate;
+#endif
+ srv_use_atomic_writes = (ibool) innobase_use_atomic_writes;
+ if (innobase_use_atomic_writes) {
+ fprintf(stderr, "InnoDB: using atomic writes.\n");
+
+ /* Force doublewrite buffer off, atomic writes replace it. */
+ if (srv_use_doublewrite_buf) {
+ fprintf(stderr, "InnoDB: Switching off doublewrite buffer "
+ "because of atomic writes.\n");
+ innobase_use_doublewrite = srv_use_doublewrite_buf = FALSE;
+ }
+
+ /* Force O_DIRECT on Unixes (on Windows writes are always unbuffered)*/
+#ifndef _WIN32
+ if(!innobase_file_flush_method ||
+ !strstr(innobase_file_flush_method, "O_DIRECT")) {
+ innobase_file_flush_method =
+ srv_file_flush_method_str = (char*)"O_DIRECT";
+ fprintf(stderr, "InnoDB: using O_DIRECT due to atomic writes.\n");
+ }
+#endif
+#ifdef HAVE_POSIX_FALLOCATE
+ /* Due to a bug in directFS, using atomics needs
+ * posix_fallocate to extend the file
+ * pwrite() past end of the file won't work
+ */
+ srv_use_posix_fallocate = TRUE;
+#endif
+ }
+
#ifdef HAVE_PSI_INTERFACE
/* Register keys with MySQL performance schema */
if (PSI_server) {
@@ -11521,6 +11555,20 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_BOOL(use_atomic_writes, innobase_use_atomic_writes,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Prevent partial page writes, via atomic writes."
+ "The option is used to prevent partial writes in case of a crash/poweroff, "
+ "as faster alternative to doublewrite buffer."
+ "Currently this option works only "
+ "on Linux only with FusionIO device, and directFS filesystem.",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Preallocate files fast, using operating system functionality. On POSIX systems, posix_fallocate system call is used.",
+ NULL, NULL, TRUE);
+
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
@@ -11887,6 +11935,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
+ MYSQL_SYSVAR(use_atomic_writes),
+ MYSQL_SYSVAR(use_fallocate),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
MYSQL_SYSVAR(read_io_threads),
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index e2d061969f3..b0d5077c4c5 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -212,6 +212,11 @@ extern ibool srv_innodb_status;
extern unsigned long long srv_stats_sample_pages;
extern ibool srv_use_doublewrite_buf;
+extern ibool srv_use_atomic_writes;
+#ifdef HAVE_POSIX_FALLOCATE
+extern ibool srv_use_posix_fallocate;
+#endif
+
extern ibool srv_use_checksums;
extern ulong srv_max_buf_pool_modified_pct;
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 46eb9c4a935..0a1d3b41d0c 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -1361,6 +1361,43 @@ os_file_set_nocache(
#endif
}
+
+#ifdef __linux__
+#include <sys/ioctl.h>
+#ifndef DFS_IOCTL_ATOMIC_WRITE_SET
+#define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint)
+#endif
+static int os_file_set_atomic_writes(os_file_t file, const char *name)
+{
+ static int first_time = 1;
+ int atomic_option = 1;
+
+ int ret = ioctl (file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic_option);
+
+ if (ret) {
+ fprintf(stderr,
+ "InnoDB : can't use atomic write on %s, errno %d\n",
+ name, errno);
+ return ret;
+ }
+ return ret;
+}
+#else
+static int os_file_set_atomic_writes(os_file_t file, const char *name)
+{
+ fprintf(stderr,
+ "InnoDB : can't use atomic writes on %s - not implemented on this platform."
+ "innodb_use_atomic_writes needs to be 0.\n",
+ name);
+#ifdef _WIN32
+ SetLastError(ERROR_INVALID_FUNCTION);
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+}
+#endif
+
/****************************************************************//**
NOTE! Use the corresponding macro os_file_create(), not directly
this function!
@@ -1512,6 +1549,13 @@ try_again:
*success = TRUE;
}
+ if (srv_use_atomic_writes && type == OS_DATA_FILE &&
+ os_file_set_atomic_writes(file, name)) {
+ CloseHandle(file);
+ *success = FALSE;
+ file = INVALID_HANDLE_VALUE;
+ }
+
return(file);
#else /* __WIN__ */
os_file_t file;
@@ -1626,6 +1670,12 @@ try_again:
file = -1;
}
#endif /* USE_FILE_LOCK */
+ if (srv_use_atomic_writes && type == OS_DATA_FILE
+ && os_file_set_atomic_writes(file, name)) {
+ close(file);
+ *success = FALSE;
+ file = -1;
+ }
return(file);
#endif /* __WIN__ */
@@ -1970,6 +2020,28 @@ os_file_set_size(
current_size = 0;
desired_size = (ib_int64_t)size + (((ib_int64_t)size_high) << 32);
+#ifdef HAVE_POSIX_FALLOCATE
+ if (srv_use_posix_fallocate) {
+ if (posix_fallocate(file, current_size, desired_size) == -1) {
+ fprintf(stderr,
+ "InnoDB: Error: preallocating data for"
+ " file %s failed at\n"
+ "InnoDB: offset 0 size %lld %lld. Operating system"
+ " error number %llu.\n"
+ "InnoDB: Check that the disk is not full"
+ " or a disk quota exceeded.\n"
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ REFMAN "operating-system-error-codes.html\n",
+ name, (long long)size_high, (long long)size, errno);
+
+ return (FALSE);
+ }
+ return (TRUE);
+ }
+#endif
+
/* Write up to 1 megabyte at a time. */
buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
* UNIV_PAGE_SIZE;
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 5872ff2c437..c0b2f6cb700 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -401,6 +401,10 @@ this many index pages */
UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
+UNIV_INTERN ibool srv_use_atomic_writes = FALSE;
+#ifdef HAVE_POSIX_FALLOCATE
+UNIV_INTERN ibool srv_use_posix_fallocate = TRUE;
+#endif
UNIV_INTERN ibool srv_use_checksums = TRUE;
UNIV_INTERN ulong srv_replication_delay = 0;
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index fb7101fdb8d..fba43ad859c 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -316,9 +316,9 @@ mutex_create_func(
/* NOTE! The very first mutexes are not put to the mutex list */
- if ((mutex == &mutex_list_mutex)
+ if (mutex == &mutex_list_mutex
#ifdef UNIV_SYNC_DEBUG
- || (mutex == &sync_thread_mutex)
+ || mutex == &sync_thread_mutex
#endif /* UNIV_SYNC_DEBUG */
) {
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 09cf84f1fdb..d48e8df5cf1 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -136,8 +136,7 @@ const char *bits_to_txt[]=
"tail 00-40 % full", "tail 40-80 % full", "tail/blob full"
};
-/*#define WRONG_BITMAP_FLUSH 1*/ /*define only for provoking bugs*/
-#undef WRONG_BITMAP_FLUSH
+#define WRONG_BITMAP_FLUSH 0 /*define to 1 only for provoking bugs*/
static my_bool _ma_read_bitmap_page(MARIA_HA *info,
MARIA_FILE_BITMAP *bitmap,
@@ -165,11 +164,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
*/
bitmap->changed_not_flushed= 1;
- if ((bitmap->non_flushable == 0)
-#ifdef WRONG_BITMAP_FLUSH
- || 1
-#endif
- )
+ if ((bitmap->non_flushable == 0) || WRONG_BITMAP_FLUSH)
{
res= pagecache_write(share->pagecache,
&bitmap->file, bitmap->page, 0,
@@ -496,7 +491,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
{
bitmap->flush_all_requested++;
bitmap->waiting_for_non_flushable++;
-#ifndef WRONG_BITMAP_FLUSH
+#if !WRONG_BITMAP_FLUSH
while (bitmap->non_flushable > 0)
{
DBUG_PRINT("info", ("waiting for bitmap to be flushable"));
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 8b5da1dbefa..16657ba80ae 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -7123,7 +7123,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
memcpy(field_pos, field_length_data, size_length);
field_length_data+= size_length;
- memcpy(field_pos + size_length, &header, sizeof(&header));
+ memcpy(field_pos + size_length, &header, sizeof(header));
header+= blob_length;
*blob_lengths++= blob_length;
break;
diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c
index c11de6f8242..64b22e45c1b 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -114,7 +114,7 @@ int main(int argc,char **argv)
sleep(1);
return 0;
}
- rnd(1);
+ (void)rnd(1);
}
for (i=0 ; i < forks ; i++)
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index af8353cdf45..397c4de4b6e 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -4865,6 +4865,24 @@ fil_extend_space_to_desired_size(
start_page_no = space->size;
file_start_page_no = space->size - node->size;
+#ifdef HAVE_POSIX_FALLOCATE
+ if (srv_use_posix_fallocate) {
+ offset_high = size_after_extend * page_size / (4ULL*1024*1024*1024);
+ offset_low = size_after_extend * page_size % (4ULL*1024*1024*1024);
+
+ mutex_exit(&fil_system->mutex);
+ success = os_file_set_size(node->name, node->handle,
+ offset_low, offset_high);
+ mutex_enter(&fil_system->mutex);
+ if (success) {
+ node->size += (size_after_extend - start_page_no);
+ space->size += (size_after_extend - start_page_no);
+ os_has_said_disk_full = FALSE;
+ }
+ goto complete_io;
+ }
+#endif
+
/* Extend at most 64 pages at a time */
buf_size = ut_min(64, size_after_extend - start_page_no) * page_size;
buf2 = mem_alloc(buf_size + page_size);
@@ -4921,6 +4939,10 @@ fil_extend_space_to_desired_size(
mem_free(buf2);
+#ifdef HAVE_POSIX_FALLOCATE
+complete_io:
+#endif
+
fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
*actual_size = space->size;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index e90b62aa3db..a50e631de32 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -186,6 +186,8 @@ static my_bool innobase_file_format_check = TRUE;
static my_bool innobase_log_archive = FALSE;
static char* innobase_log_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
+static my_bool innobase_use_atomic_writes = FALSE;
+static my_bool innobase_use_fallocate = TRUE;
static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_fast_checksum = FALSE;
@@ -3079,6 +3081,38 @@ innobase_change_buffering_inited_ok:
srv_kill_idle_transaction = 0;
#endif
+#ifdef HAVE_POSIX_FALLOCATE
+ srv_use_posix_fallocate = (ibool) innobase_use_fallocate;
+#endif
+ srv_use_atomic_writes = (ibool) innobase_use_atomic_writes;
+ if (innobase_use_atomic_writes) {
+ fprintf(stderr, "InnoDB: using atomic writes.\n");
+
+ /* Force doublewrite buffer off, atomic writes replace it. */
+ if (srv_use_doublewrite_buf) {
+ fprintf(stderr, "InnoDB: Switching off doublewrite buffer "
+ "because of atomic writes.\n");
+ innobase_use_doublewrite = srv_use_doublewrite_buf = FALSE;
+ }
+
+ /* Force O_DIRECT on Unixes (on Windows writes are always unbuffered)*/
+#ifndef _WIN32
+ if(!innobase_file_flush_method ||
+ !strstr(innobase_file_flush_method, "O_DIRECT")) {
+ innobase_file_flush_method =
+ srv_file_flush_method_str = (char*)"O_DIRECT";
+ fprintf(stderr, "InnoDB: using O_DIRECT due to atomic writes.\n");
+ }
+#endif
+#ifdef HAVE_POSIX_FALLOCATE
+ /* Due to a bug in directFS, using atomics needs
+ * posix_fallocate to extend the file
+ * pwrite() past end of the file won't work
+ */
+ srv_use_posix_fallocate = TRUE;
+#endif
+ }
+
#ifdef HAVE_PSI_INTERFACE
/* Register keys with MySQL performance schema */
if (PSI_server) {
@@ -12771,6 +12805,20 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_BOOL(use_atomic_writes, innobase_use_atomic_writes,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Prevent partial page writes, via atomic writes."
+ "The option is used to prevent partial writes in case of a crash/poweroff, "
+ "as faster alternative to doublewrite buffer."
+ "Currently this option works only "
+ "on Linux only with FusionIO device, and directFS filesystem.",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Preallocate files fast, using operating system functionality. On POSIX systems, posix_fallocate system call is used.",
+ NULL, NULL, TRUE);
+
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
@@ -13415,6 +13463,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(doublewrite_file),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
+ MYSQL_SYSVAR(use_atomic_writes),
+ MYSQL_SYSVAR(use_fallocate),
MYSQL_SYSVAR(recovery_stats),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index a64e5ee607b..586c1e73879 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -249,6 +249,11 @@ extern ulong srv_sys_stats_root_page;
#endif
extern ibool srv_use_doublewrite_buf;
+extern ibool srv_use_atomic_writes;
+#ifdef HAVE_POSIX_FALLOCATE
+extern ibool srv_use_posix_fallocate;
+#endif
+
extern ibool srv_use_checksums;
extern ibool srv_fast_checksum;
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index f4a6c33655f..8f1b3e46bb2 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -1454,6 +1454,43 @@ os_file_set_nocache(
#endif
}
+
+#ifdef __linux__
+#include <sys/ioctl.h>
+#ifndef DFS_IOCTL_ATOMIC_WRITE_SET
+#define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint)
+#endif
+static int os_file_set_atomic_writes(os_file_t file, const char *name)
+{
+ static int first_time = 1;
+ int atomic_option = 1;
+
+ int ret = ioctl (file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic_option);
+
+ if (ret) {
+ fprintf(stderr,
+ "InnoDB : can't use atomic write on %s, errno %d\n",
+ name, errno);
+ return ret;
+ }
+ return ret;
+}
+#else
+static int os_file_set_atomic_writes(os_file_t file, const char *name)
+{
+ fprintf(stderr,
+ "InnoDB : can't use atomic writes on %s - not implemented on this platform."
+ "innodb_use_atomic_writes needs to be 0.\n",
+ name);
+#ifdef _WIN32
+ SetLastError(ERROR_INVALID_FUNCTION);
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+}
+#endif
+
/****************************************************************//**
NOTE! Use the corresponding macro os_file_create(), not directly
this function!
@@ -1618,6 +1655,13 @@ try_again:
}
}
+ if (srv_use_atomic_writes && type == OS_DATA_FILE &&
+ os_file_set_atomic_writes(file, name)) {
+ CloseHandle(file);
+ *success = FALSE;
+ file = INVALID_HANDLE_VALUE;
+ }
+
return(file);
#else /* __WIN__ */
os_file_t file;
@@ -1737,6 +1781,12 @@ try_again:
file = -1;
}
#endif /* USE_FILE_LOCK */
+ if (srv_use_atomic_writes && type == OS_DATA_FILE
+ && os_file_set_atomic_writes(file, name)) {
+ close(file);
+ *success = FALSE;
+ file = -1;
+ }
return(file);
#endif /* __WIN__ */
@@ -2081,6 +2131,28 @@ os_file_set_size(
current_size = 0;
desired_size = (ib_int64_t)size + (((ib_int64_t)size_high) << 32);
+#ifdef HAVE_POSIX_FALLOCATE
+ if (srv_use_posix_fallocate) {
+ if (posix_fallocate(file, current_size, desired_size) == -1) {
+ fprintf(stderr,
+ "InnoDB: Error: preallocating data for"
+ " file %s failed at\n"
+ "InnoDB: offset 0 size %lld %lld. Operating system"
+ " error number %llu.\n"
+ "InnoDB: Check that the disk is not full"
+ " or a disk quota exceeded.\n"
+ "InnoDB: Some operating system error numbers"
+ " are described at\n"
+ "InnoDB: "
+ REFMAN "operating-system-error-codes.html\n",
+ name, (long long)size_high, (long long)size, errno);
+
+ return (FALSE);
+ }
+ return (TRUE);
+ }
+#endif
+
/* Write up to 1 megabyte at a time. */
buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
* UNIV_PAGE_SIZE;
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 1de5523f62c..6edfbaa7755 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -409,6 +409,10 @@ UNIV_INTERN ulong srv_sys_stats_root_page = 0;
#endif
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
+UNIV_INTERN ibool srv_use_atomic_writes = FALSE;
+#ifdef HAVE_POSIX_FALLOCATE
+UNIV_INTERN ibool srv_use_posix_fallocate = TRUE;
+#endif
UNIV_INTERN ibool srv_use_checksums = TRUE;
UNIV_INTERN ibool srv_fast_checksum = FALSE;
diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c
index efc43c4cbe5..25f96d9817a 100644
--- a/storage/xtradb/sync/sync0sync.c
+++ b/storage/xtradb/sync/sync0sync.c
@@ -315,9 +315,9 @@ mutex_create_func(
/* NOTE! The very first mutexes are not put to the mutex list */
- if ((mutex == &mutex_list_mutex)
+ if (mutex == &mutex_list_mutex
#ifdef UNIV_SYNC_DEBUG
- || (mutex == &sync_thread_mutex)
+ || mutex == &sync_thread_mutex
#endif /* UNIV_SYNC_DEBUG */
) {
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index c439b6023fb..b96ca0e5bbe 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -4340,6 +4340,10 @@ static const char filename_safe_char[128]=
#define MY_FILENAME_ESCAPE '@'
+/*
+ note, that we cannot trust 'e' here, it's may be fake,
+ see strconvert()
+*/
static int
my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
my_wc_t *pwc, const uchar *s, const uchar *e)
@@ -4361,7 +4365,7 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
return MY_CS_TOOSMALL3;
byte1= s[1];
- byte2= s[2];
+ byte2= byte1 ? s[2] : 0;
if (byte1 >= 0x30 && byte1 <= 0x7F &&
byte2 >= 0x30 && byte2 <= 0x7F)
@@ -4386,7 +4390,7 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
(byte2= hexlo(byte2)) >= 0)
{
int byte3= hexlo(s[3]);
- int byte4= hexlo(s[4]);
+ int byte4= hexlo(s[3] ? s[4] : 0);
if (byte3 >=0 && byte4 >=0)
{
*pwc= (byte1 << 12) + (byte2 << 8) + (byte3 << 4) + byte4;
diff --git a/strings/decimal.c b/strings/decimal.c
index edcb4c52354..edff4c02885 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -669,7 +669,7 @@ int decimal_shift(decimal_t *dec, int shift)
if (do_left)
{
do_mini_left_shift(dec, l_mini_shift, beg, end);
- mini_shift=- l_mini_shift;
+ mini_shift= -l_mini_shift;
}
else
{
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index ec89e256579..72305e81c39 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -6204,7 +6204,7 @@ static void test_date_dt()
static void test_pure_coverage()
{
MYSQL_STMT *stmt;
- MYSQL_BIND my_bind[1];
+ MYSQL_BIND my_bind[2];
int rc;
ulong length;
@@ -8880,7 +8880,7 @@ static void test_parse_error_and_bad_length()
DIE_UNLESS(rc);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
- rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
+ rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
DIE_UNLESS(rc);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
@@ -8891,7 +8891,7 @@ static void test_parse_error_and_bad_length()
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
stmt= mysql_stmt_init(mysql);
DIE_UNLESS(stmt);
- rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
+ rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
DIE_UNLESS(rc != 0);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
@@ -16926,7 +16926,8 @@ static void test_bug31669()
rc= mysql_change_user(conn, "", "", "");
DIE_UNLESS(rc);
- memset(buff, 'a', sizeof(buff));
+ memset(buff, 'a', sizeof(buff) - 1);
+ buff[sizeof(buff) - 1]= 0;
mysql_close(conn);
conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);