summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKentoku SHIBA <kentokushiba@gmail.com>2014-11-04 00:07:26 +0900
committerKentoku SHIBA <kentokushiba@gmail.com>2014-11-04 00:07:26 +0900
commitae4497bf5d61f5df45afb8eb28308c95147ab8c4 (patch)
tree47c81a1d7d0c9d17cce66be1784f21dc13b6fb5a
parent323fe245a0e1f8084b0fe23e1b8f2b37a03e67f6 (diff)
parentd1ca1c1faeb1e43df1533a10dfa0ac79433227f9 (diff)
downloadmariadb-git-ae4497bf5d61f5df45afb8eb28308c95147ab8c4.tar.gz
Merge from trunk
-rw-r--r--mysql-test/r/derived_opt.result141
-rw-r--r--mysql-test/r/func_test.result17
-rw-r--r--mysql-test/r/innodb_mrr_cpk.result82
-rw-r--r--mysql-test/r/join_cache.result12
-rw-r--r--mysql-test/r/join_outer.result23
-rw-r--r--mysql-test/r/join_outer_jcl6.result23
-rw-r--r--mysql-test/r/null.result12
-rw-r--r--mysql-test/r/selectivity.result63
-rw-r--r--mysql-test/r/selectivity_innodb.result63
-rw-r--r--mysql-test/suite/innodb/r/innodb_monitor.result585
-rw-r--r--mysql-test/suite/innodb/t/innodb_monitor.test387
-rw-r--r--mysql-test/suite/rpl/include/rpl_innodb_rows_counters.inc50
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_bug68220.result227
-rw-r--r--mysql-test/suite/rpl/t/rpl_innodb_bug68220.test59
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_adaptive_flushing_lwm_basic.result34
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result44
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result4
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_lwm_basic.result44
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_lwm_basic.test2
-rw-r--r--mysql-test/t/derived_opt.test78
-rw-r--r--mysql-test/t/func_test.test14
-rw-r--r--mysql-test/t/innodb_mrr_cpk.test67
-rw-r--r--mysql-test/t/join_outer.test24
-rw-r--r--mysql-test/t/null.test13
-rw-r--r--mysql-test/t/selectivity.test54
-rw-r--r--mysys/mf_fn_ext.c14
-rw-r--r--mysys/my_default.c2
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/item_cmpfunc.h16
-rw-r--r--sql/multi_range_read.cc21
-rw-r--r--sql/multi_range_read.h4
-rw-r--r--sql/opt_range.cc38
-rw-r--r--sql/sql_select.cc62
-rw-r--r--sql/sql_statistics.cc7
-rw-r--r--sql/table.cc13
-rw-r--r--storage/innobase/api/api0api.cc20
-rw-r--r--storage/innobase/btr/btr0cur.cc34
-rw-r--r--storage/innobase/btr/btr0pcur.cc2
-rw-r--r--storage/innobase/buf/buf0buf.cc13
-rw-r--r--storage/innobase/buf/buf0flu.cc127
-rw-r--r--storage/innobase/buf/buf0lru.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc1
-rw-r--r--storage/innobase/dict/dict0mem.cc39
-rw-r--r--storage/innobase/fil/fil0fil.cc173
-rw-r--r--storage/innobase/fts/fts0fts.cc6
-rw-r--r--storage/innobase/fts/fts0que.cc3
-rw-r--r--storage/innobase/handler/ha_innodb.cc53
-rw-r--r--storage/innobase/include/btr0cur.h12
-rw-r--r--storage/innobase/include/buf0buf.h2
-rw-r--r--storage/innobase/include/dict0mem.h12
-rw-r--r--storage/innobase/include/fil0fil.h178
-rw-r--r--storage/innobase/include/mtr0mtr.h16
-rw-r--r--storage/innobase/include/mtr0mtr.ic6
-rw-r--r--storage/innobase/include/srv0mon.h4
-rw-r--r--storage/innobase/include/srv0srv.h24
-rw-r--r--storage/innobase/include/trx0undo.h13
-rw-r--r--storage/innobase/lock/lock0wait.cc4
-rw-r--r--storage/innobase/os/os0sync.cc2
-rw-r--r--storage/innobase/row/row0ext.cc3
-rw-r--r--storage/innobase/row/row0ftsort.cc3
-rw-r--r--storage/innobase/row/row0ins.cc24
-rw-r--r--storage/innobase/row/row0log.cc4
-rw-r--r--storage/innobase/row/row0merge.cc2
-rw-r--r--storage/innobase/row/row0mysql.cc51
-rw-r--r--storage/innobase/row/row0sel.cc19
-rw-r--r--storage/innobase/row/row0umod.cc14
-rw-r--r--storage/innobase/row/row0upd.cc12
-rw-r--r--storage/innobase/srv/srv0mon.cc40
-rw-r--r--storage/innobase/srv/srv0srv.cc50
-rw-r--r--storage/innobase/sync/sync0arr.cc2
-rw-r--r--storage/innobase/trx/trx0i_s.cc2
-rw-r--r--storage/innobase/trx/trx0rec.cc8
-rw-r--r--storage/innobase/trx/trx0undo.cc10
-rw-r--r--storage/xtradb/api/api0api.cc20
-rw-r--r--storage/xtradb/btr/btr0cur.cc34
-rw-r--r--storage/xtradb/btr/btr0pcur.cc2
-rw-r--r--storage/xtradb/buf/buf0buf.cc13
-rw-r--r--storage/xtradb/buf/buf0flu.cc16
-rw-r--r--storage/xtradb/buf/buf0lru.cc4
-rw-r--r--storage/xtradb/dict/dict0dict.cc1
-rw-r--r--storage/xtradb/dict/dict0mem.cc39
-rw-r--r--storage/xtradb/fil/fil0fil.cc168
-rw-r--r--storage/xtradb/fts/fts0fts.cc6
-rw-r--r--storage/xtradb/fts/fts0que.cc3
-rw-r--r--storage/xtradb/handler/ha_innodb.cc45
-rw-r--r--storage/xtradb/include/btr0cur.h12
-rw-r--r--storage/xtradb/include/buf0buf.h2
-rw-r--r--storage/xtradb/include/dict0mem.h12
-rw-r--r--storage/xtradb/include/fil0fil.h179
-rw-r--r--storage/xtradb/include/mtr0mtr.h16
-rw-r--r--storage/xtradb/include/mtr0mtr.ic6
-rw-r--r--storage/xtradb/include/srv0mon.h4
-rw-r--r--storage/xtradb/include/srv0srv.h27
-rw-r--r--storage/xtradb/include/trx0undo.h13
-rw-r--r--storage/xtradb/lock/lock0wait.cc4
-rw-r--r--storage/xtradb/os/os0sync.cc2
-rw-r--r--storage/xtradb/row/row0ext.cc3
-rw-r--r--storage/xtradb/row/row0ftsort.cc3
-rw-r--r--storage/xtradb/row/row0ins.cc24
-rw-r--r--storage/xtradb/row/row0log.cc4
-rw-r--r--storage/xtradb/row/row0merge.cc2
-rw-r--r--storage/xtradb/row/row0mysql.cc50
-rw-r--r--storage/xtradb/row/row0sel.cc17
-rw-r--r--storage/xtradb/row/row0umod.cc14
-rw-r--r--storage/xtradb/row/row0upd.cc12
-rw-r--r--storage/xtradb/srv/srv0mon.cc40
-rw-r--r--storage/xtradb/srv/srv0srv.cc50
-rw-r--r--storage/xtradb/sync/sync0arr.cc2
-rw-r--r--storage/xtradb/trx/trx0i_s.cc2
-rw-r--r--storage/xtradb/trx/trx0rec.cc8
-rw-r--r--storage/xtradb/trx/trx0undo.cc10
117 files changed, 3411 insertions, 907 deletions
diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result
index 7d4c712eee3..a2e08eacebc 100644
--- a/mysql-test/r/derived_opt.result
+++ b/mysql-test/r/derived_opt.result
@@ -1,4 +1,5 @@
-drop table if exists t1,t2,t3;
+drop table if exists t0,t1,t2,t3;
+drop database if exists test1;
set @exit_optimizer_switch=@@optimizer_switch;
set optimizer_switch='derived_merge=on,derived_with_keys=on';
set @save_optimizer_switch=@@optimizer_switch;
@@ -353,30 +354,152 @@ pk pk
80 80
drop table t1, t2, t3, t4;
#
+# MDEV-6888: Query spends a long time in best_extension_by_limited_search with mrr enabled
+#
+create database test1;
+use test1;
+set @tmp_jcl= @@join_cache_level;
+set @tmp_os= @@optimizer_switch;
+set join_cache_level=8;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+CREATE TABLE t0 (
+f1 bigint(20) DEFAULT NULL,
+f2 char(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+INSERT INTO t0 VALUES (NULL,'numeric column is NULL'),(0,NULL),(5,'five'),(1,'one'),(2,'two');
+CREATE TABLE t1 (
+f1 decimal(64,30) DEFAULT NULL,
+f2 varchar(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES
+(NULL,'numeric column is NULL'),
+(0.000000000000000000000000000000,NULL),
+(5.000000000000000000000000000000,'five'),
+(1.000000000000000000000000000000,'one'),
+(3.000000000000000000000000000000,'three');
+CREATE TABLE t2 (
+f1 double DEFAULT NULL,
+f2 varbinary(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (NULL,'numeric column is NULL'),(0,NULL),(5,'five'),(2,'two'),(3,'three');
+create VIEW v0 AS select f1,f2 from t1 ;
+create VIEW v1 AS select tab1_v1.f1,tab1_v1.f2 from t1 tab1_v1 join v0 tab2 on tab1_v1.f1 = tab2.f1 and tab1_v1.f2 = tab2.f2;
+create VIEW v2 AS select tab1_v2.f1,tab1_v2.f2 from t2 tab1_v2 join v1 tab2 on tab1_v2.f1 = tab2.f1 and tab1_v2.f2 = tab2.f2;
+create VIEW v3 AS select tab1_v3.f1,tab1_v3.f2 from t0 tab1_v3 join v2 tab2 on tab1_v3.f1 = tab2.f1 and tab1_v3.f2 = tab2.f2;
+create VIEW v4 AS select tab1_v4.f1,tab1_v4.f2 from t1 tab1_v4 join v3 tab2 on tab1_v4.f1 = tab2.f1 and tab1_v4.f2 = tab2.f2;
+create VIEW v5 AS select tab1_v5.f1,tab1_v5.f2 from t2 tab1_v5 join v4 tab2 on tab1_v5.f1 = tab2.f1 and tab1_v5.f2 = tab2.f2;
+create VIEW v6 AS select tab1_v6.f1,tab1_v6.f2 from t0 tab1_v6 join v5 tab2 on tab1_v6.f1 = tab2.f1 and tab1_v6.f2 = tab2.f2;
+create VIEW v7 AS select tab1_v7.f1,tab1_v7.f2 from t1 tab1_v7 join v6 tab2 on tab1_v7.f1 = tab2.f1 and tab1_v7.f2 = tab2.f2;
+create VIEW v8 AS select tab1_v8.f1,tab1_v8.f2 from t2 tab1_v8 join v7 tab2 on tab1_v8.f1 = tab2.f1 and tab1_v8.f2 = tab2.f2;
+create VIEW v9 AS select tab1_v9.f1,tab1_v9.f2 from t0 tab1_v9 join v8 tab2 on tab1_v9.f1 = tab2.f1 and tab1_v9.f2 = tab2.f2;
+create VIEW v10 AS select tab1_v10.f1,tab1_v10.f2 from t1 tab1_v10 join v9 tab2 on tab1_v10.f1 = tab2.f1 and tab1_v10.f2 = tab2.f2;
+create VIEW v11 AS select tab1_v11.f1,tab1_v11.f2 from t2 tab1_v11 join v10 tab2 on tab1_v11.f1 = tab2.f1 and tab1_v11.f2 = tab2.f2;
+create VIEW v12 AS select tab1_v12.f1,tab1_v12.f2 from t0 tab1_v12 join v11 tab2 on tab1_v12.f1 = tab2.f1 and tab1_v12.f2 = tab2.f2;
+create VIEW v13 AS select tab1_v13.f1,tab1_v13.f2 from t1 tab1_v13 join v12 tab2 on tab1_v13.f1 = tab2.f1 and tab1_v13.f2 = tab2.f2;
+create VIEW v14 AS select tab1_v14.f1,tab1_v14.f2 from t2 tab1_v14 join v13 tab2 on tab1_v14.f1 = tab2.f1 and tab1_v14.f2 = tab2.f2;
+create VIEW v15 AS select tab1_v15.f1,tab1_v15.f2 from t0 tab1_v15 join v14 tab2 on tab1_v15.f1 = tab2.f1 and tab1_v15.f2 = tab2.f2;
+create VIEW v16 AS select tab1_v16.f1,tab1_v16.f2 from t1 tab1_v16 join v15 tab2 on tab1_v16.f1 = tab2.f1 and tab1_v16.f2 = tab2.f2;
+create VIEW v17 AS select tab1_v17.f1,tab1_v17.f2 from t2 tab1_v17 join v16 tab2 on tab1_v17.f1 = tab2.f1 and tab1_v17.f2 = tab2.f2;
+create VIEW v18 AS select tab1_v18.f1,tab1_v18.f2 from t0 tab1_v18 join v17 tab2 on tab1_v18.f1 = tab2.f1 and tab1_v18.f2 = tab2.f2;
+create VIEW v19 AS select tab1_v19.f1,tab1_v19.f2 from t1 tab1_v19 join v18 tab2 on tab1_v19.f1 = tab2.f1 and tab1_v19.f2 = tab2.f2;
+create VIEW v20 AS select tab1_v20.f1,tab1_v20.f2 from t2 tab1_v20 join v19 tab2 on tab1_v20.f1 = tab2.f1 and tab1_v20.f2 = tab2.f2;
+create VIEW v21 AS select tab1_v21.f1,tab1_v21.f2 from t0 tab1_v21 join v20 tab2 on tab1_v21.f1 = tab2.f1 and tab1_v21.f2 = tab2.f2;
+create VIEW v22 AS select tab1_v22.f1,tab1_v22.f2 from t1 tab1_v22 join v21 tab2 on tab1_v22.f1 = tab2.f1 and tab1_v22.f2 = tab2.f2;
+create VIEW v23 AS select tab1_v23.f1,tab1_v23.f2 from t2 tab1_v23 join v22 tab2 on tab1_v23.f1 = tab2.f1 and tab1_v23.f2 = tab2.f2;
+create VIEW v24 AS select tab1_v24.f1,tab1_v24.f2 from t0 tab1_v24 join v23 tab2 on tab1_v24.f1 = tab2.f1 and tab1_v24.f2 = tab2.f2;
+create VIEW v25 AS select tab1_v25.f1,tab1_v25.f2 from t1 tab1_v25 join v24 tab2 on tab1_v25.f1 = tab2.f1 and tab1_v25.f2 = tab2.f2;
+create VIEW v26 AS select tab1_v26.f1,tab1_v26.f2 from t2 tab1_v26 join v25 tab2 on tab1_v26.f1 = tab2.f1 and tab1_v26.f2 = tab2.f2;
+create VIEW v27 AS select tab1_v27.f1,tab1_v27.f2 from t0 tab1_v27 join v26 tab2 on tab1_v27.f1 = tab2.f1 and tab1_v27.f2 = tab2.f2;
+EXPLAIN SELECT CAST(f1 AS SIGNED INTEGER) AS f1, CAST(f2 AS CHAR) AS f2 FROM v27;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE tab1_v27 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE tab1_v26 hash_ALL NULL #hash#$hj 63 test1.tab1_v27.f1,test1.tab1_v27.f2 5 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE tab1_v25 hash_ALL NULL #hash#$hj 31 test1.tab1_v26.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v24 hash_ALL NULL #hash#$hj 60 test1.tab1_v25.f1,test1.tab1_v25.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v23 hash_ALL NULL #hash#$hj 63 test1.tab1_v24.f1,test1.tab1_v24.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v22 hash_ALL NULL #hash#$hj 31 test1.tab1_v23.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v21 hash_ALL NULL #hash#$hj 60 test1.tab1_v22.f1,test1.tab1_v22.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v20 hash_ALL NULL #hash#$hj 63 test1.tab1_v21.f1,test1.tab1_v21.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v19 hash_ALL NULL #hash#$hj 31 test1.tab1_v20.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v18 hash_ALL NULL #hash#$hj 60 test1.tab1_v19.f1,test1.tab1_v19.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v17 hash_ALL NULL #hash#$hj 63 test1.tab1_v18.f1,test1.tab1_v18.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v16 hash_ALL NULL #hash#$hj 31 test1.tab1_v17.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v15 hash_ALL NULL #hash#$hj 60 test1.tab1_v16.f1,test1.tab1_v16.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v14 hash_ALL NULL #hash#$hj 63 test1.tab1_v15.f1,test1.tab1_v15.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v13 hash_ALL NULL #hash#$hj 31 test1.tab1_v14.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v12 hash_ALL NULL #hash#$hj 60 test1.tab1_v13.f1,test1.tab1_v13.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v11 hash_ALL NULL #hash#$hj 63 test1.tab1_v12.f1,test1.tab1_v12.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v10 hash_ALL NULL #hash#$hj 31 test1.tab1_v11.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v9 hash_ALL NULL #hash#$hj 60 test1.tab1_v10.f1,test1.tab1_v10.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v8 hash_ALL NULL #hash#$hj 63 test1.tab1_v9.f1,test1.tab1_v9.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v7 hash_ALL NULL #hash#$hj 31 test1.tab1_v8.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v6 hash_ALL NULL #hash#$hj 60 test1.tab1_v7.f1,test1.tab1_v7.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v5 hash_ALL NULL #hash#$hj 63 test1.tab1_v6.f1,test1.tab1_v6.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v4 hash_ALL NULL #hash#$hj 31 test1.tab1_v5.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v3 hash_ALL NULL #hash#$hj 60 test1.tab1_v4.f1,test1.tab1_v4.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v2 hash_ALL NULL #hash#$hj 63 test1.tab1_v3.f1,test1.tab1_v3.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v1 hash_ALL NULL #hash#$hj 31 test1.tab1_v2.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t1 hash_ALL NULL #hash#$hj 85 test1.tab1_v1.f1,test1.tab1_v1.f2 5 Using where; Using join buffer (incremental, BNLH join)
+# This used to hang forever:
+EXPLAIN SELECT CAST(f1 AS SIGNED INTEGER) AS f1, CAST(f2 AS CHAR) AS f2 FROM v27;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE tab1_v27 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE tab1_v26 hash_ALL NULL #hash#$hj 63 test1.tab1_v27.f1,test1.tab1_v27.f2 5 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE tab1_v25 hash_ALL NULL #hash#$hj 31 test1.tab1_v26.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v24 hash_ALL NULL #hash#$hj 60 test1.tab1_v25.f1,test1.tab1_v25.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v23 hash_ALL NULL #hash#$hj 63 test1.tab1_v24.f1,test1.tab1_v24.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v22 hash_ALL NULL #hash#$hj 31 test1.tab1_v23.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v21 hash_ALL NULL #hash#$hj 60 test1.tab1_v22.f1,test1.tab1_v22.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v20 hash_ALL NULL #hash#$hj 63 test1.tab1_v21.f1,test1.tab1_v21.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v19 hash_ALL NULL #hash#$hj 31 test1.tab1_v20.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v18 hash_ALL NULL #hash#$hj 60 test1.tab1_v19.f1,test1.tab1_v19.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v17 hash_ALL NULL #hash#$hj 63 test1.tab1_v18.f1,test1.tab1_v18.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v16 hash_ALL NULL #hash#$hj 31 test1.tab1_v17.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v15 hash_ALL NULL #hash#$hj 60 test1.tab1_v16.f1,test1.tab1_v16.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v14 hash_ALL NULL #hash#$hj 63 test1.tab1_v15.f1,test1.tab1_v15.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v13 hash_ALL NULL #hash#$hj 31 test1.tab1_v14.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v12 hash_ALL NULL #hash#$hj 60 test1.tab1_v13.f1,test1.tab1_v13.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v11 hash_ALL NULL #hash#$hj 63 test1.tab1_v12.f1,test1.tab1_v12.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v10 hash_ALL NULL #hash#$hj 31 test1.tab1_v11.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v9 hash_ALL NULL #hash#$hj 60 test1.tab1_v10.f1,test1.tab1_v10.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v8 hash_ALL NULL #hash#$hj 63 test1.tab1_v9.f1,test1.tab1_v9.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v7 hash_ALL NULL #hash#$hj 31 test1.tab1_v8.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v6 hash_ALL NULL #hash#$hj 60 test1.tab1_v7.f1,test1.tab1_v7.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v5 hash_ALL NULL #hash#$hj 63 test1.tab1_v6.f1,test1.tab1_v6.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v4 hash_ALL NULL #hash#$hj 31 test1.tab1_v5.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v3 hash_ALL NULL #hash#$hj 60 test1.tab1_v4.f1,test1.tab1_v4.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v2 hash_ALL NULL #hash#$hj 63 test1.tab1_v3.f1,test1.tab1_v3.f2 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE tab1_v1 hash_ALL NULL #hash#$hj 31 test1.tab1_v2.f1 5 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t1 hash_ALL NULL #hash#$hj 85 test1.tab1_v1.f1,test1.tab1_v1.f2 5 Using where; Using join buffer (incremental, BNLH join)
+use test;
+drop database test1;
+set join_cache_level=@tmp_jcl;
+set optimizer_switch=@tmp_os;
+#
# MDEV-6879: Dereference of NULL primary_file->table in DsMrr_impl::get_disk_sweep_mrr_cost()
#
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, b int, c text);
-insert into t2
-select
+insert into t2
+select
A.a + B.a* 10,
A.a + B.a* 10,
-'blob-data'
+'blob-data'
from t1 A, t1 B;
set @tmp_jcl= @@join_cache_level;
set @tmp_os= @@optimizer_switch;
set join_cache_level=6;
set @@optimizer_switch='derived_merge=on,derived_with_keys=on,mrr=on';
-explain
-select * from
+explain
+select * from
t1 join
-(select * from t2 order by a limit 1000) as D1
-where
+(select * from t2 order by a limit 1000) as D1
+where
D1.a= t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
-1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 10
+1 PRIMARY <derived2> hash_ALL key0 #hash#key0 5 test.t1.a 100 Using join buffer (flat, BNLH join)
2 DERIVED t2 ALL NULL NULL NULL NULL 100 Using filesort
set join_cache_level=@tmp_jcl;
set optimizer_switch=@tmp_os;
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 2c1c416472f..97ef61047a5 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -320,3 +320,20 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not((`test`.`t1`.`a` + 0)))
drop table t1;
+#
+# Start of 10.0 tests
+#
+#
+# MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3)
+#
+SELECT NOT NOT strcmp('a','b');
+NOT NOT strcmp('a','b')
+1
+EXPLAIN EXTENDED SELECT NOT NOT strcmp('a','b');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select (strcmp('a','b') <> 0) AS `NOT NOT strcmp('a','b')`
+#
+# End of 10.0 tests
+#
diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result
index d63a9977169..99ed73a3e83 100644
--- a/mysql-test/r/innodb_mrr_cpk.result
+++ b/mysql-test/r/innodb_mrr_cpk.result
@@ -145,11 +145,47 @@ select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100;
a b c filler a b
set optimizer_switch='index_condition_pushdown=on';
drop table t1,t2;
-set @@join_cache_level= @save_join_cache_level;
-set storage_engine=@save_storage_engine;
-set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0;
#
+# MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+pk varchar(32) character set utf8 primary key,
+kp1 char(32) not null,
+col1 varchar(32),
+key (kp1)
+) engine=innodb;
+insert into t1
+select
+concat('pk-', 1000 +A.a),
+concat('kp1-', 1000 +A.a),
+concat('val-', 1000 +A.a)
+from test.t0 A ;
+create table t2 as select kp1 as a from t1;
+set join_cache_level=8;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+explain
+select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10
+1 SIMPLE t1 ref kp1 kp1 32 test.t2.a 1 Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
+a pk kp1 col1
+kp1-1000 pk-1000 kp1-1000 val-1000
+kp1-1001 pk-1001 kp1-1001 val-1001
+kp1-1002 pk-1002 kp1-1002 val-1002
+kp1-1003 pk-1003 kp1-1003 val-1003
+kp1-1004 pk-1004 kp1-1004 val-1004
+kp1-1005 pk-1005 kp1-1005 val-1005
+kp1-1006 pk-1006 kp1-1006 val-1006
+kp1-1007 pk-1007 kp1-1007 val-1007
+kp1-1008 pk-1008 kp1-1008 val-1008
+kp1-1009 pk-1009 kp1-1009 val-1009
+drop table t0,t1,t2;
+#
+#
# MDEV-3817: Wrong result with index_merge+index_merge_intersection, InnoDB table, join, AND and OR conditions
#
set @tmp_mdev3817=@@optimizer_switch;
@@ -195,40 +231,8 @@ id select_type table type possible_keys key key_len ref rows Extra
set join_cache_level= @tmp_mdev5037;
drop table t0,t1,t2;
#
-# MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
+# This must be at the end:
#
-create table t0(a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1 (
-pk varchar(32) character set utf8 primary key,
-kp1 char(32) not null,
-col1 varchar(32),
-key (kp1)
-) engine=innodb;
-insert into t1
-select
-concat('pk-', 1000 +A.a),
-concat('kp1-', 1000 +A.a),
-concat('val-', 1000 +A.a)
-from test.t0 A ;
-create table t2 as select kp1 as a from t1;
-set join_cache_level=8;
-set optimizer_switch='mrr=on,mrr_sort_keys=on';
-explain
-select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10
-1 SIMPLE t1 ref kp1 kp1 32 test.t2.a 1 Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
-select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
-a pk kp1 col1
-kp1-1000 pk-1000 kp1-1000 val-1000
-kp1-1001 pk-1001 kp1-1001 val-1001
-kp1-1002 pk-1002 kp1-1002 val-1002
-kp1-1003 pk-1003 kp1-1003 val-1003
-kp1-1004 pk-1004 kp1-1004 val-1004
-kp1-1005 pk-1005 kp1-1005 val-1005
-kp1-1006 pk-1006 kp1-1006 val-1006
-kp1-1007 pk-1007 kp1-1007 val-1007
-kp1-1008 pk-1008 kp1-1008 val-1008
-kp1-1009 pk-1009 kp1-1009 val-1009
-drop table t0,t1,t2;
+set @@join_cache_level= @save_join_cache_level;
+set storage_engine=@save_storage_engine;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index 253fb61dc27..456e17a91f7 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -498,8 +498,8 @@ CountryLanguage.Percentage > 50 AND
LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
-1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -576,8 +576,8 @@ CountryLanguage.Percentage > 50 AND
LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
-1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -654,8 +654,8 @@ CountryLanguage.Percentage > 50 AND
LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
-1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -732,8 +732,8 @@ CountryLanguage.Percentage > 50 AND
LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
-1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (incremental, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index e303c288552..40abc197a36 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2222,4 +2222,27 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
DROP TABLE t1,t2,t3;
+#
+# Bug mdev-6705: wrong on expression after constant row substitution
+# that triggers a simplification of WHERE condition
+#
+CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,8);
+CREATE TABLE t2 (c int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8),(9);
+CREATE TABLE t3 (d int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3),(8);
+EXPLAIN EXTENDED
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+WHERE b IN (1,2,3) OR b = d;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`d` = 10)) where ((`test`.`t2`.`c` = 8) and (`test`.`t3`.`d` = 8))
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+WHERE b IN (1,2,3) OR b = d;
+a b c d
+DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index beea0daa1fa..81395612269 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2233,6 +2233,29 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
DROP TABLE t1,t2,t3;
+#
+# Bug mdev-6705: wrong on expression after constant row substitution
+# that triggers a simplification of WHERE condition
+#
+CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,8);
+CREATE TABLE t2 (c int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8),(9);
+CREATE TABLE t3 (d int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3),(8);
+EXPLAIN EXTENDED
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+WHERE b IN (1,2,3) OR b = d;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`d` = 10)) where ((`test`.`t2`.`c` = 8) and (`test`.`t3`.`d` = 8))
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+WHERE b IN (1,2,3) OR b = d;
+a b c d
+DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
show variables like 'join_cache_level';
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index ce233e0db23..b5219333ef1 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -382,3 +382,15 @@ CREATE TABLE t2 (d DATE) ENGINE=MyISAM;
SELECT * FROM t1,t2 WHERE 1 IS NOT NULL AND t1.b IS NULL;
a b c d
DROP TABLE t1,t2;
+#
+# Start of 10.0 tests
+#
+#
+# MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3)
+#
+SELECT NOT NOT NULLIF(2,3);
+NOT NOT NULLIF(2,3)
+1
+#
+# End of 10.0 tests
+#
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index 9899b894ff6..d2383f24f2d 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -1346,4 +1346,67 @@ foo foo 1
foo foo 2
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
+#
+# Bug mdev-6325: wrong selectivity of a column with ref access
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, key(a));
+insert into t2 select A.a + 10*B.a, 12345 from t0 A, t0 B, t0 C;
+set use_stat_tables='preferably';
+set histogram_size=100;
+set optimizer_use_condition_selectivity=4;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+analyze table t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status Table is already up to date
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t1.a<10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 0.99 Using where
+1 SIMPLE t2 ref a a 5 test.t1.a 10 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 10))
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t2.a<10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 0.99 Using where
+1 SIMPLE t2 ref a a 5 test.t1.a 10 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 10))
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+drop table t0,t1,t2;
+#
+# Bug mdev-6843: col IS NULL in where condition when col is always NULL
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int);
+insert into t2 select NULL, a from t1;
+set use_stat_tables='preferably';
+set histogram_size=100;
+set optimizer_use_condition_selectivity=4;
+analyze table t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+explain extended
+select * from t2 A straight_join t2 B where A.a is null;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE A ALL NULL NULL NULL NULL 1000 100.00 Using where
+1 SIMPLE B ALL NULL NULL NULL NULL 1000 100.00 Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`A`.`a` AS `a`,`test`.`A`.`b` AS `b`,`test`.`B`.`a` AS `a`,`test`.`B`.`b` AS `b` from `test`.`t2` `A` straight_join `test`.`t2` `B` where isnull(`test`.`A`.`a`)
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+drop table t0,t1,t2;
set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index 013fb1d876c..c4c398a9ff6 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -1356,6 +1356,69 @@ foo foo 1
foo foo 2
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
+#
+# Bug mdev-6325: wrong selectivity of a column with ref access
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, key(a));
+insert into t2 select A.a + 10*B.a, 12345 from t0 A, t0 B, t0 C;
+set use_stat_tables='preferably';
+set histogram_size=100;
+set optimizer_use_condition_selectivity=4;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+analyze table t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t1.a<10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 0.99 Using where
+1 SIMPLE t2 ref a a 5 test.t1.a 10 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 10))
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t2.a<10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 0.99 Using where
+1 SIMPLE t2 ref a a 5 test.t1.a 10 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 10))
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+drop table t0,t1,t2;
+#
+# Bug mdev-6843: col IS NULL in where condition when col is always NULL
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int);
+insert into t2 select NULL, a from t1;
+set use_stat_tables='preferably';
+set histogram_size=100;
+set optimizer_use_condition_selectivity=4;
+analyze table t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+explain extended
+select * from t2 A straight_join t2 B where A.a is null;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE A ALL NULL NULL NULL NULL 1000 100.00 Using where
+1 SIMPLE B ALL NULL NULL NULL NULL 1000 100.00 Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`A`.`a` AS `a`,`test`.`A`.`b` AS `b`,`test`.`B`.`a` AS `a`,`test`.`B`.`b` AS `b` from `test`.`t2` `A` straight_join `test`.`t2` `B` where isnull(`test`.`A`.`a`)
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+drop table t0,t1,t2;
set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
set @tmp_ust= @@use_stat_tables;
diff --git a/mysql-test/suite/innodb/r/innodb_monitor.result b/mysql-test/suite/innodb/r/innodb_monitor.result
new file mode 100644
index 00000000000..f8d24f4e6f5
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_monitor.result
@@ -0,0 +1,585 @@
+set global innodb_monitor_disable = All;
+select name, status from information_schema.innodb_metrics;
+name status
+metadata_table_handles_opened disabled
+metadata_table_handles_closed disabled
+metadata_table_reference_count disabled
+metadata_mem_pool_size disabled
+lock_deadlocks disabled
+lock_timeouts disabled
+lock_rec_lock_waits disabled
+lock_table_lock_waits disabled
+lock_rec_lock_requests disabled
+lock_rec_lock_created disabled
+lock_rec_lock_removed disabled
+lock_rec_locks disabled
+lock_table_lock_created disabled
+lock_table_lock_removed disabled
+lock_table_locks disabled
+lock_row_lock_current_waits disabled
+lock_row_lock_time disabled
+lock_row_lock_time_max disabled
+lock_row_lock_waits disabled
+lock_row_lock_time_avg disabled
+buffer_pool_size disabled
+buffer_pool_reads disabled
+buffer_pool_read_requests disabled
+buffer_pool_write_requests disabled
+buffer_pool_wait_free disabled
+buffer_pool_read_ahead disabled
+buffer_pool_read_ahead_evicted disabled
+buffer_pool_pages_total disabled
+buffer_pool_pages_misc disabled
+buffer_pool_pages_data disabled
+buffer_pool_bytes_data disabled
+buffer_pool_pages_dirty disabled
+buffer_pool_bytes_dirty disabled
+buffer_pool_pages_free disabled
+buffer_pages_created disabled
+buffer_pages_written disabled
+buffer_pages_read disabled
+buffer_data_reads disabled
+buffer_data_written disabled
+buffer_flush_batch_scanned disabled
+buffer_flush_batch_num_scan disabled
+buffer_flush_batch_scanned_per_call disabled
+buffer_flush_batch_rescan disabled
+buffer_flush_batch_total_pages disabled
+buffer_flush_batches disabled
+buffer_flush_batch_pages disabled
+buffer_flush_neighbor_total_pages disabled
+buffer_flush_neighbor disabled
+buffer_flush_neighbor_pages disabled
+buffer_flush_n_to_flush_requested disabled
+buffer_flush_avg_page_rate disabled
+buffer_flush_lsn_avg_rate disabled
+buffer_flush_pct_for_dirty disabled
+buffer_flush_pct_for_lsn disabled
+buffer_flush_sync_waits disabled
+buffer_flush_adaptive_total_pages disabled
+buffer_flush_adaptive disabled
+buffer_flush_adaptive_pages disabled
+buffer_flush_sync_total_pages disabled
+buffer_flush_sync disabled
+buffer_flush_sync_pages disabled
+buffer_flush_background_total_pages disabled
+buffer_flush_background disabled
+buffer_flush_background_pages disabled
+buffer_LRU_batch_scanned disabled
+buffer_LRU_batch_num_scan disabled
+buffer_LRU_batch_scanned_per_call disabled
+buffer_LRU_batch_total_pages disabled
+buffer_LRU_batches disabled
+buffer_LRU_batch_pages disabled
+buffer_LRU_single_flush_scanned disabled
+buffer_LRU_single_flush_num_scan disabled
+buffer_LRU_single_flush_scanned_per_call disabled
+buffer_LRU_single_flush_failure_count disabled
+buffer_LRU_get_free_search disabled
+buffer_LRU_search_scanned disabled
+buffer_LRU_search_num_scan disabled
+buffer_LRU_search_scanned_per_call disabled
+buffer_LRU_unzip_search_scanned disabled
+buffer_LRU_unzip_search_num_scan disabled
+buffer_LRU_unzip_search_scanned_per_call disabled
+buffer_page_read_index_leaf disabled
+buffer_page_read_index_non_leaf disabled
+buffer_page_read_index_ibuf_leaf disabled
+buffer_page_read_index_ibuf_non_leaf disabled
+buffer_page_read_undo_log disabled
+buffer_page_read_index_inode disabled
+buffer_page_read_ibuf_free_list disabled
+buffer_page_read_ibuf_bitmap disabled
+buffer_page_read_system_page disabled
+buffer_page_read_trx_system disabled
+buffer_page_read_fsp_hdr disabled
+buffer_page_read_xdes disabled
+buffer_page_read_blob disabled
+buffer_page_read_zblob disabled
+buffer_page_read_zblob2 disabled
+buffer_page_read_other disabled
+buffer_page_written_index_leaf disabled
+buffer_page_written_index_non_leaf disabled
+buffer_page_written_index_ibuf_leaf disabled
+buffer_page_written_index_ibuf_non_leaf disabled
+buffer_page_written_undo_log disabled
+buffer_page_written_index_inode disabled
+buffer_page_written_ibuf_free_list disabled
+buffer_page_written_ibuf_bitmap disabled
+buffer_page_written_system_page disabled
+buffer_page_written_trx_system disabled
+buffer_page_written_fsp_hdr disabled
+buffer_page_written_xdes disabled
+buffer_page_written_blob disabled
+buffer_page_written_zblob disabled
+buffer_page_written_zblob2 disabled
+buffer_page_written_other disabled
+os_data_reads disabled
+os_data_writes disabled
+os_data_fsyncs disabled
+os_pending_reads disabled
+os_pending_writes disabled
+os_log_bytes_written disabled
+os_log_fsyncs disabled
+os_log_pending_fsyncs disabled
+os_log_pending_writes disabled
+trx_rw_commits disabled
+trx_ro_commits disabled
+trx_nl_ro_commits disabled
+trx_commits_insert_update disabled
+trx_rollbacks disabled
+trx_rollbacks_savepoint disabled
+trx_rollback_active disabled
+trx_active_transactions disabled
+trx_rseg_history_len disabled
+trx_undo_slots_used disabled
+trx_undo_slots_cached disabled
+trx_rseg_current_size disabled
+purge_del_mark_records disabled
+purge_upd_exist_or_extern_records disabled
+purge_invoked disabled
+purge_undo_log_pages disabled
+purge_dml_delay_usec disabled
+purge_stop_count disabled
+purge_resume_count disabled
+log_checkpoints disabled
+log_lsn_last_flush disabled
+log_lsn_last_checkpoint disabled
+log_lsn_current disabled
+log_lsn_checkpoint_age disabled
+log_lsn_buf_pool_oldest disabled
+log_max_modified_age_async disabled
+log_max_modified_age_sync disabled
+log_pending_log_writes disabled
+log_pending_checkpoint_writes disabled
+log_num_log_io disabled
+log_waits disabled
+log_write_requests disabled
+log_writes disabled
+compress_pages_compressed disabled
+compress_pages_decompressed disabled
+compression_pad_increments disabled
+compression_pad_decrements disabled
+index_page_splits disabled
+index_page_merge_attempts disabled
+index_page_merge_successful disabled
+index_page_reorg_attempts disabled
+index_page_reorg_successful disabled
+index_page_discards disabled
+adaptive_hash_searches disabled
+adaptive_hash_searches_btree disabled
+adaptive_hash_pages_added disabled
+adaptive_hash_pages_removed disabled
+adaptive_hash_rows_added disabled
+adaptive_hash_rows_removed disabled
+adaptive_hash_rows_deleted_no_hash_entry disabled
+adaptive_hash_rows_updated disabled
+file_num_open_files disabled
+ibuf_merges_insert disabled
+ibuf_merges_delete_mark disabled
+ibuf_merges_delete disabled
+ibuf_merges_discard_insert disabled
+ibuf_merges_discard_delete_mark disabled
+ibuf_merges_discard_delete disabled
+ibuf_merges disabled
+ibuf_size disabled
+innodb_master_thread_sleeps disabled
+innodb_activity_count disabled
+innodb_master_active_loops disabled
+innodb_master_idle_loops disabled
+innodb_background_drop_table_usec disabled
+innodb_ibuf_merge_usec disabled
+innodb_log_flush_usec disabled
+innodb_mem_validate_usec disabled
+innodb_master_purge_usec disabled
+innodb_dict_lru_usec disabled
+innodb_checkpoint_usec disabled
+innodb_dblwr_writes disabled
+innodb_dblwr_pages_written disabled
+innodb_page_size disabled
+innodb_rwlock_s_spin_waits disabled
+innodb_rwlock_x_spin_waits disabled
+innodb_rwlock_s_spin_rounds disabled
+innodb_rwlock_x_spin_rounds disabled
+innodb_rwlock_s_os_waits disabled
+innodb_rwlock_x_os_waits disabled
+dml_reads disabled
+dml_inserts disabled
+dml_deletes disabled
+dml_updates disabled
+dml_system_reads disabled
+dml_system_inserts disabled
+dml_system_deletes disabled
+dml_system_updates disabled
+ddl_background_drop_indexes disabled
+ddl_background_drop_tables disabled
+ddl_online_create_index disabled
+ddl_pending_alter_table disabled
+icp_attempts disabled
+icp_no_match disabled
+icp_out_of_range disabled
+icp_match disabled
+set global innodb_monitor_enable = all;
+select name from information_schema.innodb_metrics where status!='enabled';
+name
+set global innodb_monitor_enable = aaa;
+ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of 'aaa'
+set global innodb_monitor_disable = All;
+select name from information_schema.innodb_metrics where status!='disabled';
+name
+set global innodb_monitor_reset_all = all;
+select name from information_schema.innodb_metrics where count!=0;
+name
+set global innodb_monitor_enable = "%lock%";
+select name from information_schema.innodb_metrics
+where status != IF(name like "%lock%", 'enabled', 'disabled');
+name
+set global innodb_monitor_disable = "%lock%";
+select name, status from information_schema.innodb_metrics
+where name like "%lock%";
+name status
+lock_deadlocks disabled
+lock_timeouts disabled
+lock_rec_lock_waits disabled
+lock_table_lock_waits disabled
+lock_rec_lock_requests disabled
+lock_rec_lock_created disabled
+lock_rec_lock_removed disabled
+lock_rec_locks disabled
+lock_table_lock_created disabled
+lock_table_lock_removed disabled
+lock_table_locks disabled
+lock_row_lock_current_waits disabled
+lock_row_lock_time disabled
+lock_row_lock_time_max disabled
+lock_row_lock_waits disabled
+lock_row_lock_time_avg disabled
+innodb_rwlock_s_spin_waits disabled
+innodb_rwlock_x_spin_waits disabled
+innodb_rwlock_s_spin_rounds disabled
+innodb_rwlock_x_spin_rounds disabled
+innodb_rwlock_s_os_waits disabled
+innodb_rwlock_x_os_waits disabled
+set global innodb_monitor_enable = "%lock*";
+ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '%lock*'
+set global innodb_monitor_enable="%%%%%%%%%%%%%%%%%%%%%%%%%%%";
+select name from information_schema.innodb_metrics where status!='enabled';
+name
+set global innodb_monitor_disable="%%%%%";
+select name from information_schema.innodb_metrics where status!='disabled';
+name
+set global innodb_monitor_enable="%";
+select name from information_schema.innodb_metrics where status!='enabled';
+name
+set global innodb_monitor_disable="%_%";
+select name from information_schema.innodb_metrics where status!='disabled';
+name
+set global innodb_monitor_enable="log%%%%";
+select name from information_schema.innodb_metrics
+where status != IF(name like "log%", 'enabled', 'disabled');
+name
+set global innodb_monitor_enable="os_%a_fs_ncs";
+set global innodb_monitor_enable="os%pending%";
+select name, status from information_schema.innodb_metrics
+where name like "os%";
+name status
+os_data_reads disabled
+os_data_writes disabled
+os_data_fsyncs enabled
+os_pending_reads enabled
+os_pending_writes enabled
+os_log_bytes_written disabled
+os_log_fsyncs disabled
+os_log_pending_fsyncs enabled
+os_log_pending_writes enabled
+set global innodb_monitor_enable="";
+ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of ''
+set global innodb_monitor_enable="_";
+ERROR 42000: Variable 'innodb_monitor_enable' can't be set to the value of '_'
+set global innodb_monitor_disable = module_metadata;
+set global innodb_monitor_reset_all = module_metadata;
+set global innodb_monitor_enable = metadata_table_handles_opened;
+create table monitor_test(col int) engine = innodb;
+select * from monitor_test;
+col
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 1 NULL 1 1 NULL 1 enabled
+set global innodb_monitor_reset = metadata_table_handles_opened;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 1 NULL 1 NULL NULL 0 enabled
+drop table monitor_test;
+create table monitor_test(col int) engine = innodb;
+select * from monitor_test;
+col
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 1 NULL 1 enabled
+set global innodb_monitor_reset_all = metadata_table_handles_opened;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 1 NULL 1 enabled
+set global innodb_monitor_disable = metadata_table_handles_opened;
+set global innodb_monitor_reset = metadata_table_handles_opened;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 NULL NULL 0 disabled
+drop table monitor_test;
+create table monitor_test(col int) engine = innodb;
+select * from monitor_test;
+col
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 NULL NULL 0 disabled
+set global innodb_monitor_reset_all = metadata_table_handles_opened;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_enable = metadata_table_handles_opened;
+drop table monitor_test;
+create table monitor_test(col int) engine = innodb stats_persistent=0;
+select * from monitor_test;
+col
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 1 NULL 1 1 NULL 1 enabled
+set global innodb_monitor_enable = metadata_table_handles_closed;
+create index idx on monitor_test(col);
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_closed";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_closed 1 NULL 1 1 NULL 1 enabled
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 2 NULL 2 enabled
+metadata_table_handles_closed 1 NULL 1 1 NULL 1 enabled
+metadata_table_reference_count NULL NULL 0 NULL NULL 0 disabled
+metadata_mem_pool_size NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_disable = module_metadata;
+set global innodb_monitor_reset = module_metadata;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened 2 NULL 2 NULL NULL 0 disabled
+metadata_table_handles_closed 1 NULL 1 NULL NULL 0 disabled
+metadata_table_reference_count NULL NULL 0 NULL NULL 0 disabled
+metadata_mem_pool_size NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_reset_all = module_metadata;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+metadata_table_handles_opened NULL NULL 0 NULL NULL 0 disabled
+metadata_table_handles_closed NULL NULL 0 NULL NULL 0 disabled
+metadata_table_reference_count NULL NULL 0 NULL NULL 0 disabled
+metadata_mem_pool_size NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_enable = module_trx;
+begin;
+insert into monitor_test values(9);
+commit;
+begin;
+insert into monitor_test values(9);
+rollback;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "trx_rollbacks" or name like "trx_active_transactions";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+trx_rollbacks 1 NULL 1 1 NULL 1 enabled
+trx_active_transactions 1 0 0 1 0 0 enabled
+set global innodb_monitor_disable = module_trx;
+set global innodb_monitor_enable = module_dml;
+insert into monitor_test values(9);
+update monitor_test set col = 10 where col = 9;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 4 NULL 4 4 NULL 4 enabled
+dml_inserts 1 NULL 1 1 NULL 1 enabled
+dml_deletes 0 NULL 0 0 NULL 0 enabled
+dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
+delete from monitor_test;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 6 NULL 6 6 NULL 6 enabled
+dml_inserts 1 NULL 1 1 NULL 1 enabled
+dml_deletes 2 NULL 2 2 NULL 2 enabled
+dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
+set global innodb_monitor_reset = module_dml;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 6 NULL 6 0 NULL 0 enabled
+dml_inserts 1 NULL 1 0 NULL 0 enabled
+dml_deletes 2 NULL 2 0 NULL 0 enabled
+dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
+insert into monitor_test values(9);
+insert into monitor_test values(1);
+delete from monitor_test;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 8 NULL 8 2 NULL 2 enabled
+dml_inserts 3 NULL 3 2 NULL 2 enabled
+dml_deletes 4 NULL 4 2 NULL 2 enabled
+dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
+set global innodb_monitor_reset_all = module_dml;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 8 NULL 8 2 NULL 2 enabled
+dml_inserts 3 NULL 3 2 NULL 2 enabled
+dml_deletes 4 NULL 4 2 NULL 2 enabled
+dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
+set global innodb_monitor_disable = module_dml;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads 8 NULL 8 2 NULL 2 disabled
+dml_inserts 3 NULL 3 2 NULL 2 disabled
+dml_deletes 4 NULL 4 2 NULL 2 disabled
+dml_updates 2 NULL 2 0 NULL 0 disabled
+dml_system_reads 0 NULL 0 0 NULL 0 disabled
+dml_system_inserts 0 NULL 0 0 NULL 0 disabled
+dml_system_deletes 0 NULL 0 0 NULL 0 disabled
+dml_system_updates 0 NULL 0 0 NULL 0 disabled
+set global innodb_monitor_reset_all = module_dml;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads NULL NULL 0 NULL NULL 0 disabled
+dml_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_enable = dml_inserts;
+insert into monitor_test values(9);
+insert into monitor_test values(1);
+delete from monitor_test;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+dml_reads NULL NULL 0 NULL NULL 0 disabled
+dml_inserts 2 NULL 2 2 NULL 2 enabled
+dml_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
+set global innodb_monitor_disable = module_dml;
+drop table monitor_test;
+set global innodb_monitor_enable = file_num_open_files;
+select name, max_count, min_count, count,
+max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "file_num_open_files";
+name max_count min_count count max_count_reset min_count_reset count_reset status
+file_num_open_files # # # # # # enabled
+set global innodb_monitor_disable = file_num_open_files;
+set global innodb_monitor_enable = "icp%";
+create table monitor_test(a char(3), b int, c char(2),
+primary key (a(1), c(1)), key(b)) engine = innodb;
+insert into monitor_test values("13", 2, "aa");
+select a from monitor_test where b < 1 for update;
+a
+select name, count from information_schema.innodb_metrics
+where name like "icp%";
+name count
+icp_attempts 1
+icp_no_match 0
+icp_out_of_range 1
+icp_match 0
+select a from monitor_test where b < 3 for update;
+a
+13
+select name, count from information_schema.innodb_metrics
+where name like "icp%";
+name count
+icp_attempts 2
+icp_no_match 0
+icp_out_of_range 1
+icp_match 1
+drop table monitor_test;
+set global innodb_monitor_disable = all;
+set global innodb_monitor_reset_all = all;
+select 1 from `information_schema`.`INNODB_METRICS`
+where case (1) when (1) then (AVG_COUNT_RESET) else (1) end;
+1
+set global innodb_monitor_enable = default;
+set global innodb_monitor_disable = default;
+set global innodb_monitor_reset = default;
+set global innodb_monitor_reset_all = default;
diff --git a/mysql-test/suite/innodb/t/innodb_monitor.test b/mysql-test/suite/innodb/t/innodb_monitor.test
new file mode 100644
index 00000000000..864e0cae862
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_monitor.test
@@ -0,0 +1,387 @@
+# This is the test for Metrics Monitor Table feature.
+# Test the metrics monitor system's control system
+# and counter accuracy.
+
+--source include/have_innodb.inc
+
+set global innodb_monitor_disable = All;
+
+# Test turn on/off the monitor counter with "all" option
+# By default, they will be off
+select name, status from information_schema.innodb_metrics;
+
+# Turn on all monitor counters
+set global innodb_monitor_enable = all;
+
+# status should all change to "enabled"
+select name from information_schema.innodb_metrics where status!='enabled';
+
+# Test wrong argument to the global configure option
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_monitor_enable = aaa;
+
+# We require a valid monitor counter/module name. There is no default
+# counter name or module. A warning will be printed asking user to
+# specify a valid counter name.
+#--disable_warnings
+#set global innodb_monitor_enable = default;
+#--enable_warnings
+
+# Turn off all monitor counters, option name should be case
+# insensitive
+set global innodb_monitor_disable = All;
+
+# status should all change to "disabled"
+select name from information_schema.innodb_metrics where status!='disabled';
+
+# Reset all counter values
+set global innodb_monitor_reset_all = all;
+
+# count should all change to 0
+select name from information_schema.innodb_metrics where count!=0;
+
+# Test wildcard match, turn on all counters contain string "lock"
+set global innodb_monitor_enable = "%lock%";
+
+# All lock related counter should be enabled
+select name from information_schema.innodb_metrics
+where status != IF(name like "%lock%", 'enabled', 'disabled');
+
+# Disable them
+set global innodb_monitor_disable = "%lock%";
+
+# All lock related counter should be disabled
+select name, status from information_schema.innodb_metrics
+where name like "%lock%";
+
+# No match for "%lock*"
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_monitor_enable = "%lock*";
+
+# All counters will be turned on with wildcard match string with all "%"
+set global innodb_monitor_enable="%%%%%%%%%%%%%%%%%%%%%%%%%%%";
+
+select name from information_schema.innodb_metrics where status!='enabled';
+
+# Turn off all counters
+set global innodb_monitor_disable="%%%%%";
+
+select name from information_schema.innodb_metrics where status!='disabled';
+
+# One more round testing. All counters will be turned on with
+# single wildcard character "%"
+set global innodb_monitor_enable="%";
+
+select name from information_schema.innodb_metrics where status!='enabled';
+
+# Turn off all the counters with "%_%"
+set global innodb_monitor_disable="%_%";
+
+select name from information_schema.innodb_metrics where status!='disabled';
+
+# Turn on all counters start with "log"
+set global innodb_monitor_enable="log%%%%";
+
+select name from information_schema.innodb_metrics
+where status != IF(name like "log%", 'enabled', 'disabled');
+
+# Turn on counters "os_data_fsync" with wildcard match "os_%a_fs_ncs", "_"
+# is single character wildcard match word
+set global innodb_monitor_enable="os_%a_fs_ncs";
+
+# Turn on counters whose name contains "os" and "pending" with
+# wildcard match "os%pending%"
+set global innodb_monitor_enable="os%pending%";
+
+select name, status from information_schema.innodb_metrics
+where name like "os%";
+
+# Empty string is an invalid option
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_monitor_enable="";
+
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_monitor_enable="_";
+
+# Reset counters only in "module_metadata" module
+set global innodb_monitor_disable = module_metadata;
+
+set global innodb_monitor_reset_all = module_metadata;
+
+# Only turn on "table_open" counter
+set global innodb_monitor_enable = metadata_table_handles_opened;
+
+# Create a new table to test "metadata_table_handles_opened" counter
+create table monitor_test(col int) engine = innodb;
+
+# This will open the monitor_test table
+select * from monitor_test;
+
+# "metadata_table_handles_opened" should increment by 1
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Reset the counter value while counter is still on (started)
+# This will reset value "count_reset" but not
+# "count"
+set global innodb_monitor_reset = metadata_table_handles_opened;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# re-create table again to increment "metadata_table_handles_opened" again
+drop table monitor_test;
+
+# Create a new table to test "metadata_table_handles_opened" counter
+create table monitor_test(col int) engine = innodb;
+
+select * from monitor_test;
+
+# "metadata_table_handles_opened" should increment
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Cannot reset all monitor value while the counter is on
+set global innodb_monitor_reset_all = metadata_table_handles_opened;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Turn off the counter "metadata_table_handles_opened"
+set global innodb_monitor_disable = metadata_table_handles_opened;
+
+# Reset the counter value while counter is off (disabled)
+set global innodb_monitor_reset = metadata_table_handles_opened;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# re-create table again. Since monitor is off, "metadata_table_handles_opened"
+# should not be incremented
+drop table monitor_test;
+
+# Create a new table to test "metadata_table_handles_opened" counter
+create table monitor_test(col int) engine = innodb;
+
+# "metadata_table_handles_opened" should increment
+select * from monitor_test;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Reset all the counters, include those counter *_since_start
+set global innodb_monitor_reset_all = metadata_table_handles_opened;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Turn on "table_open" counter again
+set global innodb_monitor_enable = metadata_table_handles_opened;
+
+# Test metadata_table_handles_opened again to see if it is working correctly
+# after above round of turning on/off/reset
+drop table monitor_test;
+
+# Create a new table to test "metadata_table_handles_opened" counter
+create table monitor_test(col int) engine = innodb stats_persistent=0;
+
+select * from monitor_test;
+
+# "metadata_table_handles_opened" should increment
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_opened";
+
+# Test counter "metadata_table_handles_closed",
+# create index will close the old handle
+set global innodb_monitor_enable = metadata_table_handles_closed;
+
+create index idx on monitor_test(col);
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name = "metadata_table_handles_closed";
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+
+# Reset counters only in "module_metadata" module
+set global innodb_monitor_disable = module_metadata;
+
+set global innodb_monitor_reset = module_metadata;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+
+set global innodb_monitor_reset_all = module_metadata;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "metadata%";
+
+# Test Transaction Module
+set global innodb_monitor_enable = module_trx;
+
+begin;
+insert into monitor_test values(9);
+commit;
+
+begin;
+insert into monitor_test values(9);
+rollback;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "trx_rollbacks" or name like "trx_active_transactions";
+
+set global innodb_monitor_disable = module_trx;
+
+# Test DML Module
+set global innodb_monitor_enable = module_dml;
+
+insert into monitor_test values(9);
+
+update monitor_test set col = 10 where col = 9;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+delete from monitor_test;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+ from information_schema.innodb_metrics
+ where name like "dml%";
+
+# test reset counter while the counter is on
+set global innodb_monitor_reset = module_dml;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+# insert/delete some rows after the reset
+insert into monitor_test values(9);
+insert into monitor_test values(1);
+
+delete from monitor_test;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+# We do not allow reset_all while the counter is on, nothing
+# should be reset here
+set global innodb_monitor_reset_all = module_dml;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+# Turn off the counter
+set global innodb_monitor_disable = module_dml;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+# Reset all counter values
+set global innodb_monitor_reset_all = module_dml;
+
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+# Open individual counter "dml_inserts"
+set global innodb_monitor_enable = dml_inserts;
+
+insert into monitor_test values(9);
+insert into monitor_test values(1);
+
+delete from monitor_test;
+
+# Only counter "dml_inserts" should be updated
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "dml%";
+
+set global innodb_monitor_disable = module_dml;
+
+drop table monitor_test;
+
+set global innodb_monitor_enable = file_num_open_files;
+
+# Counters are unpredictable when innodb-file-per-table is on
+--replace_column 2 # 3 # 4 # 5 # 6 # 7 #
+select name, max_count, min_count, count,
+ max_count_reset, min_count_reset, count_reset, status
+from information_schema.innodb_metrics
+where name like "file_num_open_files";
+
+set global innodb_monitor_disable = file_num_open_files;
+
+# Test ICP module counters
+set global innodb_monitor_enable = "icp%";
+
+create table monitor_test(a char(3), b int, c char(2),
+primary key (a(1), c(1)), key(b)) engine = innodb;
+
+insert into monitor_test values("13", 2, "aa");
+
+select a from monitor_test where b < 1 for update;
+
+# should have icp_attempts = 1 and icp_out_of_range = 1
+select name, count from information_schema.innodb_metrics
+where name like "icp%";
+
+# should have icp_attempts = 2 and icp_match = 1
+select a from monitor_test where b < 3 for update;
+
+select name, count from information_schema.innodb_metrics
+where name like "icp%";
+
+drop table monitor_test;
+
+set global innodb_monitor_disable = all;
+set global innodb_monitor_reset_all = all;
+
+# Test for bug #13966091
+select 1 from `information_schema`.`INNODB_METRICS`
+where case (1) when (1) then (AVG_COUNT_RESET) else (1) end;
+
+-- disable_warnings
+set global innodb_monitor_enable = default;
+set global innodb_monitor_disable = default;
+set global innodb_monitor_reset = default;
+set global innodb_monitor_reset_all = default;
+-- enable_warnings
diff --git a/mysql-test/suite/rpl/include/rpl_innodb_rows_counters.inc b/mysql-test/suite/rpl/include/rpl_innodb_rows_counters.inc
new file mode 100644
index 00000000000..b624853cd37
--- /dev/null
+++ b/mysql-test/suite/rpl/include/rpl_innodb_rows_counters.inc
@@ -0,0 +1,50 @@
+#########################################
+# Author: Benjamin Renard benj@fb.com
+# Date: 11/15/2013
+# Purpose: Showing the difference between current innodb rows stats and the ones recorded at the beginning of the test
+# Requirements: Having @[master|slave]_[system_]rows_[read|inserted|deleted|updated] counters already created
+#########################################
+
+--connection master
+--echo ==========MASTER==========
+
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @master_rows_read;
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @master_rows_updated;
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @master_rows_deleted;
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @master_rows_inserted;
+
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @master_system_rows_read;
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @master_system_rows_updated;
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @master_system_rows_deleted;
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @master_system_rows_inserted;
+
+--sync_slave_with_master
+--echo ==========SLAVE===========
+
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @slave_rows_read;
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @slave_rows_updated;
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @slave_rows_deleted;
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @slave_rows_inserted;
+
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @slave_system_rows_read;
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @slave_system_rows_updated;
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @slave_system_rows_deleted;
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @slave_system_rows_inserted;
+
+--connection master
diff --git a/mysql-test/suite/rpl/r/rpl_innodb_bug68220.result b/mysql-test/suite/rpl/r/rpl_innodb_bug68220.result
new file mode 100644
index 00000000000..1cbcd03a113
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_innodb_bug68220.result
@@ -0,0 +1,227 @@
+include/master-slave.inc
+[connection master]
+DROP TABLE IF EXISTS testdb.t1;
+DROP DATABASE IF EXISTS testdb;
+select variable_value into @master_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select variable_value into @master_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select variable_value into @master_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select variable_value into @master_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select variable_value into @master_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select variable_value into @master_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select variable_value into @master_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select variable_value into @master_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select variable_value into @slave_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select variable_value into @slave_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select variable_value into @slave_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select variable_value into @slave_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select variable_value into @slave_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select variable_value into @slave_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select variable_value into @slave_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select variable_value into @slave_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+CREATE DATABASE testdb;
+USE testdb;
+CREATE TABLE testdb.t1 (i int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO testdb.t1 VALUES (1);
+==========MASTER==========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @master_rows_read;
+@rows_read - @master_rows_read
+0
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @master_rows_updated;
+@rows_updated - @master_rows_updated
+0
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @master_rows_deleted;
+@rows_deleted - @master_rows_deleted
+0
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @master_rows_inserted;
+@rows_inserted - @master_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @master_system_rows_read;
+@system_rows_read - @master_system_rows_read
+0
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @master_system_rows_updated;
+@system_rows_updated - @master_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @master_system_rows_deleted;
+@system_rows_deleted - @master_system_rows_deleted
+0
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @master_system_rows_inserted;
+@system_rows_inserted - @master_system_rows_inserted
+0
+==========SLAVE===========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @slave_rows_read;
+@rows_read - @slave_rows_read
+0
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @slave_rows_updated;
+@rows_updated - @slave_rows_updated
+0
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @slave_rows_deleted;
+@rows_deleted - @slave_rows_deleted
+0
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @slave_rows_inserted;
+@rows_inserted - @slave_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @slave_system_rows_read;
+@system_rows_read - @slave_system_rows_read
+3
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @slave_system_rows_updated;
+@system_rows_updated - @slave_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @slave_system_rows_deleted;
+@system_rows_deleted - @slave_system_rows_deleted
+3
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @slave_system_rows_inserted;
+@system_rows_inserted - @slave_system_rows_inserted
+3
+UPDATE t1 SET i=2 WHERE i=1;
+==========MASTER==========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @master_rows_read;
+@rows_read - @master_rows_read
+1
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @master_rows_updated;
+@rows_updated - @master_rows_updated
+1
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @master_rows_deleted;
+@rows_deleted - @master_rows_deleted
+0
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @master_rows_inserted;
+@rows_inserted - @master_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @master_system_rows_read;
+@system_rows_read - @master_system_rows_read
+0
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @master_system_rows_updated;
+@system_rows_updated - @master_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @master_system_rows_deleted;
+@system_rows_deleted - @master_system_rows_deleted
+0
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @master_system_rows_inserted;
+@system_rows_inserted - @master_system_rows_inserted
+0
+==========SLAVE===========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @slave_rows_read;
+@rows_read - @slave_rows_read
+1
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @slave_rows_updated;
+@rows_updated - @slave_rows_updated
+1
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @slave_rows_deleted;
+@rows_deleted - @slave_rows_deleted
+0
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @slave_rows_inserted;
+@rows_inserted - @slave_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @slave_system_rows_read;
+@system_rows_read - @slave_system_rows_read
+4
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @slave_system_rows_updated;
+@system_rows_updated - @slave_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @slave_system_rows_deleted;
+@system_rows_deleted - @slave_system_rows_deleted
+4
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @slave_system_rows_inserted;
+@system_rows_inserted - @slave_system_rows_inserted
+4
+DELETE FROM t1 WHERE i=2;
+==========MASTER==========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @master_rows_read;
+@rows_read - @master_rows_read
+2
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @master_rows_updated;
+@rows_updated - @master_rows_updated
+1
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @master_rows_deleted;
+@rows_deleted - @master_rows_deleted
+1
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @master_rows_inserted;
+@rows_inserted - @master_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @master_system_rows_read;
+@system_rows_read - @master_system_rows_read
+0
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @master_system_rows_updated;
+@system_rows_updated - @master_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @master_system_rows_deleted;
+@system_rows_deleted - @master_system_rows_deleted
+0
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @master_system_rows_inserted;
+@system_rows_inserted - @master_system_rows_inserted
+0
+==========SLAVE===========
+select variable_value into @rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select @rows_read - @slave_rows_read;
+@rows_read - @slave_rows_read
+2
+select variable_value into @rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select @rows_updated - @slave_rows_updated;
+@rows_updated - @slave_rows_updated
+1
+select variable_value into @rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select @rows_deleted - @slave_rows_deleted;
+@rows_deleted - @slave_rows_deleted
+1
+select variable_value into @rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select @rows_inserted - @slave_rows_inserted;
+@rows_inserted - @slave_rows_inserted
+1
+select variable_value into @system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select @system_rows_read - @slave_system_rows_read;
+@system_rows_read - @slave_system_rows_read
+5
+select variable_value into @system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select @system_rows_updated - @slave_system_rows_updated;
+@system_rows_updated - @slave_system_rows_updated
+0
+select variable_value into @system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select @system_rows_deleted - @slave_system_rows_deleted;
+@system_rows_deleted - @slave_system_rows_deleted
+5
+select variable_value into @system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+select @system_rows_inserted - @slave_system_rows_inserted;
+@system_rows_inserted - @slave_system_rows_inserted
+5
+DROP TABLE t1;
+DROP DATABASE testdb;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test
new file mode 100644
index 00000000000..37d7d106dca
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test
@@ -0,0 +1,59 @@
+--source include/have_innodb.inc
+--source include/master-slave.inc
+
+#
+# Bug#68220: innodb_rows_updated is misleading on slave when *info_repository=TABLE
+#
+
+# clean previous tests
+--connection master
+--disable_warnings
+DROP TABLE IF EXISTS testdb.t1;
+DROP DATABASE IF EXISTS testdb;
+--enable_warnings
+--sync_slave_with_master
+
+# created all the base variables at the beginning at the test
+--connection master
+select variable_value into @master_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select variable_value into @master_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select variable_value into @master_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select variable_value into @master_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select variable_value into @master_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select variable_value into @master_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select variable_value into @master_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select variable_value into @master_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+
+--connection slave
+select variable_value into @slave_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read';
+select variable_value into @slave_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated';
+select variable_value into @slave_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted';
+select variable_value into @slave_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted';
+select variable_value into @slave_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read';
+select variable_value into @slave_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated';
+select variable_value into @slave_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted';
+select variable_value into @slave_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted';
+
+--connection master
+CREATE DATABASE testdb;
+USE testdb;
+CREATE TABLE testdb.t1 (i int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+
+# insert a row and show counters on master and slave
+INSERT INTO testdb.t1 VALUES (1);
+--source suite/rpl/include/rpl_innodb_rows_counters.inc
+
+# update the row and show counters on master and slave
+UPDATE t1 SET i=2 WHERE i=1;
+--source suite/rpl/include/rpl_innodb_rows_counters.inc
+
+# delete the row and show counters on master and slave
+DELETE FROM t1 WHERE i=2;
+--source suite/rpl/include/rpl_innodb_rows_counters.inc
+
+# clean the test
+DROP TABLE t1;
+DROP DATABASE testdb;
+--sync_slave_with_master
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/sys_vars/r/innodb_adaptive_flushing_lwm_basic.result b/mysql-test/suite/sys_vars/r/innodb_adaptive_flushing_lwm_basic.result
index 1797845def2..bfd59cfd9cc 100644
--- a/mysql-test/suite/sys_vars/r/innodb_adaptive_flushing_lwm_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_adaptive_flushing_lwm_basic.result
@@ -7,55 +7,55 @@ SET @@global.innodb_adaptive_flushing_lwm = 1;
SET @@global.innodb_adaptive_flushing_lwm = DEFAULT;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-10
+10.000000
'#---------------------FN_DYNVARS_046_02-------------------------#'
SET innodb_adaptive_flushing_lwm = 1;
ERROR HY000: Variable 'innodb_adaptive_flushing_lwm' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@innodb_adaptive_flushing_lwm;
@@innodb_adaptive_flushing_lwm
-10
+10.000000
SELECT local.innodb_adaptive_flushing_lwm;
ERROR 42S02: Unknown table 'local' in field list
SET global innodb_adaptive_flushing_lwm = 1;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-1
+1.000000
'#--------------------FN_DYNVARS_046_03------------------------#'
SET @@global.innodb_adaptive_flushing_lwm = 1;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-1
+1.000000
SET @@global.innodb_adaptive_flushing_lwm = 60;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-60
+60.000000
SET @@global.innodb_adaptive_flushing_lwm = 70;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-70
+70.000000
'#--------------------FN_DYNVARS_046_04-------------------------#'
SET @@global.innodb_adaptive_flushing_lwm = -1;
Warnings:
Warning 1292 Truncated incorrect innodb_adaptive_flushing_lwm value: '-1'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-0
+0.000000
SET @@global.innodb_adaptive_flushing_lwm = "T";
ERROR 42000: Incorrect argument type to variable 'innodb_adaptive_flushing_lwm'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-0
+0.000000
SET @@global.innodb_adaptive_flushing_lwm = "Y";
ERROR 42000: Incorrect argument type to variable 'innodb_adaptive_flushing_lwm'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-0
+0.000000
SET @@global.innodb_adaptive_flushing_lwm = 71;
Warnings:
Warning 1292 Truncated incorrect innodb_adaptive_flushing_lwm value: '71'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-70
+70.000000
'#----------------------FN_DYNVARS_046_05------------------------#'
SELECT @@global.innodb_adaptive_flushing_lwm =
VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -65,32 +65,32 @@ VARIABLE_VALUE
1
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-70
+70.000000
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_adaptive_flushing_lwm';
VARIABLE_VALUE
-70
+70.000000
'#---------------------FN_DYNVARS_046_06-------------------------#'
SET @@global.innodb_adaptive_flushing_lwm = OFF;
ERROR 42000: Incorrect argument type to variable 'innodb_adaptive_flushing_lwm'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-70
+70.000000
SET @@global.innodb_adaptive_flushing_lwm = ON;
ERROR 42000: Incorrect argument type to variable 'innodb_adaptive_flushing_lwm'
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-70
+70.000000
'#---------------------FN_DYNVARS_046_07----------------------#'
SET @@global.innodb_adaptive_flushing_lwm = TRUE;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-1
+1.000000
SET @@global.innodb_adaptive_flushing_lwm = FALSE;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-0
+0.000000
SET @@global.innodb_adaptive_flushing_lwm = @global_start_value;
SELECT @@global.innodb_adaptive_flushing_lwm;
@@global.innodb_adaptive_flushing_lwm
-10
+10.000000
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
index eff72613102..d705624eb53 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
@@ -4,58 +4,64 @@ SELECT @global_start_value;
75
'#--------------------FN_DYNVARS_046_01------------------------#'
SET @@global.innodb_max_dirty_pages_pct = 0;
-SET @@global.innodb_max_dirty_pages_pct = DEFAULT;
+Warnings:
+Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '0'
+SET @@global.innodb_max_dirty_pages_pct = @global_start_value;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-75
+75.000000
'#---------------------FN_DYNVARS_046_02-------------------------#'
SET innodb_max_dirty_pages_pct = 1;
ERROR HY000: Variable 'innodb_max_dirty_pages_pct' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@innodb_max_dirty_pages_pct;
@@innodb_max_dirty_pages_pct
-75
+75.000000
SELECT local.innodb_max_dirty_pages_pct;
ERROR 42S02: Unknown table 'local' in field list
SET global innodb_max_dirty_pages_pct = 0;
+Warnings:
+Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '0'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
'#--------------------FN_DYNVARS_046_03------------------------#'
SET @@global.innodb_max_dirty_pages_pct = 0;
+Warnings:
+Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '0'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
SET @@global.innodb_max_dirty_pages_pct = 1;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-1
+1.000000
SET @@global.innodb_max_dirty_pages_pct = 99;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-99
+99.000000
'#--------------------FN_DYNVARS_046_04-------------------------#'
SET @@global.innodb_max_dirty_pages_pct = -1;
Warnings:
Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '-1'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
SET @@global.innodb_max_dirty_pages_pct = "T";
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
SET @@global.innodb_max_dirty_pages_pct = "Y";
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
SET @@global.innodb_max_dirty_pages_pct = 1001;
Warnings:
Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '1001'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-99
+99.999000
'#----------------------FN_DYNVARS_046_05------------------------#'
SELECT @@global.innodb_max_dirty_pages_pct =
VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -65,32 +71,34 @@ VARIABLE_VALUE
1
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-99
+99.999000
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_max_dirty_pages_pct';
VARIABLE_VALUE
-99
+99.999000
'#---------------------FN_DYNVARS_046_06-------------------------#'
SET @@global.innodb_max_dirty_pages_pct = OFF;
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-99
+99.999000
SET @@global.innodb_max_dirty_pages_pct = ON;
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-99
+99.999000
'#---------------------FN_DYNVARS_046_07----------------------#'
SET @@global.innodb_max_dirty_pages_pct = TRUE;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-1
+1.000000
SET @@global.innodb_max_dirty_pages_pct = FALSE;
+Warnings:
+Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct value: '0'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-0
+0.001000
SET @@global.innodb_max_dirty_pages_pct = @global_start_value;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-75
+75.000000
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
index 55de5adbc33..05aa3e5fd89 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
@@ -5,13 +5,13 @@ SET @@global.innodb_max_dirty_pages_pct = 80;
'connection con1'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-80
+80.000000
SET @@global.innodb_max_dirty_pages_pct = 70;
'connect (con2,localhost,root,,,,)'
'connection con2'
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-70
+70.000000
'connection default'
'disconnect con2'
'disconnect con1'
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_lwm_basic.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_lwm_basic.result
index 82388cebc82..676ec103664 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_lwm_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_lwm_basic.result
@@ -1,70 +1,70 @@
SET @pct_lwm_start_value = @@global.innodb_max_dirty_pages_pct_lwm;
SELECT @pct_lwm_start_value;
@pct_lwm_start_value
-0
+0.001
SET @pct_start_value = @@global.innodb_max_dirty_pages_pct;
SELECT @pct_start_value;
@pct_start_value
75
'#--------------------FN_DYNVARS_046_01------------------------#'
SET @@global.innodb_max_dirty_pages_pct_lwm = 0;
-SET @@global.innodb_max_dirty_pages_pct_lwm = DEFAULT;
+SET @@global.innodb_max_dirty_pages_pct_lwm = @pct_lwm_start_value;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.001000
'#---------------------FN_DYNVARS_046_02-------------------------#'
SET innodb_max_dirty_pages_pct_lwm = 1;
ERROR HY000: Variable 'innodb_max_dirty_pages_pct_lwm' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@innodb_max_dirty_pages_pct_lwm;
@@innodb_max_dirty_pages_pct_lwm
-0
+0.001000
SELECT local.innodb_max_dirty_pages_pct_lwm;
ERROR 42S02: Unknown table 'local' in field list
SET global innodb_max_dirty_pages_pct_lwm = 0;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
'#--------------------FN_DYNVARS_046_03------------------------#'
SET @@global.innodb_max_dirty_pages_pct_lwm = 0;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = @pct_start_value;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
'#--------------------FN_DYNVARS_046_04-------------------------#'
SET @@global.innodb_max_dirty_pages_pct_lwm = -1;
Warnings:
Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct_lwm value: '-1'
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = "T";
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct_lwm'
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = "Y";
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct_lwm'
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = @pct_start_value + 1;
Warnings:
Warning 1210 innodb_max_dirty_pages_pct_lwm cannot be set higher than innodb_max_dirty_pages_pct.
-Warning 1210 Setting innodb_max_dirty_page_pct_lwm to 75
+Warning 1210 Setting innodb_max_dirty_page_pct_lwm to 75.000000
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = 100;
Warnings:
Warning 1292 Truncated incorrect innodb_max_dirty_pages_pct_lwm value: '100'
Warning 1210 innodb_max_dirty_pages_pct_lwm cannot be set higher than innodb_max_dirty_pages_pct.
-Warning 1210 Setting innodb_max_dirty_page_pct_lwm to 75
+Warning 1210 Setting innodb_max_dirty_page_pct_lwm to 75.000000
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
'#----------------------FN_DYNVARS_046_05------------------------#'
SELECT @@global.innodb_max_dirty_pages_pct_lwm =
VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -74,36 +74,36 @@ VARIABLE_VALUE
1
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_max_dirty_pages_pct_lwm';
VARIABLE_VALUE
-75
+75.000000
'#---------------------FN_DYNVARS_046_06-------------------------#'
SET @@global.innodb_max_dirty_pages_pct_lwm = OFF;
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct_lwm'
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = ON;
ERROR 42000: Incorrect argument type to variable 'innodb_max_dirty_pages_pct_lwm'
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-75
+75.000000
'#---------------------FN_DYNVARS_046_07----------------------#'
SET @@global.innodb_max_dirty_pages_pct_lwm = TRUE;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-1
+1.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = FALSE;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.000000
SET @@global.innodb_max_dirty_pages_pct = @pct_start_value;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-75
+75.000000
SET @@global.innodb_max_dirty_pages_pct_lwm = @pct_lwm_start_value;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
@@global.innodb_max_dirty_pages_pct_lwm
-0
+0.001000
diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result
index 6f1c4c21d17..8c0af874228 100644
--- a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result
@@ -207,6 +207,10 @@ dml_reads disabled
dml_inserts disabled
dml_deletes disabled
dml_updates disabled
+dml_system_reads disabled
+dml_system_inserts disabled
+dml_system_deletes disabled
+dml_system_updates disabled
ddl_background_drop_indexes disabled
ddl_background_drop_tables disabled
ddl_online_create_index disabled
@@ -429,6 +433,10 @@ dml_reads 4 NULL 4 4 NULL 4 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 0 NULL 0 0 NULL 0 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
delete from monitor_test;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -439,6 +447,10 @@ dml_reads 6 NULL 6 6 NULL 6 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 2 NULL 2 2 NULL 2 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -449,6 +461,10 @@ dml_reads 6 NULL 6 0 NULL 0 enabled
dml_inserts 1 NULL 1 0 NULL 0 enabled
dml_deletes 2 NULL 2 0 NULL 0 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
insert into monitor_test values(9);
insert into monitor_test values(1);
delete from monitor_test;
@@ -461,6 +477,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -471,6 +491,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_disable = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -481,6 +505,10 @@ dml_reads 8 NULL 8 2 NULL 2 disabled
dml_inserts 3 NULL 3 2 NULL 2 disabled
dml_deletes 4 NULL 4 2 NULL 2 disabled
dml_updates 2 NULL 2 0 NULL 0 disabled
+dml_system_reads 0 NULL 0 0 NULL 0 disabled
+dml_system_inserts 0 NULL 0 0 NULL 0 disabled
+dml_system_deletes 0 NULL 0 0 NULL 0 disabled
+dml_system_updates 0 NULL 0 0 NULL 0 disabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -491,6 +519,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts NULL NULL 0 NULL NULL 0 disabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_enable = dml_inserts;
insert into monitor_test values(9);
insert into monitor_test values(1);
@@ -504,6 +536,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts 2 NULL 2 2 NULL 2 enabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_disable = module_dml;
drop table monitor_test;
set global innodb_monitor_enable = file_num_open_files;
diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result
index 6f1c4c21d17..8c0af874228 100644
--- a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result
@@ -207,6 +207,10 @@ dml_reads disabled
dml_inserts disabled
dml_deletes disabled
dml_updates disabled
+dml_system_reads disabled
+dml_system_inserts disabled
+dml_system_deletes disabled
+dml_system_updates disabled
ddl_background_drop_indexes disabled
ddl_background_drop_tables disabled
ddl_online_create_index disabled
@@ -429,6 +433,10 @@ dml_reads 4 NULL 4 4 NULL 4 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 0 NULL 0 0 NULL 0 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
delete from monitor_test;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -439,6 +447,10 @@ dml_reads 6 NULL 6 6 NULL 6 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 2 NULL 2 2 NULL 2 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -449,6 +461,10 @@ dml_reads 6 NULL 6 0 NULL 0 enabled
dml_inserts 1 NULL 1 0 NULL 0 enabled
dml_deletes 2 NULL 2 0 NULL 0 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
insert into monitor_test values(9);
insert into monitor_test values(1);
delete from monitor_test;
@@ -461,6 +477,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -471,6 +491,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_disable = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -481,6 +505,10 @@ dml_reads 8 NULL 8 2 NULL 2 disabled
dml_inserts 3 NULL 3 2 NULL 2 disabled
dml_deletes 4 NULL 4 2 NULL 2 disabled
dml_updates 2 NULL 2 0 NULL 0 disabled
+dml_system_reads 0 NULL 0 0 NULL 0 disabled
+dml_system_inserts 0 NULL 0 0 NULL 0 disabled
+dml_system_deletes 0 NULL 0 0 NULL 0 disabled
+dml_system_updates 0 NULL 0 0 NULL 0 disabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -491,6 +519,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts NULL NULL 0 NULL NULL 0 disabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_enable = dml_inserts;
insert into monitor_test values(9);
insert into monitor_test values(1);
@@ -504,6 +536,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts 2 NULL 2 2 NULL 2 enabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_disable = module_dml;
drop table monitor_test;
set global innodb_monitor_enable = file_num_open_files;
diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result
index 6f1c4c21d17..8c0af874228 100644
--- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result
@@ -207,6 +207,10 @@ dml_reads disabled
dml_inserts disabled
dml_deletes disabled
dml_updates disabled
+dml_system_reads disabled
+dml_system_inserts disabled
+dml_system_deletes disabled
+dml_system_updates disabled
ddl_background_drop_indexes disabled
ddl_background_drop_tables disabled
ddl_online_create_index disabled
@@ -429,6 +433,10 @@ dml_reads 4 NULL 4 4 NULL 4 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 0 NULL 0 0 NULL 0 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
delete from monitor_test;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -439,6 +447,10 @@ dml_reads 6 NULL 6 6 NULL 6 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 2 NULL 2 2 NULL 2 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -449,6 +461,10 @@ dml_reads 6 NULL 6 0 NULL 0 enabled
dml_inserts 1 NULL 1 0 NULL 0 enabled
dml_deletes 2 NULL 2 0 NULL 0 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
insert into monitor_test values(9);
insert into monitor_test values(1);
delete from monitor_test;
@@ -461,6 +477,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -471,6 +491,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_disable = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -481,6 +505,10 @@ dml_reads 8 NULL 8 2 NULL 2 disabled
dml_inserts 3 NULL 3 2 NULL 2 disabled
dml_deletes 4 NULL 4 2 NULL 2 disabled
dml_updates 2 NULL 2 0 NULL 0 disabled
+dml_system_reads 0 NULL 0 0 NULL 0 disabled
+dml_system_inserts 0 NULL 0 0 NULL 0 disabled
+dml_system_deletes 0 NULL 0 0 NULL 0 disabled
+dml_system_updates 0 NULL 0 0 NULL 0 disabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -491,6 +519,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts NULL NULL 0 NULL NULL 0 disabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_enable = dml_inserts;
insert into monitor_test values(9);
insert into monitor_test values(1);
@@ -504,6 +536,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts 2 NULL 2 2 NULL 2 enabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_disable = module_dml;
drop table monitor_test;
set global innodb_monitor_enable = file_num_open_files;
diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result
index 6f1c4c21d17..8c0af874228 100644
--- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result
@@ -207,6 +207,10 @@ dml_reads disabled
dml_inserts disabled
dml_deletes disabled
dml_updates disabled
+dml_system_reads disabled
+dml_system_inserts disabled
+dml_system_deletes disabled
+dml_system_updates disabled
ddl_background_drop_indexes disabled
ddl_background_drop_tables disabled
ddl_online_create_index disabled
@@ -429,6 +433,10 @@ dml_reads 4 NULL 4 4 NULL 4 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 0 NULL 0 0 NULL 0 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
delete from monitor_test;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -439,6 +447,10 @@ dml_reads 6 NULL 6 6 NULL 6 enabled
dml_inserts 1 NULL 1 1 NULL 1 enabled
dml_deletes 2 NULL 2 2 NULL 2 enabled
dml_updates 2 NULL 2 2 NULL 2 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -449,6 +461,10 @@ dml_reads 6 NULL 6 0 NULL 0 enabled
dml_inserts 1 NULL 1 0 NULL 0 enabled
dml_deletes 2 NULL 2 0 NULL 0 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
insert into monitor_test values(9);
insert into monitor_test values(1);
delete from monitor_test;
@@ -461,6 +477,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -471,6 +491,10 @@ dml_reads 8 NULL 8 2 NULL 2 enabled
dml_inserts 3 NULL 3 2 NULL 2 enabled
dml_deletes 4 NULL 4 2 NULL 2 enabled
dml_updates 2 NULL 2 0 NULL 0 enabled
+dml_system_reads 0 NULL 0 0 NULL 0 enabled
+dml_system_inserts 0 NULL 0 0 NULL 0 enabled
+dml_system_deletes 0 NULL 0 0 NULL 0 enabled
+dml_system_updates 0 NULL 0 0 NULL 0 enabled
set global innodb_monitor_disable = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -481,6 +505,10 @@ dml_reads 8 NULL 8 2 NULL 2 disabled
dml_inserts 3 NULL 3 2 NULL 2 disabled
dml_deletes 4 NULL 4 2 NULL 2 disabled
dml_updates 2 NULL 2 0 NULL 0 disabled
+dml_system_reads 0 NULL 0 0 NULL 0 disabled
+dml_system_inserts 0 NULL 0 0 NULL 0 disabled
+dml_system_deletes 0 NULL 0 0 NULL 0 disabled
+dml_system_updates 0 NULL 0 0 NULL 0 disabled
set global innodb_monitor_reset_all = module_dml;
select name, max_count, min_count, count,
max_count_reset, min_count_reset, count_reset, status
@@ -491,6 +519,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts NULL NULL 0 NULL NULL 0 disabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_enable = dml_inserts;
insert into monitor_test values(9);
insert into monitor_test values(1);
@@ -504,6 +536,10 @@ dml_reads NULL NULL 0 NULL NULL 0 disabled
dml_inserts 2 NULL 2 2 NULL 2 enabled
dml_deletes NULL NULL 0 NULL NULL 0 disabled
dml_updates NULL NULL 0 NULL NULL 0 disabled
+dml_system_reads NULL NULL 0 NULL NULL 0 disabled
+dml_system_inserts NULL NULL 0 NULL NULL 0 disabled
+dml_system_deletes NULL NULL 0 NULL NULL 0 disabled
+dml_system_updates NULL NULL 0 NULL NULL 0 disabled
set global innodb_monitor_disable = module_dml;
drop table monitor_test;
set global innodb_monitor_enable = file_num_open_files;
diff --git a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test
index 7e70ed11351..5b4eaa41598 100644
--- a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test
@@ -44,7 +44,7 @@ SELECT @global_start_value;
########################################################################
SET @@global.innodb_max_dirty_pages_pct = 0;
-SET @@global.innodb_max_dirty_pages_pct = DEFAULT;
+SET @@global.innodb_max_dirty_pages_pct = @global_start_value;
SELECT @@global.innodb_max_dirty_pages_pct;
--echo '#---------------------FN_DYNVARS_046_02-------------------------#'
diff --git a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_lwm_basic.test b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_lwm_basic.test
index 7a6da2e6a08..d81b6cc725b 100644
--- a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_lwm_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_lwm_basic.test
@@ -47,7 +47,7 @@ SELECT @pct_start_value;
########################################################################
SET @@global.innodb_max_dirty_pages_pct_lwm = 0;
-SET @@global.innodb_max_dirty_pages_pct_lwm = DEFAULT;
+SET @@global.innodb_max_dirty_pages_pct_lwm = @pct_lwm_start_value;
SELECT @@global.innodb_max_dirty_pages_pct_lwm;
--echo '#---------------------FN_DYNVARS_046_02-------------------------#'
diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test
index e3b76015b65..7f19553e4e5 100644
--- a/mysql-test/t/derived_opt.test
+++ b/mysql-test/t/derived_opt.test
@@ -1,6 +1,7 @@
# Initialize
--disable_warnings
-drop table if exists t1,t2,t3;
+drop table if exists t0,t1,t2,t3;
+drop database if exists test1;
--enable_warnings
set @exit_optimizer_switch=@@optimizer_switch;
@@ -273,28 +274,89 @@ limit 10;
drop table t1, t2, t3, t4;
--echo #
+--echo # MDEV-6888: Query spends a long time in best_extension_by_limited_search with mrr enabled
+--echo #
+create database test1;
+use test1;
+
+set @tmp_jcl= @@join_cache_level;
+set @tmp_os= @@optimizer_switch;
+set join_cache_level=8;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+
+CREATE TABLE t0 (
+ f1 bigint(20) DEFAULT NULL,
+ f2 char(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+INSERT INTO t0 VALUES (NULL,'numeric column is NULL'),(0,NULL),(5,'five'),(1,'one'),(2,'two');
+
+CREATE TABLE t1 (
+ f1 decimal(64,30) DEFAULT NULL,
+ f2 varchar(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+INSERT INTO t1 VALUES
+(NULL,'numeric column is NULL'),
+(0.000000000000000000000000000000,NULL),
+(5.000000000000000000000000000000,'five'),
+(1.000000000000000000000000000000,'one'),
+(3.000000000000000000000000000000,'three');
+
+CREATE TABLE t2 (
+ f1 double DEFAULT NULL,
+ f2 varbinary(50) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (NULL,'numeric column is NULL'),(0,NULL),(5,'five'),(2,'two'),(3,'three');
+
+create VIEW v0 AS select f1,f2 from t1 ;
+
+let $cnt= 27;
+while ($cnt)
+{
+# i runs from 1 to 27
+ let $i= `select 28 - $cnt`;
+ let $prev=`select $i - 1`;
+
+# rem = i mod 3
+ let $rem= `select MOD($i, 3)`;
+# view uses $i, $prev and $rem:
+ eval create VIEW v$i AS select tab1_v$i.f1,tab1_v$i.f2 from t$rem tab1_v$i join v$prev tab2 on tab1_v$i.f1 = tab2.f1 and tab1_v$i.f2 = tab2.f2;
+ dec $cnt;
+}
+
+EXPLAIN SELECT CAST(f1 AS SIGNED INTEGER) AS f1, CAST(f2 AS CHAR) AS f2 FROM v27;
+--echo # This used to hang forever:
+EXPLAIN SELECT CAST(f1 AS SIGNED INTEGER) AS f1, CAST(f2 AS CHAR) AS f2 FROM v27;
+
+use test;
+drop database test1;
+set join_cache_level=@tmp_jcl;
+set optimizer_switch=@tmp_os;
+
+
+--echo #
--echo # MDEV-6879: Dereference of NULL primary_file->table in DsMrr_impl::get_disk_sweep_mrr_cost()
--echo #
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, b int, c text);
-insert into t2
-select
+insert into t2
+select
A.a + B.a* 10,
A.a + B.a* 10,
- 'blob-data'
+ 'blob-data'
from t1 A, t1 B;
set @tmp_jcl= @@join_cache_level;
set @tmp_os= @@optimizer_switch;
set join_cache_level=6;
set @@optimizer_switch='derived_merge=on,derived_with_keys=on,mrr=on';
-explain
-select * from
+explain
+select * from
t1 join
- (select * from t2 order by a limit 1000) as D1
-where
+ (select * from t2 order by a limit 1000) as D1
+where
D1.a= t1.a;
set join_cache_level=@tmp_jcl;
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index 6a99b975e81..d3703de26c5 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -180,3 +180,17 @@ select * from t1 where not (a+0);
explain extended select * from t1 where not (a+0);
drop table t1;
+
+--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3)
+--echo #
+SELECT NOT NOT strcmp('a','b');
+EXPLAIN EXTENDED SELECT NOT NOT strcmp('a','b');
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test
index 16702104a57..cb79c238f2b 100644
--- a/mysql-test/t/innodb_mrr_cpk.test
+++ b/mysql-test/t/innodb_mrr_cpk.test
@@ -134,12 +134,40 @@ set optimizer_switch='index_condition_pushdown=on';
drop table t1,t2;
-set @@join_cache_level= @save_join_cache_level;
-set storage_engine=@save_storage_engine;
-set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0;
--echo #
+--echo # MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
+--echo #
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (
+ pk varchar(32) character set utf8 primary key,
+ kp1 char(32) not null,
+ col1 varchar(32),
+ key (kp1)
+) engine=innodb;
+
+insert into t1
+select
+ concat('pk-', 1000 +A.a),
+ concat('kp1-', 1000 +A.a),
+ concat('val-', 1000 +A.a)
+from test.t0 A ;
+
+create table t2 as select kp1 as a from t1;
+
+set join_cache_level=8;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+explain
+select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
+select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
+
+drop table t0,t1,t2;
+
+--echo #
+--echo #
--echo # MDEV-3817: Wrong result with index_merge+index_merge_intersection, InnoDB table, join, AND and OR conditions
--echo #
@@ -190,37 +218,12 @@ set join_cache_level=3;
explain SELECT 1 FROM (SELECT url, id FROM t2 LIMIT 1 OFFSET 20) derived RIGHT JOIN t1 ON t1.id = derived.id;
set join_cache_level= @tmp_mdev5037;
-
drop table t0,t1,t2;
--echo #
---echo # MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
+--echo # This must be at the end:
--echo #
-create table t0(a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1 (
- pk varchar(32) character set utf8 primary key,
- kp1 char(32) not null,
- col1 varchar(32),
- key (kp1)
-) engine=innodb;
-
-insert into t1
-select
- concat('pk-', 1000 +A.a),
- concat('kp1-', 1000 +A.a),
- concat('val-', 1000 +A.a)
-from test.t0 A ;
-
-create table t2 as select kp1 as a from t1;
-
-set join_cache_level=8;
-set optimizer_switch='mrr=on,mrr_sort_keys=on';
-explain
-select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
-select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
-
-drop table t0,t1,t2;
-
-
+set @@join_cache_level= @save_join_cache_level;
+set storage_engine=@save_storage_engine;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 7a70c413e8d..19c5f64de78 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1777,4 +1777,28 @@ SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
DROP TABLE t1,t2,t3;
+--echo #
+--echo # Bug mdev-6705: wrong on expression after constant row substitution
+--echo # that triggers a simplification of WHERE condition
+--echo #
+
+CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,8);
+
+CREATE TABLE t2 (c int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8),(9);
+
+CREATE TABLE t3 (d int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3),(8);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+ WHERE b IN (1,2,3) OR b = d;
+
+SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
+ WHERE b IN (1,2,3) OR b = d;
+
+DROP TABLE t1,t2,t3;
+
+
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index 81951a9ce68..40f66946822 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -295,3 +295,16 @@ CREATE TABLE t2 (d DATE) ENGINE=MyISAM;
SELECT * FROM t1,t2 WHERE 1 IS NOT NULL AND t1.b IS NULL;
DROP TABLE t1,t2;
+
+--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3)
+--echo #
+SELECT NOT NOT NULLIF(2,3);
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test
index 8cb2620550e..5db6f3b9d6a 100644
--- a/mysql-test/t/selectivity.test
+++ b/mysql-test/t/selectivity.test
@@ -889,4 +889,58 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit
DROP TABLE t1,t2;
+--echo #
+--echo # Bug mdev-6325: wrong selectivity of a column with ref access
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, key(a));
+insert into t2 select A.a + 10*B.a, 12345 from t0 A, t0 B, t0 C;
+
+set use_stat_tables='preferably';
+set histogram_size=100;
+
+set optimizer_use_condition_selectivity=4;
+analyze table t1 persistent for all;
+analyze table t2 persistent for all;
+
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t1.a<10;
+explain extended
+select * from t1 straight_join t2 where t1.a=t2.a and t2.a<10;
+
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+
+drop table t0,t1,t2;
+
+--echo #
+--echo # Bug mdev-6843: col IS NULL in where condition when col is always NULL
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (a int, b int);
+insert into t2 select NULL, a from t1;
+
+set use_stat_tables='preferably';
+set histogram_size=100;
+
+set optimizer_use_condition_selectivity=4;
+analyze table t2 persistent for all;
+
+explain extended
+select * from t2 A straight_join t2 B where A.a is null;
+
+set histogram_size=@save_histogram_size;
+set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+
+drop table t0,t1,t2;
+
set use_stat_tables=@save_use_stat_tables;
+
diff --git a/mysys/mf_fn_ext.c b/mysys/mf_fn_ext.c
index cbf0d5dd9e4..b78d73074da 100644
--- a/mysys/mf_fn_ext.c
+++ b/mysys/mf_fn_ext.c
@@ -29,7 +29,7 @@
(normally '.') after the directory name.
RETURN VALUES
- Pointer to to the extension character. If there isn't any extension,
+ Pointer to the extension character. If there isn't any extension,
points at the end ASCII(0) of the filename.
*/
@@ -49,7 +49,7 @@ char *fn_ext(const char *name)
if (!(gpos= strrchr(name, FN_LIBCHAR)))
gpos= name;
#endif
- pos=strchr(gpos,FN_EXTCHAR);
+ pos= strchr(gpos, FN_EXTCHAR);
DBUG_RETURN((char*) (pos ? pos : strend(gpos)));
} /* fn_ext */
@@ -58,7 +58,7 @@ char *fn_ext(const char *name)
Return a pointer to the extension of the filename.
SYNOPSIS
- fn_ext()
+ fn_ext2()
name Name of file
DESCRIPTION
@@ -66,7 +66,7 @@ char *fn_ext(const char *name)
(normally '.') after the directory name.
RETURN VALUES
- Pointer to to the extension character. If there isn't any extension,
+ Pointer to the extension character. If there isn't any extension,
points at the end ASCII(0) of the filename.
*/
@@ -86,6 +86,8 @@ char *fn_ext2(const char *name)
if (!(gpos= strrchr(name, FN_LIBCHAR)))
gpos= name;
#endif
- pos=strrchr(gpos,FN_EXTCHAR);
+ // locate the last occurence of FN_EXTCHAR
+ pos= strrchr(gpos, FN_EXTCHAR);
DBUG_RETURN((char*) (pos ? pos : strend(gpos)));
-} /* fn_ext */
+} /* fn_ext2 */
+
diff --git a/mysys/my_default.c b/mysys/my_default.c
index 8eb99d21b73..0bd76a1cff0 100644
--- a/mysys/my_default.c
+++ b/mysys/my_default.c
@@ -849,7 +849,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
for (i= 0; i < (uint) search_dir->number_of_files; i++)
{
search_file= search_dir->dir_entry + i;
- ext= fn_ext(search_file->name);
+ ext= fn_ext2(search_file->name);
/* check extension */
for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
diff --git a/sql/item.h b/sql/item.h
index 22d147028ef..36bd68e1b0b 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -164,6 +164,12 @@ public:
default: return "UNKNOWN";
}
}
+ int sortcmp(const String *s, const String *t) const
+ {
+ return collation->coll->strnncollsp(collation,
+ (uchar *) s->ptr(), s->length(),
+ (uchar *) t->ptr(), t->length(), 0);
+ }
};
/*************************************************************************/
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index fdc6df6fd94..62f63501d86 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1970,14 +1970,14 @@ longlong Item_func_lt::val_int()
longlong Item_func_strcmp::val_int()
{
DBUG_ASSERT(fixed == 1);
- String *a=args[0]->val_str(&cmp.value1);
- String *b=args[1]->val_str(&cmp.value2);
+ String *a= args[0]->val_str(&value1);
+ String *b= args[1]->val_str(&value2);
if (!a || !b)
{
null_value=1;
return 0;
}
- int value= sortcmp(a,b,cmp.cmp_collation.collation);
+ int value= cmp_collation.sortcmp(a, b);
null_value=0;
return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 71674c61d47..d4a1c6b1384 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -695,21 +695,18 @@ public:
};
-class Item_func_strcmp :public Item_bool_func2
+class Item_func_strcmp :public Item_int_func
{
+ String value1, value2;
+ DTCollation cmp_collation;
public:
- Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
+ Item_func_strcmp(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
- optimize_type select_optimize() const { return OPTIMIZE_NONE; }
+ uint decimal_precision() const { return 1; }
const char *func_name() const { return "strcmp"; }
-
- virtual inline void print(String *str, enum_query_type query_type)
- {
- Item_func::print(str, query_type);
- }
void fix_length_and_dec()
{
- Item_bool_func2::fix_length_and_dec();
+ agg_arg_charsets_for_comparison(cmp_collation, args, 2);
fix_char_length(2); // returns "1" or "0" or "-1"
}
};
@@ -803,6 +800,7 @@ public:
Item_func_nullif(Item *a,Item *b)
:Item_bool_func2(a,b), cached_result_type(INT_RESULT)
{}
+ bool is_bool_func() { return false; }
double val_real();
longlong val_int();
String *val_str(String *str);
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index 4665957528f..2d22adce8d9 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -471,17 +471,18 @@ void Mrr_ordered_index_reader::position()
void Mrr_ordered_index_reader::resume_read()
{
TABLE *table= file->get_table();
- if (read_was_interrupted)
+
+ if (!read_was_interrupted)
+ return;
+
+ KEY *used_index= &table->key_info[file->active_index];
+ key_restore(table->record[0], saved_key_tuple,
+ used_index, used_index->key_length);
+ if (saved_primary_key)
{
- KEY *used_index= &table->key_info[file->active_index];
- key_restore(table->record[0], saved_key_tuple,
- used_index, used_index->key_length);
- if (saved_primary_key)
- {
- key_restore(table->record[0], saved_primary_key,
- &table->key_info[table->s->primary_key],
- table->key_info[table->s->primary_key].key_length);
- }
+ key_restore(table->record[0], saved_primary_key,
+ &table->key_info[table->s->primary_key],
+ table->key_info[table->s->primary_key].key_length);
}
}
diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h
index 155a6e78f0b..ffae6d63124 100644
--- a/sql/multi_range_read.h
+++ b/sql/multi_range_read.h
@@ -340,8 +340,8 @@ private:
uchar *saved_key_tuple; /* Saved current key tuple */
uchar *saved_primary_key; /* Saved current primary key tuple */
- /*
- TRUE<=> saved_key_tuple (and saved_primary_key when applicable) have
+ /*
+ TRUE<=> saved_key_tuple (and saved_primary_key when applicable) have
valid values.
*/
bool read_was_interrupted;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 00e81767203..6871a6bd0af 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3487,6 +3487,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
my_bitmap_init(&handled_columns, buf, table->s->fields, FALSE);
/*
+ Calculate the selectivity of the range conditions supported by indexes.
+
First, take into account possible range accesses.
range access estimates are the most precise, we prefer them to any other
estimate sources.
@@ -3532,6 +3534,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
break;
bitmap_set_bit(&handled_columns, key_part->fieldnr-1);
}
+ double selectivity_mult;
if (i)
{
/*
@@ -3547,7 +3550,6 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
*/
double f1= key_info->actual_rec_per_key(i-1);
double f2= key_info->actual_rec_per_key(i);
- double selectivity_mult;
if (f1 > 0 && f2 > 0)
selectivity_mult= f1 / f2;
else
@@ -3559,8 +3561,23 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
*/
selectivity_mult= ((double)(i+1)) / i;
}
- table->cond_selectivity*= selectivity_mult;
+ table->cond_selectivity*= selectivity_mult;
}
+ /*
+ We need to set selectivity for fields supported by indexes.
+ For single-component indexes and for some first components
+ of other indexes we do it here. For the remaining fields
+ we do it later in this function, in the same way as for the
+ fields not used in any indexes.
+ */
+ if (i == 1)
+ {
+ uint fieldnr= key_info->key_part[0].fieldnr;
+ table->field[fieldnr-1]->cond_selectivity= quick_cond_selectivity;
+ if (i != used_key_parts)
+ table->field[fieldnr-1]->cond_selectivity*= selectivity_mult;
+ bitmap_clear_bit(used_fields, fieldnr-1);
+ }
}
}
}
@@ -3568,10 +3585,9 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
/*
Second step: calculate the selectivity of the range conditions not
- supported by any index
+ supported by any index and selectivity of the range condition
+ over the fields whose selectivity has not been set yet.
*/
- bitmap_subtract(used_fields, &handled_columns);
- /* no need to do: my_bitmap_free(&handled_columns); */
if (thd->variables.optimizer_use_condition_selectivity > 2 &&
!bitmap_is_clear_all(used_fields))
@@ -3647,9 +3663,12 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
for (Field **field_ptr= table->field; *field_ptr; field_ptr++)
{
Field *table_field= *field_ptr;
- if (bitmap_is_set(table->read_set, table_field->field_index) &&
+ if (bitmap_is_set(used_fields, table_field->field_index) &&
table_field->cond_selectivity < 1.0)
- table->cond_selectivity*= table_field->cond_selectivity;
+ {
+ if (!bitmap_is_set(&handled_columns, table_field->field_index))
+ table->cond_selectivity*= table_field->cond_selectivity;
+ }
}
free_alloc:
@@ -3658,10 +3677,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
}
- /* Calculate the selectivity of the range conditions supported by indexes */
-
- bitmap_clear_all(used_fields);
-
+ bitmap_union(used_fields, &handled_columns);
/* Check if we can improve selectivity estimates by using sampling */
ulong check_rows=
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 127c73ca873..c04fbe10a3b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3834,6 +3834,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
join->impossible_where= false;
if (conds && const_count)
{
+ COND_EQUAL *orig_cond_equal = join->cond_equal;
conds->update_used_tables();
conds= remove_eq_conds(join->thd, conds, &join->cond_value);
if (conds && conds->type() == Item::COND_ITEM &&
@@ -3860,7 +3861,21 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
join->cond_equal->current_level.empty();
join->cond_equal->current_level.push_back((Item_equal*) conds);
}
- }
+ }
+
+ if (orig_cond_equal != join->cond_equal)
+ {
+ /*
+ If join->cond_equal has changed all references to it from COND_EQUAL
+ objects associated with ON expressions must be updated.
+ */
+ for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
+ {
+ if (*s->on_expr_ref && s->cond_equal &&
+ s->cond_equal->upper_levels == orig_cond_equal)
+ s->cond_equal->upper_levels= join->cond_equal;
+ }
+ }
}
/* Calc how many (possible) matched records in each table */
@@ -4407,8 +4422,7 @@ add_key_field(JOIN *join,
if (is_const)
{
stat[0].const_keys.merge(possible_keys);
- if (possible_keys.is_clear_all())
- bitmap_set_bit(&field->table->cond_set, field->field_index);
+ bitmap_set_bit(&field->table->cond_set, field->field_index);
}
else if (!eq_func)
{
@@ -10550,6 +10564,19 @@ uint check_join_cache_usage(JOIN_TAB *tab,
}
/*
+ Don't use BKA for materialized tables. We could actually have a
+ meaningful use of BKA when linked join buffers are used.
+
+ The problem is, the temp.table is not filled (actually not even opened
+ properly) yet, and this doesn't let us call
+ handler->multi_range_read_info(). It is possible to come up with
+ estimates, etc. without acessing the table, but it seems not to worth the
+ effort now.
+ */
+ if (tab->table->pos_in_table_list->is_materialized_derived())
+ no_bka_cache= true;
+
+ /*
Don't use join buffering if we're dictated not to by no_jbuf_after
(This is not meaningfully used currently)
*/
@@ -10614,21 +10641,8 @@ uint check_join_cache_usage(JOIN_TAB *tab,
goto no_join_cache;
if (tab->ref.is_access_triggered())
goto no_join_cache;
-
- /*
- Don't use BKA for materialized tables. We could actually have a
- meaningful use of BKA when linked join buffers are used.
-
- The problem is, the temp.table is not filled (actually not even opened
- properly) yet, and this doesn't let us call
- handler->multi_range_read_info(). It is possible to come up with
- estimates, etc. without acessing the table, but it seems not to worth the
- effort now.
- */
- if (tab->table->pos_in_table_list->is_materialized_derived())
- goto no_join_cache;
- if (!tab->is_ref_for_hash_join())
+ if (!tab->is_ref_for_hash_join() && !no_bka_cache)
{
flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
if (tab->table->covering_keys.is_set(tab->ref.key))
@@ -13186,10 +13200,18 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
if (upper)
{
TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field);
- if (item_const && upper->get_const())
+ Item *upper_const= upper->get_const();
+ if (item_const && upper_const)
{
- /* Upper item also has "field_item=const". Don't produce equality here */
- item= 0;
+ /*
+ Upper item also has "field_item=const".
+ Don't produce equality if const is equal to item_const.
+ */
+ Item_func_eq *func= new Item_func_eq(item_const, upper_const);
+ func->set_cmp_func();
+ func->quick_fix_field();
+ if (func->val_int())
+ item= 0;
}
else
{
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index a38df24cfb7..9807a26f772 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -3502,7 +3502,12 @@ double get_column_range_cardinality(Field *field,
!(range_flag & NEAR_MIN);
if (col_non_nulls < 1)
- res= 0; /* this is likely wrong, see MDEV-6843 */
+ {
+ if (nulls_incl)
+ res= col_nulls;
+ else
+ res= 0;
+ }
else if (min_endp && max_endp && min_endp->length == max_endp->length &&
!memcmp(min_endp->key, max_endp->key, min_endp->length))
{
diff --git a/sql/table.cc b/sql/table.cc
index aba9779667f..c84b8ab17f6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6067,11 +6067,19 @@ bool TABLE::alloc_keys(uint key_count)
}
+/*
+ Given a field, fill key_part_info
+ @param keyinfo Key to where key part is added (we will
+ only adjust key_length there)
+ @param field IN Table field for which key part is needed
+ @param key_part_info OUT key part structure to be filled.
+ @param fieldnr Field's number.
+*/
void TABLE::create_key_part_by_field(KEY *keyinfo,
KEY_PART_INFO *key_part_info,
Field *field, uint fieldnr)
-{
- field->flags|= PART_KEY_FLAG;
+{
+ DBUG_ASSERT(field->field_index + 1 == (int)fieldnr);
key_part_info->null_bit= field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) record[0]);
@@ -6228,6 +6236,7 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
(*reg_field)->key_start.set_bit(key);
(*reg_field)->part_of_key.set_bit(key);
create_key_part_by_field(keyinfo, key_part_info, *reg_field, fld_idx+1);
+ (*reg_field)->flags|= PART_KEY_FLAG;
key_start= FALSE;
key_part_info++;
}
diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc
index a060cbc7270..4788b78ebd7 100644
--- a/storage/innobase/api/api0api.cc
+++ b/storage/innobase/api/api0api.cc
@@ -427,7 +427,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap);
+ tuple->heap, NULL);
ut_a(len != UNIV_SQL_NULL);
}
@@ -1531,7 +1531,11 @@ ib_execute_insert_query_graph(
dict_table_n_rows_inc(table);
- srv_stats.n_rows_inserted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_inserted.inc();
+ } else {
+ srv_stats.n_rows_inserted.inc();
+ }
}
trx->op_info = "";
@@ -1885,9 +1889,17 @@ ib_execute_update_query_graph(
dict_table_n_rows_dec(table);
- srv_stats.n_rows_deleted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.inc();
+ } else {
+ srv_stats.n_rows_deleted.inc();
+ }
} else {
- srv_stats.n_rows_updated.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.inc();
+ } else {
+ srv_stats.n_rows_updated.inc();
+ }
}
} else if (err == DB_RECORD_NOT_FOUND) {
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index bd3d688a0c2..f4972edefa9 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3610,7 +3610,8 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2) /*!< in: search mode for range end */
+ ulint mode2, /*!< in: search mode for range end */
+ trx_t* trx) /*!< in: trx */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3628,7 +3629,7 @@ btr_estimate_n_rows_in_range(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
cursor.path_arr = path1;
@@ -3646,7 +3647,7 @@ btr_estimate_n_rows_in_range(
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
cursor.path_arr = path2;
@@ -5228,7 +5229,8 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset) /*!< in: offset on the first BLOB page */
+ ulint offset, /*!< in: offset on the first BLOB page */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint copied_len = 0;
@@ -5240,7 +5242,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5443,7 +5445,8 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset) /*!< in: offset on the first BLOB page */
+ ulint offset, /*!< in: offset on the first BLOB page */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5454,7 +5457,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset));
+ page_no, offset, trx));
}
}
@@ -5475,7 +5478,8 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len)/*!< in: length of data, in bytes */
+ ulint local_len,/*!< in: length of data, in bytes */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint space_id;
ulint page_no;
@@ -5514,7 +5518,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset));
+ offset, trx));
}
/*******************************************************************//**
@@ -5533,7 +5537,8 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap) /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint space_id;
ulint page_no;
@@ -5564,7 +5569,8 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset);
+ page_no, offset,
+ trx);
return(buf);
}
@@ -5583,7 +5589,8 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap) /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint local_len;
const byte* data;
@@ -5614,6 +5621,7 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap));
+ zip_size, local_len, heap,
+ trx));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index 82a2b6dbf6b..01d2e1bb8e2 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -486,7 +486,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start(mtr);
+ mtr_start_trx(mtr, mtr->trx);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 6f00d2e43b5..18917259ed5 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -4937,22 +4937,22 @@ Returns the ratio in percents of modified pages in the buffer pool /
database pages in the buffer pool.
@return modified page percentage ratio */
UNIV_INTERN
-ulint
+double
buf_get_modified_ratio_pct(void)
/*============================*/
{
- ulint ratio;
+ double percentage = 0.0;
ulint lru_len = 0;
ulint free_len = 0;
ulint flush_list_len = 0;
buf_get_total_list_len(&lru_len, &free_len, &flush_list_len);
- ratio = (100 * flush_list_len) / (1 + lru_len + free_len);
+ percentage = (100.0 * flush_list_len) / (1.0 + lru_len + free_len);
/* 1 + is there to avoid division by zero */
- return(ratio);
+ return(percentage);
}
/*******************************************************************//**
@@ -5165,6 +5165,8 @@ buf_print_io_instance(
"Database pages %lu\n"
"Old database pages %lu\n"
"Modified db pages %lu\n"
+ "Percent of dirty pages(LRU & free pages): %.3f\n"
+ "Max dirty pages percent: %.3f\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
pool_info->pool_size,
@@ -5172,6 +5174,9 @@ buf_print_io_instance(
pool_info->lru_len,
pool_info->old_lru_len,
pool_info->flush_list_len,
+ (((double) pool_info->flush_list_len) /
+ (pool_info->lru_len + pool_info->free_list_len + 1.0)) * 100.0,
+ srv_max_buf_pool_modified_pct,
pool_info->n_pend_reads,
pool_info->n_pending_flush_lru,
pool_info->n_pending_flush_list,
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index fa2edb90b8e..8d6706cec53 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -75,6 +75,15 @@ in thrashing. */
/* @} */
+/** Handled page counters for a single flush */
+struct flush_counters_t {
+ ulint flushed; /*!< number of dirty pages flushed */
+ ulint evicted; /*!< number of clean pages evicted, including
+ evicted uncompressed page images */
+ ulint unzip_LRU_evicted;/*!< number of uncompressed page images
+ evicted */
+};
+
/******************************************************************//**
Increases flush_list size in bytes with zip_size for compressed page,
UNIV_PAGE_SIZE for uncompressed page in inline function */
@@ -1434,12 +1443,14 @@ it is a best effort attempt and it is not guaranteed that after a call
to this function there will be 'max' blocks in the free list.
@return number of blocks for which the write request was queued. */
static
-ulint
+void
buf_flush_LRU_list_batch(
/*=====================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ulint max) /*!< in: desired number of
+ ulint max, /*!< in: desired number of
blocks in the free_list */
+ flush_counters_t* n) /*!< out: flushed/evicted page
+ counts */
{
buf_page_t* bpage;
ulint count = 0;
@@ -1449,8 +1460,13 @@ buf_flush_LRU_list_batch(
ut_ad(buf_pool_mutex_own(buf_pool));
+ n->flushed = 0;
+ n->evicted = 0;
+ n->unzip_LRU_evicted = 0;
+
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL && count < max
+ && (n->flushed + n->evicted) < max
&& free_len < srv_LRU_scan_depth
&& lru_len > BUF_LRU_MIN_LEN) {
@@ -1478,6 +1494,7 @@ buf_flush_LRU_list_batch(
if (buf_LRU_free_page(bpage, true)) {
/* buf_pool->mutex was potentially
released and reacquired. */
+ n->evicted++;
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
} else {
bpage = UT_LIST_GET_PREV(LRU, bpage);
@@ -1500,7 +1517,7 @@ buf_flush_LRU_list_batch(
}
if (!buf_flush_page_and_try_neighbors(
- bpage, BUF_FLUSH_LRU, max, &count)) {
+ bpage, BUF_FLUSH_LRU, max, &n->flushed)) {
bpage = prev_bpage;
} else {
@@ -1529,7 +1546,7 @@ buf_flush_LRU_list_batch(
/* We keep track of all flushes happening as part of LRU
flush. When estimating the desired rate at which flush_list
should be flushed, we factor in this value. */
- buf_lru_flush_page_count += count;
+ buf_lru_flush_page_count += n->flushed;
ut_ad(buf_pool_mutex_own(buf_pool));
@@ -1540,8 +1557,6 @@ buf_flush_LRU_list_batch(
MONITOR_LRU_BATCH_SCANNED_PER_CALL,
scanned);
}
-
- return(count);
}
/*******************************************************************//**
@@ -1551,24 +1566,28 @@ Whether LRU or unzip_LRU is used depends on the state of the system.
or in case of unzip_LRU the number of blocks actually moved to the
free list */
static
-ulint
+void
buf_do_LRU_batch(
/*=============*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ulint max) /*!< in: desired number of
+ ulint max, /*!< in: desired number of
blocks in the free_list */
+ flush_counters_t* n) /*!< out: flushed/evicted page
+ counts */
{
- ulint count = 0;
if (buf_LRU_evict_from_unzip_LRU(buf_pool)) {
- count += buf_free_from_unzip_LRU_list_batch(buf_pool, max);
+ n->unzip_LRU_evicted = buf_free_from_unzip_LRU_list_batch(buf_pool, max);
+ } else {
+ n->unzip_LRU_evicted = 0;
}
- if (max > count) {
- count += buf_flush_LRU_list_batch(buf_pool, max - count);
+ if (max > n->unzip_LRU_evicted) {
+ buf_flush_LRU_list_batch(buf_pool, max - n->unzip_LRU_evicted, n);
+ } else {
+ n->evicted = 0;
+ n->flushed = 0;
}
-
- return(count);
}
/*******************************************************************//**
@@ -1667,7 +1686,7 @@ end up waiting for these latches! NOTE 2: in the case of a flush list flush,
the calling thread is not allowed to own any latches on pages!
@return number of blocks for which the write request was queued */
static
-ulint
+void
buf_flush_batch(
/*============*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
@@ -1678,13 +1697,14 @@ buf_flush_batch(
ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- lsn_t lsn_limit) /*!< in: in the case of BUF_FLUSH_LIST
+ lsn_t lsn_limit, /*!< in: in the case of BUF_FLUSH_LIST
all blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
min_n), otherwise ignored */
+ flush_counters_t* n) /*!< out: flushed/evicted page
+ counts */
{
- ulint count = 0;
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
#ifdef UNIV_SYNC_DEBUG
@@ -1698,10 +1718,11 @@ buf_flush_batch(
the flush functions. */
switch (flush_type) {
case BUF_FLUSH_LRU:
- count = buf_do_LRU_batch(buf_pool, min_n);
+ buf_do_LRU_batch(buf_pool, min_n, n);
break;
case BUF_FLUSH_LIST:
- count = buf_do_flush_list_batch(buf_pool, min_n, lsn_limit);
+ n->flushed = buf_do_flush_list_batch(buf_pool, min_n, lsn_limit);
+ n->evicted = 0;
break;
default:
ut_error;
@@ -1710,15 +1731,13 @@ buf_flush_batch(
buf_pool_mutex_exit(buf_pool);
#ifdef UNIV_DEBUG
- if (buf_debug_prints && count > 0) {
+ if (buf_debug_prints && n->flushed > 0) {
fprintf(stderr, flush_type == BUF_FLUSH_LRU
? "Flushed %lu pages in LRU flush\n"
: "Flushed %lu pages in flush list flush\n",
- (ulong) count);
+ (ulong) n->flushed);
}
#endif /* UNIV_DEBUG */
-
- return(count);
}
/******************************************************************//**
@@ -1847,29 +1866,21 @@ buf_flush_LRU(
ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- ulint* n_processed) /*!< out: the number of pages
- which were processed is passed
- back to caller. Ignored if NULL */
+ flush_counters_t *n) /*!< out: flushed/evicted page
+ counts */
{
- ulint page_count;
-
- if (n_processed) {
- *n_processed = 0;
- }
-
if (!buf_flush_start(buf_pool, BUF_FLUSH_LRU)) {
+ n->flushed = 0;
+ n->evicted = 0;
+ n->unzip_LRU_evicted = 0;
return(false);
}
- page_count = buf_flush_batch(buf_pool, BUF_FLUSH_LRU, min_n, 0);
+ buf_flush_batch(buf_pool, BUF_FLUSH_LRU, min_n, 0, n);
buf_flush_end(buf_pool, BUF_FLUSH_LRU);
- buf_flush_common(BUF_FLUSH_LRU, page_count);
-
- if (n_processed) {
- *n_processed = page_count;
- }
+ buf_flush_common(BUF_FLUSH_LRU, n->flushed);
return(true);
}
@@ -1917,7 +1928,7 @@ buf_flush_list(
/* Flush to lsn_limit in all buffer pool instances */
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
- ulint page_count = 0;
+ flush_counters_t n;
buf_pool = buf_pool_from_array(i);
@@ -1937,23 +1948,23 @@ buf_flush_list(
continue;
}
- page_count = buf_flush_batch(
- buf_pool, BUF_FLUSH_LIST, min_n, lsn_limit);
+ buf_flush_batch(
+ buf_pool, BUF_FLUSH_LIST, min_n, lsn_limit, &n);
buf_flush_end(buf_pool, BUF_FLUSH_LIST);
- buf_flush_common(BUF_FLUSH_LIST, page_count);
+ buf_flush_common(BUF_FLUSH_LIST, n.flushed);
if (n_processed) {
- *n_processed += page_count;
+ *n_processed += n.flushed;
}
- if (page_count) {
+ if (n.flushed) {
MONITOR_INC_VALUE_CUMULATIVE(
MONITOR_FLUSH_BATCH_TOTAL_PAGE,
MONITOR_FLUSH_BATCH_COUNT,
MONITOR_FLUSH_BATCH_PAGES,
- page_count);
+ n.flushed);
}
}
@@ -2091,7 +2102,7 @@ buf_flush_LRU_tail(void)
j < scan_depth;
j += PAGE_CLEANER_LRU_BATCH_CHUNK_SIZE) {
- ulint n_flushed = 0;
+ flush_counters_t n;
/* Currently page_cleaner is the only thread
that can trigger an LRU flush. It is possible
@@ -2099,7 +2110,7 @@ buf_flush_LRU_tail(void)
still running, */
if (buf_flush_LRU(buf_pool,
PAGE_CLEANER_LRU_BATCH_CHUNK_SIZE,
- &n_flushed)) {
+ &n)) {
/* Allowed only one batch per
buffer pool instance. */
@@ -2107,8 +2118,8 @@ buf_flush_LRU_tail(void)
buf_pool, BUF_FLUSH_LRU);
}
- if (n_flushed) {
- total_flushed += n_flushed;
+ if (n.flushed) {
+ total_flushed += n.flushed;
} else {
/* Nothing to flush */
break;
@@ -2411,25 +2422,16 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
- /* The page_cleaner skips sleep if the server is
- idle and there are no pending IOs in the buffer pool
- and there is work to do. */
- if (srv_check_activity(last_activity)
- || buf_get_n_pending_read_ios()
- || n_flushed == 0) {
- page_cleaner_sleep_if_needed(next_loop_time);
- }
+ page_cleaner_sleep_if_needed(next_loop_time);
next_loop_time = ut_time_ms() + 1000;
if (srv_check_activity(last_activity)) {
last_activity = srv_get_activity_count();
- /* Flush pages from end of LRU if required */
- n_flushed = buf_flush_LRU_tail();
-
/* Flush pages from flush_list if required */
- n_flushed += page_cleaner_flush_pages_if_needed();
+ page_cleaner_flush_pages_if_needed();
+ n_flushed = 0;
} else {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
@@ -2443,6 +2445,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}
+
+ /* Flush pages from end of LRU if required */
+ n_flushed = buf_flush_LRU_tail();
}
ut_ad(srv_shutdown_state > 0);
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 8574a6101e7..36eae54c17f 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1193,7 +1193,7 @@ buf_LRU_check_size_of_non_data_objects(
buf_lru_switched_on_innodb_mon = TRUE;
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
}
} else if (buf_lru_switched_on_innodb_mon) {
@@ -1342,7 +1342,7 @@ loop:
mon_value_was = srv_print_innodb_monitor;
started_monitor = TRUE;
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
}
/* If we have scanned the whole LRU and still are unable to
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 51e62fefa6b..bbeebf5a034 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1481,7 +1481,6 @@ struct dict_foreign_remove_partial
if (table != NULL) {
table->referenced_set.erase(foreign);
}
- dict_foreign_free(foreign);
}
};
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 885627a61bc..fefa34ead23 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -53,6 +53,14 @@ Created 1/8/1996 Heikki Tuuri
UNIV_INTERN mysql_pfs_key_t autoinc_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+/** System databases */
+static const char* innobase_system_databases[] = {
+ "mysql/",
+ "information_schema/",
+ "performance_schema/",
+ NullS
+};
+
/**********************************************************************//**
Creates a table memory object.
@return own: table object */
@@ -85,6 +93,7 @@ dict_mem_table_create(
table->flags2 = (unsigned int) flags2;
table->name = static_cast<char*>(ut_malloc(strlen(name) + 1));
memcpy(table->name, name, strlen(name) + 1);
+ table->is_system_db = dict_mem_table_is_system(table->name);
table->space = (unsigned int) space;
table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS);
@@ -131,6 +140,36 @@ dict_mem_table_create(
}
/****************************************************************//**
+Determines if a table belongs to a system database
+@return */
+UNIV_INTERN
+bool
+dict_mem_table_is_system(
+/*================*/
+ char *name) /*!< in: table name */
+{
+ ut_ad(name);
+
+ /* table has the following format: database/table
+ and some system table are of the form SYS_* */
+ if (strchr(name, '/')) {
+ int table_len = strlen(name);
+ const char *system_db;
+ int i = 0;
+ while ((system_db = innobase_system_databases[i++])
+ && (system_db != NullS)) {
+ int len = strlen(system_db);
+ if (table_len > len && !strncmp(name, system_db, len)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 08839f751ff..ba0476b1772 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -140,180 +140,9 @@ UNIV_INTERN mysql_pfs_key_t fil_system_mutex_key;
UNIV_INTERN mysql_pfs_key_t fil_space_latch_key;
#endif /* UNIV_PFS_RWLOCK */
-/** File node of a tablespace or the log data space */
-struct fil_node_t {
- fil_space_t* space; /*!< backpointer to the space where this node
- belongs */
- char* name; /*!< path to the file */
- ibool open; /*!< TRUE if file open */
- os_file_t handle; /*!< OS handle to the file, if file open */
- os_event_t sync_event;/*!< Condition event to group and
- serialize calls to fsync */
- ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
- device or a raw disk partition */
- ulint size; /*!< size of the file in database pages, 0 if
- not known yet; the possible last incomplete
- megabyte may be ignored if space == 0 */
- ulint n_pending;
- /*!< count of pending i/o's on this file;
- closing of the file is not allowed if
- this is > 0 */
- ulint n_pending_flushes;
- /*!< count of pending flushes on this file;
- closing of the file is not allowed if
- this is > 0 */
- ibool being_extended;
- /*!< TRUE if the node is currently
- being extended. */
- ib_int64_t modification_counter;/*!< when we write to the file we
- increment this by one */
- ib_int64_t flush_counter;/*!< up to what
- modification_counter value we have
- flushed the modifications to disk */
- UT_LIST_NODE_T(fil_node_t) chain;
- /*!< link field for the file chain */
- UT_LIST_NODE_T(fil_node_t) LRU;
- /*!< link field for the LRU list */
- ulint magic_n;/*!< FIL_NODE_MAGIC_N */
-};
-
-/** Value of fil_node_t::magic_n */
-#define FIL_NODE_MAGIC_N 89389
-
-/** Tablespace or log data space: let us call them by a common name space */
-struct fil_space_t {
- char* name; /*!< space name = the path to the first file in
- it */
- ulint id; /*!< space id */
- ib_int64_t tablespace_version;
- /*!< in DISCARD/IMPORT this timestamp
- is used to check if we should ignore
- an insert buffer merge request for a
- page because it actually was for the
- previous incarnation of the space */
- ibool mark; /*!< this is set to TRUE at database startup if
- the space corresponds to a table in the InnoDB
- data dictionary; so we can print a warning of
- orphaned tablespaces */
- ibool stop_ios;/*!< TRUE if we want to rename the
- .ibd file of tablespace and want to
- stop temporarily posting of new i/o
- requests on the file */
- ibool stop_new_ops;
- /*!< we set this TRUE when we start
- deleting a single-table tablespace.
- When this is set following new ops
- are not allowed:
- * read IO request
- * ibuf merge
- * file flush
- Note that we can still possibly have
- new write operations because we don't
- check this flag when doing flush
- batches. */
- ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
- FIL_ARCH_LOG */
- UT_LIST_BASE_NODE_T(fil_node_t) chain;
- /*!< base node for the file chain */
- ulint size; /*!< space size in pages; 0 if a single-table
- tablespace whose size we do not know yet;
- last incomplete megabytes in data files may be
- ignored if space == 0 */
- ulint flags; /*!< tablespace flags; see
- fsp_flags_is_valid(),
- fsp_flags_get_zip_size() */
- ulint n_reserved_extents;
- /*!< number of reserved free extents for
- ongoing operations like B-tree page split */
- ulint n_pending_flushes; /*!< this is positive when flushing
- the tablespace to disk; dropping of the
- tablespace is forbidden if this is positive */
- ulint n_pending_ops;/*!< this is positive when we
- have pending operations against this
- tablespace. The pending operations can
- be ibuf merges or lock validation code
- trying to read a block.
- Dropping of the tablespace is forbidden
- if this is positive */
- hash_node_t hash; /*!< hash chain node */
- hash_node_t name_hash;/*!< hash chain the name_hash table */
-#ifndef UNIV_HOTBACKUP
- rw_lock_t latch; /*!< latch protecting the file space storage
- allocation */
-#endif /* !UNIV_HOTBACKUP */
- UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
- /*!< list of spaces with at least one unflushed
- file we have written to */
- bool is_in_unflushed_spaces;
- /*!< true if this space is currently in
- unflushed_spaces */
- UT_LIST_NODE_T(fil_space_t) space_list;
- /*!< list of all spaces */
- ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
-};
-
-/** Value of fil_space_t::magic_n */
-#define FIL_SPACE_MAGIC_N 89472
-
-/** The tablespace memory cache; also the totality of logs (the log
-data space) is stored here; below we talk about tablespaces, but also
-the ib_logfiles form a 'space' and it is handled here */
-struct fil_system_t {
-#ifndef UNIV_HOTBACKUP
- ib_mutex_t mutex; /*!< The mutex protecting the cache */
-#endif /* !UNIV_HOTBACKUP */
- hash_table_t* spaces; /*!< The hash table of spaces in the
- system; they are hashed on the space
- id */
- hash_table_t* name_hash; /*!< hash table based on the space
- name */
- UT_LIST_BASE_NODE_T(fil_node_t) LRU;
- /*!< base node for the LRU list of the
- most recently used open files with no
- pending i/o's; if we start an i/o on
- the file, we first remove it from this
- list, and return it to the start of
- the list when the i/o ends;
- log files and the system tablespace are
- not put to this list: they are opened
- after the startup, and kept open until
- shutdown */
- UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
- /*!< base node for the list of those
- tablespaces whose files contain
- unflushed writes; those spaces have
- at least one file node where
- modification_counter > flush_counter */
- ulint n_open; /*!< number of files currently open */
- ulint max_n_open; /*!< n_open is not allowed to exceed
- this */
- ib_int64_t modification_counter;/*!< when we write to a file we
- increment this by one */
- ulint max_assigned_id;/*!< maximum space id in the existing
- tables, or assigned during the time
- mysqld has been up; at an InnoDB
- startup we scan the data dictionary
- and set here the maximum of the
- space id's of the tables there */
- ib_int64_t tablespace_version;
- /*!< a counter which is incremented for
- every space object memory creation;
- every space mem object gets a
- 'timestamp' from this; in DISCARD/
- IMPORT this is used to check if we
- should ignore an insert buffer merge
- request */
- UT_LIST_BASE_NODE_T(fil_space_t) space_list;
- /*!< list of all file spaces */
- ibool space_id_reuse_warned;
- /* !< TRUE if fil_space_create()
- has issued a warning about
- potential space_id reuse */
-};
-
/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
-static fil_system_t* fil_system = NULL;
+fil_system_t* fil_system = NULL;
/** Determine if (i) is a user tablespace id or not. */
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 848d60f6e3f..ae61b77c6de 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -3393,7 +3393,8 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg));
+ doc->self_heap->arg),
+ NULL);
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -7077,7 +7078,8 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg));
+ static_cast<mem_heap_t*>(doc.self_heap->arg),
+ NULL);
} else {
doc.text.f_str = static_cast<byte*>(
dfield_get_data(dfield));
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index f26fd89ac76..8f4813e4b3f 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1918,7 +1918,8 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap);
+ dfield_get_len(dfield), phrase->heap,
+ NULL);
} else {
cur_len = dfield_get_len(dfield);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 388032f3c96..166b2e6a79f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -669,6 +669,14 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_rows_read, SHOW_LONG},
{"rows_updated",
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
+ {"system_rows_deleted",
+ (char*) &export_vars.innodb_system_rows_deleted, SHOW_LONG},
+ {"system_rows_inserted",
+ (char*) &export_vars.innodb_system_rows_inserted, SHOW_LONG},
+ {"system_rows_read",
+ (char*) &export_vars.innodb_system_rows_read, SHOW_LONG},
+ {"system_rows_updated",
+ (char*) &export_vars.innodb_system_rows_updated, SHOW_LONG},
{"num_open_files",
(char*) &export_vars.innodb_num_open_files, SHOW_LONG},
{"truncated_status_writes",
@@ -3115,7 +3123,7 @@ innobase_change_buffering_inited_ok:
" cannot be set higher than"
" innodb_max_dirty_pages_pct.\n"
"InnoDB: Setting"
- " innodb_max_dirty_pages_pct_lwm to %lu\n",
+ " innodb_max_dirty_pages_pct_lwm to %lf\n",
srv_max_buf_pool_modified_pct);
srv_max_dirty_pages_pct_lwm = srv_max_buf_pool_modified_pct;
@@ -7892,7 +7900,13 @@ ha_innobase::index_read(
case DB_SUCCESS:
error = 0;
table->status = 0;
- srv_stats.n_rows_read.add((size_t) prebuilt->trx->id, 1);
+ if (prebuilt->table->is_system_db) {
+ srv_stats.n_system_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ } else {
+ srv_stats.n_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ }
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_KEY_NOT_FOUND;
@@ -8168,7 +8182,13 @@ ha_innobase::general_fetch(
case DB_SUCCESS:
error = 0;
table->status = 0;
- srv_stats.n_rows_read.add((size_t) prebuilt->trx->id, 1);
+ if (prebuilt->table->is_system_db) {
+ srv_stats.n_system_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ } else {
+ srv_stats.n_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ }
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_END_OF_FILE;
@@ -10842,7 +10862,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2);
+ mode2, prebuilt->trx);
} else {
n_rows = HA_POS_ERROR;
@@ -14275,7 +14295,7 @@ innodb_max_dirty_pages_pct_update(
const void* save) /*!< in: immediate result
from check function */
{
- ulong in_val = *static_cast<const ulong*>(save);
+ double in_val = *static_cast<const double*>(save);
if (in_val < srv_max_dirty_pages_pct_lwm) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
@@ -14285,7 +14305,7 @@ innodb_max_dirty_pages_pct_update(
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"Lowering"
- " innodb_max_dirty_page_pct_lwm to %lu",
+ " innodb_max_dirty_page_pct_lwm to %lf",
in_val);
srv_max_dirty_pages_pct_lwm = in_val;
@@ -14309,7 +14329,7 @@ innodb_max_dirty_pages_pct_lwm_update(
const void* save) /*!< in: immediate result
from check function */
{
- ulong in_val = *static_cast<const ulong*>(save);
+ double in_val = *static_cast<const double*>(save);
if (in_val > srv_max_buf_pool_modified_pct) {
in_val = srv_max_buf_pool_modified_pct;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -14320,7 +14340,7 @@ innodb_max_dirty_pages_pct_lwm_update(
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"Setting innodb_max_dirty_page_pct_lwm"
- " to %lu",
+ " to %lf",
in_val);
}
@@ -16019,9 +16039,8 @@ innodb_status_output_update(
const void* save __attribute__((unused)))
{
*static_cast<my_bool*>(var_ptr) = *static_cast<const my_bool*>(save);
- /* The lock timeout monitor thread also takes care of this
- output. */
- os_event_set(lock_sys->timeout_event);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
}
static SHOW_VAR innodb_status_variables_export[]= {
@@ -16248,22 +16267,22 @@ static MYSQL_SYSVAR_STR(log_group_home_dir, srv_log_group_home_dir,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Path to InnoDB log files.", NULL, NULL, NULL);
-static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
+static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, innodb_max_dirty_pages_pct_update, 75, 0, 99, 0);
+ NULL, innodb_max_dirty_pages_pct_update, 75.0, 0.001, 99.999, 0);
-static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct_lwm,
+static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct_lwm,
srv_max_dirty_pages_pct_lwm,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages at which flushing kicks in.",
- NULL, innodb_max_dirty_pages_pct_lwm_update, 0, 0, 99, 0);
+ NULL, innodb_max_dirty_pages_pct_lwm_update, 0.001, 0.000, 99.999, 0);
-static MYSQL_SYSVAR_ULONG(adaptive_flushing_lwm,
+static MYSQL_SYSVAR_DOUBLE(adaptive_flushing_lwm,
srv_adaptive_flushing_lwm,
PLUGIN_VAR_RQCMDARG,
"Percentage of log capacity below which no adaptive flushing happens.",
- NULL, NULL, 10, 0, 70, 0);
+ NULL, NULL, 10.0, 0.0, 70.0, 0);
static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
PLUGIN_VAR_NOCMDARG,
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index f1e4406fcf7..d0fd5c2158a 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -561,7 +561,8 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2); /*!< in: search mode for range end */
+ ulint mode2, /*!< in: search mode for range end */
+ trx_t* trx); /*!< in: trx */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -697,7 +698,8 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len);/*!< in: length of data, in bytes */
+ ulint local_len,/*!< in: length of data, in bytes */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -714,7 +716,8 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap); /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -729,7 +732,8 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap); /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 3f2ac4980cf..31ec6b9ef8b 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -794,7 +794,7 @@ Returns the ratio in percents of modified pages in the buffer pool /
database pages in the buffer pool.
@return modified page percentage ratio */
UNIV_INTERN
-ulint
+double
buf_get_modified_ratio_pct(void);
/*============================*/
/**********************************************************************//**
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index f5326fbdb41..802d7b3af53 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -256,6 +256,14 @@ dict_mem_table_create(
ulint n_cols, /*!< in: number of columns */
ulint flags, /*!< in: table flags */
ulint flags2); /*!< in: table flags2 */
+/**********************************************************************//**
+Determines if a table belongs to a system database
+@return */
+UNIV_INTERN
+bool
+dict_mem_table_is_system(
+/*==================*/
+ char *name); /*!< in: table name */
/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
@@ -880,6 +888,10 @@ struct dict_table_t{
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
+ bool is_system_db;
+ /*!< True if the table belongs to a system
+ database (mysql, information_schema or
+ performance_schema) */
#ifndef UNIV_HOTBACKUP
hash_node_t name_hash; /*!< hash chain node */
hash_node_t id_hash; /*!< hash chain node */
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index b607ca36d70..798423eeddd 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -33,6 +33,7 @@ Created 10/25/1995 Heikki Tuuri
#include "dict0types.h"
#include "ut0byte.h"
#include "os0file.h"
+#include "hash0hash.h"
#ifndef UNIV_HOTBACKUP
#include "sync0rw.h"
#include "ibuf0types.h"
@@ -190,6 +191,183 @@ struct fsp_open_info {
#endif /* UNIV_LOG_ARCHIVE */
};
+struct fil_space_t;
+
+/** File node of a tablespace or the log data space */
+struct fil_node_t {
+ fil_space_t* space; /*!< backpointer to the space where this node
+ belongs */
+ char* name; /*!< path to the file */
+ ibool open; /*!< TRUE if file open */
+ os_file_t handle; /*!< OS handle to the file, if file open */
+ os_event_t sync_event;/*!< Condition event to group and
+ serialize calls to fsync */
+ ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
+ device or a raw disk partition */
+ ulint size; /*!< size of the file in database pages, 0 if
+ not known yet; the possible last incomplete
+ megabyte may be ignored if space == 0 */
+ ulint n_pending;
+ /*!< count of pending i/o's on this file;
+ closing of the file is not allowed if
+ this is > 0 */
+ ulint n_pending_flushes;
+ /*!< count of pending flushes on this file;
+ closing of the file is not allowed if
+ this is > 0 */
+ ibool being_extended;
+ /*!< TRUE if the node is currently
+ being extended. */
+ ib_int64_t modification_counter;/*!< when we write to the file we
+ increment this by one */
+ ib_int64_t flush_counter;/*!< up to what
+ modification_counter value we have
+ flushed the modifications to disk */
+ UT_LIST_NODE_T(fil_node_t) chain;
+ /*!< link field for the file chain */
+ UT_LIST_NODE_T(fil_node_t) LRU;
+ /*!< link field for the LRU list */
+ ulint magic_n;/*!< FIL_NODE_MAGIC_N */
+};
+
+/** Value of fil_node_t::magic_n */
+#define FIL_NODE_MAGIC_N 89389
+
+/** Tablespace or log data space: let us call them by a common name space */
+struct fil_space_t {
+ char* name; /*!< space name = the path to the first file in
+ it */
+ ulint id; /*!< space id */
+ ib_int64_t tablespace_version;
+ /*!< in DISCARD/IMPORT this timestamp
+ is used to check if we should ignore
+ an insert buffer merge request for a
+ page because it actually was for the
+ previous incarnation of the space */
+ ibool mark; /*!< this is set to TRUE at database startup if
+ the space corresponds to a table in the InnoDB
+ data dictionary; so we can print a warning of
+ orphaned tablespaces */
+ ibool stop_ios;/*!< TRUE if we want to rename the
+ .ibd file of tablespace and want to
+ stop temporarily posting of new i/o
+ requests on the file */
+ ibool stop_new_ops;
+ /*!< we set this TRUE when we start
+ deleting a single-table tablespace.
+ When this is set following new ops
+ are not allowed:
+ * read IO request
+ * ibuf merge
+ * file flush
+ Note that we can still possibly have
+ new write operations because we don't
+ check this flag when doing flush
+ batches. */
+ ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
+ FIL_ARCH_LOG */
+ UT_LIST_BASE_NODE_T(fil_node_t) chain;
+ /*!< base node for the file chain */
+ ulint size; /*!< space size in pages; 0 if a single-table
+ tablespace whose size we do not know yet;
+ last incomplete megabytes in data files may be
+ ignored if space == 0 */
+ ulint flags; /*!< tablespace flags; see
+ fsp_flags_is_valid(),
+ fsp_flags_get_zip_size() */
+ ulint n_reserved_extents;
+ /*!< number of reserved free extents for
+ ongoing operations like B-tree page split */
+ ulint n_pending_flushes; /*!< this is positive when flushing
+ the tablespace to disk; dropping of the
+ tablespace is forbidden if this is positive */
+ ulint n_pending_ops;/*!< this is positive when we
+ have pending operations against this
+ tablespace. The pending operations can
+ be ibuf merges or lock validation code
+ trying to read a block.
+ Dropping of the tablespace is forbidden
+ if this is positive */
+ hash_node_t hash; /*!< hash chain node */
+ hash_node_t name_hash;/*!< hash chain the name_hash table */
+#ifndef UNIV_HOTBACKUP
+ rw_lock_t latch; /*!< latch protecting the file space storage
+ allocation */
+#endif /* !UNIV_HOTBACKUP */
+ UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
+ /*!< list of spaces with at least one unflushed
+ file we have written to */
+ bool is_in_unflushed_spaces;
+ /*!< true if this space is currently in
+ unflushed_spaces */
+ UT_LIST_NODE_T(fil_space_t) space_list;
+ /*!< list of all spaces */
+ ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
+};
+
+/** Value of fil_space_t::magic_n */
+#define FIL_SPACE_MAGIC_N 89472
+
+/** The tablespace memory cache; also the totality of logs (the log
+data space) is stored here; below we talk about tablespaces, but also
+the ib_logfiles form a 'space' and it is handled here */
+struct fil_system_t {
+#ifndef UNIV_HOTBACKUP
+ ib_mutex_t mutex; /*!< The mutex protecting the cache */
+#endif /* !UNIV_HOTBACKUP */
+ hash_table_t* spaces; /*!< The hash table of spaces in the
+ system; they are hashed on the space
+ id */
+ hash_table_t* name_hash; /*!< hash table based on the space
+ name */
+ UT_LIST_BASE_NODE_T(fil_node_t) LRU;
+ /*!< base node for the LRU list of the
+ most recently used open files with no
+ pending i/o's; if we start an i/o on
+ the file, we first remove it from this
+ list, and return it to the start of
+ the list when the i/o ends;
+ log files and the system tablespace are
+ not put to this list: they are opened
+ after the startup, and kept open until
+ shutdown */
+ UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
+ /*!< base node for the list of those
+ tablespaces whose files contain
+ unflushed writes; those spaces have
+ at least one file node where
+ modification_counter > flush_counter */
+ ulint n_open; /*!< number of files currently open */
+ ulint max_n_open; /*!< n_open is not allowed to exceed
+ this */
+ ib_int64_t modification_counter;/*!< when we write to a file we
+ increment this by one */
+ ulint max_assigned_id;/*!< maximum space id in the existing
+ tables, or assigned during the time
+ mysqld has been up; at an InnoDB
+ startup we scan the data dictionary
+ and set here the maximum of the
+ space id's of the tables there */
+ ib_int64_t tablespace_version;
+ /*!< a counter which is incremented for
+ every space object memory creation;
+ every space mem object gets a
+ 'timestamp' from this; in DISCARD/
+ IMPORT this is used to check if we
+ should ignore an insert buffer merge
+ request */
+ UT_LIST_BASE_NODE_T(fil_space_t) space_list;
+ /*!< list of all file spaces */
+ ibool space_id_reuse_warned;
+ /* !< TRUE if fil_space_create()
+ has issued a warning about
+ potential space_id reuse */
+};
+
+/** The tablespace memory cache. This variable is NULL before the module is
+initialized. */
+extern fil_system_t* fil_system;
+
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
Returns the version number of a tablespace, -1 if not found.
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index ed7fd76d425..b91dbd0353c 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -35,6 +35,7 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
+#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -204,10 +205,22 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
+mtr_start_trx(
+/*======*/
+ mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx) /*!< in: transaction */
+ __attribute__((nonnull (1)));
+/***************************************************************//**
+Starts a mini-transaction. */
+UNIV_INLINE
+void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
- __attribute__((nonnull));
+{
+ mtr_start_trx(mtr, NULL);
+}
+ __attribute__((nonnull))
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -403,6 +416,7 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
+ trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index a9f02430220..44d548e9b64 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -43,9 +43,10 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start(
+mtr_start_trx(
/*======*/
- mtr_t* mtr) /*!< out: mini-transaction */
+ mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx) /*!< in: transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -58,6 +59,7 @@ mtr_start(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
+ mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index e2ab81bf53a..2d90f47eefe 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -369,6 +369,10 @@ enum monitor_id_t {
MONITOR_OLVD_ROW_INSERTED,
MONITOR_OLVD_ROW_DELETED,
MONITOR_OLVD_ROW_UPDTATED,
+ MONITOR_OLVD_SYSTEM_ROW_READ,
+ MONITOR_OLVD_SYSTEM_ROW_INSERTED,
+ MONITOR_OLVD_SYSTEM_ROW_DELETED,
+ MONITOR_OLVD_SYSTEM_ROW_UPDATED,
/* Data DDL related counters */
MONITOR_MODULE_DDL_STATS,
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 7bf698f0a66..aebc622cb20 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -126,6 +126,18 @@ struct srv_stats_t {
/** Number of rows inserted */
ulint_ctr_64_t n_rows_inserted;
+
+ /** Number of system rows read. */
+ ulint_ctr_64_t n_system_rows_read;
+
+ /** Number of system rows updated */
+ ulint_ctr_64_t n_system_rows_updated;
+
+ /** Number of system rows deleted */
+ ulint_ctr_64_t n_system_rows_deleted;
+
+ /** Number of system rows inserted */
+ ulint_ctr_64_t n_system_rows_inserted;
};
extern const char* srv_main_thread_op_info;
@@ -320,10 +332,10 @@ extern ulint srv_win_file_flush_method;
extern ulint srv_max_n_open_files;
-extern ulong srv_max_dirty_pages_pct;
-extern ulong srv_max_dirty_pages_pct_lwm;
+extern double srv_max_dirty_pages_pct;
+extern double srv_max_dirty_pages_pct_lwm;
-extern ulong srv_adaptive_flushing_lwm;
+extern double srv_adaptive_flushing_lwm;
extern ulong srv_flushing_avg_loops;
extern ulong srv_force_recovery;
@@ -354,7 +366,7 @@ extern ibool srv_use_atomic_writes;
extern ibool srv_use_posix_fallocate;
#endif
-extern ulong srv_max_buf_pool_modified_pct;
+extern double srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
extern ulong srv_max_purge_lag_delay;
@@ -846,6 +858,10 @@ struct export_var_t{
ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */
ulint innodb_rows_updated; /*!< srv_n_rows_updated */
ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
+ ulint innodb_system_rows_read; /*!< srv_n_system_rows_read */
+ ulint innodb_system_rows_inserted; /*!< srv_n_system_rows_inserted */
+ ulint innodb_system_rows_updated; /*!< srv_n_system_rows_updated */
+ ulint innodb_system_rows_deleted; /*!< srv_n_system_rows_deleted*/
ulint innodb_num_open_files; /*!< fil_n_file_opened */
ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
ulint innodb_available_undo_logs; /*!< srv_available_undo_logs */
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index 61b0dabb1e6..660551961a6 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -243,22 +243,13 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end_func(
+trx_undo_truncate_end(
/*=======================*/
-#ifdef UNIV_DEBUG
- const trx_t* trx, /*!< in: transaction whose undo log it is */
-#endif /* UNIV_DEBUG */
+ trx_t* trx, /*!< in: transaction whose undo log it is */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
__attribute__((nonnull));
-#ifdef UNIV_DEBUG
-# define trx_undo_truncate_end(trx,undo,limit) \
- trx_undo_truncate_end_func(trx,undo,limit)
-#else /* UNIV_DEBUG */
-# define trx_undo_truncate_end(trx,undo,limit) \
- trx_undo_truncate_end_func(undo,limit)
-#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index a1c35e20ead..4f4a0eb223b 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -259,10 +259,6 @@ lock_wait_suspend_thread(
}
}
- /* Wake the lock timeout monitor thread, if it is suspended */
-
- os_event_set(lock_sys->timeout_event);
-
lock_wait_mutex_exit();
trx_mutex_exit(trx);
diff --git a/storage/innobase/os/os0sync.cc b/storage/innobase/os/os0sync.cc
index e42c5900c0c..779152a3a56 100644
--- a/storage/innobase/os/os0sync.cc
+++ b/storage/innobase/os/os0sync.cc
@@ -686,7 +686,7 @@ os_event_wait_time_low(
tv.tv_usec += time_in_usec;
if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
- tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
+ tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND;
tv.tv_usec %= MICROSECS_IN_A_SECOND;
}
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index 32b78391d6a..ad852577ad2 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -78,7 +78,8 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len);
+ buf, ext->max_len, zip_size, field, f_len,
+ NULL);
}
}
}
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 94af15dc658..b11a9f0d85a 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -660,7 +660,8 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap);
+ zip_size, data_len, blob_heap,
+ NULL);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 49bb5980548..9ea173494d9 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1294,7 +1294,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
/* Restore pcur position */
@@ -1322,7 +1322,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1530,7 +1530,7 @@ run_again:
}
}
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Store old value on n_fields_cmp */
@@ -2331,7 +2331,7 @@ row_ins_clust_index_entry_low(
|| n_uniq == dict_index_get_n_unique(index));
ut_ad(!n_uniq || n_uniq == dict_index_get_n_unique(index));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED;
@@ -2544,9 +2544,10 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static __attribute__((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_and_check_if_aborted(
+row_ins_sec_mtr_start_trx_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2554,7 +2555,7 @@ row_ins_sec_mtr_start_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
if (!check) {
return(false);
@@ -2612,13 +2613,14 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
+ trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Ensure that we acquire index->lock when inserting into an
index with index->online_status == ONLINE_INDEX_COMPLETE, but
@@ -2679,8 +2681,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_and_check_if_aborted(
- &mtr, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
+ &mtr, trx, index, check, search_mode)) {
goto func_exit;
}
@@ -2714,8 +2716,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_and_check_if_aborted(
- &mtr, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
+ &mtr, trx, index, check, search_mode)) {
goto func_exit;
}
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 24abd885f60..fd0c54d889b 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -980,7 +980,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len);
+ blob_field, field_len, zip_size, field, len, NULL);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1371,7 +1371,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap);
+ i, &len, heap, NULL);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 86b47c9f3bd..e9d8bd50d6a 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2246,7 +2246,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap);
+ mrec, offsets, zip_size, i, &len, heap, NULL);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index da79c53808b..efc89ff1f34 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1394,7 +1394,11 @@ error_exit:
que_thr_stop_for_mysql_no_error(thr, trx);
- srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ }
/* Not protected by dict_table_stats_lock() for performance
reasons, we would rather get garbage in stat_n_rows (which is
@@ -1784,9 +1788,20 @@ run_again:
with a latch. */
dict_table_n_rows_dec(prebuilt->table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
+
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
/* We update table statistics only if it is a DELETE or UPDATE
@@ -1850,7 +1865,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Restore the cursor position and find the record */
@@ -2010,9 +2025,19 @@ run_again:
with a latch. */
dict_table_n_rows_dec(table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
row_update_statistics_if_needed(table);
@@ -2200,23 +2225,23 @@ err_exit:
/* The lock timeout monitor thread also takes care
of InnoDB monitor prints */
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_lock_monitor)) {
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_tablespace_monitor)) {
srv_print_innodb_tablespace_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_table_monitor)) {
srv_print_innodb_table_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
#ifdef UNIV_MEM_DEBUG
} else if (STR_EQ(table_name, table_name_len,
S_innodb_mem_validate)) {
@@ -3412,7 +3437,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
fsp_header_init(space,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3441,7 +3466,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3488,7 +3513,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index e5a7694cb93..abfa06130d8 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -132,7 +132,8 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len);
+ clust_field, clust_len,
+ NULL);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -451,7 +452,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap);
+ field_no, &len, heap, NULL);
/* data == NULL means that the
externally stored field was not
@@ -1398,7 +1399,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1438,7 +1439,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
}
if (search_latch_locked) {
@@ -2809,7 +2810,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap);
+ field_no, &len, heap, NULL);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -3885,7 +3886,7 @@ row_search_for_mysql(
}
}
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -4015,7 +4016,7 @@ release_search_latch_if_needed:
}
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
}
}
@@ -5002,7 +5003,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5067,7 +5068,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index e513d3d6d8b..8580aa45145 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -297,7 +297,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
online = dict_index_is_online_ddl(index);
if (online) {
@@ -326,7 +326,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a pessimistic
descent down the index tree */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -371,7 +371,7 @@ row_undo_mod_clust(
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -384,7 +384,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a
pessimistic descent down the index tree */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -431,7 +431,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -487,7 +487,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
which cannot be purged yet, requires its existence. If some requires,
we should delete mark the record. */
- mtr_start(&mtr_vers);
+ mtr_start_trx(&mtr_vers, thr_get_trx(thr));
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -603,7 +603,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index db810e28735..a8c2eaa6683 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -210,7 +210,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -984,7 +984,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len);
+ buf, *len, zip_size, data, local_len, NULL);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1685,7 +1685,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -2152,7 +2152,7 @@ row_upd_clust_rec(
/* We may have to modify the tree structure: do a pessimistic descent
down the index tree */
- mtr_start(mtr);
+ mtr_start_trx(mtr, thr_get_trx(thr));
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2319,7 +2319,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2373,7 +2373,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc
index 64417b1e5fb..f29621bc90a 100644
--- a/storage/innobase/srv/srv0mon.cc
+++ b/storage/innobase/srv/srv0mon.cc
@@ -1165,6 +1165,26 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DEFAULT_ON),
MONITOR_DEFAULT_START, MONITOR_OLVD_ROW_UPDTATED},
+ {"dml_system_reads", "dml", "Number of system rows read",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_READ},
+
+ {"dml_system_inserts", "dml", "Number of system rows inserted",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_INSERTED},
+
+ {"dml_system_deletes", "dml", "Number of system rows deleted",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_DELETED},
+
+ {"dml_system_updates", "dml", "Number of system rows updated",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_UPDATED},
+
/* ========== Counters for DDL operations ========== */
{"module_ddl", "ddl", "Statistics for DDLs",
MONITOR_MODULE,
@@ -1683,6 +1703,26 @@ srv_mon_process_existing_counter(
value = srv_stats.n_rows_updated;
break;
+ /* innodb_system_rows_read */
+ case MONITOR_OLVD_SYSTEM_ROW_READ:
+ value = srv_stats.n_system_rows_read;
+ break;
+
+ /* innodb_system_rows_inserted */
+ case MONITOR_OLVD_SYSTEM_ROW_INSERTED:
+ value = srv_stats.n_system_rows_inserted;
+ break;
+
+ /* innodb_system_rows_deleted */
+ case MONITOR_OLVD_SYSTEM_ROW_DELETED:
+ value = srv_stats.n_system_rows_deleted;
+ break;
+
+ /* innodb_system_rows_updated */
+ case MONITOR_OLVD_SYSTEM_ROW_UPDATED:
+ value = srv_stats.n_system_rows_updated;
+ break;
+
/* innodb_row_lock_current_waits */
case MONITOR_OVLD_ROW_LOCK_CURRENT_WAIT:
value = srv_stats.n_lock_wait_current_count;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index bc0e8e625e3..f40576615d4 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -276,12 +276,12 @@ in the buffer pool to all database pages in the buffer pool smaller than
the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
-UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
-UNIV_INTERN ulong srv_max_dirty_pages_pct_lwm = 50;
+UNIV_INTERN double srv_max_buf_pool_modified_pct = 75.0;
+UNIV_INTERN double srv_max_dirty_pages_pct_lwm = 50.0;
/* This is the percentage of log capacity at which adaptive flushing,
if enabled, will kick in. */
-UNIV_INTERN ulong srv_adaptive_flushing_lwm = 10;
+UNIV_INTERN double srv_adaptive_flushing_lwm = 10.0;
/* Number of iterations over which adaptive flushing is averaged. */
UNIV_INTERN ulong srv_flushing_avg_loops = 30;
@@ -377,6 +377,10 @@ static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
+static ulint srv_n_system_rows_inserted_old = 0;
+static ulint srv_n_system_rows_updated_old = 0;
+static ulint srv_n_system_rows_deleted_old = 0;
+static ulint srv_n_system_rows_read_old = 0;
UNIV_INTERN ulint srv_truncated_status_writes = 0;
UNIV_INTERN ulint srv_available_undo_logs = 0;
@@ -1110,6 +1114,11 @@ srv_refresh_innodb_monitor_stats(void)
srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
srv_n_rows_read_old = srv_stats.n_rows_read;
+ srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted;
+ srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated;
+ srv_n_system_rows_deleted_old = srv_stats.n_system_rows_deleted;
+ srv_n_system_rows_read_old = srv_stats.n_system_rows_read;
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -1301,11 +1310,33 @@ srv_printf_innodb_monitor(
/ time_elapsed,
((ulint) srv_stats.n_rows_read - srv_n_rows_read_old)
/ time_elapsed);
-
+ fprintf(file,
+ "Number of system rows inserted " ULINTPF
+ ", updated " ULINTPF ", deleted " ULINTPF
+ ", read " ULINTPF "\n",
+ (ulint) srv_stats.n_system_rows_inserted,
+ (ulint) srv_stats.n_system_rows_updated,
+ (ulint) srv_stats.n_system_rows_deleted,
+ (ulint) srv_stats.n_system_rows_read);
+ fprintf(file,
+ "%.2f inserts/s, %.2f updates/s,"
+ " %.2f deletes/s, %.2f reads/s\n",
+ ((ulint) srv_stats.n_system_rows_inserted
+ - srv_n_system_rows_inserted_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_updated
+ - srv_n_system_rows_updated_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_deleted
+ - srv_n_system_rows_deleted_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_read
+ - srv_n_system_rows_read_old) / time_elapsed);
srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
srv_n_rows_updated_old = srv_stats.n_rows_updated;
srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
srv_n_rows_read_old = srv_stats.n_rows_read;
+ srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted;
+ srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated;
+ srv_n_system_rows_deleted_old = srv_stats.n_system_rows_deleted;
+ srv_n_system_rows_read_old = srv_stats.n_system_rows_read;
fputs("----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n"
@@ -1460,6 +1491,17 @@ srv_export_innodb_status(void)
export_vars.innodb_rows_deleted = srv_stats.n_rows_deleted;
+ export_vars.innodb_system_rows_read = srv_stats.n_system_rows_read;
+
+ export_vars.innodb_system_rows_inserted =
+ srv_stats.n_system_rows_inserted;
+
+ export_vars.innodb_system_rows_updated =
+ srv_stats.n_system_rows_updated;
+
+ export_vars.innodb_system_rows_deleted =
+ srv_stats.n_system_rows_deleted;
+
export_vars.innodb_num_open_files = fil_n_file_opened;
export_vars.innodb_truncated_status_writes =
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index f643e5b794f..46238d732ba 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -1074,7 +1074,7 @@ sync_array_print_long_waits(
(ulong) os_file_n_pending_pwrites);
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
os_thread_sleep(30000000);
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index 01ccfb8a6d0..993006efc6d 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -1639,7 +1639,7 @@ trx_i_s_create_lock_id(
} else {
/* table lock */
res_len = ut_snprintf(lock_id, lock_id_size,
- TRX_ID_FMT":" UINT64PF,
+ TRX_ID_FMT ":" UINT64PF,
row->lock_trx_id,
row->lock_table_id);
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index a698b37c2a6..11ad7fe4afd 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -466,7 +466,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len);
+ ext_buf, prefix_len, zip_size, field, *len, NULL);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -1247,7 +1247,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1336,7 +1336,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1373,7 +1373,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 290271c6cab..edb85a89c17 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1067,11 +1067,9 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end_func(
+trx_undo_truncate_end(
/*=======================*/
-#ifdef UNIV_DEBUG
- const trx_t* trx, /*!< in: transaction whose undo log it is */
-#endif /* UNIV_DEBUG */
+ trx_t* trx, /*!< in: transaction whose undo log it is */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1086,7 +1084,7 @@ trx_undo_truncate_end_func(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
trunc_here = NULL;
@@ -1773,7 +1771,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&rseg->mutex);
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc
index a060cbc7270..4788b78ebd7 100644
--- a/storage/xtradb/api/api0api.cc
+++ b/storage/xtradb/api/api0api.cc
@@ -427,7 +427,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap);
+ tuple->heap, NULL);
ut_a(len != UNIV_SQL_NULL);
}
@@ -1531,7 +1531,11 @@ ib_execute_insert_query_graph(
dict_table_n_rows_inc(table);
- srv_stats.n_rows_inserted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_inserted.inc();
+ } else {
+ srv_stats.n_rows_inserted.inc();
+ }
}
trx->op_info = "";
@@ -1885,9 +1889,17 @@ ib_execute_update_query_graph(
dict_table_n_rows_dec(table);
- srv_stats.n_rows_deleted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.inc();
+ } else {
+ srv_stats.n_rows_deleted.inc();
+ }
} else {
- srv_stats.n_rows_updated.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.inc();
+ } else {
+ srv_stats.n_rows_updated.inc();
+ }
}
} else if (err == DB_RECORD_NOT_FOUND) {
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 5d8b5c04d68..5307489c5de 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3801,7 +3801,8 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2) /*!< in: search mode for range end */
+ ulint mode2, /*!< in: search mode for range end */
+ trx_t* trx) /*!< in: trx */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3819,7 +3820,7 @@ btr_estimate_n_rows_in_range(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
cursor.path_arr = path1;
@@ -3837,7 +3838,7 @@ btr_estimate_n_rows_in_range(
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
cursor.path_arr = path2;
@@ -5430,7 +5431,8 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset) /*!< in: offset on the first BLOB page */
+ ulint offset, /*!< in: offset on the first BLOB page */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint copied_len = 0;
@@ -5442,7 +5444,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5645,7 +5647,8 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset) /*!< in: offset on the first BLOB page */
+ ulint offset, /*!< in: offset on the first BLOB page */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5656,7 +5659,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset));
+ page_no, offset, trx));
}
}
@@ -5677,7 +5680,8 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len)/*!< in: length of data, in bytes */
+ ulint local_len,/*!< in: length of data, in bytes */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint space_id;
ulint page_no;
@@ -5716,7 +5720,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset));
+ offset, trx));
}
/*******************************************************************//**
@@ -5735,7 +5739,8 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap) /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint space_id;
ulint page_no;
@@ -5766,7 +5771,8 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset);
+ page_no, offset,
+ trx);
return(buf);
}
@@ -5785,7 +5791,8 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap) /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint local_len;
const byte* data;
@@ -5816,6 +5823,7 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap));
+ zip_size, local_len, heap,
+ trx));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0pcur.cc b/storage/xtradb/btr/btr0pcur.cc
index 28a60de6ba2..dd6ef484fc3 100644
--- a/storage/xtradb/btr/btr0pcur.cc
+++ b/storage/xtradb/btr/btr0pcur.cc
@@ -501,7 +501,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start(mtr);
+ mtr_start_trx(mtr, mtr->trx);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 98b6787dda4..abb4a6f3ab9 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -5203,22 +5203,22 @@ Returns the ratio in percents of modified pages in the buffer pool /
database pages in the buffer pool.
@return modified page percentage ratio */
UNIV_INTERN
-ulint
+double
buf_get_modified_ratio_pct(void)
/*============================*/
{
- ulint ratio;
+ double percentage = 0.0;
ulint lru_len = 0;
ulint free_len = 0;
ulint flush_list_len = 0;
buf_get_total_list_len(&lru_len, &free_len, &flush_list_len);
- ratio = (100 * flush_list_len) / (1 + lru_len + free_len);
+ percentage = (100.0 * flush_list_len) / (1.0 + lru_len + free_len);
/* 1 + is there to avoid division by zero */
- return(ratio);
+ return(percentage);
}
/*******************************************************************//**
@@ -5434,6 +5434,8 @@ buf_print_io_instance(
"Database pages %lu\n"
"Old database pages %lu\n"
"Modified db pages %lu\n"
+ "Percent of dirty pages(LRU & free pages): %.3f\n"
+ "Max dirty pages percent: %.3f\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
pool_info->pool_size,
@@ -5442,6 +5444,9 @@ buf_print_io_instance(
pool_info->lru_len,
pool_info->old_lru_len,
pool_info->flush_list_len,
+ (((double) pool_info->flush_list_len) /
+ (pool_info->lru_len + pool_info->free_list_len + 1.0)) * 100.0,
+ srv_max_buf_pool_modified_pct,
pool_info->n_pend_reads,
pool_info->n_pending_flush_lru,
pool_info->n_pending_flush_list,
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index d1656a4dd48..827e01e2096 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -2694,14 +2694,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
srv_current_thread_priority = srv_cleaner_thread_priority;
- /* The page_cleaner skips sleep if the server is
- idle and there are no pending IOs in the buffer pool
- and there is work to do. */
- if (srv_check_activity(last_activity)
- || buf_get_n_pending_read_ios()
- || n_flushed == 0) {
- page_cleaner_sleep_if_needed(next_loop_time);
- }
+ page_cleaner_sleep_if_needed(next_loop_time);
page_cleaner_sleep_time
= page_cleaner_adapt_flush_sleep_time();
@@ -2709,6 +2702,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
next_loop_time = ut_time_ms() + page_cleaner_sleep_time;
server_active = srv_check_activity(last_activity);
+
if (server_active
|| ut_time_ms() - last_activity_time < 1000) {
@@ -2719,7 +2713,8 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
}
/* Flush pages from flush_list if required */
- n_flushed += page_cleaner_flush_pages_if_needed();
+ page_cleaner_flush_pages_if_needed();
+ n_flushed = 0;
} else {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
@@ -2733,6 +2728,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}
+
+ /* Flush pages from end of LRU if required */
+ n_flushed = buf_flush_LRU_tail();
}
ut_ad(srv_shutdown_state > 0);
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index 3b0319e4e79..e9b6d8f3fb5 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1282,7 +1282,7 @@ buf_LRU_check_size_of_non_data_objects(
buf_lru_switched_on_innodb_mon = TRUE;
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
}
} else if (buf_lru_switched_on_innodb_mon) {
@@ -1497,7 +1497,7 @@ loop:
mon_value_was = srv_print_innodb_monitor;
started_monitor = TRUE;
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
}
/* If we have scanned the whole LRU and still are unable to
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 3ccade0bfc4..5ac932e98a3 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -1481,7 +1481,6 @@ struct dict_foreign_remove_partial
if (table != NULL) {
table->referenced_set.erase(foreign);
}
- dict_foreign_free(foreign);
}
};
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index 5e0ffab4bf7..164d2e36e71 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -53,6 +53,14 @@ Created 1/8/1996 Heikki Tuuri
UNIV_INTERN mysql_pfs_key_t autoinc_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+/** System databases */
+static const char* innobase_system_databases[] = {
+ "mysql/",
+ "information_schema/",
+ "performance_schema/",
+ NullS
+};
+
/**********************************************************************//**
Creates a table memory object.
@return own: table object */
@@ -88,6 +96,7 @@ dict_mem_table_create(
table->flags2 = (unsigned int) flags2;
table->name = static_cast<char*>(ut_malloc(strlen(name) + 1));
memcpy(table->name, name, strlen(name) + 1);
+ table->is_system_db = dict_mem_table_is_system(table->name);
table->space = (unsigned int) space;
table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS);
@@ -144,6 +153,36 @@ dict_mem_table_create(
}
/****************************************************************//**
+Determines if a table belongs to a system database
+@return */
+UNIV_INTERN
+bool
+dict_mem_table_is_system(
+/*================*/
+ char *name) /*!< in: table name */
+{
+ ut_ad(name);
+
+ /* table has the following format: database/table
+ and some system table are of the form SYS_* */
+ if (strchr(name, '/')) {
+ int table_len = strlen(name);
+ const char *system_db;
+ int i = 0;
+ while ((system_db = innobase_system_databases[i++])
+ && (system_db != NullS)) {
+ int len = strlen(system_db);
+ if (table_len > len && !strncmp(name, system_db, len)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 852311d3864..759cdfc9f45 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -140,181 +140,15 @@ UNIV_INTERN mysql_pfs_key_t fil_system_mutex_key;
UNIV_INTERN mysql_pfs_key_t fil_space_latch_key;
#endif /* UNIV_PFS_RWLOCK */
-/** File node of a tablespace or the log data space */
-struct fil_node_t {
- fil_space_t* space; /*!< backpointer to the space where this node
- belongs */
- char* name; /*!< path to the file */
- ibool open; /*!< TRUE if file open */
- os_file_t handle; /*!< OS handle to the file, if file open */
- os_event_t sync_event;/*!< Condition event to group and
- serialize calls to fsync */
- ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
- device or a raw disk partition */
- ulint size; /*!< size of the file in database pages, 0 if
- not known yet; the possible last incomplete
- megabyte may be ignored if space == 0 */
- ulint n_pending;
- /*!< count of pending i/o's on this file;
- closing of the file is not allowed if
- this is > 0 */
- ulint n_pending_flushes;
- /*!< count of pending flushes on this file;
- closing of the file is not allowed if
- this is > 0 */
- ibool being_extended;
- /*!< TRUE if the node is currently
- being extended. */
- ib_int64_t modification_counter;/*!< when we write to the file we
- increment this by one */
- ib_int64_t flush_counter;/*!< up to what
- modification_counter value we have
- flushed the modifications to disk */
- UT_LIST_NODE_T(fil_node_t) chain;
- /*!< link field for the file chain */
- UT_LIST_NODE_T(fil_node_t) LRU;
- /*!< link field for the LRU list */
- ulint magic_n;/*!< FIL_NODE_MAGIC_N */
-};
-
/** Value of fil_node_t::magic_n */
#define FIL_NODE_MAGIC_N 89389
-/** Tablespace or log data space: let us call them by a common name space */
-struct fil_space_t {
- char* name; /*!< space name = the path to the first file in
- it */
- ulint id; /*!< space id */
- ib_int64_t tablespace_version;
- /*!< in DISCARD/IMPORT this timestamp
- is used to check if we should ignore
- an insert buffer merge request for a
- page because it actually was for the
- previous incarnation of the space */
- ibool mark; /*!< this is set to TRUE at database startup if
- the space corresponds to a table in the InnoDB
- data dictionary; so we can print a warning of
- orphaned tablespaces */
- ibool stop_ios;/*!< TRUE if we want to rename the
- .ibd file of tablespace and want to
- stop temporarily posting of new i/o
- requests on the file */
- ibool stop_new_ops;
- /*!< we set this TRUE when we start
- deleting a single-table tablespace.
- When this is set following new ops
- are not allowed:
- * read IO request
- * ibuf merge
- * file flush
- Note that we can still possibly have
- new write operations because we don't
- check this flag when doing flush
- batches. */
- ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
- FIL_ARCH_LOG */
- UT_LIST_BASE_NODE_T(fil_node_t) chain;
- /*!< base node for the file chain */
- ulint size; /*!< space size in pages; 0 if a single-table
- tablespace whose size we do not know yet;
- last incomplete megabytes in data files may be
- ignored if space == 0 */
- ulint flags; /*!< tablespace flags; see
- fsp_flags_is_valid(),
- fsp_flags_get_zip_size() */
- ulint n_reserved_extents;
- /*!< number of reserved free extents for
- ongoing operations like B-tree page split */
- ulint n_pending_flushes; /*!< this is positive when flushing
- the tablespace to disk; dropping of the
- tablespace is forbidden if this is positive */
- ulint n_pending_ops;/*!< this is positive when we
- have pending operations against this
- tablespace. The pending operations can
- be ibuf merges or lock validation code
- trying to read a block.
- Dropping of the tablespace is forbidden
- if this is positive */
- hash_node_t hash; /*!< hash chain node */
- hash_node_t name_hash;/*!< hash chain the name_hash table */
-#ifndef UNIV_HOTBACKUP
- prio_rw_lock_t latch; /*!< latch protecting the file space storage
- allocation */
-#endif /* !UNIV_HOTBACKUP */
- UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
- /*!< list of spaces with at least one unflushed
- file we have written to */
- bool is_in_unflushed_spaces;
- /*!< true if this space is currently in
- unflushed_spaces */
- ibool is_corrupt;
- UT_LIST_NODE_T(fil_space_t) space_list;
- /*!< list of all spaces */
- ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
-};
-
/** Value of fil_space_t::magic_n */
#define FIL_SPACE_MAGIC_N 89472
-/** The tablespace memory cache; also the totality of logs (the log
-data space) is stored here; below we talk about tablespaces, but also
-the ib_logfiles form a 'space' and it is handled here */
-struct fil_system_t {
-#ifndef UNIV_HOTBACKUP
- ib_mutex_t mutex; /*!< The mutex protecting the cache */
-#endif /* !UNIV_HOTBACKUP */
- hash_table_t* spaces; /*!< The hash table of spaces in the
- system; they are hashed on the space
- id */
- hash_table_t* name_hash; /*!< hash table based on the space
- name */
- UT_LIST_BASE_NODE_T(fil_node_t) LRU;
- /*!< base node for the LRU list of the
- most recently used open files with no
- pending i/o's; if we start an i/o on
- the file, we first remove it from this
- list, and return it to the start of
- the list when the i/o ends;
- log files and the system tablespace are
- not put to this list: they are opened
- after the startup, and kept open until
- shutdown */
- UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
- /*!< base node for the list of those
- tablespaces whose files contain
- unflushed writes; those spaces have
- at least one file node where
- modification_counter > flush_counter */
- ulint n_open; /*!< number of files currently open */
- ulint max_n_open; /*!< n_open is not allowed to exceed
- this */
- ib_int64_t modification_counter;/*!< when we write to a file we
- increment this by one */
- ulint max_assigned_id;/*!< maximum space id in the existing
- tables, or assigned during the time
- mysqld has been up; at an InnoDB
- startup we scan the data dictionary
- and set here the maximum of the
- space id's of the tables there */
- ib_int64_t tablespace_version;
- /*!< a counter which is incremented for
- every space object memory creation;
- every space mem object gets a
- 'timestamp' from this; in DISCARD/
- IMPORT this is used to check if we
- should ignore an insert buffer merge
- request */
- UT_LIST_BASE_NODE_T(fil_space_t) space_list;
- /*!< list of all file spaces */
- ibool space_id_reuse_warned;
- /* !< TRUE if fil_space_create()
- has issued a warning about
- potential space_id reuse */
-};
-
/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
-static fil_system_t* fil_system = NULL;
+fil_system_t* fil_system = NULL;
/** Determine if (i) is a user tablespace id or not. */
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 8884e944dfd..d57f1e09b54 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -3393,7 +3393,8 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg));
+ doc->self_heap->arg),
+ NULL);
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -7077,7 +7078,8 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg));
+ static_cast<mem_heap_t*>(doc.self_heap->arg),
+ NULL);
} else {
doc.text.f_str = static_cast<byte*>(
dfield_get_data(dfield));
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index beeb31abb9e..1ca5f80b182 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1918,7 +1918,8 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap);
+ dfield_get_len(dfield), phrase->heap,
+ NULL);
} else {
cur_len = dfield_get_len(dfield);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index d91cc962b43..18acdd5dbca 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -864,6 +864,14 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_rows_read, SHOW_LONG},
{"rows_updated",
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
+ {"system_rows_deleted",
+ (char*) &export_vars.innodb_system_rows_deleted, SHOW_LONG},
+ {"system_rows_inserted",
+ (char*) &export_vars.innodb_system_rows_inserted, SHOW_LONG},
+ {"system_rows_read",
+ (char*) &export_vars.innodb_system_rows_read, SHOW_LONG},
+ {"system_rows_updated",
+ (char*) &export_vars.innodb_system_rows_updated, SHOW_LONG},
{"s_lock_os_waits",
(char*) &export_vars.innodb_s_lock_os_waits, SHOW_LONGLONG},
{"s_lock_spin_rounds",
@@ -3517,7 +3525,7 @@ innobase_change_buffering_inited_ok:
" cannot be set higher than"
" innodb_max_dirty_pages_pct.\n"
"InnoDB: Setting"
- " innodb_max_dirty_pages_pct_lwm to %lu\n",
+ " innodb_max_dirty_pages_pct_lwm to %lf\n",
srv_max_buf_pool_modified_pct);
srv_max_dirty_pages_pct_lwm = srv_max_buf_pool_modified_pct;
@@ -8513,7 +8521,13 @@ ha_innobase::index_read(
case DB_SUCCESS:
error = 0;
table->status = 0;
- srv_stats.n_rows_read.add((size_t) prebuilt->trx->id, 1);
+ if (prebuilt->table->is_system_db) {
+ srv_stats.n_system_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ } else {
+ srv_stats.n_rows_read.add(
+ (size_t) prebuilt->trx->id, 1);
+ }
#ifdef EXTENDED_FOR_USERSTAT
rows_read++;
if (active_index < MAX_KEY)
@@ -11512,7 +11526,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2);
+ mode2, prebuilt->trx);
} else {
n_rows = HA_POS_ERROR;
@@ -15051,7 +15065,7 @@ innodb_max_dirty_pages_pct_update(
const void* save) /*!< in: immediate result
from check function */
{
- ulong in_val = *static_cast<const ulong*>(save);
+ double in_val = *static_cast<const double*>(save);
if (in_val < srv_max_dirty_pages_pct_lwm) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
@@ -15061,7 +15075,7 @@ innodb_max_dirty_pages_pct_update(
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"Lowering"
- " innodb_max_dirty_page_pct_lwm to %lu",
+ " innodb_max_dirty_page_pct_lwm to %lf",
in_val);
srv_max_dirty_pages_pct_lwm = in_val;
@@ -15085,7 +15099,7 @@ innodb_max_dirty_pages_pct_lwm_update(
const void* save) /*!< in: immediate result
from check function */
{
- ulong in_val = *static_cast<const ulong*>(save);
+ double in_val = *static_cast<const double*>(save);
if (in_val > srv_max_buf_pool_modified_pct) {
in_val = srv_max_buf_pool_modified_pct;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -15096,7 +15110,7 @@ innodb_max_dirty_pages_pct_lwm_update(
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"Setting innodb_max_dirty_page_pct_lwm"
- " to %lu",
+ " to %lf",
in_val);
}
@@ -17055,9 +17069,8 @@ innodb_status_output_update(
const void* save __attribute__((unused)))
{
*static_cast<my_bool*>(var_ptr) = *static_cast<const my_bool*>(save);
- /* The lock timeout monitor thread also takes care of this
- output. */
- os_event_set(lock_sys->timeout_event);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
}
static SHOW_VAR innodb_status_variables_export[]= {
@@ -17339,22 +17352,22 @@ static MYSQL_SYSVAR_ULONG(log_arch_expire_sec,
"Expiration time for archived innodb transaction logs.",
NULL, innodb_log_archive_expire_update, 0, 0, ~0UL, 0);
-static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
+static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, innodb_max_dirty_pages_pct_update, 75, 0, 99, 0);
+ NULL, innodb_max_dirty_pages_pct_update, 75.0, 0.001, 99.999, 0);
-static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct_lwm,
+static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct_lwm,
srv_max_dirty_pages_pct_lwm,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages at which flushing kicks in.",
- NULL, innodb_max_dirty_pages_pct_lwm_update, 0, 0, 99, 0);
+ NULL, innodb_max_dirty_pages_pct_lwm_update, 0.001, 0.000, 99.999, 0);
-static MYSQL_SYSVAR_ULONG(adaptive_flushing_lwm,
+static MYSQL_SYSVAR_DOUBLE(adaptive_flushing_lwm,
srv_adaptive_flushing_lwm,
PLUGIN_VAR_RQCMDARG,
"Percentage of log capacity below which no adaptive flushing happens.",
- NULL, NULL, 10, 0, 70, 0);
+ NULL, NULL, 10.0, 0.0, 70.0, 0);
static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
PLUGIN_VAR_NOCMDARG,
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index 4ed66e76fe0..f4b91b08fc5 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -567,7 +567,8 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2); /*!< in: search mode for range end */
+ ulint mode2, /*!< in: search mode for range end */
+ trx_t* trx); /*!< in: trx */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -703,7 +704,8 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len);/*!< in: length of data, in bytes */
+ ulint local_len,/*!< in: length of data, in bytes */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -720,7 +722,8 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap); /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -735,7 +738,8 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap); /*!< in: mem heap */
+ mem_heap_t* heap, /*!< in: mem heap */
+ trx_t* trx); /*!< in: transaction handle */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 0f77404b1de..ad10b8d1eb2 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -792,7 +792,7 @@ Returns the ratio in percents of modified pages in the buffer pool /
database pages in the buffer pool.
@return modified page percentage ratio */
UNIV_INTERN
-ulint
+double
buf_get_modified_ratio_pct(void);
/*============================*/
/**********************************************************************//**
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 9652d4d335f..f45f664e0c3 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -266,6 +266,14 @@ dict_mem_table_create(
bool nonshared);/*!< in: whether the table object is a dummy
one that does not need the initialization of
locking-related fields. */
+/**********************************************************************//**
+Determines if a table belongs to a system database
+@return true if table belong to a system database */
+UNIV_INTERN
+bool
+dict_mem_table_is_system(
+/*==================*/
+ char *name); /*!< in: table name */
/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
@@ -894,6 +902,10 @@ struct dict_table_t{
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
+ bool is_system_db;
+ /*!< True if the table belongs to a system
+ database (mysql, information_schema or
+ performance_schema) */
#ifndef UNIV_HOTBACKUP
hash_node_t name_hash; /*!< hash chain node */
hash_node_t id_hash; /*!< hash chain node */
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index f7ff367484e..d6be9fae31c 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -33,6 +33,7 @@ Created 10/25/1995 Heikki Tuuri
#include "dict0types.h"
#include "ut0byte.h"
#include "os0file.h"
+#include "hash0hash.h"
#ifndef UNIV_HOTBACKUP
#include "sync0rw.h"
#include "ibuf0types.h"
@@ -188,6 +189,184 @@ struct fsp_open_info {
ulint flags; /*!< Tablespace flags */
};
+struct fil_space_t;
+
+/** File node of a tablespace or the log data space */
+struct fil_node_t {
+ fil_space_t* space; /*!< backpointer to the space where this node
+ belongs */
+ char* name; /*!< path to the file */
+ ibool open; /*!< TRUE if file open */
+ os_file_t handle; /*!< OS handle to the file, if file open */
+ os_event_t sync_event;/*!< Condition event to group and
+ serialize calls to fsync */
+ ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
+ device or a raw disk partition */
+ ulint size; /*!< size of the file in database pages, 0 if
+ not known yet; the possible last incomplete
+ megabyte may be ignored if space == 0 */
+ ulint n_pending;
+ /*!< count of pending i/o's on this file;
+ closing of the file is not allowed if
+ this is > 0 */
+ ulint n_pending_flushes;
+ /*!< count of pending flushes on this file;
+ closing of the file is not allowed if
+ this is > 0 */
+ ibool being_extended;
+ /*!< TRUE if the node is currently
+ being extended. */
+ ib_int64_t modification_counter;/*!< when we write to the file we
+ increment this by one */
+ ib_int64_t flush_counter;/*!< up to what
+ modification_counter value we have
+ flushed the modifications to disk */
+ UT_LIST_NODE_T(fil_node_t) chain;
+ /*!< link field for the file chain */
+ UT_LIST_NODE_T(fil_node_t) LRU;
+ /*!< link field for the LRU list */
+ ulint magic_n;/*!< FIL_NODE_MAGIC_N */
+};
+
+/** Value of fil_node_t::magic_n */
+#define FIL_NODE_MAGIC_N 89389
+
+/** Tablespace or log data space: let us call them by a common name space */
+struct fil_space_t {
+ char* name; /*!< space name = the path to the first file in
+ it */
+ ulint id; /*!< space id */
+ ib_int64_t tablespace_version;
+ /*!< in DISCARD/IMPORT this timestamp
+ is used to check if we should ignore
+ an insert buffer merge request for a
+ page because it actually was for the
+ previous incarnation of the space */
+ ibool mark; /*!< this is set to TRUE at database startup if
+ the space corresponds to a table in the InnoDB
+ data dictionary; so we can print a warning of
+ orphaned tablespaces */
+ ibool stop_ios;/*!< TRUE if we want to rename the
+ .ibd file of tablespace and want to
+ stop temporarily posting of new i/o
+ requests on the file */
+ ibool stop_new_ops;
+ /*!< we set this TRUE when we start
+ deleting a single-table tablespace.
+ When this is set following new ops
+ are not allowed:
+ * read IO request
+ * ibuf merge
+ * file flush
+ Note that we can still possibly have
+ new write operations because we don't
+ check this flag when doing flush
+ batches. */
+ ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
+ FIL_ARCH_LOG */
+ UT_LIST_BASE_NODE_T(fil_node_t) chain;
+ /*!< base node for the file chain */
+ ulint size; /*!< space size in pages; 0 if a single-table
+ tablespace whose size we do not know yet;
+ last incomplete megabytes in data files may be
+ ignored if space == 0 */
+ ulint flags; /*!< tablespace flags; see
+ fsp_flags_is_valid(),
+ fsp_flags_get_zip_size() */
+ ulint n_reserved_extents;
+ /*!< number of reserved free extents for
+ ongoing operations like B-tree page split */
+ ulint n_pending_flushes; /*!< this is positive when flushing
+ the tablespace to disk; dropping of the
+ tablespace is forbidden if this is positive */
+ ulint n_pending_ops;/*!< this is positive when we
+ have pending operations against this
+ tablespace. The pending operations can
+ be ibuf merges or lock validation code
+ trying to read a block.
+ Dropping of the tablespace is forbidden
+ if this is positive */
+ hash_node_t hash; /*!< hash chain node */
+ hash_node_t name_hash;/*!< hash chain the name_hash table */
+#ifndef UNIV_HOTBACKUP
+ prio_rw_lock_t latch; /*!< latch protecting the file space storage
+ allocation */
+#endif /* !UNIV_HOTBACKUP */
+ UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
+ /*!< list of spaces with at least one unflushed
+ file we have written to */
+ bool is_in_unflushed_spaces;
+ /*!< true if this space is currently in
+ unflushed_spaces */
+ ibool is_corrupt;
+ UT_LIST_NODE_T(fil_space_t) space_list;
+ /*!< list of all spaces */
+ ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
+};
+
+/** Value of fil_space_t::magic_n */
+#define FIL_SPACE_MAGIC_N 89472
+
+/** The tablespace memory cache; also the totality of logs (the log
+data space) is stored here; below we talk about tablespaces, but also
+the ib_logfiles form a 'space' and it is handled here */
+struct fil_system_t {
+#ifndef UNIV_HOTBACKUP
+ ib_mutex_t mutex; /*!< The mutex protecting the cache */
+#endif /* !UNIV_HOTBACKUP */
+ hash_table_t* spaces; /*!< The hash table of spaces in the
+ system; they are hashed on the space
+ id */
+ hash_table_t* name_hash; /*!< hash table based on the space
+ name */
+ UT_LIST_BASE_NODE_T(fil_node_t) LRU;
+ /*!< base node for the LRU list of the
+ most recently used open files with no
+ pending i/o's; if we start an i/o on
+ the file, we first remove it from this
+ list, and return it to the start of
+ the list when the i/o ends;
+ log files and the system tablespace are
+ not put to this list: they are opened
+ after the startup, and kept open until
+ shutdown */
+ UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
+ /*!< base node for the list of those
+ tablespaces whose files contain
+ unflushed writes; those spaces have
+ at least one file node where
+ modification_counter > flush_counter */
+ ulint n_open; /*!< number of files currently open */
+ ulint max_n_open; /*!< n_open is not allowed to exceed
+ this */
+ ib_int64_t modification_counter;/*!< when we write to a file we
+ increment this by one */
+ ulint max_assigned_id;/*!< maximum space id in the existing
+ tables, or assigned during the time
+ mysqld has been up; at an InnoDB
+ startup we scan the data dictionary
+ and set here the maximum of the
+ space id's of the tables there */
+ ib_int64_t tablespace_version;
+ /*!< a counter which is incremented for
+ every space object memory creation;
+ every space mem object gets a
+ 'timestamp' from this; in DISCARD/
+ IMPORT this is used to check if we
+ should ignore an insert buffer merge
+ request */
+ UT_LIST_BASE_NODE_T(fil_space_t) space_list;
+ /*!< list of all file spaces */
+ ibool space_id_reuse_warned;
+ /* !< TRUE if fil_space_create()
+ has issued a warning about
+ potential space_id reuse */
+};
+
+/** The tablespace memory cache. This variable is NULL before the module is
+initialized. */
+extern fil_system_t* fil_system;
+
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
Returns the version number of a tablespace, -1 if not found.
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index 0730e870b3f..827039953be 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -35,6 +35,7 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
+#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -204,10 +205,22 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
+mtr_start_trx(
+/*======*/
+ mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx) /*!< in: transaction */
+ __attribute__((nonnull (1)));
+/***************************************************************//**
+Starts a mini-transaction. */
+UNIV_INLINE
+void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
- __attribute__((nonnull));
+{
+ mtr_start_trx(mtr, NULL);
+}
+ __attribute__((nonnull))
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -403,6 +416,7 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
+ trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index cc021038001..aade8c3d82a 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -43,9 +43,10 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start(
+mtr_start_trx(
/*======*/
- mtr_t* mtr) /*!< out: mini-transaction */
+ mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx) /*!< in: transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -58,6 +59,7 @@ mtr_start(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
+ mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h
index e2ab81bf53a..2d90f47eefe 100644
--- a/storage/xtradb/include/srv0mon.h
+++ b/storage/xtradb/include/srv0mon.h
@@ -369,6 +369,10 @@ enum monitor_id_t {
MONITOR_OLVD_ROW_INSERTED,
MONITOR_OLVD_ROW_DELETED,
MONITOR_OLVD_ROW_UPDTATED,
+ MONITOR_OLVD_SYSTEM_ROW_READ,
+ MONITOR_OLVD_SYSTEM_ROW_INSERTED,
+ MONITOR_OLVD_SYSTEM_ROW_DELETED,
+ MONITOR_OLVD_SYSTEM_ROW_UPDATED,
/* Data DDL related counters */
MONITOR_MODULE_DDL_STATS,
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 14f2d68ff45..dcb92ca41a3 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -127,8 +127,23 @@ struct srv_stats_t {
/** Number of rows inserted */
ulint_ctr_64_t n_rows_inserted;
+ /** Number of system rows read. */
+ ulint_ctr_64_t n_system_rows_read;
+
+ /** Number of system rows updated */
+ ulint_ctr_64_t n_system_rows_updated;
+
+ /** Number of system rows deleted */
+ ulint_ctr_64_t n_system_rows_deleted;
+
+ /** Number of system rows inserted */
+ ulint_ctr_64_t n_system_rows_inserted;
+
+ /** Number of lock deadlocks */
ulint_ctr_1_t lock_deadlock_count;
+ /** Number of lock waits that have been up to max time (i.e.) lock
+ wait timeout */
ulint_ctr_1_t n_lock_max_wait_time;
};
@@ -388,10 +403,10 @@ extern ulint srv_win_file_flush_method;
extern ulint srv_max_n_open_files;
-extern ulong srv_max_dirty_pages_pct;
-extern ulong srv_max_dirty_pages_pct_lwm;
+extern double srv_max_dirty_pages_pct;
+extern double srv_max_dirty_pages_pct_lwm;
-extern ulong srv_adaptive_flushing_lwm;
+extern double srv_adaptive_flushing_lwm;
extern ulong srv_flushing_avg_loops;
extern ulong srv_force_recovery;
@@ -423,7 +438,7 @@ extern ulong srv_checksum_algorithm;
extern ulong srv_log_arch_expire_sec;
-extern ulong srv_max_buf_pool_modified_pct;
+extern double srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
extern ulong srv_max_purge_lag_delay;
@@ -1052,6 +1067,10 @@ struct export_var_t{
ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */
ulint innodb_rows_updated; /*!< srv_n_rows_updated */
ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
+ ulint innodb_system_rows_read; /*!< srv_n_system_rows_read */
+ ulint innodb_system_rows_inserted; /*!< srv_n_system_rows_inserted */
+ ulint innodb_system_rows_updated; /*!< srv_n_system_rows_updated */
+ ulint innodb_system_rows_deleted; /*!< srv_n_system_rows_deleted*/
ulint innodb_num_open_files; /*!< fil_n_file_opened */
ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
ulint innodb_available_undo_logs; /*!< srv_available_undo_logs */
diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h
index 61b0dabb1e6..660551961a6 100644
--- a/storage/xtradb/include/trx0undo.h
+++ b/storage/xtradb/include/trx0undo.h
@@ -243,22 +243,13 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end_func(
+trx_undo_truncate_end(
/*=======================*/
-#ifdef UNIV_DEBUG
- const trx_t* trx, /*!< in: transaction whose undo log it is */
-#endif /* UNIV_DEBUG */
+ trx_t* trx, /*!< in: transaction whose undo log it is */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
__attribute__((nonnull));
-#ifdef UNIV_DEBUG
-# define trx_undo_truncate_end(trx,undo,limit) \
- trx_undo_truncate_end_func(trx,undo,limit)
-#else /* UNIV_DEBUG */
-# define trx_undo_truncate_end(trx,undo,limit) \
- trx_undo_truncate_end_func(undo,limit)
-#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index a1c35e20ead..4f4a0eb223b 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -259,10 +259,6 @@ lock_wait_suspend_thread(
}
}
- /* Wake the lock timeout monitor thread, if it is suspended */
-
- os_event_set(lock_sys->timeout_event);
-
lock_wait_mutex_exit();
trx_mutex_exit(trx);
diff --git a/storage/xtradb/os/os0sync.cc b/storage/xtradb/os/os0sync.cc
index e42c5900c0c..779152a3a56 100644
--- a/storage/xtradb/os/os0sync.cc
+++ b/storage/xtradb/os/os0sync.cc
@@ -686,7 +686,7 @@ os_event_wait_time_low(
tv.tv_usec += time_in_usec;
if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
- tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
+ tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND;
tv.tv_usec %= MICROSECS_IN_A_SECOND;
}
diff --git a/storage/xtradb/row/row0ext.cc b/storage/xtradb/row/row0ext.cc
index 32b78391d6a..ad852577ad2 100644
--- a/storage/xtradb/row/row0ext.cc
+++ b/storage/xtradb/row/row0ext.cc
@@ -78,7 +78,8 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len);
+ buf, ext->max_len, zip_size, field, f_len,
+ NULL);
}
}
}
diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc
index 54f6f7bcc0f..e27c4c2805a 100644
--- a/storage/xtradb/row/row0ftsort.cc
+++ b/storage/xtradb/row/row0ftsort.cc
@@ -663,7 +663,8 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap);
+ zip_size, data_len, blob_heap,
+ NULL);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index 75eb5735a14..d01f1080e5a 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1294,7 +1294,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
/* Restore pcur position */
@@ -1322,7 +1322,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1530,7 +1530,7 @@ run_again:
}
}
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Store old value on n_fields_cmp */
@@ -2343,7 +2343,7 @@ row_ins_clust_index_entry_low(
|| n_uniq == dict_index_get_n_unique(index));
ut_ad(!n_uniq || n_uniq == dict_index_get_n_unique(index));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) {
@@ -2571,9 +2571,10 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static __attribute__((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_and_check_if_aborted(
+row_ins_sec_mtr_start_trx_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
+ trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2581,7 +2582,7 @@ row_ins_sec_mtr_start_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
if (!check) {
return(false);
@@ -2639,13 +2640,14 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
+ trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Ensure that we acquire index->lock when inserting into an
index with index->online_status == ONLINE_INDEX_COMPLETE, but
@@ -2706,8 +2708,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_and_check_if_aborted(
- &mtr, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
+ &mtr, trx, index, check, search_mode)) {
goto func_exit;
}
@@ -2741,8 +2743,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_and_check_if_aborted(
- &mtr, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
+ &mtr, trx, index, check, search_mode)) {
goto func_exit;
}
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 1240cf7fcc5..cfedf1210ea 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -981,7 +981,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len);
+ blob_field, field_len, zip_size, field, len, NULL);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1372,7 +1372,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap);
+ i, &len, heap, NULL);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index e074604e3cb..5d88d750478 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -2252,7 +2252,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap);
+ mrec, offsets, zip_size, i, &len, heap, NULL);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index fffcf7dc4b8..e98c3a824c6 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1395,7 +1395,11 @@ error_exit:
if (UNIV_LIKELY(!(trx->fake_changes))) {
- srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ }
/* Not protected by dict_table_stats_lock() for performance
reasons, we would rather get garbage in stat_n_rows (which is
@@ -1793,9 +1797,19 @@ run_again:
with a latch. */
dict_table_n_rows_dec(prebuilt->table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
/* We update table statistics only if it is a DELETE or UPDATE
@@ -1859,7 +1873,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Restore the cursor position and find the record */
@@ -2024,9 +2038,19 @@ run_again:
with a latch. */
dict_table_n_rows_dec(table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
row_update_statistics_if_needed(table);
@@ -2214,23 +2238,23 @@ err_exit:
/* The lock timeout monitor thread also takes care
of InnoDB monitor prints */
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_lock_monitor)) {
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_tablespace_monitor)) {
srv_print_innodb_tablespace_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_table_monitor)) {
srv_print_innodb_table_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
#ifdef UNIV_MEM_DEBUG
} else if (STR_EQ(table_name, table_name_len,
S_innodb_mem_validate)) {
@@ -3426,7 +3450,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
fsp_header_init(space,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3455,7 +3479,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3502,7 +3526,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index fd50e2240b5..75adc341d2e 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -133,7 +133,8 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len);
+ clust_field, clust_len,
+ NULL);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -452,7 +453,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap);
+ field_no, &len, heap, NULL);
/* data == NULL means that the
externally stored field was not
@@ -1400,7 +1401,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1441,7 +1442,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
}
if (search_latch_locked) {
@@ -2815,7 +2816,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap);
+ field_no, &len, heap, NULL);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -3882,7 +3883,7 @@ row_search_for_mysql(
}
}
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -5020,7 +5021,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5085,7 +5086,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/xtradb/row/row0umod.cc b/storage/xtradb/row/row0umod.cc
index 29252c7834a..6a23e1a6c12 100644
--- a/storage/xtradb/row/row0umod.cc
+++ b/storage/xtradb/row/row0umod.cc
@@ -267,7 +267,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
online = dict_index_is_online_ddl(index);
if (online) {
@@ -296,7 +296,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a pessimistic
descent down the index tree */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -341,7 +341,7 @@ row_undo_mod_clust(
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -354,7 +354,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a
pessimistic descent down the index tree */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -401,7 +401,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -457,7 +457,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
which cannot be purged yet, requires its existence. If some requires,
we should delete mark the record. */
- mtr_start(&mtr_vers);
+ mtr_start_trx(&mtr_vers, thr_get_trx(thr));
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -573,7 +573,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 1cdd447cd93..d7a5ec547ff 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -212,7 +212,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start(mtr);
+ mtr_start_trx(mtr, trx);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -986,7 +986,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len);
+ buf, *len, zip_size, data, local_len, NULL);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1687,7 +1687,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -2160,7 +2160,7 @@ row_upd_clust_rec(
/* We may have to modify the tree structure: do a pessimistic descent
down the index tree */
- mtr_start(mtr);
+ mtr_start_trx(mtr, thr_get_trx(thr));
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2330,7 +2330,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2386,7 +2386,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, thr_get_trx(thr));
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc
index 64417b1e5fb..f29621bc90a 100644
--- a/storage/xtradb/srv/srv0mon.cc
+++ b/storage/xtradb/srv/srv0mon.cc
@@ -1165,6 +1165,26 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DEFAULT_ON),
MONITOR_DEFAULT_START, MONITOR_OLVD_ROW_UPDTATED},
+ {"dml_system_reads", "dml", "Number of system rows read",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_READ},
+
+ {"dml_system_inserts", "dml", "Number of system rows inserted",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_INSERTED},
+
+ {"dml_system_deletes", "dml", "Number of system rows deleted",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_DELETED},
+
+ {"dml_system_updates", "dml", "Number of system rows updated",
+ static_cast<monitor_type_t>(
+ MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+ MONITOR_DEFAULT_START, MONITOR_OLVD_SYSTEM_ROW_UPDATED},
+
/* ========== Counters for DDL operations ========== */
{"module_ddl", "ddl", "Statistics for DDLs",
MONITOR_MODULE,
@@ -1683,6 +1703,26 @@ srv_mon_process_existing_counter(
value = srv_stats.n_rows_updated;
break;
+ /* innodb_system_rows_read */
+ case MONITOR_OLVD_SYSTEM_ROW_READ:
+ value = srv_stats.n_system_rows_read;
+ break;
+
+ /* innodb_system_rows_inserted */
+ case MONITOR_OLVD_SYSTEM_ROW_INSERTED:
+ value = srv_stats.n_system_rows_inserted;
+ break;
+
+ /* innodb_system_rows_deleted */
+ case MONITOR_OLVD_SYSTEM_ROW_DELETED:
+ value = srv_stats.n_system_rows_deleted;
+ break;
+
+ /* innodb_system_rows_updated */
+ case MONITOR_OLVD_SYSTEM_ROW_UPDATED:
+ value = srv_stats.n_system_rows_updated;
+ break;
+
/* innodb_row_lock_current_waits */
case MONITOR_OVLD_ROW_LOCK_CURRENT_WAIT:
value = srv_stats.n_lock_wait_current_count;
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index e0e15202991..a86a76faab4 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -347,12 +347,12 @@ in the buffer pool to all database pages in the buffer pool smaller than
the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
-UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
-UNIV_INTERN ulong srv_max_dirty_pages_pct_lwm = 50;
+UNIV_INTERN double srv_max_buf_pool_modified_pct = 75.0;
+UNIV_INTERN double srv_max_dirty_pages_pct_lwm = 50.0;
/* This is the percentage of log capacity at which adaptive flushing,
if enabled, will kick in. */
-UNIV_INTERN ulong srv_adaptive_flushing_lwm = 10;
+UNIV_INTERN double srv_adaptive_flushing_lwm = 10.0;
/* Number of iterations over which adaptive flushing is averaged. */
UNIV_INTERN ulong srv_flushing_avg_loops = 30;
@@ -498,6 +498,10 @@ static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
+static ulint srv_n_system_rows_inserted_old = 0;
+static ulint srv_n_system_rows_updated_old = 0;
+static ulint srv_n_system_rows_deleted_old = 0;
+static ulint srv_n_system_rows_read_old = 0;
UNIV_INTERN ulint srv_truncated_status_writes = 0;
UNIV_INTERN ulint srv_available_undo_logs = 0;
@@ -1262,6 +1266,11 @@ srv_refresh_innodb_monitor_stats(void)
srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
srv_n_rows_read_old = srv_stats.n_rows_read;
+ srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted;
+ srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated;
+ srv_n_system_rows_deleted_old = srv_stats.n_system_rows_deleted;
+ srv_n_system_rows_read_old = srv_stats.n_system_rows_read;
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -1567,11 +1576,33 @@ srv_printf_innodb_monitor(
/ time_elapsed,
((ulint) srv_stats.n_rows_read - srv_n_rows_read_old)
/ time_elapsed);
-
+ fprintf(file,
+ "Number of system rows inserted " ULINTPF
+ ", updated " ULINTPF ", deleted " ULINTPF
+ ", read " ULINTPF "\n",
+ (ulint) srv_stats.n_system_rows_inserted,
+ (ulint) srv_stats.n_system_rows_updated,
+ (ulint) srv_stats.n_system_rows_deleted,
+ (ulint) srv_stats.n_system_rows_read);
+ fprintf(file,
+ "%.2f inserts/s, %.2f updates/s,"
+ " %.2f deletes/s, %.2f reads/s\n",
+ ((ulint) srv_stats.n_system_rows_inserted
+ - srv_n_system_rows_inserted_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_updated
+ - srv_n_system_rows_updated_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_deleted
+ - srv_n_system_rows_deleted_old) / time_elapsed,
+ ((ulint) srv_stats.n_system_rows_read
+ - srv_n_system_rows_read_old) / time_elapsed);
srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
srv_n_rows_updated_old = srv_stats.n_rows_updated;
srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
srv_n_rows_read_old = srv_stats.n_rows_read;
+ srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted;
+ srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated;
+ srv_n_system_rows_deleted_old = srv_stats.n_system_rows_deleted;
+ srv_n_system_rows_read_old = srv_stats.n_system_rows_read;
/* Only if lock_print_info_summary proceeds correctly,
before we call the lock_print_info_all_transactions
@@ -1845,6 +1876,17 @@ srv_export_innodb_status(void)
export_vars.innodb_rows_deleted = srv_stats.n_rows_deleted;
+ export_vars.innodb_system_rows_read = srv_stats.n_system_rows_read;
+
+ export_vars.innodb_system_rows_inserted =
+ srv_stats.n_system_rows_inserted;
+
+ export_vars.innodb_system_rows_updated =
+ srv_stats.n_system_rows_updated;
+
+ export_vars.innodb_system_rows_deleted =
+ srv_stats.n_system_rows_deleted;
+
export_vars.innodb_num_open_files = fil_n_file_opened;
export_vars.innodb_truncated_status_writes =
diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index 7ad9fe8d40b..1b9bbff03a9 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -1166,7 +1166,7 @@ sync_array_print_long_waits(
(ulong) os_file_n_pending_pwrites);
srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
os_thread_sleep(30000000);
diff --git a/storage/xtradb/trx/trx0i_s.cc b/storage/xtradb/trx/trx0i_s.cc
index 794ee432ca4..3230ac8308c 100644
--- a/storage/xtradb/trx/trx0i_s.cc
+++ b/storage/xtradb/trx/trx0i_s.cc
@@ -1653,7 +1653,7 @@ trx_i_s_create_lock_id(
} else {
/* table lock */
res_len = ut_snprintf(lock_id, lock_id_size,
- TRX_ID_FMT":" UINT64PF,
+ TRX_ID_FMT ":" UINT64PF,
row->lock_trx_id,
row->lock_table_id);
}
diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc
index a698b37c2a6..11ad7fe4afd 100644
--- a/storage/xtradb/trx/trx0rec.cc
+++ b/storage/xtradb/trx/trx0rec.cc
@@ -466,7 +466,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len);
+ ext_buf, prefix_len, zip_size, field, *len, NULL);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -1247,7 +1247,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1336,7 +1336,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1373,7 +1373,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index 290271c6cab..edb85a89c17 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/trx/trx0undo.cc
@@ -1067,11 +1067,9 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end_func(
+trx_undo_truncate_end(
/*=======================*/
-#ifdef UNIV_DEBUG
- const trx_t* trx, /*!< in: transaction whose undo log it is */
-#endif /* UNIV_DEBUG */
+ trx_t* trx, /*!< in: transaction whose undo log it is */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1086,7 +1084,7 @@ trx_undo_truncate_end_func(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
trunc_here = NULL;
@@ -1773,7 +1771,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
mutex_enter(&rseg->mutex);