mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
MDEV-8143: InnoDB: Database page corruption on disk or a failed file read
Analysis: Problem was that we did create crypt data for encrypted table but this new crypt data was not written to page 0. Instead a default crypt data was written to page 0 at table creation. Fixed by explicitly writing new crypt data to page 0 after successfull table creation.
This commit is contained in:
parent
be2038e3cb
commit
f8cacd03a7
17 changed files with 335 additions and 36 deletions
|
@ -217,11 +217,11 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where
|
|||
t1.c1 = t2.c1 and t1.b = t2.b;
|
||||
count(*)
|
||||
2000
|
||||
SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted';
|
||||
variable_value = 0
|
||||
SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted';
|
||||
variable_value >= 0
|
||||
1
|
||||
SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted';
|
||||
variable_value = 0
|
||||
SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted';
|
||||
variable_value >= 0
|
||||
1
|
||||
drop procedure innodb_insert_proc;
|
||||
drop table innodb_normal;
|
||||
|
@ -229,3 +229,11 @@ drop table innodb_compact;
|
|||
drop table innodb_compressed;
|
||||
drop table innodb_dynamic;
|
||||
drop table innodb_redundant;
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ENCRYPTION_KEY_ID=2 ENCRYPTED=YES;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
# Restarting server...
|
||||
SELECT * FROM t1;
|
||||
pk
|
||||
1
|
||||
2
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
--innodb-encrypt-log
|
||||
--innodb-encrypt-log=ON
|
||||
--innodb-encrypt-tables=ON
|
||||
|
||||
|
|
|
@ -133,9 +133,8 @@ t1.c1 = t2.c1 and t1.b = t2.b;
|
|||
select count(*) from innodb_redundant t1, innodb_normal t2 where
|
||||
t1.c1 = t2.c1 and t1.b = t2.b;
|
||||
|
||||
# After alter+restart these should be 0
|
||||
SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted';
|
||||
SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted';
|
||||
SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted';
|
||||
SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted';
|
||||
|
||||
drop procedure innodb_insert_proc;
|
||||
drop table innodb_normal;
|
||||
|
@ -144,6 +143,19 @@ drop table innodb_compressed;
|
|||
drop table innodb_dynamic;
|
||||
drop table innodb_redundant;
|
||||
|
||||
#
|
||||
# MDEV-8143: InnoDB: Database page corruption on disk or a failed file read
|
||||
#
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ENCRYPTION_KEY_ID=2 ENCRYPTED=YES;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
--echo # Restarting server...
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# reset system
|
||||
--disable_query_log
|
||||
EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig;
|
||||
|
|
|
@ -5701,6 +5701,10 @@ buf_page_encrypt_before_write(
|
|||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(src_frame);
|
||||
#endif
|
||||
|
||||
if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
/* Encryption is disabled */
|
||||
return const_cast<byte*>(src_frame);
|
||||
|
@ -5754,6 +5758,11 @@ buf_page_encrypt_before_write(
|
|||
ut_ad(key_version == 0 || key_version >= bpage->key_version);
|
||||
bpage->key_version = key_version;
|
||||
bpage->real_size = page_size;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* First we compress the page content */
|
||||
ulint out_len = 0;
|
||||
|
@ -5775,6 +5784,10 @@ buf_page_encrypt_before_write(
|
|||
|
||||
bpage->real_size = out_len;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
/* And then we encrypt the page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
|
@ -5784,6 +5797,10 @@ buf_page_encrypt_before_write(
|
|||
dst_frame);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
// return dst_frame which will be written
|
||||
return dst_frame;
|
||||
}
|
||||
|
@ -5822,6 +5839,10 @@ buf_page_decrypt_after_read(
|
|||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
|
@ -5830,6 +5851,10 @@ buf_page_decrypt_after_read(
|
|||
/* Mark this slot as free */
|
||||
slot->reserved = false;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
} else {
|
||||
/* the page we read is encrypted */
|
||||
/* Find free slot from temporary memory array */
|
||||
|
@ -5837,12 +5862,22 @@ buf_page_decrypt_after_read(
|
|||
|
||||
memcpy(slot->crypt_buf, dst_frame, size);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
|
||||
/* decrypt from crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
|
||||
/* decompress from dst_frame to comp_buf and then copy to
|
||||
buffer pool */
|
||||
if (page_compressed) {
|
||||
|
@ -5852,6 +5887,10 @@ buf_page_decrypt_after_read(
|
|||
&bpage->write_size);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* Mark this slot as free */
|
||||
slot->reserved = false;
|
||||
}
|
||||
|
|
|
@ -272,8 +272,10 @@ Create a fil_space_crypt_t object
|
|||
@return crypt object */
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t*
|
||||
fil_space_create_crypt_data(uint key_id)
|
||||
/*=========================*/
|
||||
fil_space_create_crypt_data(
|
||||
/*========================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||
uint key_id) /*!< in: encryption key id */
|
||||
{
|
||||
const uint iv_length = CRYPT_SCHEME_1_IV_LEN;
|
||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
||||
|
@ -282,7 +284,8 @@ fil_space_create_crypt_data(uint key_id)
|
|||
|
||||
memset(crypt_data, 0, sz);
|
||||
|
||||
if (!srv_encrypt_tables) {
|
||||
if (encrypt_mode == FIL_SPACE_ENCRYPTION_OFF ||
|
||||
(!srv_encrypt_tables && encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT)) {
|
||||
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
|
||||
crypt_data->min_key_version = 0;
|
||||
} else {
|
||||
|
@ -515,10 +518,15 @@ fil_space_write_crypt_data(
|
|||
{
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
/* If no crypt data is stored on memory cache for this space
|
||||
or space is not encrypted and encryption is not enabled, then
|
||||
do not continue writing crypt data to page 0. */
|
||||
if (crypt_data == NULL || !srv_encrypt_tables) {
|
||||
/* If no crypt data is stored on memory cache for this space,
|
||||
then do not continue writing crypt data to page 0. */
|
||||
if (crypt_data == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If tablespace encryption is disabled and encryption mode is
|
||||
DEFAULT, then do not continue writing crypt data to page 0. */
|
||||
if (!srv_encrypt_tables && crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -577,7 +585,7 @@ fil_parse_write_crypt_data(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(key_id);
|
||||
fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(encryption, key_id);
|
||||
crypt_data->page0_offset = offset;
|
||||
crypt_data->min_key_version = min_key_version;
|
||||
crypt_data->encryption = encryption;
|
||||
|
@ -1112,7 +1120,7 @@ fil_crypt_start_encrypting_space(
|
|||
* crypt data in page 0 */
|
||||
|
||||
/* 1 - create crypt data */
|
||||
crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
if (crypt_data == NULL) {
|
||||
mutex_exit(&fil_crypt_threads_mutex);
|
||||
return pending_op;
|
||||
|
|
|
@ -3474,7 +3474,7 @@ fil_create_new_single_table_tablespace(
|
|||
}
|
||||
|
||||
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
|
||||
fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY));
|
||||
fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY));
|
||||
|
||||
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
|
||||
err = DB_ERROR;
|
||||
|
|
|
@ -11718,12 +11718,12 @@ ha_innobase::create(
|
|||
/* If user has requested that table should be encrypted or table
|
||||
should remain as unencrypted store crypt data */
|
||||
if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
ulint maxsize;
|
||||
ulint maxsize=0;
|
||||
ulint zip_size = fil_space_get_zip_size(innobase_table->space);
|
||||
fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space);
|
||||
fil_space_crypt_t* crypt_data;
|
||||
|
||||
crypt_data = fil_space_create_crypt_data(key_id);
|
||||
crypt_data = fil_space_create_crypt_data(encrypt, key_id);
|
||||
crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize);
|
||||
crypt_data->encryption = encrypt;
|
||||
|
||||
|
@ -11733,7 +11733,29 @@ ha_innobase::create(
|
|||
crypt_data->iv_length = old_crypt_data->iv_length;
|
||||
}
|
||||
|
||||
mtr_t mtr;
|
||||
mtr_start(&mtr);
|
||||
/* Get page 0*/
|
||||
ulint offset = 0;
|
||||
buf_block_t* block = buf_page_get_gen(innobase_table->space,
|
||||
zip_size,
|
||||
offset,
|
||||
RW_X_LATCH,
|
||||
NULL,
|
||||
BUF_GET,
|
||||
__FILE__, __LINE__,
|
||||
&mtr);
|
||||
|
||||
/* Set up new crypt data */
|
||||
fil_space_set_crypt_data(innobase_table->space, crypt_data);
|
||||
|
||||
/* Compute location to store crypt data */
|
||||
byte* frame = buf_block_get_frame(block);
|
||||
|
||||
/* Write crypt data to page 0 */
|
||||
fil_space_write_crypt_data(innobase_table->space, frame, crypt_data->page0_offset, maxsize, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
innobase_copy_frm_flags_from_create_info(innobase_table, create_info);
|
||||
|
|
|
@ -118,7 +118,10 @@ fil_space_crypt_cleanup();
|
|||
Create crypt data, i.e data that is used for a single tablespace */
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t *
|
||||
fil_space_create_crypt_data(uint key_id);
|
||||
fil_space_create_crypt_data(
|
||||
/*========================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||
uint key_id); /*!< in: encryption key id */
|
||||
|
||||
/*********************************************************************
|
||||
Destroy crypt data */
|
||||
|
|
|
@ -105,4 +105,70 @@ fil_node_get_block_size(
|
|||
return (node->file_block_size);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/****************************************************************//**
|
||||
Validate page type.
|
||||
@return true if valid, false if not */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
fil_page_type_validate(
|
||||
const byte* page) /*!< in: page */
|
||||
{
|
||||
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
|
||||
#ifdef UNIV_ENCRYPTION_EXTRA_DEBUG
|
||||
uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED);
|
||||
ulint space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
ulint offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
||||
ib_uint64_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
|
||||
ulint compressed_len = mach_read_from_2(page + FIL_PAGE_DATA);
|
||||
fil_system_enter();
|
||||
fil_space_t* rspace = fil_space_get_by_id(space);
|
||||
fil_system_exit();
|
||||
|
||||
/* Dump out the page info */
|
||||
fprintf(stderr, "InnoDB: Space %lu offset %lu name %s page_type %lu page_type_name %s\n"
|
||||
"InnoDB: key_version %u page_compressed %d lsn %lu compressed_len %lu\n",
|
||||
space, offset, rspace->name, page_type, fil_get_page_type_name(page_type),
|
||||
key_version, page_compressed, lsn, compressed_len);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
/* Validate page type */
|
||||
if (!((page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
||||
page_type == FIL_PAGE_INDEX ||
|
||||
page_type == FIL_PAGE_UNDO_LOG ||
|
||||
page_type == FIL_PAGE_INODE ||
|
||||
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
||||
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
||||
page_type == FIL_PAGE_IBUF_BITMAP ||
|
||||
page_type == FIL_PAGE_TYPE_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
||||
page_type == FIL_PAGE_TYPE_XDES ||
|
||||
page_type == FIL_PAGE_TYPE_BLOB ||
|
||||
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
||||
page_type == FIL_PAGE_TYPE_COMPRESSED))) {
|
||||
|
||||
ut_ad(page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
||||
page_type == FIL_PAGE_INDEX ||
|
||||
page_type == FIL_PAGE_UNDO_LOG ||
|
||||
page_type == FIL_PAGE_INODE ||
|
||||
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
||||
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
||||
page_type == FIL_PAGE_IBUF_BITMAP ||
|
||||
page_type == FIL_PAGE_TYPE_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
||||
page_type == FIL_PAGE_TYPE_XDES ||
|
||||
page_type == FIL_PAGE_TYPE_BLOB ||
|
||||
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
||||
page_type == FIL_PAGE_TYPE_COMPRESSED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#endif /* fil0fil_ic */
|
||||
|
|
|
@ -1120,7 +1120,7 @@ check_first_page:
|
|||
|
||||
*sum_of_new_sizes += srv_data_file_sizes[i];
|
||||
|
||||
crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
}
|
||||
|
||||
ret = os_file_close(files[i]);
|
||||
|
|
|
@ -5859,6 +5859,10 @@ buf_page_encrypt_before_write(
|
|||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(src_frame);
|
||||
#endif
|
||||
|
||||
if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
/* Encryption is disabled */
|
||||
return const_cast<byte*>(src_frame);
|
||||
|
@ -5912,6 +5916,11 @@ buf_page_encrypt_before_write(
|
|||
ut_ad(key_version == 0 || key_version >= bpage->key_version);
|
||||
bpage->key_version = key_version;
|
||||
bpage->real_size = page_size;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* First we compress the page content */
|
||||
ulint out_len = 0;
|
||||
|
@ -5933,6 +5942,10 @@ buf_page_encrypt_before_write(
|
|||
|
||||
bpage->real_size = out_len;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
/* And then we encrypt the page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
|
@ -5942,6 +5955,10 @@ buf_page_encrypt_before_write(
|
|||
dst_frame);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
// return dst_frame which will be written
|
||||
return dst_frame;
|
||||
}
|
||||
|
@ -5977,6 +5994,10 @@ buf_page_decrypt_after_read(
|
|||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
|
@ -5985,22 +6006,40 @@ buf_page_decrypt_after_read(
|
|||
/* Mark this slot as free */
|
||||
slot->reserved = false;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
} else {
|
||||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
memcpy(slot->crypt_buf, dst_frame, size);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
|
||||
/* decrypt from crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
|
||||
if (page_compressed) {
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
&bpage->write_size);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mark this slot as free */
|
||||
|
|
|
@ -272,8 +272,10 @@ Create a fil_space_crypt_t object
|
|||
@return crypt object */
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t*
|
||||
fil_space_create_crypt_data(uint key_id)
|
||||
/*=========================*/
|
||||
fil_space_create_crypt_data(
|
||||
/*========================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||
uint key_id) /*!< in: encryption key id */
|
||||
{
|
||||
const uint iv_length = CRYPT_SCHEME_1_IV_LEN;
|
||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
||||
|
@ -282,7 +284,8 @@ fil_space_create_crypt_data(uint key_id)
|
|||
|
||||
memset(crypt_data, 0, sz);
|
||||
|
||||
if (!srv_encrypt_tables) {
|
||||
if (encrypt_mode == FIL_SPACE_ENCRYPTION_OFF ||
|
||||
(!srv_encrypt_tables && encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT)) {
|
||||
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
|
||||
crypt_data->min_key_version = 0;
|
||||
} else {
|
||||
|
@ -515,10 +518,15 @@ fil_space_write_crypt_data(
|
|||
{
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
/* If no crypt data is stored on memory cache for this space
|
||||
or space is not encrypted and encryption is not enabled, then
|
||||
do not continue writing crypt data to page 0. */
|
||||
if (crypt_data == NULL || !srv_encrypt_tables) {
|
||||
/* If no crypt data is stored on memory cache for this space,
|
||||
then do not continue writing crypt data to page 0. */
|
||||
if (crypt_data == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If tablespace encryption is disabled and encryption mode is
|
||||
DEFAULT, then do not continue writing crypt data to page 0. */
|
||||
if (!srv_encrypt_tables && crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -577,7 +585,7 @@ fil_parse_write_crypt_data(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(key_id);
|
||||
fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(encryption, key_id);
|
||||
crypt_data->page0_offset = offset;
|
||||
crypt_data->min_key_version = min_key_version;
|
||||
crypt_data->encryption = encryption;
|
||||
|
@ -1112,7 +1120,7 @@ fil_crypt_start_encrypting_space(
|
|||
* crypt data in page 0 */
|
||||
|
||||
/* 1 - create crypt data */
|
||||
crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
if (crypt_data == NULL) {
|
||||
mutex_exit(&fil_crypt_threads_mutex);
|
||||
return pending_op;
|
||||
|
|
|
@ -3508,7 +3508,7 @@ fil_create_new_single_table_tablespace(
|
|||
}
|
||||
|
||||
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
|
||||
fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY));
|
||||
fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY));
|
||||
|
||||
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
|
||||
err = DB_ERROR;
|
||||
|
|
|
@ -12231,12 +12231,12 @@ ha_innobase::create(
|
|||
/* If user has requested that table should be encrypted or table
|
||||
should remain as unencrypted store crypt data */
|
||||
if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
ulint maxsize;
|
||||
ulint maxsize=0;
|
||||
ulint zip_size = fil_space_get_zip_size(innobase_table->space);
|
||||
fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space);
|
||||
fil_space_crypt_t* crypt_data;
|
||||
|
||||
crypt_data = fil_space_create_crypt_data(key_id);
|
||||
crypt_data = fil_space_create_crypt_data(encrypt, key_id);
|
||||
crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize);
|
||||
crypt_data->encryption = encrypt;
|
||||
|
||||
|
@ -12246,7 +12246,29 @@ ha_innobase::create(
|
|||
crypt_data->iv_length = old_crypt_data->iv_length;
|
||||
}
|
||||
|
||||
mtr_t mtr;
|
||||
mtr_start(&mtr);
|
||||
/* Get page 0*/
|
||||
ulint offset = 0;
|
||||
buf_block_t* block = buf_page_get_gen(innobase_table->space,
|
||||
zip_size,
|
||||
offset,
|
||||
RW_X_LATCH,
|
||||
NULL,
|
||||
BUF_GET,
|
||||
__FILE__, __LINE__,
|
||||
&mtr);
|
||||
|
||||
/* Set up new crypt data */
|
||||
fil_space_set_crypt_data(innobase_table->space, crypt_data);
|
||||
|
||||
/* Compute location to store crypt data */
|
||||
byte* frame = buf_block_get_frame(block);
|
||||
|
||||
/* Write crypt data to page 0 */
|
||||
fil_space_write_crypt_data(innobase_table->space, frame, crypt_data->page0_offset, maxsize, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
innobase_copy_frm_flags_from_create_info(innobase_table, create_info);
|
||||
|
|
|
@ -118,7 +118,10 @@ fil_space_crypt_cleanup();
|
|||
Create crypt data, i.e data that is used for a single tablespace */
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t *
|
||||
fil_space_create_crypt_data(uint key_id);
|
||||
fil_space_create_crypt_data(
|
||||
/*========================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||
uint key_id); /*!< in: encryption key id */
|
||||
|
||||
/*********************************************************************
|
||||
Destroy crypt data */
|
||||
|
|
|
@ -105,4 +105,71 @@ fil_node_get_block_size(
|
|||
return (node->file_block_size);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/****************************************************************//**
|
||||
Validate page type.
|
||||
@return true if valid, false if not */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
fil_page_type_validate(
|
||||
const byte* page) /*!< in: page */
|
||||
{
|
||||
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
|
||||
#ifdef UNIV_ENCRYPTION_EXTRA_DEBUG
|
||||
uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED);
|
||||
ulint space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
ulint offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
||||
ib_uint64_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
|
||||
ulint compressed_len = mach_read_from_2(page + FIL_PAGE_DATA);
|
||||
fil_system_enter();
|
||||
fil_space_t* rspace = fil_space_get_by_id(space);
|
||||
fil_system_exit();
|
||||
|
||||
|
||||
/* Dump out the page info */
|
||||
fprintf(stderr, "InnoDB: Space %lu offset %lu name %s page_type %lu page_type_name %s\n"
|
||||
"InnoDB: key_version %u page_compressed %d lsn %lu compressed_len %lu\n",
|
||||
space, offset, rspace->name, page_type, fil_get_page_type_name(page_type),
|
||||
key_version, page_compressed, lsn, compressed_len);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
/* Validate page type */
|
||||
if (!((page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
||||
page_type == FIL_PAGE_INDEX ||
|
||||
page_type == FIL_PAGE_UNDO_LOG ||
|
||||
page_type == FIL_PAGE_INODE ||
|
||||
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
||||
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
||||
page_type == FIL_PAGE_IBUF_BITMAP ||
|
||||
page_type == FIL_PAGE_TYPE_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
||||
page_type == FIL_PAGE_TYPE_XDES ||
|
||||
page_type == FIL_PAGE_TYPE_BLOB ||
|
||||
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
||||
page_type == FIL_PAGE_TYPE_COMPRESSED))) {
|
||||
|
||||
ut_ad(page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
||||
page_type == FIL_PAGE_INDEX ||
|
||||
page_type == FIL_PAGE_UNDO_LOG ||
|
||||
page_type == FIL_PAGE_INODE ||
|
||||
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
||||
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
||||
page_type == FIL_PAGE_IBUF_BITMAP ||
|
||||
page_type == FIL_PAGE_TYPE_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
||||
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
||||
page_type == FIL_PAGE_TYPE_XDES ||
|
||||
page_type == FIL_PAGE_TYPE_BLOB ||
|
||||
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
||||
page_type == FIL_PAGE_TYPE_COMPRESSED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#endif /* fil0fil_ic */
|
||||
|
|
|
@ -1154,7 +1154,7 @@ check_first_page:
|
|||
|
||||
*sum_of_new_sizes += srv_data_file_sizes[i];
|
||||
|
||||
crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
}
|
||||
|
||||
ret = os_file_close(files[i]);
|
||||
|
|
Loading…
Reference in a new issue