[Commits] 6fb92442e2e: MDEV-12610: MariaDB start is slow

jan jan.lindstrom at mariadb.com
Wed Jun 7 13:29:54 EEST 2017


revision-id: 6fb92442e2e33d0cbe56395972aef50cc8a84f5d (mariadb-10.1.24-7-g6fb92442e2e)
parent(s): 112b21da37dad0fbb28bc65f9ab5a3ba6c0c2186
author: Jan Lindström
committer: Jan Lindström
timestamp: 2017-06-07 10:48:47 +0300
message:

MDEV-12610: MariaDB start is slow

Problem appears to be that the function fsp_flags_try_adjust()
is being unconditionally invoked on every .ibd file on startup.
Based on performance investigation also the top function
fsp_header_get_crypt_offset() needs to addressed.

Ported fsp_header_get_encryption_offset() function from 10.2

fil_space_crypt_t::write_page0: Use new fsp_header_get_encryption_offset
function.

fil_crypt_find_space_to_rotate(): Now that page 0 for every .ibd
file is not read on startup we need to check has page 0 read
from space that we investigate for key rotation, if it is not read
we read it by using fil_node_open_file().

fil_space_crypt_get_status(): Now that page 0 for every .ibd
file is not read on startup here also we need to read page 0
if it is not yet read using fil_node_open_file(). This is needed
as tests use IS query to wait until background encryption
or decryption has finished and this function is used to
produce results.

fil_node_open_file(): Make function visible outside and use
fil_header_get_encryption_offset() function.

Removed old fsp_header_get_crypt_offset function.

---
 .../suite/encryption/r/innodb_lotoftables.result   | 28 ++++++++---------
 storage/innobase/buf/buf0buf.cc                    |  1 +
 storage/innobase/fil/fil0crypt.cc                  | 30 +++++++++++++++++--
 storage/innobase/fil/fil0fil.cc                    | 35 +++++++++++++++-------
 storage/innobase/fsp/fsp0fsp.cc                    | 25 +---------------
 storage/innobase/include/fil0fil.h                 | 12 ++++++++
 storage/innobase/include/fsp0fsp.h                 | 21 ++++++-------
 storage/xtradb/buf/buf0buf.cc                      |  1 +
 storage/xtradb/fil/fil0crypt.cc                    | 30 +++++++++++++++++--
 storage/xtradb/fil/fil0fil.cc                      | 35 +++++++++++++++-------
 storage/xtradb/fsp/fsp0fsp.cc                      | 25 +---------------
 storage/xtradb/include/fil0fil.h                   | 12 ++++++++
 storage/xtradb/include/fsp0fsp.h                   | 21 ++++++-------
 13 files changed, 168 insertions(+), 108 deletions(-)

diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result
index 418ab175a01..b7cfdd2db9d 100644
--- a/mysql-test/suite/encryption/r/innodb_lotoftables.result
+++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result
@@ -12,13 +12,13 @@ create database innodb_encrypted_1;
 use innodb_encrypted_1;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	3
+Innodb_pages0_read	1
 set autocommit=0;
 set autocommit=1;
 commit work;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	3
+Innodb_pages0_read	1
 # should be 100
 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%';
 COUNT(*)
@@ -88,47 +88,47 @@ Innodb_pages0_read	3
 # Restart Success!
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 use test;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 use innodb_encrypted_1;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 use innodb_encrypted_2;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 use innodb_encrypted_3;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 use innodb_encrypted_1;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	1
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	101
 use innodb_encrypted_2;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	101
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	201
 use innodb_encrypted_3;
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	201
 show status like 'innodb_pages0_read%';
 Variable_name	Value
-Innodb_pages0_read	303
+Innodb_pages0_read	301
 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%';
 COUNT(*)
 100
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 9b9d0b37f13..97cc162422f 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -4555,6 +4555,7 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
 		!bpage->encrypted &&
 		fil_space_verify_crypt_checksum(dst_frame, zip_size,
 			space, bpage->offset));
