diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2014-11-04 00:07:26 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2014-11-04 00:07:26 +0900 |
commit | ae4497bf5d61f5df45afb8eb28308c95147ab8c4 (patch) | |
tree | 47c81a1d7d0c9d17cce66be1784f21dc13b6fb5a | |
parent | 323fe245a0e1f8084b0fe23e1b8f2b37a03e67f6 (diff) | |
parent | d1ca1c1faeb1e43df1533a10dfa0ac79433227f9 (diff) | |
download | mariadb-git-ae4497bf5d61f5df45afb8eb28308c95147ab8c4.tar.gz |
Merge from trunk
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); |