summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2016-04-28 16:59:33 +0300
committerMonty <monty@mariadb.org>2016-04-28 16:59:33 +0300
commit9c846373f02d6431d83add639e7560a69ba885a2 (patch)
tree101d110d3ec9a4796b4050779fb052120fd6d516
parentfabeab781920dfcaf8e606708ba2c6812f6ae5d8 (diff)
parentd5822a3ad0657040114cdc185c6387b9eb3a12b2 (diff)
downloadmariadb-git-9c846373f02d6431d83add639e7560a69ba885a2.tar.gz
Merge commit 'd5822a3ad0657040114cdc185c6387b9eb3a12b2' into 10.2
-rw-r--r--.gitignore1
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake11
-rw-r--r--include/mysql/plugin.h4
-rw-r--r--include/mysql/plugin_audit.h.pp3
-rw-r--r--include/mysql/plugin_auth.h.pp3
-rw-r--r--include/mysql/plugin_encryption.h.pp3
-rw-r--r--include/mysql/plugin_ftparser.h.pp3
-rw-r--r--include/mysql/plugin_password_validation.h.pp3
-rw-r--r--libmysqld/lib_sql.cc3
-rw-r--r--mysql-test/include/crash_mysqld.inc18
-rw-r--r--mysql-test/r/delayed.result34
-rw-r--r--mysql-test/r/group_by.result14
-rw-r--r--mysql-test/std_data/bad2_master.info35
-rw-r--r--mysql-test/std_data/bad3_master.info37
-rw-r--r--mysql-test/std_data/bad4_master.info35
-rw-r--r--mysql-test/std_data/bad5_master.info35
-rw-r--r--mysql-test/std_data/bad6_master.info36
-rw-r--r--mysql-test/std_data/bad_master.info35
-rw-r--r--mysql-test/suite/galera/include/galera_sst_set_mysqldump.inc1
-rw-r--r--mysql-test/suite/galera/r/galera_ist_mysqldump.result1
-rw-r--r--mysql-test/suite/galera/r/galera_sst_mysqldump.result1
-rw-r--r--mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result1
-rw-r--r--mysql-test/suite/galera/r/mysql-wsrep#237.result1
-rw-r--r--mysql-test/suite/galera/r/mysql-wsrep#33.result1
-rw-r--r--mysql-test/suite/galera/t/mysql-wsrep#237.test2
-rw-r--r--mysql-test/suite/rpl/r/rpl_upgrade_master_info.result88
-rw-r--r--mysql-test/suite/rpl/t/rpl_upgrade_master_info.test163
-rw-r--r--mysql-test/t/delayed.test41
-rw-r--r--mysql-test/t/group_by.test10
-rw-r--r--sql/mysqld.cc100
-rw-r--r--sql/opt_range.cc12
-rw-r--r--sql/rpl_mi.cc81
-rw-r--r--sql/slave.cc1
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/sql_base.h4
-rw-r--r--sql/sql_class.cc16
-rw-r--r--sql/sql_class.h16
-rw-r--r--sql/sql_insert.cc19
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_show.cc21
-rw-r--r--sql/sql_show.h2
-rw-r--r--sql/table.h1
-rw-r--r--storage/innobase/dict/dict0boot.cc20
-rw-r--r--storage/innobase/fil/fil0fil.cc6
-rw-r--r--storage/innobase/include/log0crypt.h10
-rw-r--r--storage/innobase/include/ut0ut.h25
-rw-r--r--storage/innobase/log/log0crypt.cc43
-rw-r--r--storage/innobase/log/log0recv.cc2
-rw-r--r--storage/innobase/ut/ut0ut.cc17
-rw-r--r--storage/tokudb/ha_tokudb.h6
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result4
-rw-r--r--storage/xtradb/dict/dict0boot.cc20
-rw-r--r--storage/xtradb/fil/fil0fil.cc8
-rw-r--r--storage/xtradb/include/log0crypt.h10
-rw-r--r--storage/xtradb/include/ut0ut.h29
-rw-r--r--storage/xtradb/log/log0crypt.cc43
-rw-r--r--storage/xtradb/log/log0recv.cc2
-rw-r--r--storage/xtradb/os/os0file.cc2
-rw-r--r--storage/xtradb/ut/ut0ut.cc17
-rw-r--r--win/packaging/extra.wxs.in11
61 files changed, 1004 insertions, 178 deletions
diff --git a/.gitignore b/.gitignore
index 4c7efe9a119..f2064537da4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ Docs/INFO_SRC
Makefile
TAGS
Testing/
+tmp/
VERSION.dep
configure
client/async_example
diff --git a/config.h.cmake b/config.h.cmake
index 048ce816a43..f35e33ebe1a 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -189,6 +189,7 @@
#cmakedefine HAVE_PREAD 1
#cmakedefine HAVE_PAUSE_INSTRUCTION 1
#cmakedefine HAVE_FAKE_PAUSE_INSTRUCTION 1
+#cmakedefine HAVE_HMT_PRIORITY_INSTRUCTION 1
#cmakedefine HAVE_RDTSCLL 1
#cmakedefine HAVE_READ_REAL_TIME 1
#cmakedefine HAVE_PTHREAD_ATTR_CREATE 1
diff --git a/configure.cmake b/configure.cmake
index 294c5e24ca8..4470bee3223 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -784,6 +784,17 @@ IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC)
}
" HAVE_FAKE_PAUSE_INSTRUCTION)
ENDIF()
+ IF (NOT HAVE_PAUSE_INSTRUCTION)
+ CHECK_C_SOURCE_COMPILES("
+ #include <sys/platform/ppc.h>
+ int main()
+ {
+ __ppc_set_ppr_low();
+ __ppc_set_ppr_med();
+ return 0;
+ }
+ " HAVE_HMT_PRIORITY_INSTRUCTION)
+ ENDIF()
ENDIF()
CHECK_SYMBOL_EXISTS(tcgetattr "termios.h" HAVE_TCGETATTR 1)
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index cfa4b13a7ef..b3c71c65488 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -194,8 +194,10 @@ struct st_mysql_show_var {
enum enum_mysql_show_type type;
};
+struct system_status_var;
+
#define SHOW_VAR_FUNC_BUFF_SIZE (256 * sizeof(void*))
-typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, enum enum_var_type);
+typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
/*
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
index 8fc935262e2..aaf41c74a54 100644
--- a/include/mysql/plugin_audit.h.pp
+++ b/include/mysql/plugin_audit.h.pp
@@ -281,7 +281,8 @@ struct st_mysql_show_var {
void *value;
enum enum_mysql_show_type type;
};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
+struct system_status_var;
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index 046f92b5ab8..10cd10bf9c8 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -281,7 +281,8 @@ struct st_mysql_show_var {
void *value;
enum enum_mysql_show_type type;
};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
+struct system_status_var;
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
index 850dbf05a58..46d3c3d5a55 100644
--- a/include/mysql/plugin_encryption.h.pp
+++ b/include/mysql/plugin_encryption.h.pp
@@ -281,7 +281,8 @@ struct st_mysql_show_var {
void *value;
enum enum_mysql_show_type type;
};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
+struct system_status_var;
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
index ee1056a36d7..17de800875e 100644
--- a/include/mysql/plugin_ftparser.h.pp
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -281,7 +281,8 @@ struct st_mysql_show_var {
void *value;
enum enum_mysql_show_type type;
};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
+struct system_status_var;
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
index 0f14ac1eb53..1abdbd30f57 100644
--- a/include/mysql/plugin_password_validation.h.pp
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -281,7 +281,8 @@ struct st_mysql_show_var {
void *value;
enum enum_mysql_show_type type;
};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
+struct system_status_var;
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 476981023fd..a067856b287 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -517,6 +517,9 @@ int init_embedded_server(int argc, char **argv, char **groups)
if (my_thread_init())
return 1;
+ if (init_early_variables())
+ return 1;
+
if (argc)
{
argcp= &argc;
diff --git a/mysql-test/include/crash_mysqld.inc b/mysql-test/include/crash_mysqld.inc
new file mode 100644
index 00000000000..4190d24d801
--- /dev/null
+++ b/mysql-test/include/crash_mysqld.inc
@@ -0,0 +1,18 @@
+# Crash mysqld hard and wait until it's restarted
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+# Write file to make mysql-test-run.pl expect crash and restart
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Setup the mysqld to crash at shutdown
+SET debug_dbug="d,crash_shutdown";
+--error 2013
+shutdown;
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index 80b99115055..d54fa40f2da 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -476,3 +476,37 @@ connection con1;
disconnect con1;
connection default;
drop tables tm, t1, t2;
+#
+# MDEV-9621 INSERT DELAYED fails on insert for tables with many columns
+#
+CREATE TABLE t1 (
+a int,b int,c int,d int,e int,f int,g int,h int,i int,j int,k int,l int,m int,n int,o int,p int,q int,r int,s int,t int,u int,v int,x int,y int,z int
+) ENGINE=MyISAM;
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+drop table t1;
+#
+# INSERT DELAYED hangs if table was crashed
+#
+create table t1 (a int, b int) engine=myisam;
+insert into t1 values (1,1);
+SET debug_dbug="d,crash_shutdown";
+shutdown;
+ERROR HY000: Lost connection to MySQL server during query
+call mtr.add_suppression(" marked as crashed and should be repaired");
+call mtr.add_suppression("Checking table");
+insert delayed into t1 values (2,2);
+Warnings:
+Error 145 Table './test/t1' is marked as crashed and should be repaired
+Error 1194 Table 't1' is marked as crashed and should be repaired
+Error 1034 1 client is using or hasn't closed the table properly
+insert delayed into t1 values (3,3);
+flush tables t1;
+select * from t1;
+a b
+1 1
+2 2
+3 3
+drop table t1;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 40d72db8ab3..f27ae67adff 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -2709,3 +2709,17 @@ NULL
100098
100099
drop table t0,t1,t2;
+#
+# MDEV-9602 crash in st_key::actual_rec_per_key when group by constant
+#
+create table t1 (a date not null,unique (a)) engine=innodb;
+Warnings:
+Warning 1286 Unknown storage engine 'innodb'
+Warning 1266 Using storage engine MyISAM for table 't1'
+select distinct a from t1 group by 'a';
+a
+insert into t1 values("2001-02-02"),("2001-02-03");
+select distinct a from t1 group by 'a';
+a
+2001-02-02
+drop table t1;
diff --git a/mysql-test/std_data/bad2_master.info b/mysql-test/std_data/bad2_master.info
new file mode 100644
index 00000000000..61722562748
--- /dev/null
+++ b/mysql-test/std_data/bad2_master.info
@@ -0,0 +1,35 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+=0
diff --git a/mysql-test/std_data/bad3_master.info b/mysql-test/std_data/bad3_master.info
new file mode 100644
index 00000000000..6e632cd9a49
--- /dev/null
+++ b/mysql-test/std_data/bad3_master.info
@@ -0,0 +1,37 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+
+
+0
diff --git a/mysql-test/std_data/bad4_master.info b/mysql-test/std_data/bad4_master.info
new file mode 100644
index 00000000000..87572efc8a4
--- /dev/null
+++ b/mysql-test/std_data/bad4_master.info
@@ -0,0 +1,35 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+d=1
diff --git a/mysql-test/std_data/bad5_master.info b/mysql-test/std_data/bad5_master.info
new file mode 100644
index 00000000000..4ea8113250b
--- /dev/null
+++ b/mysql-test/std_data/bad5_master.info
@@ -0,0 +1,35 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+using_gtid
diff --git a/mysql-test/std_data/bad6_master.info b/mysql-test/std_data/bad6_master.info
new file mode 100644
index 00000000000..0f48f4871f0
--- /dev/null
+++ b/mysql-test/std_data/bad6_master.info
@@ -0,0 +1,36 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+END_MARKER
+do_domain_ids=20 Hulubulu!!?!
diff --git a/mysql-test/std_data/bad_master.info b/mysql-test/std_data/bad_master.info
new file mode 100644
index 00000000000..1541fdf2c61
--- /dev/null
+++ b/mysql-test/std_data/bad_master.info
@@ -0,0 +1,35 @@
+33
+mysql-bin.000001
+4
+127.0.0.1
+root
+
+3310
+60
+0
+
+
+
+
+
+0
+1800.000
+
+0
+
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+using_gtid=1
+
diff --git a/mysql-test/suite/galera/include/galera_sst_set_mysqldump.inc b/mysql-test/suite/galera/include/galera_sst_set_mysqldump.inc
index 5f87d23dcc1..cbd2c1c817a 100644
--- a/mysql-test/suite/galera/include/galera_sst_set_mysqldump.inc
+++ b/mysql-test/suite/galera/include/galera_sst_set_mysqldump.inc
@@ -6,6 +6,7 @@
--connection node_1
# We need a user with a password to perform SST, otherwise we hit LP #1378253
+CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst';
--let $wsrep_sst_auth_orig = `SELECT @@wsrep_sst_auth`
diff --git a/mysql-test/suite/galera/r/galera_ist_mysqldump.result b/mysql-test/suite/galera/r/galera_ist_mysqldump.result
index 9a5b4e8a76f..788d60051b5 100644
--- a/mysql-test/suite/galera/r/galera_ist_mysqldump.result
+++ b/mysql-test/suite/galera/r/galera_ist_mysqldump.result
@@ -1,4 +1,5 @@
Setting SST method to mysqldump ...
+CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst';
SET GLOBAL wsrep_sst_auth = 'sst:';
SET GLOBAL wsrep_sst_method = 'mysqldump';
diff --git a/mysql-test/suite/galera/r/galera_sst_mysqldump.result b/mysql-test/suite/galera/r/galera_sst_mysqldump.result
index e35c4055f45..5c0d9a45d41 100644
--- a/mysql-test/suite/galera/r/galera_sst_mysqldump.result
+++ b/mysql-test/suite/galera/r/galera_sst_mysqldump.result
@@ -1,4 +1,5 @@
Setting SST method to mysqldump ...
+CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst';
SET GLOBAL wsrep_sst_auth = 'sst:';
SET GLOBAL wsrep_sst_method = 'mysqldump';
diff --git a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result
index 7d30b356aa9..227e1c15444 100644
--- a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result
+++ b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result
@@ -1,4 +1,5 @@
Setting SST method to mysqldump ...
+CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst';
SET GLOBAL wsrep_sst_auth = 'sst:';
SET GLOBAL wsrep_sst_method = 'mysqldump';
diff --git a/mysql-test/suite/galera/r/mysql-wsrep#237.result b/mysql-test/suite/galera/r/mysql-wsrep#237.result
index 3fd9aed1480..1889a8feca0 100644
--- a/mysql-test/suite/galera/r/mysql-wsrep#237.result
+++ b/mysql-test/suite/galera/r/mysql-wsrep#237.result
@@ -8,3 +8,4 @@ SLEEP(1)
0
SET DEBUG_SYNC= 'now SIGNAL continue';
DROP TABLE t;
+SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/suite/galera/r/mysql-wsrep#33.result b/mysql-test/suite/galera/r/mysql-wsrep#33.result
index 62af519ad32..fc647a2000d 100644
--- a/mysql-test/suite/galera/r/mysql-wsrep#33.result
+++ b/mysql-test/suite/galera/r/mysql-wsrep#33.result
@@ -1,4 +1,5 @@
Setting SST method to mysqldump ...
+CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst';
SET GLOBAL wsrep_sst_auth = 'sst:';
SET GLOBAL wsrep_sst_method = 'mysqldump';
diff --git a/mysql-test/suite/galera/t/mysql-wsrep#237.test b/mysql-test/suite/galera/t/mysql-wsrep#237.test
index 7a65cb52ae9..f2dd6bce711 100644
--- a/mysql-test/suite/galera/t/mysql-wsrep#237.test
+++ b/mysql-test/suite/galera/t/mysql-wsrep#237.test
@@ -29,3 +29,5 @@ SET DEBUG_SYNC= 'now SIGNAL continue';
--reap
DROP TABLE t;
+--connection node_1a
+SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/suite/rpl/r/rpl_upgrade_master_info.result b/mysql-test/suite/rpl/r/rpl_upgrade_master_info.result
new file mode 100644
index 00000000000..f966f18964b
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_upgrade_master_info.result
@@ -0,0 +1,88 @@
+include/master-slave.inc
+[connection master]
+*** MDEV-9383: Server fails to read master.info after upgrade 10.0 -> 10.1 ***
+include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=CURRENT_POS;
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1;
+a
+1
+include/stop_slave.inc
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+INSERT INTO t1 VALUES (2);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+include/stop_slave.inc
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+INSERT INTO t1 VALUES (3);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+include/stop_slave.inc
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+INSERT INTO t1 VALUES (4);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+4
+include/stop_slave.inc
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+INSERT INTO t1 VALUES (5);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+4
+5
+include/stop_slave.inc
+include/rpl_stop_server.inc [server_number=2]
+include/rpl_start_server.inc [server_number=2]
+INSERT INTO t1 VALUES (6);
+include/save_master_gtid.inc
+CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1;
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+4
+5
+6
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_upgrade_master_info.test b/mysql-test/suite/rpl/t/rpl_upgrade_master_info.test
new file mode 100644
index 00000000000..e81e7c0d714
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_upgrade_master_info.test
@@ -0,0 +1,163 @@
+--source include/master-slave.inc
+
+--echo *** MDEV-9383: Server fails to read master.info after upgrade 10.0 -> 10.1 ***
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=CURRENT_POS;
+--let $datadir= `SELECT @@datadir`
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1;
+
+--source include/stop_slave.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad2_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+INSERT INTO t1 VALUES (2);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--source include/stop_slave.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad3_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+INSERT INTO t1 VALUES (3);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--source include/stop_slave.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad4_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+INSERT INTO t1 VALUES (4);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--source include/stop_slave.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad5_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+INSERT INTO t1 VALUES (5);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--source include/stop_slave.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+--remove_file $datadir/master.info
+--copy_file $MYSQL_TEST_DIR/std_data/bad6_master.info $datadir/master.info
+
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+--source include/wait_until_connected_again.inc
+
+--connection master
+INSERT INTO t1 VALUES (6);
+--source include/save_master_gtid.inc
+
+--connection slave
+# Fix the port after we replaced master.info.
+--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
+eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1;
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+
+# Cleanup
+--connection master
+DROP TABLE t1;
+--source include/rpl_end.inc
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index 85f28de128b..dea16c84a51 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -1,5 +1,12 @@
# delayed works differently in embedded server
--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+# Avoid CrashReporter popup on Mac
+--source include/not_crashrep.inc
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug_sync.inc
+
#
# test of DELAYED insert and timestamps
# (Can't be tested with purify :( )
@@ -601,3 +608,37 @@ disconnect con1;
--source include/wait_until_disconnected.inc
connection default;
drop tables tm, t1, t2;
+
+--echo #
+--echo # MDEV-9621 INSERT DELAYED fails on insert for tables with many columns
+--echo #
+
+CREATE TABLE t1 (
+ a int,b int,c int,d int,e int,f int,g int,h int,i int,j int,k int,l int,m int,n int,o int,p int,q int,r int,s int,t int,u int,v int,x int,y int,z int
+) ENGINE=MyISAM;
+
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+drop table t1;
+
+--echo #
+--echo # INSERT DELAYED hangs if table was crashed
+--echo #
+
+create table t1 (a int, b int) engine=myisam;
+insert into t1 values (1,1);
+
+# Will come back with t1 crashed.
+--source include/crash_mysqld.inc
+
+call mtr.add_suppression(" marked as crashed and should be repaired");
+call mtr.add_suppression("Checking table");
+
+--replace_result '\\' '/'
+insert delayed into t1 values (2,2);
+insert delayed into t1 values (3,3);
+flush tables t1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 318166e6896..f0007186ab2 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1818,3 +1818,13 @@ from t1
group by t1.b;
drop table t0,t1,t2;
+
+--echo #
+--echo # MDEV-9602 crash in st_key::actual_rec_per_key when group by constant
+--echo #
+
+create table t1 (a date not null,unique (a)) engine=innodb;
+select distinct a from t1 group by 'a';
+insert into t1 values("2001-02-02"),("2001-02-03");
+select distinct a from t1 group by 'a';
+drop table t1;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a67cea47fc9..9843a1bf67c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4087,40 +4087,45 @@ extern "C" {
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
{
THD *thd= current_thd;
- /* If thread specific memory */
- if (likely(is_thread_specific))
+
+ if (likely(is_thread_specific)) /* If thread specific memory */
{
- if (mysqld_server_initialized || thd)
- {
- /*
- THD may not be set if we are called from my_net_init() before THD
- thread has started.
- However, this should never happen, so better to assert and
- fix this.
- */
- DBUG_ASSERT(thd);
- if (thd)
- {
- DBUG_PRINT("info", ("memory_used: %lld size: %lld",
- (longlong) thd->status_var.local_memory_used,
- size));
- thd->status_var.local_memory_used+= size;
- DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
- !debug_assert_on_not_freed_memory);
- }
- }
+ /*
+ When thread specfic is set, both mysqld_server_initialized and thd
+ must be set
+ */
+ DBUG_ASSERT(mysqld_server_initialized && thd);
+
+ DBUG_PRINT("info", ("thd memory_used: %lld size: %lld",
+ (longlong) thd->status_var.local_memory_used,
+ size));
+ thd->status_var.local_memory_used+= size;
+ DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
+ !debug_assert_on_not_freed_memory);
}
else if (likely(thd))
+ {
+ DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld",
+ (longlong) thd->status_var.global_memory_used,
+ size));
thd->status_var.global_memory_used+= size;
+ }
else
{
- // workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
- int64 volatile * volatile ptr=&global_status_var.global_memory_used;
- my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED);
+ update_global_memory_status(size);
+#ifndef EMBEDDED_LIBRARY
+ /*
+ Check if we have missed some mallocs. THis can't be done for embedded
+ server as the main code may have done calls to malloc before starting
+ the embedded library.
+ */
+ DBUG_ASSERT(global_status_var.global_memory_used >= 0);
+#endif
}
}
}
+
/**
Create a replication file name or base for file names.
@@ -4157,6 +4162,22 @@ rpl_make_log_name(const char *opt,
DBUG_RETURN(NULL);
}
+/* We have to setup my_malloc_size_cb_func early to catch all mallocs */
+
+static int init_early_variables()
+{
+ if (pthread_key_create(&THR_THD, NULL))
+ {
+ fprintf(stderr, "Fatal error: Can't create thread-keys\n");
+ return 1;
+ }
+ set_current_thd(0);
+ set_malloc_size_cb(my_malloc_size_cb_func);
+ global_status_var.global_memory_used= 0;
+ return 0;
+}
+
+
static int init_common_variables()
{
umask(((~my_umask) & 0666));
@@ -4168,15 +4189,6 @@ static int init_common_variables()
connection_errors_peer_addr= 0;
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
- if (pthread_key_create(&THR_THD, NULL))
- {
- sql_print_error("Can't create thread-keys");
- return 1;
- }
-
- set_current_thd(0);
- set_malloc_size_cb(my_malloc_size_cb_func);
-
init_libstrings();
tzset(); // Set tzname
@@ -4713,6 +4725,7 @@ static int init_thread_environment()
mysql_mutex_init(key_LOCK_global_system_variables,
&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
mysql_mutex_record_order(&LOCK_active_mi, &LOCK_global_system_variables);
+ mysql_mutex_record_order(&LOCK_status, &LOCK_thread_count);
mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash,
&LOCK_system_variables_hash);
mysql_mutex_init(key_LOCK_prepared_stmt_count,
@@ -5186,6 +5199,9 @@ static int init_server_components()
variables even when a wsrep provider is not loaded.
*/
+ /* It's now safe to use thread specific memory */
+ mysqld_server_initialized= 1;
+
wsrep_thr_init();
if (WSREP_ON && !wsrep_recovery && !opt_abort) /* WSREP BEFORE SE */
@@ -5636,6 +5652,9 @@ int mysqld_main(int argc, char **argv)
sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
mysqld_server_started= mysqld_server_initialized= 0;
+ if (init_early_variables())
+ exit(1);
+
#ifdef HAVE_NPTL
ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
#endif
@@ -5938,9 +5957,6 @@ int mysqld_main(int argc, char **argv)
if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
unireg_abort(1);
- /* It's now safe to use thread specific memory */
- mysqld_server_initialized= 1;
-
if (WSREP_ON)
{
if (opt_bootstrap)
@@ -8309,15 +8325,16 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff,
+ struct system_status_var *status_var,
enum enum_var_type scope)
{
var->type= SHOW_LONGLONG;
var->value= buff;
if (scope == OPT_GLOBAL)
- *(longlong*) buff= (global_status_var.local_memory_used +
- global_status_var.global_memory_used);
+ *(longlong*) buff= (status_var->global_memory_used +
+ status_var->local_memory_used);
else
- *(longlong*) buff= thd->status_var.local_memory_used;
+ *(longlong*) buff= status_var->local_memory_used;
return 0;
}
@@ -8746,7 +8763,9 @@ static int mysql_init_variables(void)
prepared_stmt_count= 0;
mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
- bzero((char *) &global_status_var, sizeof(global_status_var));
+ /* Clear all except global_memory_used */
+ bzero((char*) &global_status_var, offsetof(STATUS_VAR,
+ last_cleared_system_status_var));
opt_large_pages= 0;
opt_super_large_pages= 0;
#if defined(ENABLED_DEBUG_SYNC)
@@ -9992,6 +10011,7 @@ void refresh_status(THD *thd)
/* Reset thread's status variables */
thd->set_status_var_init();
+ thd->status_var.global_memory_used= 0;
bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var));
thd->start_bytes_received= 0;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index af027ad6fdc..a69709bbf03 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -13105,7 +13105,17 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
num_blocks= (ha_rows)(table_records / keys_per_block) + 1;
/* Compute the number of keys in a group. */
- keys_per_group= (ha_rows) index_info->actual_rec_per_key(group_key_parts - 1);
+ if (!group_key_parts)
+ {
+ /* Summary over the whole table */
+ keys_per_group= table_records;
+ }
+ else
+ {
+ keys_per_group= (ha_rows) index_info->actual_rec_per_key(group_key_parts -
+ 1);
+ }
+
if (keys_per_group == 0) /* If there is no statistics try to guess */
/* each group contains 10% of all records */
keys_per_group= (table_records / 10) + 1;
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index df721342d1d..02dbac46eb5 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -205,43 +205,56 @@ void init_master_log_pos(Master_info* mi)
/**
Parses the IO_CACHE for "key=" and returns the "key".
+ If no '=' found, returns the whole line (for END_MARKER).
@param key [OUT] Key buffer
@param max_size [IN] Maximum buffer size
@param f [IN] IO_CACHE file
+ @param found_equal [OUT] Set true if a '=' was found.
@retval 0 Either "key=" or '\n' found
@retval 1 EOF
*/
-static int read_mi_key_from_file(char *key, int max_size, IO_CACHE *f)
+static int
+read_mi_key_from_file(char *key, int max_size, IO_CACHE *f, bool *found_equal)
{
int i= 0, c;
- char *last_p;
DBUG_ENTER("read_key_from_file");
- while (((c= my_b_get(f)) != '\n') && (c != my_b_EOF))
+ *found_equal= false;
+ if (max_size <= 0)
+ DBUG_RETURN(1);
+ for (;;)
{
- last_p= key + i;
-
- if (i < max_size)
+ if (i >= max_size-1)
{
- if (c == '=')
- {
- /* We found '=', replace it by 0 and return. */
- *last_p= 0;
- DBUG_RETURN(0);
- }
- else
- *last_p= c;
+ key[i] = '\0';
+ DBUG_RETURN(0);
+ }
+ c= my_b_get(f);
+ if (c == my_b_EOF)
+ {
+ DBUG_RETURN(1);
+ }
+ else if (c == '\n')
+ {
+ key[i]= '\0';
+ DBUG_RETURN(0);
+ }
+ else if (c == '=')
+ {
+ key[i]= '\0';
+ *found_equal= true;
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ key[i]= c;
+ ++i;
}
- ++i;
}
-
- if (c == my_b_EOF)
- DBUG_RETURN(1);
-
- DBUG_RETURN(0);
+ /* NotReached */
}
enum {
@@ -539,6 +552,10 @@ file '%s')", fname);
if (lines >= LINE_FOR_LAST_MYSQL_FUTURE)
{
uint i;
+ bool got_eq;
+ bool seen_using_gtid= false;
+ bool seen_do_domain_ids=false, seen_ignore_domain_ids=false;
+
/* Skip lines used by / reserved for MySQL >= 5.6. */
for (i= LINE_FOR_FIRST_MYSQL_5_6; i <= LINE_FOR_LAST_MYSQL_FUTURE; ++i)
{
@@ -551,11 +568,12 @@ file '%s')", fname);
for "key=" and returns the "key" if found. The "value" can then the
parsed on case by case basis. The "unknown" lines would be ignored to
facilitate downgrades.
+ 10.0 does not have the END_MARKER before any left-overs at the end
+ of the file. So ignore any but the first occurrence of a key.
*/
- while (!read_mi_key_from_file(buf, sizeof(buf), &mi->file))
+ while (!read_mi_key_from_file(buf, sizeof(buf), &mi->file, &got_eq))
{
- /* using_gtid */
- if (!strncmp(buf, STRING_WITH_LEN("using_gtid")))
+ if (got_eq && !seen_using_gtid && !strcmp(buf, "using_gtid"))
{
int val;
if (!init_intvar_from_file(&val, &mi->file, 0))
@@ -566,15 +584,13 @@ file '%s')", fname);
mi->using_gtid= Master_info::USE_GTID_SLAVE_POS;
else
mi->using_gtid= Master_info::USE_GTID_NO;
- continue;
+ seen_using_gtid= true;
} else {
sql_print_error("Failed to initialize master info using_gtid");
goto errwithmsg;
}
}
-
- /* DO_DOMAIN_IDS */
- if (!strncmp(buf, STRING_WITH_LEN("do_domain_ids")))
+ else if (got_eq && !seen_do_domain_ids && !strcmp(buf, "do_domain_ids"))
{
if (mi->domain_id_filter.init_ids(&mi->file,
Domain_id_filter::DO_DOMAIN_IDS))
@@ -582,11 +598,10 @@ file '%s')", fname);
sql_print_error("Failed to initialize master info do_domain_ids");
goto errwithmsg;
}
- continue;
+ seen_do_domain_ids= true;
}
-
- /* IGNORE_DOMAIN_IDS */
- if (!strncmp(buf, STRING_WITH_LEN("ignore_domain_ids")))
+ else if (got_eq && !seen_ignore_domain_ids &&
+ !strcmp(buf, "ignore_domain_ids"))
{
if (mi->domain_id_filter.init_ids(&mi->file,
Domain_id_filter::IGNORE_DOMAIN_IDS))
@@ -595,9 +610,9 @@ file '%s')", fname);
"ignore_domain_ids");
goto errwithmsg;
}
- continue;
+ seen_ignore_domain_ids= true;
}
- else if (!strncmp(buf, STRING_WITH_LEN("END_MARKER")))
+ else if (!got_eq && !strcmp(buf, "END_MARKER"))
{
/*
Guard agaist extra left-overs at the end of file, in case a later
diff --git a/sql/slave.cc b/sql/slave.cc
index 93506bc2ccd..30a0018f490 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4955,7 +4955,6 @@ err_during_init:
delete serial_rgi;
mysql_mutex_unlock(&LOCK_thread_count);
- THD_CHECK_SENTRY(thd);
delete thd;
thread_safe_decrement32(&service_thread_count);
signal_thd_deleted();
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 6cc78a4c294..18e7ee950e6 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2551,8 +2551,13 @@ retry_share:
(void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
table_list);
else if (share->crashed)
- (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR,
- table_list);
+ {
+ if (!(flags & MYSQL_OPEN_IGNORE_REPAIR))
+ (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR,
+ table_list);
+ else
+ table_list->crashed= 1; /* Mark that table was crashed */
+ }
goto err_lock;
}
if (open_table_entry_fini(thd, share, table))
diff --git a/sql/sql_base.h b/sql/sql_base.h
index ecadd31d3f9..d6bd0e2ace7 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -107,6 +107,10 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
table flush, wait on thr_lock.c locks) while opening and locking table.
*/
#define MYSQL_OPEN_IGNORE_KILLED 0x8000
+/**
+ Don't try to auto-repair table
+*/
+#define MYSQL_OPEN_IGNORE_REPAIR 0x10000
/** Please refer to the internals manual. */
#define MYSQL_OPEN_REOPEN (MYSQL_OPEN_IGNORE_FLUSH |\
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index e3b70566597..e189fd7e582 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -908,7 +908,8 @@ THD::THD(bool is_wsrep_applier)
*/
THD *old_THR_THD= current_thd;
set_current_thd(this);
- status_var.local_memory_used= status_var.global_memory_used= 0;
+ status_var.local_memory_used= sizeof(THD);
+ status_var.global_memory_used= 0;
main_da.init();
/*
@@ -1641,6 +1642,8 @@ THD::~THD()
that memory allocation counting is done correctly
*/
set_current_thd(this);
+ if (!status_in_global)
+ add_status_to_global();
/* Ensure that no one is using THD */
mysql_mutex_lock(&LOCK_thd_data);
@@ -1703,6 +1706,7 @@ THD::~THD()
if (xid_hash_pins)
lf_hash_put_pins(xid_hash_pins);
/* Ensure everything is freed */
+ status_var.local_memory_used-= sizeof(THD);
if (status_var.local_memory_used != 0)
{
DBUG_PRINT("error", ("memory_used: %lld", status_var.local_memory_used));
@@ -1710,7 +1714,7 @@ THD::~THD()
DBUG_ASSERT(status_var.local_memory_used == 0 ||
!debug_assert_on_not_freed_memory);
}
-
+ update_global_memory_status(status_var.global_memory_used);
set_current_thd(orig_thd == this ? 0 : orig_thd);
DBUG_VOID_RETURN;
}
@@ -1729,6 +1733,7 @@ THD::~THD()
other types are handled explicitely
*/
+
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
{
ulong *end= (ulong*) ((uchar*) to_var +
@@ -1748,12 +1753,17 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
to_var->binlog_bytes_written+= from_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time;
to_var->busy_time+= from_var->busy_time;
- to_var->local_memory_used+= from_var->local_memory_used;
/*
Update global_memory_used. We have to do this with atomic_add as the
global value can change outside of LOCK_status.
*/
+ if (to_var == &global_status_var)
+ {
+ DBUG_PRINT("info", ("global memory_used: %lld size: %lld",
+ (longlong) global_status_var.global_memory_used,
+ (longlong) from_var->global_memory_used));
+ }
// workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
int64 volatile * volatile ptr= &to_var->global_memory_used;
my_atomic_add64_explicit(ptr, from_var->global_memory_used,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index b68a6e5ebd9..e0792a4059f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -824,6 +824,20 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
STATUS_VAR *dec_var);
+/*
+ Update global_memory_used. We have to do this with atomic_add as the
+ global value can change outside of LOCK_status.
+*/
+inline void update_global_memory_status(int64 size)
+{
+ DBUG_PRINT("info", ("global memory_used: %lld size: %lld",
+ (longlong) global_status_var.global_memory_used,
+ size));
+ // workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
+ int64 volatile * volatile ptr= &global_status_var.global_memory_used;
+ my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED);
+}
+
/**
Get collation by name, send error to client on failure.
@param name Collation name
@@ -3846,9 +3860,11 @@ public:
void add_status_to_global()
{
+ DBUG_ASSERT(status_in_global == 0);
mysql_mutex_lock(&LOCK_status);
add_to_status(&global_status_var, &status_var);
/* Mark that this THD status has already been added in global status */
+ status_var.global_memory_used= 0;
status_in_global= 1;
mysql_mutex_unlock(&LOCK_status);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 6e40ac02274..65af14b62f6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2017,6 +2017,7 @@ public:
mysql_cond_t cond, cond_client;
volatile uint tables_in_use,stacked_inserts;
volatile bool status;
+ bool retry;
/**
When the handler thread starts, it clones a metadata lock ticket
which protects against GRL and ticket for the table to be inserted.
@@ -2041,7 +2042,7 @@ public:
Delayed_insert(SELECT_LEX *current_select)
:locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0),
- status(0), handler_thread_initialized(FALSE), group_count(0)
+ status(0), retry(0), handler_thread_initialized(FALSE), group_count(0)
{
DBUG_ENTER("Delayed_insert constructor");
thd.security_ctx->user=(char*) delayed_user;
@@ -2300,7 +2301,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
}
if (di->thd.killed)
{
- if (di->thd.is_error())
+ if (di->thd.is_error() && ! di->retry)
{
/*
Copy the error message. Note that we don't treat fatal
@@ -2526,7 +2527,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
copy->vcol_set= copy->def_vcol_set;
}
copy->tmp_set.bitmap= 0; // To catch errors
- bzero((char*) bitmap, share->column_bitmap_size + (share->vfields ? 3 : 2));
+ bzero((char*) bitmap, share->column_bitmap_size * (share->vfields ? 3 : 2));
copy->read_set= &copy->def_read_set;
copy->write_set= &copy->def_write_set;
@@ -2535,7 +2536,6 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
/* Got fatal error */
error:
tables_in_use--;
- status=1;
mysql_cond_signal(&cond); // Inform thread about abort
DBUG_RETURN(0);
}
@@ -2777,13 +2777,20 @@ bool Delayed_insert::open_and_lock_table()
/*
Use special prelocking strategy to get ER_DELAYED_NOT_SUPPORTED
error for tables with engines which don't support delayed inserts.
+
+ We can't do auto-repair in insert delayed thread, as it would hang
+ when trying to an exclusive MDL_LOCK on the table during repair
+ as the connection thread has a SHARED_WRITE lock.
*/
if (!(table= open_n_lock_single_table(&thd, &table_list,
TL_WRITE_DELAYED,
- MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK,
+ MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |
+ MYSQL_OPEN_IGNORE_REPAIR,
&prelocking_strategy)))
{
- thd.fatal_error(); // Abort waiting inserts
+ /* If table was crashed, then upper level should retry open+repair */
+ retry= table_list.crashed;
+ thd.fatal_error(); // Abort waiting inserts
return TRUE;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3389af5c147..a6bb89f05df 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5308,6 +5308,7 @@ end_with_restore_list:
}
case SQLCOM_SHUTDOWN:
#ifndef EMBEDDED_LIBRARY
+ DBUG_EXECUTE_IF("crash_shutdown", DBUG_SUICIDE(););
if (check_global_access(thd,SHUTDOWN_ACL))
goto error;
kill_mysql(thd);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1102050e29c..f41fb394b47 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2960,8 +2960,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
thread in this thread. However it's better that we notice it eventually
than hide it.
*/
- table->field[12]->store((longlong) (tmp->status_var.local_memory_used +
- sizeof(THD)),
+ table->field[12]->store((longlong) tmp->status_var.local_memory_used,
FALSE);
table->field[12]->set_notnull();
table->field[13]->store((longlong) tmp->get_examined_row_count(), TRUE);
@@ -3257,7 +3256,8 @@ static bool show_status_array(THD *thd, const char *wild,
*/
for (var=variables; var->type == SHOW_FUNC ||
var->type == SHOW_SIMPLE_FUNC; var= &tmp)
- ((mysql_show_var_func)(var->value))(thd, &tmp, buff, scope);
+ ((mysql_show_var_func)(var->value))(thd, &tmp, buff,
+ status_var, scope);
SHOW_TYPE show_type=var->type;
if (show_type == SHOW_ARRAY)
@@ -3389,10 +3389,14 @@ end:
DBUG_RETURN(res);
}
-/* collect status for all running threads */
+/*
+ collect status for all running threads
+ Return number of threads used
+*/
-void calc_sum_of_all_status(STATUS_VAR *to)
+uint calc_sum_of_all_status(STATUS_VAR *to)
{
+ uint count= 0;
DBUG_ENTER("calc_sum_of_all_status");
/* Ensure that thread id not killed during loop */
@@ -3403,16 +3407,21 @@ void calc_sum_of_all_status(STATUS_VAR *to)
/* Get global values as base */
*to= global_status_var;
+ to->local_memory_used= 0;
/* Add to this status from existing threads */
while ((tmp= it++))
{
+ count++;
if (!tmp->status_in_global)
+ {
add_to_status(to, &tmp->status_var);
+ to->local_memory_used+= tmp->status_var.local_memory_used;
+ }
}
mysql_mutex_unlock(&LOCK_thread_count);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(count);
}
diff --git a/sql/sql_show.h b/sql/sql_show.h
index 9dae78e7f0e..dbae2a42b39 100644
--- a/sql/sql_show.h
+++ b/sql/sql_show.h
@@ -102,7 +102,7 @@ bool mysqld_show_authors(THD *thd);
bool mysqld_show_contributors(THD *thd);
bool mysqld_show_privileges(THD *thd);
char *make_backup_log_name(char *buff, const char *name, const char* log_ext);
-void calc_sum_of_all_status(STATUS_VAR *to);
+uint calc_sum_of_all_status(STATUS_VAR *to);
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
const LEX_STRING *definer_host);
int add_status_vars(SHOW_VAR *list);
diff --git a/sql/table.h b/sql/table.h
index aa7c11ba3d8..a105df31e93 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1964,6 +1964,7 @@ struct TABLE_LIST
bool updating; /* for replicate-do/ignore table */
bool force_index; /* prefer index over table scan */
bool ignore_leaves; /* preload only non-leaf nodes */
+ bool crashed; /* Table was found crashed */
table_map dep_tables; /* tables the table depends on */
table_map on_expr_dep_tables; /* tables on expression depends on */
struct st_nested_join *nested_join; /* if the element is a nested join */
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 573357b54ee..0dff05567d7 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -458,12 +458,22 @@ dict_boot(void)
if (err == DB_SUCCESS) {
if (srv_read_only_mode && !ibuf_is_empty()) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Change buffer must be empty when --innodb-read-only "
- "is set!");
+ if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Change buffer must be empty when --innodb-read-only "
+ "is set! "
+ "You can try to recover the database with innodb_force_recovery=5");
+
+ err = DB_ERROR;
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Change buffer not empty when --innodb-read-only "
+ "is set! but srv_force_recovery = %d, ignoring.",
+ srv_force_recovery);
+ }
+ }
- err = DB_ERROR;
- } else {
+ if (err == DB_SUCCESS) {
/* Load definitions of other indexes on system tables */
dict_load_sys_table(dict_sys->sys_tables);
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index d918b21d779..22abf592adc 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -737,11 +737,9 @@ fil_node_open_file(
}
}
- if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
+ if (size_bytes >= (1024*1024)) {
/* Truncate the size to whole extent size. */
- size_bytes = ut_2pow_round(size_bytes,
- FSP_EXTENT_SIZE *
- UNIV_PAGE_SIZE);
+ size_bytes = ut_2pow_round(size_bytes, (1024*1024));
}
if (!fsp_flags_is_compressed(flags)) {
diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h
index 7e737853465..6b164e90d6e 100644
--- a/storage/innobase/include/log0crypt.h
+++ b/storage/innobase/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -117,4 +117,12 @@ log_crypt_print_error(
/*==================*/
log_crypt_err_t err_info); /*!< out: error info */
+/*********************************************************************//**
+Print checkpoint no from log block and all encryption keys from
+checkpoints if they are present. Used for problem analysis. */
+void
+log_crypt_print_checkpoint_keys(
+/*============================*/
+ const byte* log_block);
+
#endif // log0crypt.h
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index e2635248b03..176f132704a 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -88,15 +88,32 @@ private:
the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
independent way by using YieldProcessor. */
# define UT_RELAX_CPU() YieldProcessor()
-# elif defined(HAVE_ATOMIC_BUILTINS)
+# elif defined(__powerpc__)
+#include <sys/platform/ppc.h>
# define UT_RELAX_CPU() do { \
- volatile lint volatile_var; \
- os_compare_and_swap_lint(&volatile_var, 0, 1); \
+ volatile lint volatile_var = __ppc_get_timebase(); \
} while (0)
# else
# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
# endif
+#if defined (__GNUC__)
+# define UT_COMPILER_BARRIER() __asm__ __volatile__ ("":::"memory")
+#elif defined (_MSC_VER)
+# define UT_COMPILER_BARRIER() _ReadWriteBarrier()
+#else
+# define UT_COMPILER_BARRIER()
+#endif
+
+# if defined(HAVE_HMT_PRIORITY_INSTRUCTION)
+#include <sys/platform/ppc.h>
+# define UT_LOW_PRIORITY_CPU() __ppc_set_ppr_low()
+# define UT_RESUME_PRIORITY_CPU() __ppc_set_ppr_med()
+# else
+# define UT_LOW_PRIORITY_CPU() ((void)0)
+# define UT_RESUME_PRIORITY_CPU() ((void)0)
+# endif
+
/*********************************************************************//**
Delays execution for at most max_wait_us microseconds or returns earlier
if cond becomes true.
@@ -342,7 +359,7 @@ Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++.
@return dummy value */
UNIV_INTERN
-ulint
+void
ut_delay(
/*=====*/
ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index 852148899e9..db2e84d7e45 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -127,12 +127,35 @@ static
const crypt_info_t*
get_crypt_info(
/*===========*/
- const byte* log_block) {
+ const byte* log_block)
+{
ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block);
return get_crypt_info(checkpoint_no);
}
/*********************************************************************//**
+Print checkpoint no from log block and all encryption keys from
+checkpoints if they are present. Used for problem analysis. */
+void
+log_crypt_print_checkpoint_keys(
+/*============================*/
+ const byte* log_block)
+{
+ ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block);
+
+ if (crypt_info.size()) {
+ fprintf(stderr, "InnoDB: redo log checkpoint: %lu [ chk key ]: ", checkpoint_no);
+ for (size_t i = 0; i < crypt_info.size(); i++) {
+ struct crypt_info_t* it = &crypt_info[i];
+ fprintf(stderr, "[ %lu %u ] ",
+ it->checkpoint_no,
+ it->key_version);
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+/*********************************************************************//**
Call AES CTR to encrypt/decrypt log blocks. */
static
Crypt_result
@@ -278,12 +301,22 @@ Add crypt info to set if it is not already present
@return true if successfull, false if not- */
static
bool
-add_crypt_info(crypt_info_t* info)
+add_crypt_info(
+/*===========*/
+ crypt_info_t* info, /*!< in: crypt info */
+ bool checkpoint_read)/*!< in: do we read checkpoint */
{
+ const crypt_info_t* found=NULL;
/* so that no one is searching array while we modify it */
ut_ad(mutex_own(&(log_sys->mutex)));
- if (get_crypt_info(info->checkpoint_no) != NULL) {
+ found = get_crypt_info(info->checkpoint_no);
+
+ /* If one crypt info is found then we add a new one only if we
+ are reading checkpoint from the log. New checkpoints will always
+ use the first created crypt info. */
+ if (found != NULL &&
+ ( found->checkpoint_no == info->checkpoint_no || !checkpoint_read)) {
// already present...
return true;
}
@@ -356,7 +389,7 @@ log_crypt_set_ver_and_key(
}
- add_crypt_info(&info);
+ add_crypt_info(&info, false);
}
/********************************************************
@@ -514,7 +547,7 @@ log_crypt_read_checkpoint_buf(
memcpy(info.crypt_msg, buf + 8, MY_AES_BLOCK_SIZE);
memcpy(info.crypt_nonce, buf + 24, MY_AES_BLOCK_SIZE);
- if (!add_crypt_info(&info)) {
+ if (!add_crypt_info(&info, true)) {
return false;
}
buf += LOG_CRYPT_ENTRY_SIZE;
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 2304f4885c2..d574cd55397 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2714,6 +2714,8 @@ recv_scan_log_recs(
/* Garbage or an incompletely written log block */
+ /* Print checkpoint encryption keys if present */
+ log_crypt_print_checkpoint_keys(log_block);
finished = TRUE;
if (maybe_encrypted) {
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index a5970c1dc3f..bde40220db3 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -45,9 +45,6 @@ Created 5/11/1994 Heikki Tuuri
# include <string>
#endif /* UNIV_HOTBACKUP */
-/** A constant to prevent the compiler from optimizing ut_delay() away. */
-UNIV_INTERN ibool ut_always_false = FALSE;
-
#ifdef __WIN__
/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
@@ -397,25 +394,21 @@ Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++.
@return dummy value */
UNIV_INTERN
-ulint
+void
ut_delay(
/*=====*/
ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
{
- ulint i, j;
+ ulint i;
- j = 0;
+ UT_LOW_PRIORITY_CPU();
for (i = 0; i < delay * 50; i++) {
- j += i;
UT_RELAX_CPU();
+ UT_COMPILER_BARRIER();
}
- if (ut_always_false) {
- ut_always_false = (ibool) j;
- }
-
- return(j);
+ UT_RESUME_PRIORITY_CPU();
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h
index e263cabb0d1..5b387924b1e 100644
--- a/storage/tokudb/ha_tokudb.h
+++ b/storage/tokudb/ha_tokudb.h
@@ -602,6 +602,12 @@ public:
// ICP introduced in MariaDB 5.5
Item* idx_cond_push(uint keyno, class Item* idx_cond);
+#ifdef MARIADB_BASE_VERSION
+ void cancel_pushed_idx_cond()
+ {
+ invalidate_icp();
+ }
+#endif
#if TOKU_INCLUDE_ALTER_56
public:
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result
index 2975d7d3116..12fec571d87 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result
@@ -110,7 +110,7 @@ a b c d e
5 1 10 NULL NULL
show status like '%Handler_read_prev%';
Variable_name Value
-Handler_read_prev 41
+Handler_read_prev 800
flush status;
show status like '%Handler_read_prev%';
Variable_name Value
@@ -142,7 +142,7 @@ a b c d e
20 1 10 NULL NULL
show status like '%Handler_read_prev%';
Variable_name Value
-Handler_read_prev 21
+Handler_read_prev 400
flush status;
show status like '%Handler_read_next%';
Variable_name Value
diff --git a/storage/xtradb/dict/dict0boot.cc b/storage/xtradb/dict/dict0boot.cc
index 0a21264e23d..59f210fcab9 100644
--- a/storage/xtradb/dict/dict0boot.cc
+++ b/storage/xtradb/dict/dict0boot.cc
@@ -464,12 +464,22 @@ dict_boot(void)
if (err == DB_SUCCESS) {
if (srv_read_only_mode && !ibuf_is_empty()) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Change buffer must be empty when --innodb-read-only "
- "is set!");
+ if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Change buffer must be empty when --innodb-read-only "
+ "is set!"
+ "You can try to recover the database with innodb_force_recovery=5");
+
+ err = DB_ERROR;
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Change buffer not empty when --innodb-read-only "
+ "is set! but srv_force_recovery = %d, ignoring.",
+ srv_force_recovery);
+ }
+ }
- err = DB_ERROR;
- } else {
+ if (err == DB_SUCCESS) {
/* Load definitions of other indexes on system tables */
dict_load_sys_table(dict_sys->sys_tables);
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index b60a0e9ddaf..2da234ad094 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -739,11 +739,9 @@ fil_node_open_file(
}
}
- if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
+ if (size_bytes >= (1024*1024)) {
/* Truncate the size to whole extent size. */
- size_bytes = ut_2pow_round(size_bytes,
- FSP_EXTENT_SIZE *
- UNIV_PAGE_SIZE);
+ size_bytes = ut_2pow_round(size_bytes, (1024*1024));
}
if (!fsp_flags_is_compressed(flags)) {
@@ -5683,7 +5681,7 @@ fil_space_get_node(
/* Found! */
break;
} else {
- *block_offset -= node->size;
+ (*block_offset) -= node->size;
node = UT_LIST_GET_NEXT(chain, node);
}
}
diff --git a/storage/xtradb/include/log0crypt.h b/storage/xtradb/include/log0crypt.h
index 7e737853465..6b164e90d6e 100644
--- a/storage/xtradb/include/log0crypt.h
+++ b/storage/xtradb/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -117,4 +117,12 @@ log_crypt_print_error(
/*==================*/
log_crypt_err_t err_info); /*!< out: error info */
+/*********************************************************************//**
+Print checkpoint no from log block and all encryption keys from
+checkpoints if they are present. Used for problem analysis. */
+void
+log_crypt_print_checkpoint_keys(
+/*============================*/
+ const byte* log_block);
+
#endif // log0crypt.h
diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h
index 9228c25d8be..980ac337002 100644
--- a/storage/xtradb/include/ut0ut.h
+++ b/storage/xtradb/include/ut0ut.h
@@ -80,20 +80,37 @@ private:
# elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
# define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop")
-# elif defined(HAVE_ATOMIC_BUILTINS)
-# define UT_RELAX_CPU() do { \
- volatile lint volatile_var; \
- os_compare_and_swap_lint(&volatile_var, 0, 1); \
- } while (0)
# elif defined(HAVE_WINDOWS_ATOMICS)
/* In the Win32 API, the x86 PAUSE instruction is executed by calling
the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
independent way by using YieldProcessor. */
# define UT_RELAX_CPU() YieldProcessor()
+# elif defined(__powerpc__)
+#include <sys/platform/ppc.h>
+# define UT_RELAX_CPU() do { \
+ volatile lint volatile_var = __ppc_get_timebase(); \
+ } while (0)
# else
# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
# endif
+#if defined (__GNUC__)
+# define UT_COMPILER_BARRIER() __asm__ __volatile__ ("":::"memory")
+#elif defined (_MSC_VER)
+# define UT_COMPILER_BARRIER() _ReadWriteBarrier()
+#else
+# define UT_COMPILER_BARRIER()
+#endif
+
+# if defined(HAVE_HMT_PRIORITY_INSTRUCTION)
+#include <sys/platform/ppc.h>
+# define UT_LOW_PRIORITY_CPU() __ppc_set_ppr_low()
+# define UT_RESUME_PRIORITY_CPU() __ppc_set_ppr_med()
+# else
+# define UT_LOW_PRIORITY_CPU() ((void)0)
+# define UT_RESUME_PRIORITY_CPU() ((void)0)
+# endif
+
/*********************************************************************//**
Delays execution for at most max_wait_us microseconds or returns earlier
if cond becomes true.
@@ -334,7 +351,7 @@ Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++.
@return dummy value */
UNIV_INTERN
-ulint
+void
ut_delay(
/*=====*/
ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc
index 852148899e9..db2e84d7e45 100644
--- a/storage/xtradb/log/log0crypt.cc
+++ b/storage/xtradb/log/log0crypt.cc
@@ -127,12 +127,35 @@ static
const crypt_info_t*
get_crypt_info(
/*===========*/
- const byte* log_block) {
+ const byte* log_block)
+{
ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block);
return get_crypt_info(checkpoint_no);
}
/*********************************************************************//**
+Print checkpoint no from log block and all encryption keys from
+checkpoints if they are present. Used for problem analysis. */
+void
+log_crypt_print_checkpoint_keys(
+/*============================*/
+ const byte* log_block)
+{
+ ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block);
+
+ if (crypt_info.size()) {
+ fprintf(stderr, "InnoDB: redo log checkpoint: %lu [ chk key ]: ", checkpoint_no);
+ for (size_t i = 0; i < crypt_info.size(); i++) {
+ struct crypt_info_t* it = &crypt_info[i];
+ fprintf(stderr, "[ %lu %u ] ",
+ it->checkpoint_no,
+ it->key_version);
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+/*********************************************************************//**
Call AES CTR to encrypt/decrypt log blocks. */
static
Crypt_result
@@ -278,12 +301,22 @@ Add crypt info to set if it is not already present
@return true if successfull, false if not- */
static
bool
-add_crypt_info(crypt_info_t* info)
+add_crypt_info(
+/*===========*/
+ crypt_info_t* info, /*!< in: crypt info */
+ bool checkpoint_read)/*!< in: do we read checkpoint */
{
+ const crypt_info_t* found=NULL;
/* so that no one is searching array while we modify it */
ut_ad(mutex_own(&(log_sys->mutex)));
- if (get_crypt_info(info->checkpoint_no) != NULL) {
+ found = get_crypt_info(info->checkpoint_no);
+
+ /* If one crypt info is found then we add a new one only if we
+ are reading checkpoint from the log. New checkpoints will always
+ use the first created crypt info. */
+ if (found != NULL &&
+ ( found->checkpoint_no == info->checkpoint_no || !checkpoint_read)) {
// already present...
return true;
}
@@ -356,7 +389,7 @@ log_crypt_set_ver_and_key(
}
- add_crypt_info(&info);
+ add_crypt_info(&info, false);
}
/********************************************************
@@ -514,7 +547,7 @@ log_crypt_read_checkpoint_buf(
memcpy(info.crypt_msg, buf + 8, MY_AES_BLOCK_SIZE);
memcpy(info.crypt_nonce, buf + 24, MY_AES_BLOCK_SIZE);
- if (!add_crypt_info(&info)) {
+ if (!add_crypt_info(&info, true)) {
return false;
}
buf += LOG_CRYPT_ENTRY_SIZE;
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index f98adbbca08..23ca8b1381f 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -2786,6 +2786,8 @@ recv_scan_log_recs(
/* Garbage or an incompletely written log block */
+ /* Print checkpoint encryption keys if present */
+ log_crypt_print_checkpoint_keys(log_block);
finished = TRUE;
if (maybe_encrypted) {
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index b2b3e256211..2bb094e115d 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -1561,7 +1561,7 @@ os_file_set_nocache_if_needed(os_file_t file, const char* name,
}
if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT
- || (type == OS_LOG_FILE
+ || (type == OS_DATA_FILE
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)))) {
os_file_set_nocache(file, name, mode_str);
diff --git a/storage/xtradb/ut/ut0ut.cc b/storage/xtradb/ut/ut0ut.cc
index 4eade1fe26e..acedb56879a 100644
--- a/storage/xtradb/ut/ut0ut.cc
+++ b/storage/xtradb/ut/ut0ut.cc
@@ -46,9 +46,6 @@ Created 5/11/1994 Heikki Tuuri
# include <string>
#endif /* UNIV_HOTBACKUP */
-/** A constant to prevent the compiler from optimizing ut_delay() away. */
-UNIV_INTERN ibool ut_always_false = FALSE;
-
#ifdef __WIN__
/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
@@ -398,25 +395,21 @@ Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++.
@return dummy value */
UNIV_INTERN
-ulint
+void
ut_delay(
/*=====*/
ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
{
- ulint i, j;
+ ulint i;
- j = 0;
+ UT_LOW_PRIORITY_CPU();
for (i = 0; i < delay * 50; i++) {
- j += i;
UT_RELAX_CPU();
+ UT_COMPILER_BARRIER();
}
- if (ut_always_false) {
- ut_always_false = (ibool) j;
- }
-
- return(j);
+ UT_RESUME_PRIORITY_CPU();
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in
index 3425a76427b..978a5c9c90d 100644
--- a/win/packaging/extra.wxs.in
+++ b/win/packaging/extra.wxs.in
@@ -542,17 +542,6 @@
Value="utf8" />
</Component>
- <!--- Grant service account permission to the database folder (Windows 7 and later) -->
- <Component Id="C.serviceaccount.permission" Guid="*" Directory='DATADIR' Transitive='yes'>
- <Condition><![CDATA[SERVICENAME AND (VersionNT > 600)]]></Condition>
- <RegistryValue Root='HKLM'
- Key='SOFTWARE\Monty Program AB\@CPACK_WIX_PACKAGE_NAME@'
- Name='servicepermission' Value='1' Type='string' KeyPath='yes'/>
- <CreateFolder>
- <util:PermissionEx User="NT SERVICE\[SERVICENAME]" GenericAll="yes" />
- </CreateFolder>
- </Component>
-
<!-- Shortcuts in program menu (mysql client etc) -->
<Component Id="c.shortcuts" Guid="*" Directory="ShortcutFolder">
<!-- shortcut to my.ini-->