+
 	if (!still_encrypted) {
 		/* If traditional checksums match, we assume that page is
 		not anymore encrypted. */
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 2131a936656..23f2ca9b1f3 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -386,7 +386,8 @@ fil_space_crypt_t::write_page0(
 		page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 	const uint len = sizeof(iv);
 	ulint zip_size = fsp_header_get_zip_size(page);
-	const ulint offset = fsp_header_get_crypt_offset(zip_size);
+	const ulint offset = FSP_HEADER_OFFSET
+		+ fsp_header_get_encryption_offset(zip_size);
 	page0_offset = offset;
 
 	/*
@@ -1125,6 +1126,7 @@ fil_crypt_start_encrypting_space(
 	fil_space_t*	space)
 {
 	bool recheck = false;
+
 	mutex_enter(&fil_crypt_threads_mutex);
 
 	fil_space_crypt_t *crypt_data = space->crypt_data;
@@ -1191,8 +1193,7 @@ fil_crypt_start_encrypting_space(
 		byte* frame = buf_block_get_frame(block);
 		crypt_data->type = CRYPT_SCHEME_1;
 		crypt_data->write_page0(frame, &mtr);
-
-
+		space->page_0_crypt_read = true;
 		mtr_commit(&mtr);
 
 		/* record lsn of update */
@@ -1620,6 +1621,17 @@ fil_crypt_find_space_to_rotate(
 	}
 
 	while (!state->should_shutdown() && state->space) {
+		/* If there is no crypt data and we have not yet read
+		page 0 for this tablespace, we need to read it before
+		we can continue. */
+		if (!state->space->page_0_crypt_read) {
+			mutex_enter(&fil_system->mutex);
+			if (!state->space->chain.start->open) {
+				fil_node_open_file(state->space->chain.start, fil_system, state->space);
+			}
+			mutex_exit(&fil_system->mutex);
+		}
+
 		if (fil_crypt_space_needs_rotation(state, key_state, recheck)) {
 			ut_ad(key_state->key_id);
 			/* init state->min_key_version_found before
@@ -2544,6 +2556,18 @@ fil_space_crypt_get_status(
 	memset(status, 0, sizeof(*status));
 
 	ut_ad(space->n_pending_ops > 0);
+
+	/* If there is no crypt data and we have not yet read
+	page 0 for this tablespace, we need to read it before
+	we can continue. */
+	if (!space->page_0_crypt_read) {
+		mutex_enter(&fil_system->mutex);
+		if (!space->chain.start->open) {
+			fil_node_open_file(space->chain.start, fil_system, const_cast<fil_space_t*>(space));
+		}
+		mutex_exit(&fil_system->mutex);
+	}
+
 	fil_space_crypt_t* crypt_data = space->crypt_data;
 	status->space = space->id;
 
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index e19ef110b4f..60568edac53 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -568,7 +568,7 @@ fil_node_create(
 Opens a file of a node of a tablespace. The caller must own the fil_system
 mutex.
 @return false if the file can't be opened, otherwise true */
-static
+UNIV_INTERN
 bool
 fil_node_open_file(
 /*===============*/
@@ -654,9 +654,10 @@ fil_node_open_file(
 		/* Try to read crypt_data from page 0 if it is not yet
 		read. */
 		if (!node->space->page_0_crypt_read) {
-			ulint offset = fsp_header_get_crypt_offset(
-				fsp_flags_get_zip_size(flags));
-			ut_ad(node->space->crypt_data == NULL);
+			ut_ad(!node->space->crypt_data);
+			const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					fsp_flags_get_zip_size(flags));
 			node->space->crypt_data = fil_space_read_crypt_data(space_id, page, offset);
 			node->space->page_0_crypt_read = true;
 		}
@@ -2401,8 +2402,9 @@ fil_read_first_page(
 		/* Possible encryption crypt data is also stored only to first page
 		of the first datafile. */
 
-		ulint offset = fsp_header_get_crypt_offset(
-			fsp_flags_get_zip_size(*flags));
+		const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					fsp_flags_get_zip_size(*flags));
 
 		cdata = fil_space_read_crypt_data(*space_id, page, offset);
 
@@ -4005,6 +4007,7 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
 		    space_id, fsp_flags_get_zip_size(flags), 0, RW_X_LATCH,
 		    &mtr)) {
 		ulint f = fsp_header_get_flags(b->frame);
+
 		/* Suppress the message if only the DATA_DIR flag to differs. */
 		if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) {
 			ib_logf(IB_LOG_LEVEL_WARN,
@@ -4018,6 +4021,7 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
 					 flags, MLOG_4BYTES, &mtr);
 		}
 	}
+
 	mtr_commit(&mtr);
 }
 
@@ -4437,7 +4441,17 @@ fil_open_single_table_tablespace(
 
 	mem_free(def.filepath);
 
-	if (err == DB_SUCCESS && !srv_read_only_mode) {
+	/* We need to check fsp flags when no errors has happened and
+	server was not started on read only mode and tablespace validation
+	was requested or flags contain other table options except
+	low order bits to FSP_FLAGS_POS_PAGE_SSIZE position.
+	Note that flag comparison is pessimistic. Adjust is required
+	only when flags contain buggy MariaDB 10.1.0 -
+	MariaDB 10.1.20 flags.  */
+	if (err == DB_SUCCESS
+	    && !srv_read_only_mode
+	    && (validate
+		|| flags >= (1U << FSP_FLAGS_POS_PAGE_SSIZE))) {
 		fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK);
 	}
 
@@ -6887,12 +6901,13 @@ fil_tablespace_iterate(
 		/* In MariaDB/MySQL 5.6 tablespace does not exist
 		during import, therefore we can't use space directly
 		here. */
-		ulint crypt_data_offset = fsp_header_get_crypt_offset(
-			callback.get_zip_size());
+		const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					callback.get_zip_size());
 
 		/* read (optional) crypt data */
 		iter.crypt_data = fil_space_read_crypt_data(
-			0, page, crypt_data_offset);
+			0, page, offset);
 
 		/* Compressed pages can't be optimised for block IO for now.
 		We do the IMPORT page by page. */
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 98cd11f3369..2b02631d898 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,6 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -4144,30 +4145,6 @@ fsp_print(
 #endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************************//**
-Compute offset after xdes where crypt data can be stored
- at param[in]	zip_size	Compressed size or 0
- at return	offset */
-ulint
-fsp_header_get_crypt_offset(
-	const ulint   zip_size)
-{
-	ulint pageno = 0;
-	/* compute first page_no that will have xdes stored on page != 0*/
-	for (ulint i = 0;
-	     (pageno = xdes_calc_descriptor_page(zip_size, i)) == 0; )
-		i++;
-
-	/* use pageno prior to this...i.e last page on page 0 */
-	ut_ad(pageno > 0);
-	pageno--;
-
-	ulint iv_offset = XDES_ARR_OFFSET +
-		XDES_SIZE * (1 + xdes_calc_descriptor_index(zip_size, pageno));
-
-	return FSP_HEADER_OFFSET + iv_offset;
-}
-
-/**********************************************************************//**
 Checks if a single page is free.
 @return	true if free */
 UNIV_INTERN
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index ba440cb2a1c..221b679877c 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -792,6 +792,18 @@ class FilSpace
 	fil_space_t*	m_space;
 };
 
+/********************************************************************//**
+Opens a file of a node of a tablespace. The caller must own the fil_system
+mutex.
+ at return false if the file can't be opened, otherwise true */
+UNIV_INTERN
+bool
+fil_node_open_file(
+/*===============*/
+	fil_node_t*	node,	/*!< in: file node */
+	fil_system_t*	system,	/*!< in: tablespace memory cache */
+	fil_space_t*	space)	/*!< in: space */
+	MY_ATTRIBUTE((warn_unused_result));
 /** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
 the first page of a first data file at database startup.
 @param[in]	data_file		open data file
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 905e98cc1e6..13dac818c84 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -508,6 +508,17 @@ ulint
 fsp_header_get_zip_size(
 /*====================*/
 	const page_t*	page);	/*!< in: first page of a tablespace */
+
+/** Get the byte offset of encryption information in page 0.
+ at param[in]	ps	page size
+ at return	byte offset relative to FSP_HEADER_OFFSET */
+inline MY_ATTRIBUTE((pure, warn_unused_result))
+ulint
+fsp_header_get_encryption_offset(ulint zip_size)
+{
+	return (XDES_ARR_OFFSET + XDES_SIZE * (zip_size ? zip_size : UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE);
+}
+
 /**********************************************************************//**
 Writes the space id and flags to a tablespace header.  The flags contain
 row type, physical/compressed page size, and logical/uncompressed page
@@ -1042,16 +1053,6 @@ fsp_flags_get_page_size(
 /*====================*/
 	ulint	flags);		/*!< in: tablespace flags */
 
-/*********************************************************************
-Compute offset after xdes where crypt data can be stored
- at param[in]	zip_size	Compressed size or 0
- at return	offset */
-UNIV_INTERN
-ulint
-fsp_header_get_crypt_offset(
-	const ulint zip_size)
-	MY_ATTRIBUTE((warn_unused_result));
-
 #define fsp_page_is_free(space,page,mtr) \
 	fsp_page_is_free_func(space,page,mtr, __FILE__, __LINE__)
 
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index da4ab059d07..03dc1346517 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -4642,6 +4642,7 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
 		!bpage->encrypted &&
 		fil_space_verify_crypt_checksum(dst_frame, zip_size,
 			space, bpage->offset));
