[Commits] 6d92f3f: MDEV-9931: InnoDB reads first page of every .ibd file at startup

Jan Lindström jan.lindstrom at mariadb.com
Wed Sep 21 11:03:08 EEST 2016


revision-id: 6d92f3f119559d0509e107335b45b69a1d245fba (mariadb-10.1.14-49-g6d92f3f)
parent(s): e786a57255dcfff0e10ba688c8a21a1fc5573f00
committer: Jan Lindström
timestamp: 2016-09-21 11:00:14 +0300
message:

MDEV-9931: InnoDB reads first page of every .ibd file at startup

Delay reading crypt_info from first page of every .ibd file
when it is really needed.

---
 .../suite/encryption/r/innodb_lotoftables.result   | 154 ++++++++++++
 .../suite/encryption/t/innodb-log-encrypt.test     |   2 +-
 .../t/innodb_encryption_row_compressed.opt         |   4 +
 .../t/innodb_encryption_row_compressed.test        | 125 ++++++++++
 .../suite/encryption/t/innodb_lotoftables.opt      |   3 +
 .../suite/encryption/t/innodb_lotoftables.test     | 273 +++++++++++++++++++++
 storage/innobase/include/page0page.ic              |  13 +-
 storage/xtradb/btr/btr0btr.cc                      |  22 +-
 storage/xtradb/buf/buf0buf.cc                      |   3 +
 storage/xtradb/buf/buf0flu.cc                      |   6 +
 storage/xtradb/dict/dict0load.cc                   |  13 +-
 storage/xtradb/fil/fil0crypt.cc                    |  31 ++-
 storage/xtradb/fil/fil0fil.cc                      |  71 +++++-
 storage/xtradb/handler/ha_innodb.cc                |   3 +
 storage/xtradb/include/btr0btr.ic                  |   4 +-
 storage/xtradb/include/dict0mem.h                  |   2 +
 storage/xtradb/include/fil0crypt.h                 |   3 +-
 storage/xtradb/include/fil0fil.h                   |  15 +-
 storage/xtradb/include/fsp0fsp.ic                  |   3 +
 storage/xtradb/include/srv0mon.h                   |   1 +
 storage/xtradb/include/srv0srv.h                   |   6 +-
 storage/xtradb/os/os0file.cc                       |   1 +
 storage/xtradb/row/row0mysql.cc                    |   8 +-
 storage/xtradb/srv/srv0mon.cc                      |  11 +
 storage/xtradb/srv/srv0srv.cc                      |   1 +
 storage/xtradb/srv/srv0start.cc                    |  26 +-
 26 files changed, 753 insertions(+), 51 deletions(-)

diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result
new file mode 100644
index 0000000..5e3eaef
--- /dev/null
+++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result
@@ -0,0 +1,154 @@
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+SHOW VARIABLES LIKE 'innodb_encrypt%';
+Variable_name	Value
+innodb_encrypt_log	OFF
+innodb_encrypt_tables	OFF
+innodb_encryption_rotate_key_age	1
+innodb_encryption_rotation_iops	100
+innodb_encryption_threads	0
+create database innodb_encrypted_1;
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	1
+set autocommit=0;
+set autocommit=1;
+commit work;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	1
+# should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+create database innodb_encrypted_2;
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+set autocommit=0;
+commit work;
+set autocommit=1;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+# should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+# should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+create database innodb_encrypted_3;
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+set autocommit=0;
+commit work;
+set autocommit=1;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+# should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+# should be 200
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+200
+use test;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+200
+SET GLOBAL innodb_encrypt_tables = on;
+SET GLOBAL innodb_encryption_threads=4;
+# Wait until all encrypted tables have been encrypted
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+200
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+# Success!
+# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
+# Restart Success!
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+use test;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	3
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	103
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	103
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	203
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	203
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	203
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+200
+SET GLOBAL innodb_encrypt_tables = off;
+SET GLOBAL innodb_encryption_threads=4;
+# Wait until all default encrypted tables have been decrypted
+# should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+100
+# should be 200
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+COUNT(*)
+200
+show status like 'innodb_pages0_read%';
+Variable_name	Value
+Innodb_pages0_read	303
+use test;
+drop database innodb_encrypted_1;
+drop database innodb_encrypted_2;
+drop database innodb_encrypted_3;
diff --git a/mysql-test/suite/encryption/t/innodb-log-encrypt.test b/mysql-test/suite/encryption/t/innodb-log-encrypt.test
index 7c2e6f8..a5f659e 100644
--- a/mysql-test/suite/encryption/t/innodb-log-encrypt.test
+++ b/mysql-test/suite/encryption/t/innodb-log-encrypt.test
@@ -105,7 +105,7 @@ insert into t1 values(5004, substring(MD5(RAND()), -64), REPEAT('publicmessage',
 -- source include/search_pattern_in_file.inc
 
 drop procedure innodb_insert_proc;
-drop table t1;
+#drop table t1;
 
 # reset system
 --disable_query_log
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt
new file mode 100644
index 0000000..7ebf81a
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt
@@ -0,0 +1,4 @@
+--innodb-encrypt-tables=ON
+--innodb-encryption-rotate-key-age=15
+--innodb-encryption-threads=4
+--innodb-tablespaces-encryption
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test
new file mode 100644
index 0000000..0a28c16
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test
@@ -0,0 +1,125 @@
+-- source include/have_innodb.inc
+-- source include/have_file_key_management_plugin.inc
+-- source include/not_embedded.inc
+
+--disable_query_log
+let $innodb_file_format_orig = `SELECT @@innodb_file_format`;
+let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`;
+--enable_query_log
+
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+
+create table innodb_compressed1(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed encrypted=yes;
+create table innodb_compressed2(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=1 encrypted=yes;
+create table innodb_compressed3(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=2 encrypted=yes;
+create table innodb_compressed4(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=4 encrypted=yes;
+
+insert into innodb_compressed1 values (1, 20, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (2, 20, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (3, 30, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (4, 30, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (5, 30, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (6, 30, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (7, 30, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (8, 20, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (9, 20, 'private', 'evenmoreprivate');
+insert into innodb_compressed1 values (10, 20, 'private', 'evenmoreprivate');
+
+insert into innodb_compressed2 select * from innodb_compressed1;
+insert into innodb_compressed3 select * from innodb_compressed1;
+insert into innodb_compressed4 select * from innodb_compressed1;
+
+--source include/restart_mysqld.inc
+
+--let $MYSQLD_DATADIR=`select @@datadir`
+--let t1_IBD = $MYSQLD_DATADIR/test/innodb_compressed1.ibd
+--let t2_IBD = $MYSQLD_DATADIR/test/innodb_compressed2.ibd
+--let t3_IBD = $MYSQLD_DATADIR/test/innodb_compressed3.ibd
+--let t4_IBD = $MYSQLD_DATADIR/test/innodb_compressed4.ibd
+--let SEARCH_RANGE = 10000000
+--let SEARCH_PATTERN=private
+--echo # t1 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t1_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t2 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t2_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t3 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t3_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t4 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t4_IBD
+-- source include/search_pattern_in_file.inc
+
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+
+select * from innodb_compressed1 where d = 20;
+select * from innodb_compressed1 where d = 30;
+select * from innodb_compressed2 where d = 20;
+select * from innodb_compressed2 where d = 30;
+select * from innodb_compressed3 where d = 20;
+select * from innodb_compressed3 where d = 30;
+select * from innodb_compressed4 where d = 20;
+select * from innodb_compressed4 where d = 30;
+
+update innodb_compressed1 set d = d + 10 where d = 30;
+update innodb_compressed2 set d = d + 10 where d = 30;
+update innodb_compressed3 set d = d + 10 where d = 30;
+update innodb_compressed4 set d = d + 10 where d = 30;
+
+insert into innodb_compressed1 values (20, 60, 'newprivate', 'newevenmoreprivate');
+insert into innodb_compressed2 values (20, 60, 'newprivate', 'newevenmoreprivate');
+insert into innodb_compressed3 values (20, 60, 'newprivate', 'newevenmoreprivate');
+insert into innodb_compressed4 values (20, 60, 'newprivate', 'newevenmoreprivate');
+
+--let SEARCH_PATTERN=private
+--echo # t1 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t1_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t2 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t2_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t3 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t3_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t4 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t4_IBD
+-- source include/search_pattern_in_file.inc
+
+--source include/restart_mysqld.inc
+
+select * from innodb_compressed1 where d = 40;
+select * from innodb_compressed1 where d = 60;
+select * from innodb_compressed2 where d = 40;
+select * from innodb_compressed2 where d = 60;
+select * from innodb_compressed3 where d = 40;
+select * from innodb_compressed3 where d = 60;
+select * from innodb_compressed4 where d = 40;
+select * from innodb_compressed4 where d = 60;
+
+--let SEARCH_PATTERN=private
+--echo # t1 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t1_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t2 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t2_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t3 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t3_IBD
+-- source include/search_pattern_in_file.inc
+--echo # t4 yes on expecting NOT FOUND
+-- let SEARCH_FILE=$t4_IBD
+-- source include/search_pattern_in_file.inc
+
+drop table innodb_compressed1;
+drop table innodb_compressed2;
+drop table innodb_compressed3;
+drop table innodb_compressed4;
+
+# reset system
+--disable_query_log
+EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig;
+EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig;
+--enable_query_log
diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.opt b/mysql-test/suite/encryption/t/innodb_lotoftables.opt
new file mode 100644
index 0000000..ffb5a29
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_lotoftables.opt
@@ -0,0 +1,3 @@
+--innodb-tablespaces-encryption
+--innodb-encrypt-tables=off
+--innodb-encryption-threads=0
diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.test b/mysql-test/suite/encryption/t/innodb_lotoftables.test
new file mode 100644
index 0000000..72552f7
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_lotoftables.test
@@ -0,0 +1,273 @@
+-- source include/have_innodb.inc
+-- source include/have_example_key_management_plugin.inc
+
+# embedded does not support restart
+-- source include/not_embedded.inc
+
+--disable_query_log
+let $innodb_file_format_orig = `SELECT @@innodb_file_format`;
+let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`;
+let $innodb_encryption_threads_orig = `SELECT @@global.innodb_encryption_threads`;
+--enable_query_log
+
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+
+SHOW VARIABLES LIKE 'innodb_encrypt%';
+
+#
+# This will create 100 tables where that could be
+# encrypted an unencrypt
+#
+create database innodb_encrypted_1;
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+set autocommit=0;
+let $tables = 100;
+
+--disable_query_log
+while ($tables)
+{
+  eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb;
+  commit;
+  let $rows = 100;
+  while($rows)
+  {
+    eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
+    dec $rows;
+  }
+  commit;
+  dec $tables;
+}
+--enable_query_log
+
+set autocommit=1;
+commit work;
+show status like 'innodb_pages0_read%';
+#
+# Verify
+#
+--echo # should be 100
+
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%';
+
+#
+# This will create 100 tables that are encrypted always
+#
+create database innodb_encrypted_2;
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+set autocommit=0;
+
+--disable_query_log
+let $tables = 100;
+while ($tables)
+{
+  eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb encrypted=yes;
+  commit;
+  let $rows = 100;
+  while($rows)
+  {
+    eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
+    dec $rows;
+  }
+  commit;
+  dec $tables;
+}
+--enable_query_log
+
+commit work;
+set autocommit=1;
+show status like 'innodb_pages0_read%';
+#
+# Verify
+#
+--echo # should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+--echo # should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+
+#
+# This will create 100 tables that are not encrypted
+#
+create database innodb_encrypted_3;
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+set autocommit=0;
+
+--disable_query_log
+let $tables = 100;
+while ($tables)
+{
+  eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb encrypted=no;
+  commit;
+  let $rows = 100;
+  while($rows)
+  {
+    eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
+    dec $rows;
+  }
+  commit;
+  dec $tables;
+}
+--enable_query_log
+
+commit work;
+set autocommit=1;
+show status like 'innodb_pages0_read%';
+#
+# Verify
+#
+--echo # should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+--echo # should be 200
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+
+use test;
+show status like 'innodb_pages0_read%';
+
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+
+SET GLOBAL innodb_encrypt_tables = on;
+SET GLOBAL innodb_encryption_threads=4;
+
+--echo # Wait until all encrypted tables have been encrypted
+let $cnt=600;
+while ($cnt)
+{
+    let $success=`SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`;
+    if ($success)
+    {
+        let $cnt=0;
+    }
+    if (!$success)
+    {
+        real_sleep 1;
+        dec $cnt;
+    }
+}
+if (!$success)
+{
+    SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+    SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+    SHOW STATUS LIKE 'innodb_encryption%';
+    -- die Timeout waiting for encryption threads
+}
+
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+show status like 'innodb_pages0_read%';
+
+--echo # Success!
+--echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
+-- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0
+-- source include/restart_mysqld.inc
+
+--echo # Restart Success!
+show status like 'innodb_pages0_read%';
+
+show status like 'innodb_pages0_read%';
+use test;
+show status like 'innodb_pages0_read%';
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+
+use innodb_encrypted_1;
+show status like 'innodb_pages0_read%';
+--disable_result_log
+--disable_query_log
+let $tables = 100;
+while ($tables)
+{
+  eval select * from t_$tables;
+  dec $tables;
+}
+--enable_query_log
+--enable_result_log
+
+show status like 'innodb_pages0_read%';
+
+use innodb_encrypted_2;
+show status like 'innodb_pages0_read%';
+
+--disable_result_log
+--disable_query_log
+let $tables = 100;
+while ($tables)
+{
+  eval select * from t_$tables;
+  dec $tables;
+}
+--enable_query_log
+--enable_result_log
+
+show status like 'innodb_pages0_read%';
+
+use innodb_encrypted_3;
+show status like 'innodb_pages0_read%';
+--disable_result_log
+--disable_query_log
+let $tables = 100;
+while ($tables)
+{
+  eval select * from t_$tables;
+  dec $tables;
+}
+--enable_query_log
+--enable_result_log
+
+show status like 'innodb_pages0_read%';
+
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+
+SET GLOBAL innodb_encrypt_tables = off;
+SET GLOBAL innodb_encryption_threads=4;
+
+--echo # Wait until all default encrypted tables have been decrypted
+let $cnt=600;
+while ($cnt)
+{
+    let $success=`SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0`;
+    if ($success)
+    {
+        let $cnt=0;
+    }
+    if (!$success)
+    {
+        real_sleep 1;
+        dec $cnt;
+    }
+}
+if (!$success)
+{
+    SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+    SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+    SHOW STATUS LIKE 'innodb_encryption%';
+    -- die Timeout waiting for encryption threads
+}
+
+--echo # should be 100
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%';
+--echo # should be 200
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
+show status like 'innodb_pages0_read%';
+
+#
+# Cleanup
+#
+use test;
+drop database innodb_encrypted_1;
+drop database innodb_encrypted_2;
+drop database innodb_encrypted_3;
+
+--disable_query_log
+EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig;
+EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig;
+EVAL SET GLOBAL innodb_encryption_threads = $innodb_encryption_threads_orig;
+--enable_query_log
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index cde3cad..dd04864 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -52,6 +52,7 @@ page_align(
 {
 	return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
 }
+
 #ifndef UNIV_INNOCHECKSUM
 /************************************************************//**
 Gets the offset within a page.
@@ -230,18 +231,6 @@ page_header_reset_last_insert(
 #endif /* !UNIV_HOTBACKUP */
 
 #endif /* !UNIV_INNOCHECKSUM */
-/************************************************************//**
-Determine whether the page is in new-style compact format.
- at return nonzero if the page is in compact format, zero if it is in
-old-style format */
-UNIV_INLINE
-ulint
-page_is_comp(
-/*=========*/
-	const page_t*	page)	/*!< in: index page */
-{
-	return(page_header_get_field(page, PAGE_N_HEAP) & 0x8000);
-}
 
 #ifndef UNIV_INNOCHECKSUM
 /************************************************************//**
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index caa35d3..9a70bf3 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -743,14 +743,16 @@ btr_root_block_get(
 	block = btr_block_get(space, zip_size, root_page_no, mode, (dict_index_t*)index, mtr);
 
 	if (!block) {
-		index->table->is_encrypted = TRUE;
-		index->table->corrupted = FALSE;
-
-		ib_push_warning(index->table->thd, DB_DECRYPTION_FAILED,
-			"Table %s in tablespace %lu is encrypted but encryption service or"
-			" used key_id is not available. "
-			" Can't continue reading table.",
-			index->table->name, space);
+		if (index && index->table) {
+			index->table->is_encrypted = TRUE;
+			index->table->corrupted = FALSE;
+
+			ib_push_warning(index->table->thd, DB_DECRYPTION_FAILED,
+				"Table %s in tablespace %lu is encrypted but encryption service or"
+				" used key_id is not available. "
+				" Can't continue reading table.",
+				index->table->name, space);
+		}
 
 		return NULL;
 	}
@@ -1840,6 +1842,10 @@ btr_free_but_not_root(
 	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
 			    NULL, &mtr);
 
+	if (!root) {
+		return;
+	}
+
 	SRV_CORRUPT_TABLE_CHECK(root,
 	{
 		mtr_commit(&mtr);
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 556096c..2f5fd74 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -6270,6 +6270,9 @@ buf_page_encrypt_before_write(
 					      zip_size,
 					      dst_frame);
 
+		fprintf(stderr, "JAN2: src_frame %p dst_frame %p tmp %p bpage %p\n",
+			src_frame, dst_frame, tmp,  ((buf_block_t*) bpage)->frame);
+
 		ulint key_version = mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
 		ut_ad(key_version == 0 || key_version >= bpage->key_version);
 		bpage->key_version = key_version;
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index 2440637..ddc56b8 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -947,6 +947,12 @@ buf_flush_write_block_low(
 
 	frame = buf_page_encrypt_before_write(bpage, frame, space_id);
 
+	fprintf(stderr, "JAN0: frame %p bpage %p\n", frame, ((buf_block_t*) bpage)->frame);
+	fprintf(stderr, "JAN: frame\n");
+	//	buf_page_print(frame, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+	fprintf(stderr, "JAN1: bpage->frame\n");
+	//	buf_page_print(((buf_block_t*) bpage)->frame, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+
 	if (!srv_use_doublewrite_buf || !buf_dblwr) {
 		fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
 			sync,
diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc
index 3d3a35e..76a9195 100644
--- a/storage/xtradb/dict/dict0load.cc
+++ b/storage/xtradb/dict/dict0load.cc
@@ -1154,11 +1154,14 @@ dict_check_tablespaces_and_store_max_id(
 					space_id, name);
 			}
 
-			/* We need to read page 0 to get (optional) IV
-			regardless if encryptions is turned on or not,
-			since if it's off we should decrypt a potentially
-			already encrypted table */
-			bool read_page_0 = true;
+			/* We could read page 0 to get (optional) IV
+			if encryption is turned on, if it's off
+			we will read the page 0 later and find out
+			if we should decrypt a potentially
+			already encrypted table
+			bool read_page_0 = srv_encrypt_tables; */
+
+			bool read_page_0 = false;
 
 			/* We set the 2nd param (fix_dict = true)
 			here because we already have an x-lock on
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index ceffa95..dfd9103 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -666,6 +666,30 @@ fil_space_encrypt(
 
 	byte* tmp = fil_encrypt_buf(crypt_data, space, offset, lsn, src_frame, zip_size, dst_frame);
 
+#ifdef UNIV_DEBUG
+	{
+		/* Verify that encrypted buffer is not corrupted */
+		byte* tmp_mem = (byte *)malloc(UNIV_PAGE_SIZE);
+		dberr_t err = DB_SUCCESS;
+		bool corrupted1 = buf_page_is_corrupted(false, src_frame, zip_size);
+		bool ok = fil_space_decrypt(crypt_data, tmp_mem, zip_size ? zip_size : UNIV_PAGE_SIZE, tmp, &err);
+		bool corrupted = buf_page_is_corrupted(false, tmp_mem, zip_size);
+		bool different = memcmp(tmp_mem, src_frame, zip_size ? zip_size : UNIV_PAGE_SIZE);
+
+		if (!ok || corrupted || corrupted1 || err != DB_SUCCESS || different) {
+			fprintf(stderr, "JAN: ok %d corrupted %d corrupted1 %d DIFF %d\n", ok ,corrupted, corrupted1, different);
+			fprintf(stderr, "JAN1: src_frame\n");
+			buf_page_print(src_frame, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+			fprintf(stderr, "JAN2: encrypted_frame\n");
+			buf_page_print(tmp, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+			fprintf(stderr, "JAN1: decrypted_frame\n");
+			buf_page_print(tmp_mem, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+			ut_error;
+		}
+		free(tmp_mem);
+	}
+#endif /* UNIV_DEBUG */
+
 	return tmp;
 }
 
@@ -2426,7 +2450,8 @@ UNIV_INTERN
 void
 fil_space_crypt_mark_space_closing(
 /*===============================*/
-	ulint	space)	/*!< in: Space id */
+	ulint			space,		/*!< in: tablespace id */
+	fil_space_crypt_t*	crypt_data)	/*!< in: crypt_data or NULL */
 {
 	if (!fil_crypt_threads_inited) {
 		return;
@@ -2434,7 +2459,9 @@ fil_space_crypt_mark_space_closing(
 
 	mutex_enter(&fil_crypt_threads_mutex);
 
-	fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
+	if (!crypt_data) {
+		crypt_data = fil_space_get_crypt_data(space);
+	}
 
 	if (crypt_data == NULL) {
 		mutex_exit(&fil_crypt_threads_mutex);
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 9fad342..e14ae98 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1191,7 +1191,8 @@ fil_space_create(
 	ulint		id,	/*!< in: space id */
 	ulint		flags,	/*!< in: tablespace flags */
 	ulint		purpose,/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
-	fil_space_crypt_t* crypt_data) /*!< in: crypt data */
+	fil_space_crypt_t* crypt_data, /*!< in: crypt data */
+	bool		create_table) /*!< in: true if create table */
 {
 	fil_space_t*	space;
 
@@ -1285,10 +1286,23 @@ fil_space_create(
 	space->is_in_unflushed_spaces = false;
 
 	space->is_corrupt = FALSE;
+	space->crypt_data = crypt_data;
 
-	UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
+	/* In create table we write page 0 so we have already
+	"read" it and for system tablespaces we have read
+	crypt data at startup. */
+	if (create_table || crypt_data != NULL) {
+		space->page_0_crypt_read = true;
+	}
 
-	space->crypt_data = crypt_data;
+	ib_logf(IB_LOG_LEVEL_INFO,
+		"Created tablespace for space %lu name %s key_id %u encryption %d\n",
+		space->id,
+		space->name,
+		space->crypt_data ? space->crypt_data->key_id : 0,
+		space->crypt_data ? space->crypt_data->encryption : 0);
+
+	UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
 
 	mutex_exit(&fil_system->mutex);
 
@@ -2035,6 +2049,8 @@ fil_read_first_page(
 
 	os_file_read(data_file, page, 0, UNIV_PAGE_SIZE);
 
+	srv_stats.page0_read.add(1);
+
 	/* The FSP_HEADER on page 0 is only valid for the first file
 	in a tablespace.  So if this is not the first datafile, leave
 	*flags and *space_id as they were read from the first file and
@@ -2055,6 +2071,7 @@ fil_read_first_page(
 	ulint space = fsp_header_get_space_id(page);
 	ulint offset = fsp_header_get_crypt_offset(
 		fsp_flags_get_zip_size(*flags), NULL);
+
 	cdata = fil_space_read_crypt_data(space, page, offset);
 
 	if (crypt_data) {
@@ -3605,7 +3622,7 @@ fil_create_new_single_table_tablespace(
 	}
 
 	success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
-				   crypt_data);
+				   crypt_data, true);
 
 	if (!success || !fil_node_create(path, size, space_id, FALSE)) {
 		err = DB_ERROR;
@@ -3839,6 +3856,7 @@ fil_open_single_table_tablespace(
 
 		if (table) {
 			table->crypt_data = def.crypt_data;
+			table->page_0_read = true;
 		}
 
 		/* Validate this single-table-tablespace with SYS_TABLES,
@@ -3875,6 +3893,7 @@ fil_open_single_table_tablespace(
 
 		if (table) {
 			table->crypt_data = remote.crypt_data;
+			table->page_0_read = true;
 		}
 
 		/* Validate this single-table-tablespace with SYS_TABLES,
@@ -3911,6 +3930,7 @@ fil_open_single_table_tablespace(
 
 		if (table) {
 			table->crypt_data = dict.crypt_data;
+			table->page_0_read = true;
 		}
 
 		/* Validate this single-table-tablespace with SYS_TABLES,
@@ -4082,7 +4102,7 @@ fil_open_single_table_tablespace(
 	if (err != DB_SUCCESS) {
 		; // Don't load the tablespace into the cache
 	} else if (!fil_space_create(tablename, id, flags, FIL_TABLESPACE,
-				     crypt_data)) {
+				     crypt_data, false)) {
 		err = DB_ERROR;
 	} else {
 		/* We do not measure the size of the file, that is why
@@ -4688,7 +4708,7 @@ fil_load_single_table_tablespace(
 #endif /* UNIV_HOTBACKUP */
 	ibool file_space_create_success = fil_space_create(
 		tablename, fsp->id, fsp->flags, FIL_TABLESPACE,
-		fsp->crypt_data);
+		fsp->crypt_data, false);
 
 	if (!file_space_create_success) {
 		if (srv_force_recovery > 0) {
@@ -7325,7 +7345,46 @@ fil_space_get_crypt_data(
 	space = fil_space_get_by_id(id);
 
 	if (space != NULL) {
+		/* If we have not yet read the page0
+		of this tablespace we will do it now. */
+		if (!space->crypt_data && !space->page_0_crypt_read) {
+			ulint flags;
+			ulint space_id;
+			lsn_t min_flushed_lsn;
+			lsn_t max_flushed_lsn;
+			fil_node_t*	node;
+
+			ut_a(space->crypt_data == NULL);
+			node = UT_LIST_GET_FIRST(space->chain);
+
+			fil_node_prepare_for_io(node, fil_system, space);
+
+			const char* msg = fil_read_first_page(node->handle,
+				false,
+				&flags,
+				&space_id,
+				&min_flushed_lsn,
+				&max_flushed_lsn,
+				&space->crypt_data);
+
+			fil_node_complete_io(node, fil_system, OS_FILE_READ);
+			
+			ib_logf(IB_LOG_LEVEL_INFO,
+				"Read page 0 from tablespace for space %lu name %s key_id %u encryption %d handle %d\n",
+				space_id,
+				space->name,
+				space->crypt_data ? space->crypt_data->key_id : 0,
+				space->crypt_data ? space->crypt_data->encryption : 0,
+				node->handle);
+
+			ut_a(space->id == space_id);
+
+			space->page_0_crypt_read = true;
+		}
+
 		crypt_data = space->crypt_data;
+
+		ut_ad(space->page_0_crypt_read);
 	}
 
 	mutex_exit(&fil_system->mutex);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 2406ed9..a8b5b71 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1116,6 +1116,8 @@ static SHOW_VAR innodb_status_variables[]= {
   (char*) &export_vars.innodb_pages_created,		  SHOW_LONG},
   {"pages_read",
   (char*) &export_vars.innodb_pages_read,		  SHOW_LONG},
+  {"pages0_read",
+  (char*) &export_vars.innodb_page0_read,		  SHOW_LONG},
   {"pages_written",
   (char*) &export_vars.innodb_pages_written,		  SHOW_LONG},
   {"purge_trx_id",
@@ -1774,6 +1776,7 @@ innodb_page_size_validate(
 	     n <= UNIV_PAGE_SIZE_SHIFT_MAX;
 	     n++) {
 		if (page_size == (ulong) (1 << n)) {
+			fprintf(stderr, "JAN: page_ssize %ld\n", n);
 			DBUG_RETURN(n);
 		}
 	}
diff --git a/storage/xtradb/include/btr0btr.ic b/storage/xtradb/include/btr0btr.ic
index 5fc621f..1d714a5 100644
--- a/storage/xtradb/include/btr0btr.ic
+++ b/storage/xtradb/include/btr0btr.ic
@@ -60,7 +60,9 @@ btr_block_get_func(
 		NULL, BUF_GET, file, line, mtr, &err);
 
 	if (err == DB_DECRYPTION_FAILED) {
-		index->table->is_encrypted = true;
+		if (index && index->table) {
+			index->table->is_encrypted = true;
+		}
 	}
 
 	if (block) {
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index a55d531..175a444 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -1046,6 +1046,8 @@ struct dict_table_t{
 	mem_heap_t*	heap;	/*!< memory heap */
 	char*		name;	/*!< table name */
 	void*		thd;		/*!< thd */
+	bool		page_0_read; /*!< true if page 0 has
+				     been already read */
 	fil_space_crypt_t *crypt_data; /*!< crypt data if present */
 	const char*	dir_path_of_temp_table;/*!< NULL or the directory path
 				where a TEMPORARY table that was explicitly
diff --git a/storage/xtradb/include/fil0crypt.h b/storage/xtradb/include/fil0crypt.h
index 5deed1f..b656cd3 100644
--- a/storage/xtradb/include/fil0crypt.h
+++ b/storage/xtradb/include/fil0crypt.h
@@ -316,7 +316,8 @@ UNIV_INTERN
 void
 fil_space_crypt_mark_space_closing(
 /*===============================*/
-	ulint space);          /*!< in: tablespace id */
+	ulint			space,		/*!< in: tablespace id */
+	fil_space_crypt_t*	crypt_data);	/*!< in: crypt_data or NULL */
 
 /*********************************************************************
 Wait for crypt threads to stop accessing space */
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 973882a..fa5c1bc 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -321,13 +321,21 @@ struct fil_space_t {
 				/*!< true if this space is currently in
 				unflushed_spaces */
 	ibool		is_corrupt;
+				/*!< true if tablespace corrupted */
 	bool		printed_compression_failure;
 				/*!< true if we have already printed
 				compression failure */
+	fil_space_crypt_t* crypt_data;
+				/*!< tablespace crypt data or NULL */
+	bool		page_0_crypt_read;
+				/*!< tablespace crypt data has been
+				read */
+	ulint		file_block_size;
+				/*!< file system block size */
+
 	UT_LIST_NODE_T(fil_space_t) space_list;
 				/*!< list of all spaces */
-        fil_space_crypt_t* crypt_data;
-	ulint		file_block_size;/*!< file system block size */
+
 	ulint		magic_n;/*!< FIL_SPACE_MAGIC_N */
 };
 
@@ -471,7 +479,8 @@ fil_space_create(
 	ulint		zip_size,/*!< in: compressed page size, or
 				0 for uncompressed tablespaces */
 	ulint		purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
-	fil_space_crypt_t* crypt_data); /*!< in: crypt data */
+	fil_space_crypt_t* crypt_data, /*!< in: crypt data */
+	bool		create_table); /*!< in: true if create table */
 
 /*******************************************************************//**
 Assigns a new space id for a new single-table tablespace. This works simply by
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic
index ddcb87b..5cb4b31 100644
--- a/storage/xtradb/include/fsp0fsp.ic
+++ b/storage/xtradb/include/fsp0fsp.ic
@@ -120,6 +120,9 @@ fsp_flags_is_valid(
 		return(false);
 	}
 
+	fprintf(stderr, "JAN: UNIV_PAGE_SIZE %lu UNIV_PAGE_SIZE_ORIG %lu UNIV_PAGE_SSIZE_MAX %lu\n",
+		UNIV_PAGE_SIZE, UNIV_PAGE_SIZE_ORIG, UNIV_PAGE_SSIZE_MAX);
+
 #if UNIV_FORMAT_MAX != UNIV_FORMAT_B
 # error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations."
 #endif
diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h
index 33ae774..3b030d5 100644
--- a/storage/xtradb/include/srv0mon.h
+++ b/storage/xtradb/include/srv0mon.h
@@ -167,6 +167,7 @@ enum monitor_id_t {
 	MONITOR_OVLD_INDEX_PAGES_WRITTEN,
 	MONITOR_OVLD_NON_INDEX_PAGES_WRITTEN,
 	MONITOR_OVLD_PAGES_READ,
+	MONITOR_OVLD_PAGES0_READ,
 	MONITOR_OVLD_INDEX_SEC_REC_CLUSTER_READS,
 	MONITOR_OVLD_INDEX_SEC_REC_CLUSTER_READS_AVOIDED,
 	MONITOR_OVLD_BYTE_READ,
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index a2d3009..a433922 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -186,6 +186,9 @@ struct srv_stats_t {
 	/** 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;
+
+	/** Number of times page 0 is read from tablespace */
+	ulint_ctr_64_t		page0_read;
 };
 
 extern const char*	srv_main_thread_op_info;
@@ -1153,7 +1156,8 @@ struct export_var_t{
 	ulint innodb_os_log_pending_fsyncs;	/*!< fil_n_pending_log_flushes */
 	ulint innodb_page_size;			/*!< UNIV_PAGE_SIZE */
 	ulint innodb_pages_created;		/*!< buf_pool->stat.n_pages_created */
-	ulint innodb_pages_read;		/*!< buf_pool->stat.n_pages_read */
+	ulint innodb_pages_read;		/*!< buf_pool->stat.n_pages_read*/
+	ulint innodb_page0_read;		/*!< srv_stats.page0_read */
 	ulint innodb_pages_written;		/*!< buf_pool->stat.n_pages_written */
 	ib_int64_t innodb_purge_trx_id;
 	ib_int64_t innodb_purge_undo_no;
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 4010ef1..ee950fd 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -884,6 +884,7 @@ os_file_handle_error_cond_exit(
 		}
 
 		if (should_exit) {
+			ut_error;
 			exit(1);
 		}
 	}
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 9427b20..23d7edc 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3288,7 +3288,7 @@ fil_wait_crypt_bg_threads(
 	uint last = start;
 
 	if (table->space != 0) {
-		fil_space_crypt_mark_space_closing(table->space);
+		fil_space_crypt_mark_space_closing(table->space, table->crypt_data);
 	}
 
 	while (table->n_ref_count > 0) {
@@ -4212,6 +4212,12 @@ row_drop_table_for_mysql(
 		rw_lock_x_unlock(dict_index_get_lock(index));
 	}
 
+	/* If table has not yet have crypt_data, try to read it to
+	make freeing the table easier. */
+	if (!table->crypt_data) {
+		table->crypt_data = fil_space_get_crypt_data(table->space);
+	}
+
 	/* We use the private SQL parser of Innobase to generate the
 	query graphs needed in deleting the dictionary data from system
 	tables in Innobase. Deleting a row from SYS_INDEXES table also
diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc
index e72868c..1e0d21d 100644
--- a/storage/xtradb/srv/srv0mon.cc
+++ b/storage/xtradb/srv/srv0mon.cc
@@ -309,6 +309,12 @@ static monitor_info_t	innodb_counter_info[] =
 	 MONITOR_EXISTING | MONITOR_DEFAULT_ON),
 	 MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_READ},
 
+	{"buffer_pages0_read", "buffer",
+	 "Number of page 0 read (innodb_pages0_read)",
+	 static_cast<monitor_type_t>(
+	 MONITOR_EXISTING | MONITOR_DEFAULT_ON),
+	 MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES0_READ},
+
 	{"buffer_index_sec_rec_cluster_reads", "buffer",
 	 "Number of secondary record reads triggered cluster read",
 	 static_cast<monitor_type_t>(
@@ -1715,6 +1721,11 @@ srv_mon_process_existing_counter(
 		value = stat.n_pages_read;
 		break;
 
+	/* innodb_pages0_read */
+	case MONITOR_OVLD_PAGES0_READ:
+		value = srv_stats.page0_read;
+		break;
+
 	/* Number of times secondary index lookup triggered cluster lookup */
 	case MONITOR_OVLD_INDEX_SEC_REC_CLUSTER_READS:
 		value = srv_stats.n_sec_rec_cluster_reads;
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index c98bfc8..5c64020 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -1931,6 +1931,7 @@ srv_export_innodb_status(void)
 	export_vars.innodb_pages_created = stat.n_pages_created;
 
 	export_vars.innodb_pages_read = stat.n_pages_read;
+	export_vars.innodb_page0_read = srv_stats.page0_read;
 
 	export_vars.innodb_pages_written = stat.n_pages_written;
 
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index 2455dc1..d330ff3 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -705,7 +705,8 @@ create_log_files(
 		logfilename, SRV_LOG_SPACE_FIRST_ID,
 		fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
 		FIL_LOG,
-		NULL /* no encryption yet */);
+		NULL /* no encryption yet */,
+		true /* this is create */);
 	ut_a(fil_validate());
 
 	logfile0 = fil_node_create(
@@ -727,7 +728,7 @@ create_log_files(
 #ifdef UNIV_LOG_ARCHIVE
 	/* Create the file space object for archived logs. */
 	fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
-		0, FIL_LOG, NULL /* no encryption yet */);
+		0, FIL_LOG, NULL /* no encryption yet */, true /* create */);
 #endif
 	log_group_init(0, srv_n_log_files,
 		       srv_log_file_size * UNIV_PAGE_SIZE,
@@ -853,7 +854,7 @@ open_or_create_data_files(
 	ulint		space;
 	ulint		rounded_size_pages;
 	char		name[10000];
-	fil_space_crypt_t*    crypt_data;
+	fil_space_crypt_t*    crypt_data=NULL;
 
 	if (srv_n_data_files >= 1000) {
 
@@ -1184,18 +1185,20 @@ open_or_create_data_files(
 			}
 
 			*sum_of_new_sizes += srv_data_file_sizes[i];
-
-			crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
 		}
 
 		ret = os_file_close(files[i]);
 		ut_a(ret);
 
 		if (i == 0) {
+			if (!crypt_data) {
+				crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+			}
+
 			flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
+
 			fil_space_create(name, 0, flags, FIL_TABLESPACE,
-					 crypt_data);
-			crypt_data = NULL;
+					crypt_data, (*create_new_db) == true);
 		}
 
 		ut_a(fil_validate());
@@ -1342,7 +1345,8 @@ srv_undo_tablespace_open(
 		/* Set the compressed page size to 0 (non-compressed) */
 		flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
 		fil_space_create(name, space, flags, FIL_TABLESPACE,
-				 NULL /* no encryption */);
+				NULL /* no encryption */,
+				true /* create */);
 
 		ut_a(fil_validate());
 
@@ -2371,7 +2375,8 @@ innobase_start_or_create_for_mysql(void)
 				 SRV_LOG_SPACE_FIRST_ID,
 				 fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
 				 FIL_LOG,
-				 NULL /* no encryption yet */);
+				 NULL /* no encryption yet */,
+				 true /* create */);
 
 		ut_a(fil_validate());
 
@@ -2393,7 +2398,8 @@ innobase_start_or_create_for_mysql(void)
 		/* Create the file space object for archived logs. Under
 		MySQL, no archiving ever done. */
 		fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
-			0, FIL_LOG, NULL /* no encryption yet */);
+			0, FIL_LOG, NULL /* no encryption yet */,
+			true /* create */);
 #endif /* UNIV_LOG_ARCHIVE */
 		log_group_init(0, i, srv_log_file_size * UNIV_PAGE_SIZE,
 			       SRV_LOG_SPACE_FIRST_ID,



More information about the commits mailing list