+
 	if (!still_encrypted) {
 		/* If traditional checksums match, we assume that page is
 		not anymore encrypted. */
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 21c1e3b730e..4387aaa6455 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -386,7 +386,8 @@ fil_space_crypt_t::write_page0(
 		page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 	const uint len = sizeof(iv);
 	ulint zip_size = fsp_header_get_zip_size(page);
-	const ulint offset = fsp_header_get_crypt_offset(zip_size);
+	const ulint offset = FSP_HEADER_OFFSET
+		+ fsp_header_get_encryption_offset(zip_size);
 	page0_offset = offset;
 
 	/*
@@ -1125,6 +1126,7 @@ fil_crypt_start_encrypting_space(
 	fil_space_t*	space)
 {
 	bool recheck = false;
+
 	mutex_enter(&fil_crypt_threads_mutex);
 
 	fil_space_crypt_t *crypt_data = space->crypt_data;
@@ -1191,8 +1193,7 @@ fil_crypt_start_encrypting_space(
 		byte* frame = buf_block_get_frame(block);
 		crypt_data->type = CRYPT_SCHEME_1;
 		crypt_data->write_page0(frame, &mtr);
-
-
+		space->page_0_crypt_read = true;
 		mtr_commit(&mtr);
 
 		/* record lsn of update */
@@ -1620,6 +1621,17 @@ fil_crypt_find_space_to_rotate(
 	}
 
 	while (!state->should_shutdown() && state->space) {
+		/* If there is no crypt data and we have not yet read
+		page 0 for this tablespace, we need to read it before
+		we can continue. */
+		if (!state->space->page_0_crypt_read) {
+			mutex_enter(&fil_system->mutex);
+			if (!state->space->chain.start->open) {
+				fil_node_open_file(state->space->chain.start, fil_system, state->space);
+			}
+			mutex_exit(&fil_system->mutex);
+		}
+
 		if (fil_crypt_space_needs_rotation(state, key_state, recheck)) {
 			ut_ad(key_state->key_id);
 			/* init state->min_key_version_found before
@@ -2545,6 +2557,18 @@ fil_space_crypt_get_status(
 	memset(status, 0, sizeof(*status));
 
 	ut_ad(space->n_pending_ops > 0);
+
+	/* If there is no crypt data and we have not yet read
+	page 0 for this tablespace, we need to read it before
+	we can continue. */
+	if (!space->page_0_crypt_read) {
+		mutex_enter(&fil_system->mutex);
+		if (!space->chain.start->open) {
+			fil_node_open_file(space->chain.start, fil_system, const_cast<fil_space_t*>(space));
+		}
+		mutex_exit(&fil_system->mutex);
+	}
+
 	fil_space_crypt_t* crypt_data = space->crypt_data;
 	status->space = space->id;
 
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index b669d35ff15..ddd2a12cec0 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -576,7 +576,7 @@ fil_node_create(
 Opens a file of a node of a tablespace. The caller must own the fil_system
 mutex.
 @return false if the file can't be opened, otherwise true */
-static
+UNIV_INTERN
 bool
 fil_node_open_file(
 /*===============*/
@@ -662,9 +662,10 @@ fil_node_open_file(
 		/* Try to read crypt_data from page 0 if it is not yet
 		read. */
 		if (!node->space->page_0_crypt_read) {
-			ulint offset = fsp_header_get_crypt_offset(
-				fsp_flags_get_zip_size(flags));
-			ut_ad(node->space->crypt_data == NULL);
+			ut_ad(!node->space->crypt_data);
+			const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					fsp_flags_get_zip_size(flags));
 			node->space->crypt_data = fil_space_read_crypt_data(space_id, page, offset);
 			node->space->page_0_crypt_read = true;
 		}
@@ -2463,8 +2464,9 @@ fil_read_first_page(
 		/* Possible encryption crypt data is also stored only to first page
 		of the first datafile. */
 
-		ulint offset = fsp_header_get_crypt_offset(
-			fsp_flags_get_zip_size(*flags));
+		const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					fsp_flags_get_zip_size(*flags));
 
 		cdata = fil_space_read_crypt_data(*space_id, page, offset);
 
@@ -4198,6 +4200,7 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
 		    space_id, fsp_flags_get_zip_size(flags), 0, RW_X_LATCH,
 		    &mtr)) {
 		ulint f = fsp_header_get_flags(b->frame);
+
 		/* Suppress the message if only the DATA_DIR flag to differs. */
 		if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) {
 			ib_logf(IB_LOG_LEVEL_WARN,
@@ -4211,6 +4214,7 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
 					 flags, MLOG_4BYTES, &mtr);
 		}
 	}
+
 	mtr_commit(&mtr);
 }
 
@@ -4631,7 +4635,17 @@ fil_open_single_table_tablespace(
 
 	mem_free(def.filepath);
 
-	if (err == DB_SUCCESS && !srv_read_only_mode) {
+	/* We need to check fsp flags when no errors has happened and
+	server was not started on read only mode and tablespace validation
+	was requested or flags contain other table options except
+	low order bits to FSP_FLAGS_POS_PAGE_SSIZE position.
+	Note that flag comparison is pessimistic. Adjust is required
+	only when flags contain buggy MariaDB 10.1.0 -
+	MariaDB 10.1.20 flags.  */
+	if (err == DB_SUCCESS
+	    && !srv_read_only_mode
+	    && (validate
+		|| flags >= (1U << FSP_FLAGS_POS_PAGE_SSIZE))) {
 		fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK);
 	}
 
@@ -7226,12 +7240,13 @@ fil_tablespace_iterate(
 		/* In MariaDB/MySQL 5.6 tablespace does not exist
 		during import, therefore we can't use space directly
 		here. */
-		ulint crypt_data_offset = fsp_header_get_crypt_offset(
-			callback.get_zip_size());
+		const ulint offset = FSP_HEADER_OFFSET
+				+ fsp_header_get_encryption_offset(
+					callback.get_zip_size());
 
 		/* read (optional) crypt data */
 		iter.crypt_data = fil_space_read_crypt_data(
-			0, page, crypt_data_offset);
+			0, page, offset);
 
 		/* Compressed pages can't be optimised for block IO for now.
 		We do the IMPORT page by page. */
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 7929372ae6c..06a696d2422 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -1,6 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -4170,30 +4171,6 @@ fsp_print(
 #endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************************//**
-Compute offset after xdes where crypt data can be stored
- at param[in]	zip_size	Compressed size or 0
- at return	offset */
-ulint
-fsp_header_get_crypt_offset(
-	const ulint   zip_size)
-{
-	ulint pageno = 0;
-	/* compute first page_no that will have xdes stored on page != 0*/
-	for (ulint i = 0;
-	     (pageno = xdes_calc_descriptor_page(zip_size, i)) == 0; )
-		i++;
-
-	/* use pageno prior to this...i.e last page on page 0 */
-	ut_ad(pageno > 0);
-	pageno--;
-
-	ulint iv_offset = XDES_ARR_OFFSET +
-		XDES_SIZE * (1 + xdes_calc_descriptor_index(zip_size, pageno));
-
-	return FSP_HEADER_OFFSET + iv_offset;
-}
-
-/**********************************************************************//**
 Checks if a single page is free.
 @return	true if free */
 UNIV_INTERN
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index b861225f562..3af6e42002e 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -798,6 +798,18 @@ class FilSpace
 	fil_space_t*	m_space;
 };
 
+/********************************************************************//**
+Opens a file of a node of a tablespace. The caller must own the fil_system
+mutex.
+ at return false if the file can't be opened, otherwise true */
+UNIV_INTERN
+bool
+fil_node_open_file(
+/*===============*/
+	fil_node_t*	node,	/*!< in: file node */
+	fil_system_t*	system,	/*!< in: tablespace memory cache */
+	fil_space_t*	space)	/*!< in: space */
+	MY_ATTRIBUTE((warn_unused_result));
 /** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
 the first page of a first data file at database startup.
 @param[in]	data_file		open data file
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index d8f851a0846..8042b232333 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -507,6 +507,17 @@ ulint
 fsp_header_get_zip_size(
 /*====================*/
 	const page_t*	page);	/*!< in: first page of a tablespace */
+
+/** Get the byte offset of encryption information in page 0.
+ at param[in]	ps	page size
+ at return	byte offset relative to FSP_HEADER_OFFSET */
+inline MY_ATTRIBUTE((pure, warn_unused_result))
+ulint
+fsp_header_get_encryption_offset(ulint zip_size)
+{
+	return (XDES_ARR_OFFSET + XDES_SIZE * (zip_size ? zip_size : UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE);
+}
+
 /**********************************************************************//**
 Writes the space id and flags to a tablespace header.  The flags contain
 row type, physical/compressed page size, and logical/uncompressed page
@@ -1041,16 +1052,6 @@ fsp_flags_get_page_size(
 /*====================*/
 	ulint	flags);		/*!< in: tablespace flags */
 
-/*********************************************************************
-Compute offset after xdes where crypt data can be stored
- at param[in]	zip_size	Compressed size or 0
- at return	offset */
-UNIV_INTERN
-ulint
-fsp_header_get_crypt_offset(
-	const ulint zip_size)
-	MY_ATTRIBUTE((warn_unused_result));
-
 #define fsp_page_is_free(space,page,mtr) \
 	fsp_page_is_free_func(space,page,mtr, __FILE__, __LINE__)
 


More information about the commits mailing list