Browse Source

Remove MYSQL_ENCRYPTION.

MariaDB will likely never support MySQL-style encryption for
InnoDB, because we cannot link with the Oracle encryption plugin.
This is preparation for merging MDEV-11623.
pull/258/merge
Marko Mäkelä 9 years ago
parent
commit
70c11485d2
  1. 4
      storage/innobase/btr/btr0btr.cc
  2. 4
      storage/innobase/dict/dict0crea.cc
  3. 7
      storage/innobase/dict/dict0dict.cc
  4. 9
      storage/innobase/dict/dict0load.cc
  5. 255
      storage/innobase/fil/fil0fil.cc
  6. 58
      storage/innobase/fsp/fsp0file.cc
  7. 363
      storage/innobase/fsp/fsp0fsp.cc
  8. 217
      storage/innobase/handler/ha_innodb.cc
  9. 15
      storage/innobase/handler/handler0alter.cc
  10. 6
      storage/innobase/include/db0err.h
  11. 14
      storage/innobase/include/dict0dict.h
  12. 12
      storage/innobase/include/dict0dict.ic
  13. 9
      storage/innobase/include/dict0mem.h
  14. 35
      storage/innobase/include/fil0fil.h
  15. 14
      storage/innobase/include/fsp0file.h
  16. 40
      storage/innobase/include/fsp0fsp.h
  17. 8
      storage/innobase/include/fsp0fsp.ic
  18. 8
      storage/innobase/include/fsp0types.h
  19. 1
      storage/innobase/include/ha_prototypes.h
  20. 13
      storage/innobase/include/log0recv.h
  21. 254
      storage/innobase/include/os0file.h
  22. 1
      storage/innobase/include/sync0sync.h
  23. 1
      storage/innobase/include/sync0types.h
  24. 183
      storage/innobase/log/log0recv.cc
  25. 901
      storage/innobase/os/os0file.cc
  26. 274
      storage/innobase/row/row0import.cc
  27. 58
      storage/innobase/row/row0mysql.cc
  28. 238
      storage/innobase/row/row0quiesce.cc
  29. 44
      storage/innobase/srv/srv0start.cc
  30. 2
      storage/innobase/sync/sync0debug.cc
  31. 1
      storage/innobase/sync/sync0sync.cc
  32. 4
      storage/innobase/ut/ut0ut.cc

4
storage/innobase/btr/btr0btr.cc

@ -336,9 +336,7 @@ btr_root_adjust_on_import(
/* Check that the table flags and the tablespace
flags match. */
ulint flags = dict_tf_to_fsp_flags(
table->flags,
false,
dict_table_is_encrypted(table));
table->flags, false);
ulint fsp_flags = fil_space_get_flags(table->space);
err = fsp_flags_are_equal(flags, fsp_flags)
? DB_SUCCESS : DB_CORRUPTION;

4
storage/innobase/dict/dict0crea.cc

@ -494,11 +494,9 @@ dict_build_tablespace_for_table(
/* Determine the tablespace flags. */
bool is_temp = dict_table_is_temporary(table);
bool is_encrypted = dict_table_is_encrypted(table);
bool has_data_dir = DICT_TF_HAS_DATA_DIR(table->flags);
ulint fsp_flags = dict_tf_to_fsp_flags(table->flags,
is_temp,
is_encrypted);
is_temp);
/* Determine the full filepath */
if (is_temp) {

7
storage/innobase/dict/dict0dict.cc

@ -7255,13 +7255,11 @@ dict_table_t::flags | 0 | 1 | 1 | 1
fil_space_t::flags | 0 | 0 | 1 | 1
@param[in] table_flags dict_table_t::flags
@param[in] is_temp whether the tablespace is temporary
@param[in] is_encrypted whether the tablespace is encrypted
@return tablespace flags (fil_space_t::flags) */
ulint
dict_tf_to_fsp_flags(
ulint table_flags,
bool is_temp,
bool is_encrypted)
bool is_temp)
{
DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
return(ULINT_UNDEFINED););
@ -7289,8 +7287,7 @@ dict_tf_to_fsp_flags(
is_temp,
0,
0,
0,
is_encrypted);
0);
/* In addition, tablespace flags also contain if the page
compression is used for this table. */

9
storage/innobase/dict/dict0load.cc

@ -1453,10 +1453,7 @@ dict_check_sys_tables(
/* Check that the .ibd file exists. */
bool is_temp = flags2 & DICT_TF2_TEMPORARY;
bool is_encrypted = flags2 & DICT_TF2_ENCRYPTION;
ulint fsp_flags = dict_tf_to_fsp_flags(flags,
is_temp,
is_encrypted);
ulint fsp_flags = dict_tf_to_fsp_flags(flags, is_temp);
validate = true; /* Encryption */
dberr_t err = fil_ibd_open(
@ -2991,9 +2988,7 @@ dict_load_tablespace(
/* Try to open the tablespace. We set the 2nd param (fix_dict) to
false because we do not have an x-lock on dict_operation_lock */
ulint fsp_flags = dict_tf_to_fsp_flags(table->flags,
false,
dict_table_is_encrypted(table));
ulint fsp_flags = dict_tf_to_fsp_flags(table->flags, false);
dberr_t err = fil_ibd_open(
true, false, FIL_TYPE_TABLESPACE, table->space,
fsp_flags, space_name, filepath, table);

255
storage/innobase/fil/fil0fil.cc

@ -139,7 +139,7 @@ const char* fil_path_to_mysql_datadir;
Folder folder_mysql_datadir;
/** Common InnoDB file extentions */
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg", ".cfp" };
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg" };
/** The number of fsyncs done to the log */
ulint fil_n_log_flushes = 0;
@ -747,21 +747,6 @@ retry:
ut_free(buf2);
#ifdef MYSQL_ENCRYPTION
/* For encrypted tablespace, we need to check the
encrytion key and iv(initial vector) is readed. */
if (FSP_FLAGS_GET_ENCRYPTION(flags)
&& !recv_recovery_is_on()) {
if (space->encryption_type != Encryption::AES) {
ib::error()
<< "Can't read encryption"
<< " key from file "
<< node->name << "!";
return(false);
}
}
#endif
if (node->size == 0) {
ulint extent_size;
@ -1695,8 +1680,6 @@ fil_space_create(
<< " " << fil_crypt_get_type(crypt_data));
}
space->encryption_type = Encryption::NONE;
rw_lock_create(fil_space_latch_key, &space->latch, SYNC_FSP);
if (space->purpose == FIL_TYPE_TEMPORARY) {
@ -4021,17 +4004,6 @@ fil_ibd_create(
goto error_exit_1;
}
#ifdef MYSQL_ENCRYPTION
/* For encryption tablespace, initial encryption information. */
if (FSP_FLAGS_GET_ENCRYPTION(space->flags)) {
err = fil_set_encryption(space->id,
Encryption::AES,
NULL,
NULL);
ut_ad(err == DB_SUCCESS);
}
#endif /* MYSQL_ENCRYPTION */
if (!is_temp) {
mtr_t mtr;
const fil_node_t* file = UT_LIST_GET_FIRST(space->chain);
@ -4107,7 +4079,6 @@ fil_ibd_open(
bool link_file_found = false;
bool link_file_is_bad = false;
bool is_shared = FSP_FLAGS_GET_SHARED(flags);
bool is_encrypted = FSP_FLAGS_GET_ENCRYPTION(flags);
Datafile df_default; /* default location */
Datafile df_dict; /* dictionary location */
RemoteDatafile df_remote; /* remote location */
@ -4228,7 +4199,7 @@ fil_ibd_open(
normal, we only found 1. */
/* For encrypted tablespace, we need to check the
encryption in header of first page. */
if (!validate && tablespaces_found == 1 && !is_encrypted) {
if (!validate && tablespaces_found == 1) {
goto skip_validate;
}
@ -4249,21 +4220,12 @@ fil_ibd_open(
/* Make sense of these three possible locations.
First, bail out if no tablespace files were found. */
if (valid_tablespaces_found == 0) {
if (!is_encrypted) {
/* The following call prints an error message.
For encrypted tablespace we skip print, since it should
be keyring plugin issues. */
os_file_get_last_error(true);
ib::error() << "Could not find a valid tablespace file for `"
<< space_name << "`. " << TROUBLESHOOT_DATADICT_MSG;
}
os_file_get_last_error(true);
ib::error() << "Could not find a valid tablespace file for `"
<< space_name << "`. " << TROUBLESHOOT_DATADICT_MSG;
return(DB_CORRUPTION);
}
if (!validate && !is_encrypted) {
return(DB_SUCCESS);
}
if (validate && is_encrypted && fil_space_get(id)) {
if (!validate) {
return(DB_SUCCESS);
}
@ -4428,25 +4390,6 @@ skip_validate:
true, TRUE) == NULL) {
err = DB_ERROR;
}
#ifdef MYSQL_ENCRYPTION
/* For encryption tablespace, initialize encryption
information.*/
if (err == DB_SUCCESS && is_encrypted && !for_import) {
Datafile& df_current = df_remote.is_open() ?
df_remote: df_dict.is_open() ?
df_dict : df_default;
byte* key = df_current.m_encryption_key;
byte* iv = df_current.m_encryption_iv;
ut_ad(key && iv);
err = fil_set_encryption(space->id, Encryption::AES,
key, iv);
ut_ad(err == DB_SUCCESS);
}
#endif /* MYSQL_ENCRYPTION */
}
return(err);
@ -4812,21 +4755,6 @@ fil_ibd_load(
ut_error;
}
#ifdef MYSQL_ENCRYPTION
/* For encryption tablespace, initial encryption information. */
if (FSP_FLAGS_GET_ENCRYPTION(space->flags)
&& file.m_encryption_key != NULL) {
dberr_t err = fil_set_encryption(space->id,
Encryption::AES,
file.m_encryption_key,
file.m_encryption_iv);
if (err != DB_SUCCESS) {
ib::error() << "Can't set encryption information for"
" tablespace " << space->name << "!";
}
}
#endif /* MYSQL_ENCRYPTION */
return(FIL_LOAD_OK);
}
@ -5296,33 +5224,6 @@ fil_report_invalid_page_access(
_exit(1);
}
#ifdef MYSQL_ENCRYPTION
/** Set encryption information for IORequest.
@param[in,out] req_type IO request
@param[in] page_id page id
@param[in] space table space */
inline
void
fil_io_set_encryption(
IORequest& req_type,
const page_id_t& page_id,
fil_space_t* space)
{
/* Don't encrypt the log, page 0 of all tablespaces, all pages
from the system tablespace. */
if (!req_type.is_log() && page_id.page_no() > 0
&& space->encryption_type != Encryption::NONE)
{
req_type.encryption_key(space->encryption_key,
space->encryption_klen,
space->encryption_iv);
req_type.encryption_algorithm(Encryption::AES);
} else {
req_type.clear_encrypted();
}
}
#endif /* MYSQL_ENCRYPTION */
/** Reads or writes data. This operation could be asynchronous (aio).
@param[in,out] type IO context
@ -5609,11 +5510,6 @@ fil_io(
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/* Set encryption information. */
fil_io_set_encryption(req_type, page_id, space);
#endif /* MYSQL_ENCRYPTION */
req_type.block_size(node->block_size);
/* Queue the aio request */
@ -6001,8 +5897,6 @@ struct fil_iterator_t {
byte* io_buffer; /*!< Buffer to use for IO */
fil_space_crypt_t *crypt_data; /*!< MariaDB Crypt data (if encrypted) */
byte* crypt_io_buffer; /*!< MariaDB IO buffer when encrypted */
byte* encryption_key; /*!< Encryption key */
byte* encryption_iv; /*!< Encryption iv */
};
/********************************************************************//**
@ -6080,16 +5974,6 @@ fil_iterate(
dberr_t err = DB_SUCCESS;
IORequest read_request(read_type);
#ifdef MYSQL_ENCRYPTION
/* For encrypted table, set encryption information. */
if (iter.encryption_key != NULL && offset != 0) {
read_request.encryption_key(iter.encryption_key,
ENCRYPTION_KEY_LEN,
iter.encryption_iv);
read_request.encryption_algorithm(Encryption::AES);
}
#endif /* MYSQL_ENCRYPTION */
byte* readptr = io_buffer;
byte* writeptr = io_buffer;
bool encrypted = false;
@ -6266,16 +6150,6 @@ fil_iterate(
IORequest write_request(write_type);
#ifdef MYSQL_ENCRYPTION
/* For encrypted table, set encryption information. */
if (iter.encryption_key != NULL && offset != 0) {
write_request.encryption_key(iter.encryption_key,
ENCRYPTION_KEY_LEN,
iter.encryption_iv);
write_request.encryption_algorithm(Encryption::AES);
}
#endif /* MYSQL_ENCRYPTION */
/* A page was updated in the set, write back to disk.
Note: We don't have the compression algorithm, we write
out the imported file as uncompressed. */
@ -6423,26 +6297,6 @@ fil_tablespace_iterate(
+ fsp_header_get_encryption_offset(
callback.get_page_size()));
#ifdef MYSQL_ENCRYPTION
/* Set encryption info. */
iter.encryption_key = table->encryption_key;
iter.encryption_iv = table->encryption_iv;
/* Check encryption is matched or not. */
ulint space_flags = callback.get_space_flags();
if (FSP_FLAGS_GET_ENCRYPTION(space_flags)) {
ut_ad(table->encryption_key != NULL);
if (!dict_table_is_encrypted(table)) {
ib::error() << "Table is not in an encrypted"
" tablespace, but the data file which"
" trying to import is an encrypted"
" tablespace";
err = DB_IO_NO_ENCRYPT_TABLESPACE;
}
}
#endif /* MYSQL_ENCRYPTION */
if (err == DB_SUCCESS) {
/* Compressed pages can't be optimised for block IO
@ -7046,101 +6900,6 @@ fil_get_compression(
return(space == NULL ? Compression::NONE : space->compression_type);
}
/** Set the encryption type for the tablespace
@param[in] space_id Space ID of tablespace for which to set
@param[in] algorithm Encryption algorithm
@param[in] key Encryption key
@param[in] iv Encryption iv
@return DB_SUCCESS or error code */
dberr_t
fil_set_encryption(
ulint space_id,
Encryption::Type algorithm,
byte* key,
byte* iv)
{
ut_ad(!is_system_or_undo_tablespace(space_id));
if (is_system_tablespace(space_id)) {
return(DB_IO_NO_ENCRYPT_TABLESPACE);
}
mutex_enter(&fil_system->mutex);
fil_space_t* space = fil_space_get_by_id(space_id);
if (space == NULL) {
mutex_exit(&fil_system->mutex);
return(DB_NOT_FOUND);
}
ut_ad(algorithm != Encryption::NONE);
space->encryption_type = algorithm;
if (key == NULL) {
Encryption::random_value(space->encryption_key);
} else {
memcpy(space->encryption_key,
key, ENCRYPTION_KEY_LEN);
}
space->encryption_klen = ENCRYPTION_KEY_LEN;
if (iv == NULL) {
Encryption::random_value(space->encryption_iv);
} else {
memcpy(space->encryption_iv,
iv, ENCRYPTION_KEY_LEN);
}
mutex_exit(&fil_system->mutex);
return(DB_SUCCESS);
}
/** Rotate the tablespace keys by new master key.
@return true if the re-encrypt suceeds */
bool
fil_encryption_rotate()
{
fil_space_t* space;
mtr_t mtr;
byte encrypt_info[ENCRYPTION_INFO_SIZE_V2];
for (space = UT_LIST_GET_FIRST(fil_system->space_list);
space != NULL; ) {
/* Skip unencypted tablespaces. */
if (is_system_or_undo_tablespace(space->id)
|| fsp_is_system_temporary(space->id)
|| space->purpose == FIL_TYPE_LOG) {
space = UT_LIST_GET_NEXT(space_list, space);
continue;
}
if (space->encryption_type != Encryption::NONE) {
mtr_start(&mtr);
mtr.set_named_space(space->id);
space = mtr_x_lock_space(space->id, &mtr);
memset(encrypt_info, 0, ENCRYPTION_INFO_SIZE_V2);
if (!fsp_header_rotate_encryption(space,
encrypt_info,
&mtr)) {
mtr_commit(&mtr);
return(false);
}
mtr_commit(&mtr);
}
space = UT_LIST_GET_NEXT(space_list, space);
DBUG_EXECUTE_IF("ib_crash_during_rotation_for_encryption",
DBUG_SUICIDE(););
}
return(true);
}
#endif /* MYSQL_COMPRESSION */
/** Build the basic folder name from the path and length provided
@ -7300,7 +7059,6 @@ test_make_filepath()
path = MF("/this/is/a/path/with/a/filename", NULL, IBD, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename", NULL, ISL, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename", NULL, CFG, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename", NULL, CFP, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename.ibd", NULL, IBD, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename.ibd", NULL, IBD, false); DISPLAY;
path = MF("/this/is/a/path/with/a/filename.dat", NULL, IBD, false); DISPLAY;
@ -7310,7 +7068,6 @@ test_make_filepath()
path = MF(NULL, "dbname/tablespacename", IBD, false); DISPLAY;
path = MF(NULL, "dbname/tablespacename", ISL, false); DISPLAY;
path = MF(NULL, "dbname/tablespacename", CFG, false); DISPLAY;
path = MF(NULL, "dbname/tablespacename", CFP, false); DISPLAY;
path = MF(NULL, "dbname\\tablespacename", NO_EXT, false); DISPLAY;
path = MF(NULL, "dbname\\tablespacename", IBD, false); DISPLAY;
path = MF("/this/is/a/path", "dbname/tablespacename", IBD, false); DISPLAY;

58
storage/innobase/fsp/fsp0file.cc

@ -47,8 +47,6 @@ Datafile::init(
m_name = mem_strdup(name);
m_flags = flags;
m_encryption_key = NULL;
m_encryption_iv = NULL;
}
/** Release the resources. */
@ -60,16 +58,10 @@ Datafile::shutdown()
ut_free(m_name);
m_name = NULL;
ut_free(m_encryption_key);
m_encryption_key = NULL;
/* The fil_space_t::crypt_data was freed in
fil_space_free_low(). Invalidate our redundant pointer. */
m_crypt_info = NULL;
ut_free(m_encryption_iv);
m_encryption_iv = NULL;
free_filepath();
free_first_page();
}
@ -459,11 +451,6 @@ Datafile::validate_for_recovery()
break;
default:
/* For encryption tablespace, we skip the retry step,
since it is only because the keyring is not ready. */
if (FSP_FLAGS_GET_ENCRYPTION(m_flags)) {
return(err);
}
/* Re-open the file in read-write mode Attempt to restore
page 0 from doublewrite and read the space ID from a survey
of the first few pages. */
@ -602,51 +589,6 @@ Datafile::validate_first_page(lsn_t* flush_lsn,
}
#ifdef MYSQL_ENCRYPTION
/* For encrypted tablespace, check the encryption info in the
first page can be decrypt by master key, otherwise, this table
can't be open. And for importing, we skip checking it. */
if (FSP_FLAGS_GET_ENCRYPTION(m_flags) && !for_import) {
m_encryption_key = static_cast<byte*>(
ut_zalloc_nokey(ENCRYPTION_KEY_LEN));
m_encryption_iv = static_cast<byte*>(
ut_zalloc_nokey(ENCRYPTION_KEY_LEN));
#ifdef UNIV_ENCRYPT_DEBUG
fprintf(stderr, "Got from file %lu:", m_space_id);
#endif
if (!fsp_header_get_encryption_key(m_flags,
m_encryption_key,
m_encryption_iv,
m_first_page)) {
ib::error()
<< "Encryption information in"
<< " datafile: " << m_filepath
<< " can't be decrypted"
<< " , please confirm the keyfile"
<< " is match and keyring plugin"
<< " is loaded.";
m_is_valid = false;
free_first_page();
ut_free(m_encryption_key);
ut_free(m_encryption_iv);
m_encryption_key = NULL;
m_encryption_iv = NULL;
return(DB_CORRUPTION);
}
if (recv_recovery_is_on()
&& memcmp(m_encryption_key,
m_encryption_iv,
ENCRYPTION_KEY_LEN) == 0) {
ut_free(m_encryption_key);
ut_free(m_encryption_iv);
m_encryption_key = NULL;
m_encryption_iv = NULL;
}
}
#endif /* MYSQL_ENCRYPTION */
if (fil_space_read_name_and_filepath(
m_space_id, &prev_name, &prev_filepath)) {

363
storage/innobase/fsp/fsp0fsp.cc

@ -230,7 +230,6 @@ fsp_flags_is_valid(
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
bool is_shared = FSP_FLAGS_GET_SHARED(flags);
bool is_temp = FSP_FLAGS_GET_TEMPORARY(flags);
bool is_encryption = FSP_FLAGS_GET_ENCRYPTION(flags);
ulint unused = FSP_FLAGS_GET_UNUSED(flags);
bool page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
@ -285,12 +284,6 @@ fsp_flags_is_valid(
return(false);
}
/* Only single-table and not temp tablespaces use the encryption
clause. */
if (is_encryption && (is_shared || is_temp)) {
GOTO_ERROR;
}
/* Page compression level requires page compression and atomic blobs
to be set */
if (page_compression_level || page_compression) {
@ -320,7 +313,6 @@ err_exit:
<< " has_data_dir: " << has_data_dir
<< " is_shared: " << is_shared
<< " is_temp: " << is_temp
<< " is_encryption: " << is_encryption
<< " page_compressed: " << page_compression
<< " page_compression_level: " << page_compression_level;
return (false);
@ -869,178 +861,6 @@ fsp_header_init_fields(
flags);
}
#if 0 /* MySQL 5.7 Encryption */
/** Fill the encryption info.
@param[in] space tablespace
@param[in,out] encrypt_info buffer for encrypt key.
@return true if success. */
bool
fsp_header_fill_encryption_info(
fil_space_t* space,
byte* encrypt_info)
{
byte* ptr;
lint elen;
ulint master_key_id;
byte* master_key;
byte key_info[ENCRYPTION_KEY_LEN * 2];
ulint crc;
Encryption::Version version;
#ifdef UNIV_ENCRYPT_DEBUG
const byte* data;
ulint i;
#endif
/* Get master key from key ring */
Encryption::get_master_key(&master_key_id, &master_key, &version);
if (master_key == NULL) {
return(false);
}
memset(encrypt_info, 0, ENCRYPTION_INFO_SIZE_V2);
memset(key_info, 0, ENCRYPTION_KEY_LEN * 2);
/* Use the new master key to encrypt the tablespace
key. */
ut_ad(encrypt_info != NULL);
ptr = encrypt_info;
/* Write magic header. */
if (version == Encryption::ENCRYPTION_VERSION_1) {
memcpy(ptr, ENCRYPTION_KEY_MAGIC_V1, ENCRYPTION_MAGIC_SIZE);
} else {
memcpy(ptr, ENCRYPTION_KEY_MAGIC_V2, ENCRYPTION_MAGIC_SIZE);
}
ptr += ENCRYPTION_MAGIC_SIZE;
/* Write master key id. */
mach_write_to_4(ptr, master_key_id);
ptr += sizeof(ulint);
/* Write server uuid. */
if (version == Encryption::ENCRYPTION_VERSION_2) {
memcpy(ptr, Encryption::uuid, ENCRYPTION_SERVER_UUID_LEN);
ptr += ENCRYPTION_SERVER_UUID_LEN;
}
/* Write tablespace key to temp space. */
memcpy(key_info,
space->encryption_key,
ENCRYPTION_KEY_LEN);
/* Write tablespace iv to temp space. */
memcpy(key_info + ENCRYPTION_KEY_LEN,
space->encryption_iv,
ENCRYPTION_KEY_LEN);
#ifdef UNIV_ENCRYPT_DEBUG
fprintf(stderr, "Set %lu:%lu ",space->id,
Encryption::master_key_id);
for (data = (const byte*) master_key, i = 0;
i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
fprintf(stderr, " ");
for (data = (const byte*) space->encryption_key,
i = 0; i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
fprintf(stderr, " ");
for (data = (const byte*) space->encryption_iv,
i = 0; i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
fprintf(stderr, "\n");
#endif
/* Encrypt tablespace key and iv. */
elen = my_aes_encrypt(
key_info,
ENCRYPTION_KEY_LEN * 2,
ptr,
master_key,
ENCRYPTION_KEY_LEN,
my_aes_256_ecb,
NULL, false);
if (elen == MY_AES_BAD_DATA) {
my_free(master_key);
return(false);
}
ptr += ENCRYPTION_KEY_LEN * 2;
/* Write checksum bytes. */
crc = ut_crc32(key_info, ENCRYPTION_KEY_LEN * 2);
mach_write_to_4(ptr, crc);
my_free(master_key);
return(true);
}
#endif /* ! */
/** Rotate the encryption info in the space header.
@param[in] space tablespace
@param[in] encrypt_info buffer for re-encrypt key.
@param[in,out] mtr mini-transaction
@return true if success. */
bool
fsp_header_rotate_encryption(
fil_space_t* space,
byte* encrypt_info,
mtr_t* mtr)
{
buf_block_t* block;
ulint offset;
ut_ad(mtr);
const page_size_t page_size(space->flags);
#if MYSQL_ENCRYPTION
page_t* page;
ulint master_key_id;
ut_ad(space->encryption_type != Encryption::NONE);
/* Fill encryption info. */
if (!fsp_header_fill_encryption_info(space,
encrypt_info)) {
return(false);
}
#endif
/* Save the encryption info to the page 0. */
block = buf_page_get(page_id_t(space->id, 0),
page_size,
RW_SX_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
ut_ad(space->id == page_get_space_id(buf_block_get_frame(block)));
offset = fsp_header_get_encryption_offset(page_size);
ut_ad(offset != 0 && offset < UNIV_PAGE_SIZE);
#if MYSQL_ENCRYPTION
page = buf_block_get_frame(block);
/* If is in recovering, skip all master key id is rotated
tablespaces. */
master_key_id = mach_read_from_4(
page + offset + ENCRYPTION_MAGIC_SIZE);
if (recv_recovery_is_on()
&& master_key_id == Encryption::master_key_id) {
ut_ad(memcmp(page + offset,
ENCRYPTION_KEY_MAGIC_V1,
ENCRYPTION_MAGIC_SIZE) == 0
|| memcmp(page + offset,
ENCRYPTION_KEY_MAGIC_V2,
ENCRYPTION_MAGIC_SIZE) == 0);
return(true);
}
mlog_write_string(page + offset,
encrypt_info,
ENCRYPTION_INFO_SIZE_V2,
mtr);
#endif /* MYSQL_ENCRYPTION */
return(true);
}
/** Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0.
@param[in] space_id space id
@ -1102,31 +922,6 @@ fsp_header_init(
fsp_fill_free_list(!is_system_tablespace(space_id),
space, header, mtr);
#if 0 /* MySQL 5.7 Encryption */
/* For encryption tablespace, we need to save the encryption
info to the page 0. */
if (FSP_FLAGS_GET_ENCRYPTION(space->flags)) {
ulint offset = fsp_header_get_encryption_offset(page_size);
byte encryption_info[ENCRYPTION_INFO_SIZE_V2];
if (offset == 0)
return(false);
if (!fsp_header_fill_encryption_info(space,
encryption_info)) {
space->encryption_type = Encryption::NONE;
memset(space->encryption_key, 0, ENCRYPTION_KEY_LEN);
memset(space->encryption_iv, 0, ENCRYPTION_KEY_LEN);
return(false);
}
mlog_write_string(page + offset,
encryption_info,
ENCRYPTION_INFO_SIZE_V2,
mtr);
}
#endif /* ! */
if (space_id == srv_sys_space.space_id()) {
if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, univ_page_size, DICT_IBUF_ID_MIN + space_id,
@ -1181,164 +976,6 @@ fsp_header_get_page_size(
return(page_size_t(fsp_header_get_flags(page)));
}
#if 0 /* MySQL 5.7 Encryption */
/** Decoding the encryption info
from the first page of a tablespace.
@param[in/out] key key
@param[in/out] iv iv
@param[in] encryption_info encrytion info.
@return true if success */
bool
fsp_header_decode_encryption_info(
byte* key,
byte* iv,
byte* encryption_info)
{
byte* ptr;
ulint master_key_id;
byte* master_key = NULL;
lint elen;
byte key_info[ENCRYPTION_KEY_LEN * 2];
ulint crc1;
ulint crc2;
char srv_uuid[ENCRYPTION_SERVER_UUID_LEN + 1];
Encryption::Version version;
#ifdef UNIV_ENCRYPT_DEBUG
const byte* data;
ulint i;
#endif
ptr = encryption_info;
/* For compatibility with 5.7.11, we need to handle the
encryption information which created in this old version. */
if (memcmp(ptr, ENCRYPTION_KEY_MAGIC_V1,
ENCRYPTION_MAGIC_SIZE) == 0) {
version = Encryption::ENCRYPTION_VERSION_1;
} else {
version = Encryption::ENCRYPTION_VERSION_2;
}
/* Check magic. */
if (version == Encryption::ENCRYPTION_VERSION_2
&& memcmp(ptr, ENCRYPTION_KEY_MAGIC_V2, ENCRYPTION_MAGIC_SIZE) != 0) {
/* We ignore report error for recovery,
since the encryption info maybe hasn't writen
into datafile when the table is newly created. */
if (!recv_recovery_is_on()) {
return(false);
} else {
return(true);
}
}
ptr += ENCRYPTION_MAGIC_SIZE;
/* Get master key id. */
master_key_id = mach_read_from_4(ptr);
ptr += sizeof(ulint);
/* Get server uuid. */
if (version == Encryption::ENCRYPTION_VERSION_2) {
memset(srv_uuid, 0, ENCRYPTION_SERVER_UUID_LEN + 1);
memcpy(srv_uuid, ptr, ENCRYPTION_SERVER_UUID_LEN);
ptr += ENCRYPTION_SERVER_UUID_LEN;
}
/* Get master key by key id. */
memset(key_info, 0, ENCRYPTION_KEY_LEN * 2);
if (version == Encryption::ENCRYPTION_VERSION_1) {
Encryption::get_master_key(master_key_id, NULL, &master_key);
} else {
Encryption::get_master_key(master_key_id, srv_uuid, &master_key);
}
if (master_key == NULL) {
return(false);
}
#ifdef UNIV_ENCRYPT_DEBUG
fprintf(stderr, "%lu ", master_key_id);
for (data = (const byte*) master_key, i = 0;
i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
#endif
/* Decrypt tablespace key and iv. */
elen = my_aes_decrypt(
ptr,
ENCRYPTION_KEY_LEN * 2,
key_info,
master_key,
ENCRYPTION_KEY_LEN,
my_aes_256_ecb, NULL, false);
if (elen == MY_AES_BAD_DATA) {
my_free(master_key);
return(NULL);
}
/* Check checksum bytes. */
ptr += ENCRYPTION_KEY_LEN * 2;
crc1 = mach_read_from_4(ptr);
crc2 = ut_crc32(key_info, ENCRYPTION_KEY_LEN * 2);
if (crc1 != crc2) {
ib::error() << "Failed to decrpt encryption information,"
<< " please check key file is not changed!";
return(false);
}
/* Get tablespace key */
memcpy(key, key_info, ENCRYPTION_KEY_LEN);
/* Get tablespace iv */
memcpy(iv, key_info + ENCRYPTION_KEY_LEN,
ENCRYPTION_KEY_LEN);
#ifdef UNIV_ENCRYPT_DEBUG
fprintf(stderr, " ");
for (data = (const byte*) key,
i = 0; i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
fprintf(stderr, " ");
for (data = (const byte*) iv,
i = 0; i < ENCRYPTION_KEY_LEN; i++)
fprintf(stderr, "%02lx", (ulong)*data++);
fprintf(stderr, "\n");
#endif
my_free(master_key);
if (Encryption::master_key_id < master_key_id) {
Encryption::master_key_id = master_key_id;
memcpy(Encryption::uuid, srv_uuid, ENCRYPTION_SERVER_UUID_LEN);
}
return(true);
}
/** Reads the encryption key from the first page of a tablespace.
@param[in] fsp_flags tablespace flags
@param[in/out] key tablespace key
@param[in/out] iv tablespace iv
@param[in] page first page of a tablespace
@return true if success */
bool
fsp_header_get_encryption_key(
ulint fsp_flags,
byte* key,
byte* iv,
page_t* page)
{
ulint offset;
const page_size_t page_size(fsp_flags);
offset = fsp_header_get_encryption_offset(page_size);
if (offset == 0) {
return(false);
}
return(fsp_header_decode_encryption_info(key, iv, page + offset));
}
#endif /* ! */
/**********************************************************************//**
Increases the space size field of a space. */
void

217
storage/innobase/handler/ha_innodb.cc

@ -608,8 +608,7 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(rtr_path_mutex),
PSI_KEY(rtr_ssn_mutex),
PSI_KEY(trx_sys_mutex),
PSI_KEY(zip_pad_mutex),
PSI_KEY(master_key_id_mutex),
PSI_KEY(zip_pad_mutex)
};
# endif /* UNIV_PFS_MUTEX */
@ -2887,60 +2886,6 @@ Compression::validate(const char* algorithm)
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/** Check if the string is "" or "n".
@param[in] algorithm Encryption algorithm to check
@return true if no algorithm requested */
bool
Encryption::is_none(const char* algorithm)
{
/* NULL is the same as NONE */
if (algorithm == NULL
|| innobase_strcasecmp(algorithm, "n") == 0
|| innobase_strcasecmp(algorithm, "") == 0) {
return(true);
}
return(false);
}
/** Check the encryption option and set it
@param[in] option encryption option
@param[in/out] encryption The encryption algorithm
@return DB_SUCCESS or DB_UNSUPPORTED */
dberr_t
Encryption::set_algorithm(
const char* option,
Encryption* encryption)
{
if (is_none(option)) {
encryption->m_type = NONE;
} else if (innobase_strcasecmp(option, "y") == 0) {
encryption->m_type = AES;
} else {
return(DB_UNSUPPORTED);
}
return(DB_SUCCESS);
}
/** Check for supported ENCRYPT := (Y | N) supported values
@param[in] option Encryption option
@param[out] encryption The encryption algorithm
@return DB_SUCCESS or DB_UNSUPPORTED */
dberr_t
Encryption::validate(const char* option)
{
Encryption encryption;
return(encryption.set_algorithm(option, &encryption));
}
#endif /* MYSQL_ENCRYPTION */
/*********************************************************************//**
Compute the next autoinc value.
@ -3961,67 +3906,6 @@ innobase_init_abort()
DBUG_RETURN(1);
}
#ifdef MYSQL_ENCRYPTION
/* mutex protecting the master_key_id */
ib_mutex_t master_key_id_mutex;
/** Rotate the encrypted tablespace keys according to master key
rotation.
@return false on success, true on failure */
bool
innobase_encryption_key_rotation()
{
byte* master_key = NULL;
bool ret = FALSE;
/* Require the mutex to block other rotate request. */
mutex_enter(&master_key_id_mutex);
/* Check if keyring loaded and the currently master key
can be fetched. */
if (Encryption::master_key_id != 0) {
ulint master_key_id;
Encryption::Version version;
Encryption::get_master_key(&master_key_id,
&master_key,
&version);
if (master_key == NULL) {
mutex_exit(&master_key_id_mutex);
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING, MYF(0));
return(true);
}
my_free(master_key);
}
master_key = NULL;
/* Generate the new master key. */
Encryption::create_master_key(&master_key);
if (master_key == NULL) {
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING, MYF(0));
mutex_exit(&master_key_id_mutex);
return(true);
}
ret = !fil_encryption_rotate();
my_free(master_key);
/* If rotation failure, return error */
if (ret) {
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING, MYF(0));
}
/* Release the mutex. */
mutex_exit(&master_key_id_mutex);
return(ret);
}
#endif /* MYSQL_ENCRYPTION */
/** Return partitioning flags. */
static uint innobase_partition_flags()
{
@ -4160,11 +4044,6 @@ innobase_init(
innodb_remember_check_sysvar_funcs();
#ifdef MYSQL_ENCRYPTION
innobase_hton->rotate_encryption_master_key =
innobase_encryption_key_rotation;
#endif
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
#ifndef DBUG_OFF
@ -4742,11 +4621,6 @@ innobase_change_buffering_inited_ok:
DBUG_RETURN(innobase_init_abort());
}
#ifdef MYSQL_ENCRYPTION
/* Create mutex to protect encryption master_key_id. */
mutex_create(LATCH_ID_MASTER_KEY_ID_MUTEX, &master_key_id_mutex);
#endif
/* Adjust the innodb_undo_logs config object */
innobase_undo_logs_init_default_max();
@ -4850,10 +4724,6 @@ innobase_end(
hash_table_free(innobase_open_tables);
innobase_open_tables = NULL;
#ifdef MYSQL_ENCRYPTION
mutex_free(&master_key_id_mutex);
#endif
if (!abort_loop && thd_destructor_myvar) {
// may be UNINSTALL PLUGIN statement
thd_destructor_myvar->abort = 1;
@ -6887,28 +6757,6 @@ ha_innobase::open(
is_part = NULL;
}
#ifdef MYSQL_ENCRYPTION
/* For encrypted table, check if the encryption info in data
file can't be retrieved properly, mark it as corrupted. */
if (ib_table != NULL
&& dict_table_is_encrypted(ib_table)
&& ib_table->ibd_file_missing
&& !dict_table_is_discarded(ib_table)) {
/* Mark this table as corrupted, so the drop table
or force recovery can still use it, but not others. */
dict_table_close(ib_table, FALSE, FALSE);
ib_table = NULL;
is_part = NULL;
free_share(m_share);
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING, MYF(0));
DBUG_RETURN(HA_ERR_TABLE_CORRUPT);
}
#endif
if (NULL == ib_table) {
if (is_part) {
@ -12262,13 +12110,6 @@ err_col:
err = DB_UNSUPPORTED;
dict_mem_table_free(table);
} else if (m_create_info->encrypt_type.length > 0
&& !Encryption::is_none(
m_create_info->encrypt_type.str)) {
my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0));
err = DB_UNSUPPORTED;
dict_mem_table_free(table);
} else {
#endif /* MYSQL_COMPRESSION */
@ -12325,39 +12166,6 @@ err_col:
algorithm = NULL;
}
const char* encrypt = m_create_info->encrypt_type.str;
if (!(m_flags2 & DICT_TF2_USE_FILE_PER_TABLE)
&& m_create_info->encrypt_type.length > 0
&& !Encryption::is_none(encrypt)) {
my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0));
err = DB_UNSUPPORTED;
dict_mem_table_free(table);
} else if (!Encryption::is_none(encrypt)) {
/* Set the encryption flag. */
byte* master_key = NULL;
ulint master_key_id;
Encryption::Version version;
/* Check if keyring is ready. */
Encryption::get_master_key(&master_key_id,
&master_key,
&version);
if (master_key == NULL) {
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING,
MYF(0));
err = DB_UNSUPPORTED;
dict_mem_table_free(table);
} else {
my_free(master_key);
DICT_TF2_FLAG_SET(table,
DICT_TF2_ENCRYPTION);
}
}
#endif /* MYSQL_COMPRESSION */
if (err == DB_SUCCESS) {
@ -13472,29 +13280,6 @@ create_table_info_t::innobase_table_flags()
}
#endif
#ifdef MYSQL_ENCRYPTION
/* Validate the page encryption parameter. */
if (m_create_info->encrypt_type.length > 0) {
const char* encryption = m_create_info->encrypt_type.str;
if (Encryption::validate(encryption) != DB_SUCCESS) {
/* Incorrect encryption option */
my_error(ER_INVALID_ENCRYPTION_OPTION, MYF(0));
DBUG_RETURN(false);
}
if (m_use_shared_space
|| (m_create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if (!Encryption::is_none(encryption)) {
/* Can't encrypt shared tablespace */
my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0));
DBUG_RETURN(false);
}
}
}
#endif /* MYSQL_ENCRYPTION */
/* Check if there are any FTS indexes defined on this table. */
for (uint i = 0; i < m_form->s->keys; i++) {
const KEY* key = &m_form->key_info[i];

15
storage/innobase/handler/handler0alter.cc

@ -588,21 +588,6 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
#ifdef MYSQL_ENCRYPTION
/* We don't support change encryption attribute with
inplace algorithm. */
char* old_encryption = this->table->s->encrypt_type.str;
char* new_encryption = altered_table->s->encrypt_type.str;
if (Encryption::is_none(old_encryption)
!= Encryption::is_none(new_encryption)) {
ha_alter_info->unsupported_reason =
innobase_get_err_msg(
ER_UNSUPPORTED_ALTER_ENCRYPTION_INPLACE);
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
#endif /* MYSQL_ENCRYPTION */
update_thd();
trx_search_latch_release_if_reserved(m_prebuilt->trx);

6
storage/innobase/include/db0err.h

@ -158,12 +158,6 @@ enum dberr_t {
DB_IO_NO_PUNCH_HOLE_TABLESPACE, /*!< The tablespace doesn't support
punch hole */
DB_IO_DECRYPT_FAIL, /*!< Failure to decrypt a page
after reading it from disk */
DB_IO_NO_ENCRYPT_TABLESPACE, /*!< The tablespace doesn't support
encrypt */
DB_IO_PARTIAL_FAILED, /*!< Partial IO request failed */
DB_FORCED_ABORT, /*!< Transaction was forced to rollback

14
storage/innobase/include/dict0dict.h

@ -1035,13 +1035,11 @@ fil_space_t::flags | 0 | 0 | 1 | 1
==================================================================
@param[in] table_flags dict_table_t::flags
@param[in] is_temp whether the tablespace is temporary
@param[in] is_encrypted whether the tablespace is encrypted
@return tablespace flags (fil_space_t::flags) */
ulint
dict_tf_to_fsp_flags(
ulint table_flags,
bool is_temp,
bool is_encrypted = false)
bool is_temp)
MY_ATTRIBUTE((const));
/** Extract the page size from table flags.
@ -1975,16 +1973,6 @@ dict_table_is_temporary(
const dict_table_t* table) /*!< in: table to check */
MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Check if it is a encrypted table.
@return true if table encryption flag is set. */
UNIV_INLINE
bool
dict_table_is_encrypted(
/*====================*/
const dict_table_t* table) /*!< in: table to check */
MY_ATTRIBUTE((warn_unused_result));
/** Check if the table is in a shared tablespace (System or General).
@param[in] id Space ID to check
@return true if id is a shared tablespace, false if not. */

12
storage/innobase/include/dict0dict.ic

@ -1744,18 +1744,6 @@ dict_table_is_temporary(
return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY));
}
/********************************************************************//**
Check if it is a encrypted table.
@return true if table encrypted flag is set. */
UNIV_INLINE
bool
dict_table_is_encrypted(
/*====================*/
const dict_table_t* table) /*!< in: table to check */
{
return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_ENCRYPTION));
}
/** Check if the table is in a shared tablespace (System or General).
@param[in] id Space ID to check
@return true if id is a shared tablespace, false if not. */

9
storage/innobase/include/dict0mem.h

@ -334,9 +334,6 @@ use its own tablespace instead of the system tablespace. */
index tables) of a FTS table are in HEX format. */
#define DICT_TF2_FTS_AUX_HEX_NAME 64
/** Encryption table bit. */
#define DICT_TF2_ENCRYPTION 256
/* @} */
#define DICT_TF2_FLAG_SET(table, flag) \
@ -1779,12 +1776,6 @@ public:
/** mysql_row_templ_t for base columns used for compute the virtual
columns */
dict_vcol_templ_t* vc_templ;
/** encryption key, it's only for export/import */
byte* encryption_key;
/** encryption iv, it's only for export/import */
byte* encryption_iv;
};
/*******************************************************************//**

35
storage/innobase/include/fil0fil.h

@ -169,18 +169,6 @@ struct fil_space_t {
/** Compression algorithm */
Compression::Type compression_type;
/** Encryption algorithm */
Encryption::Type encryption_type;
/** Encrypt key */
byte encryption_key[ENCRYPTION_KEY_LEN];
/** Encrypt key length*/
ulint encryption_klen;
/** Encrypt initial vector */
byte encryption_iv[ENCRYPTION_KEY_LEN];
/** MariaDB encryption data */
fil_space_crypt_t* crypt_data;
@ -267,14 +255,12 @@ enum ib_extention {
NO_EXT = 0,
IBD = 1,
ISL = 2,
CFG = 3,
CFP = 4
CFG = 3
};
extern const char* dot_ext[];
#define DOT_IBD dot_ext[IBD]
#define DOT_ISL dot_ext[ISL]
#define DOT_CFG dot_ext[CFG]
#define DOT_CPF dot_ext[CFP]
/** Wrapper for a path to a directory.
This folder may or may not yet esist. Since not all directory paths
@ -1654,25 +1640,6 @@ fil_get_compression(
ulint space_id)
MY_ATTRIBUTE((warn_unused_result));
/** Set the encryption type for the tablespace
@param[in] space Space ID of tablespace for which to set
@param[in] algorithm Encryption algorithm
@param[in] key Encryption key
@param[in] iv Encryption iv
@return DB_SUCCESS or error code */
dberr_t
fil_set_encryption(
ulint space_id,
Encryption::Type algorithm,
byte* key,
byte* iv)
MY_ATTRIBUTE((warn_unused_result));
/**
@return true if the re-encrypt success */
bool
fil_encryption_rotate();
/** Write MLOG_FILE_NAME records if a persistent tablespace was modified
for the first time since the latest fil_names_clear().
@param[in,out] space tablespace

14
storage/innobase/include/fsp0file.h

@ -67,8 +67,6 @@ public:
m_first_page(),
m_last_os_error(),
m_file_info(),
m_encryption_key(NULL),
m_encryption_iv(NULL),
m_crypt_info()
{
/* No op */
@ -92,8 +90,6 @@ public:
m_first_page(),
m_last_os_error(),
m_file_info(),
m_encryption_key(NULL),
m_encryption_iv(NULL),
m_crypt_info()
{
ut_ad(m_name != NULL);
@ -115,8 +111,6 @@ public:
m_first_page(),
m_last_os_error(),
m_file_info(),
m_encryption_key(NULL),
m_encryption_iv(NULL),
m_crypt_info()
{
m_name = mem_strdup(file.m_name);
@ -175,8 +169,6 @@ public:
it should be reread if needed */
m_first_page_buf = NULL;
m_first_page = NULL;
m_encryption_key = NULL;
m_encryption_iv = NULL;
/* Do not copy crypt info it is read from first page */
m_crypt_info = NULL;
@ -484,12 +476,6 @@ public:
struct stat m_file_info;
#endif /* WIN32 */
/** Encryption key read from first page */
byte* m_encryption_key;
/** Encryption iv read from first page */
byte* m_encryption_iv;
/** Encryption information */
fil_space_crypt_t* m_crypt_info;
};

40
storage/innobase/include/fsp0fsp.h

@ -336,31 +336,6 @@ page_size_t
fsp_header_get_page_size(
const page_t* page);
/** Decoding the encryption info
from the first page of a tablespace.
@param[in/out] key key
@param[in/out] iv iv
@param[in] encryption_info encrytion info.
@return true if success */
bool
fsp_header_decode_encryption_info(
byte* key,
byte* iv,
byte* encryption_info);
/** Reads the encryption key from the first page of a tablespace.
@param[in] fsp_flags tablespace flags
@param[in/out] key tablespace key
@param[in/out] iv tablespace iv
@param[in] page first page of a tablespace
@return true if success */
bool
fsp_header_get_encryption_key(
ulint fsp_flags,
byte* key,
byte* iv,
page_t* page);
/** Get the byte offset of encryption information in page 0.
@param[in] ps page size
@return byte offset relative to FSP_HEADER_OFFSET */
@ -392,17 +367,6 @@ fsp_header_init_fields(
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
/** Rotate the encryption info in the space header.
@param[in] space tablespace
@param[in] encrypt_info buffer for re-encrypt key.
@param[in,out] mtr mini-transaction
@return true if success. */
bool
fsp_header_rotate_encryption(
fil_space_t* space,
byte* encrypt_info,
mtr_t* mtr);
/** Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0.
@param[in] space_id space id
@ -696,7 +660,6 @@ fsp_flags_are_equal(
@param[in] has_data_dir This tablespace is in a remote location.
@param[in] is_shared This tablespace can be shared by many tables.
@param[in] is_temporary This tablespace is temporary.
@param[in] is_encrypted This tablespace is encrypted.
@return tablespace flags after initialization */
UNIV_INLINE
ulint
@ -708,8 +671,7 @@ fsp_flags_init(
bool is_temporary,
bool page_compression,
ulint page_compression_level,
ulint not_used,
bool is_encrypted = false);
ulint not_used);
/** Convert a 32 bit integer tablespace flags to the 32 bit table flags.
This can only be done for a tablespace that was built as a file-per-table

8
storage/innobase/include/fsp0fsp.ic

@ -181,7 +181,6 @@ fsp_flags_set_page_size(
@param[in] has_data_dir This tablespace is in a remote location.
@param[in] is_shared This tablespace can be shared by many tables.
@param[in] is_temporary This tablespace is temporary.
@param[in] is_encrypted This tablespace is encrypted.
@param[in] page_compressed Table uses page compression
@param[in] page_compression_level Page compression level
@param[in] not_used For future
@ -196,8 +195,7 @@ fsp_flags_init(
bool is_temporary,
bool page_compression,
ulint page_compression_level,
ulint not_used,
bool is_encrypted)
ulint not_used)
{
ut_ad(page_size.physical() <= page_size.logical());
ut_ad(!page_size.is_compressed() || atomic_blobs);
@ -231,10 +229,6 @@ fsp_flags_init(
flags |= FSP_FLAGS_MASK_TEMPORARY;
}
if (is_encrypted) {
flags |= FSP_FLAGS_MASK_ENCRYPTION;
}
/* In addition, tablespace flags also contain if the page
compression is used for this table. */
if (page_compression) {

8
storage/innobase/include/fsp0types.h

@ -351,10 +351,6 @@ is a tablespace with encryption. */
#define FSP_FLAGS_MASK_TEMPORARY \
((~(~0U << FSP_FLAGS_WIDTH_TEMPORARY)) \
<< FSP_FLAGS_POS_TEMPORARY)
/** Bit mask of the ENCRYPTION field */
#define FSP_FLAGS_MASK_ENCRYPTION \
((~(~0U << FSP_FLAGS_WIDTH_ENCRYPTION)) \
<< FSP_FLAGS_POS_ENCRYPTION)
/** Bit mask of the PAGE_COMPRESSION field */
#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
@ -396,10 +392,6 @@ is a tablespace with encryption. */
#define FSP_FLAGS_GET_TEMPORARY(flags) \
((flags & FSP_FLAGS_MASK_TEMPORARY) \
>> FSP_FLAGS_POS_TEMPORARY)
/** Return the contents of the ENCRYPTION field */
#define FSP_FLAGS_GET_ENCRYPTION(flags) \
((flags & FSP_FLAGS_MASK_ENCRYPTION) \
>> FSP_FLAGS_POS_ENCRYPTION)
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)

1
storage/innobase/include/ha_prototypes.h

@ -42,7 +42,6 @@ struct fts_string_t;
// JAN: TODO missing features:
#undef MYSQL_57_SELECT_COUNT_OPTIMIZATION
#undef MYSQL_COMPRESSION
#undef MYSQL_ENCRYPTION
#undef MYSQL_FT_INIT_EXT
#undef MYSQL_INNODB_API_CB
#undef MYSQL_INNODB_PARTITIONING

13
storage/innobase/include/log0recv.h

@ -190,16 +190,6 @@ struct recv_dblwr_t {
list pages;
};
/* Recovery encryption information */
typedef struct recv_encryption {
ulint space_id; /*!< the page number */
byte* key; /*!< encryption key */
byte* iv; /*!< encryption iv */
} recv_encryption_t;
typedef std::vector<recv_encryption_t, ut_allocator<recv_encryption_t> >
encryption_list_t;
/** Recovery system data structure */
struct recv_sys_t{
ib_mutex_t mutex; /*!< mutex protecting the fields apply_log_recs,
@ -266,9 +256,6 @@ struct recv_sys_t{
addresses in the hash table */
recv_dblwr_t dblwr;
encryption_list_t* /*!< Encryption information list */
encryption_list;
};
/** The recovery system */

254
storage/innobase/include/os0file.h

@ -293,209 +293,6 @@ struct Compression {
Type m_type;
};
/** Encryption key length */
static const ulint ENCRYPTION_KEY_LEN = 32;
/** Encryption magic bytes size */
static const ulint ENCRYPTION_MAGIC_SIZE = 3;
/** Encryption magic bytes for 5.7.11, it's for checking the encryption information
version. */
static const char ENCRYPTION_KEY_MAGIC_V1[] = "lCA";
/** Encryption magic bytes for 5.7.12+, it's for checking the encryption information
version. */
static const char ENCRYPTION_KEY_MAGIC_V2[] = "lCB";
/** Encryption master key prifix */
static const char ENCRYPTION_MASTER_KEY_PRIFIX[] = "INNODBKey";
/** Encryption master key prifix size */
static const ulint ENCRYPTION_MASTER_KEY_PRIFIX_LEN = 9;
/** Encryption master key prifix size */
static const ulint ENCRYPTION_MASTER_KEY_NAME_MAX_LEN = 100;
/** UUID of server instance, it's needed for composing master key name */
static const ulint ENCRYPTION_SERVER_UUID_LEN = 36;
/** Encryption information total size for 5.7.11: magic number + master_key_id +
key + iv + checksum */
static const ulint ENCRYPTION_INFO_SIZE_V1 = (ENCRYPTION_MAGIC_SIZE \
+ (ENCRYPTION_KEY_LEN * 2) \
+ 2 * sizeof(ulint));
/** Encryption information total size: magic number + master_key_id +
key + iv + server_uuid + checksum */
static const ulint ENCRYPTION_INFO_SIZE_V2 = (ENCRYPTION_MAGIC_SIZE \
+ (ENCRYPTION_KEY_LEN * 2) \
+ ENCRYPTION_SERVER_UUID_LEN \
+ 2 * sizeof(ulint));
class IORequest;
/** Encryption algorithm. */
struct Encryption {
/** Algorithm types supported */
enum Type {
/** No encryption */
NONE = 0,
/** Use AES */
AES = 1,
};
/** Encryption information format version */
enum Version {
/** Version in 5.7.11 */
ENCRYPTION_VERSION_1 = 0,
/** Version in > 5.7.11 */
ENCRYPTION_VERSION_2 = 1,
};
/** Default constructor */
Encryption() : m_type(NONE) { };
/** Specific constructor
@param[in] type Algorithm type */
explicit Encryption(Type type)
:
m_type(type)
{
#ifdef UNIV_DEBUG
switch (m_type) {
case NONE:
case AES:
default:
ut_error;
}
#endif /* UNIV_DEBUG */
}
/** Copy constructor */
Encryption(const Encryption& other)
:
m_type(other.m_type),
m_key(other.m_key),
m_klen(other.m_klen),
m_iv(other.m_iv)
{ };
/** Check if page is encrypted page or not
@param[in] page page which need to check
@return true if it is a encrypted page */
static bool is_encrypted_page(const byte* page)
MY_ATTRIBUTE((warn_unused_result));
/** Check the encryption option and set it
@param[in] option encryption option
@param[in/out] encryption The encryption type
@return DB_SUCCESS or DB_UNSUPPORTED */
dberr_t set_algorithm(const char* option, Encryption* type)
MY_ATTRIBUTE((warn_unused_result));
/** Validate the algorithm string.
@param[in] algorithm Encryption algorithm to check
@return DB_SUCCESS or error code */
static dberr_t validate(const char* algorithm)
MY_ATTRIBUTE((warn_unused_result));
/** Convert to a "string".
@param[in] type The encryption type
@return the string representation */
static const char* to_string(Type type)
MY_ATTRIBUTE((warn_unused_result));
/** Check if the string is "empty" or "none".
@param[in] algorithm Encryption algorithm to check
@return true if no algorithm requested */
static bool is_none(const char* algorithm)
MY_ATTRIBUTE((warn_unused_result));
/** Generate random encryption value for key and iv.
@param[in,out] value Encryption value */
static void random_value(byte* value);
/** Create new master key for key rotation.
@param[in,out] master_key master key */
static void create_master_key(byte** master_key);
/** Get master key by key id.
@param[in] master_key_id master key id
@param[in] srv_uuid uuid of server instance
@param[in,out] master_key master key */
static void get_master_key(ulint master_key_id,
char* srv_uuid,
byte** master_key);
/** Get current master key and key id.
@param[in,out] master_key_id master key id
@param[in,out] master_key master key
@param[in,out] version encryption information version */
static void get_master_key(ulint* master_key_id,
byte** master_key,
Encryption::Version* version);
/** Encrypt the page data contents. Page type can't be
FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
FIL_PAGE_ENCRYPTED_RTREE.
@param[in] type IORequest
@param[in,out] src page data which need to encrypt
@param[in] src_len Size of the source in bytes
@param[in,out] dst destination area
@param[in,out] dst_len Size of the destination in bytes
@return buffer data, dst_len will have the length of the data */
byte* encrypt(
const IORequest& type,
byte* src,
ulint src_len,
byte* dst,
ulint* dst_len)
MY_ATTRIBUTE((warn_unused_result));
/** Decrypt the page data contents. Page type must be
FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
FIL_PAGE_ENCRYPTED_RTREE, if not then the source contents are
left unchanged and DB_SUCCESS is returned.
@param[in] type IORequest
@param[in,out] src Data read from disk, decrypt
data will be copied to this page
@param[in] src_len source data length
@param[in,out] dst Scratch area to use for decrypt
@param[in] dst_len Size of the scratch area in bytes
@return DB_SUCCESS or error code */
dberr_t decrypt(
const IORequest& type,
byte* src,
ulint src_len,
byte* dst,
ulint dst_len)
MY_ATTRIBUTE((warn_unused_result));
/** Encrypt type */
Type m_type;
/** Encrypt key */
byte* m_key;
/** Encrypt key length*/
ulint m_klen;
/** Encrypt initial vector */
byte* m_iv;
/** Current master key id */
static ulint master_key_id;
/** Current uuid of server instance */
static char uuid[ENCRYPTION_SERVER_UUID_LEN + 1];
};
/** Types for AIO operations @{ */
/** No transformations during read/write, write as is. */
@ -744,54 +541,6 @@ public:
m_type |= NO_COMPRESSION;
}
/** Set encryption algorithm
@param[in] type The encryption algorithm to use */
void encryption_algorithm(Encryption::Type type)
{
if (type == Encryption::NONE) {
return;
}
m_encryption.m_type = type;
}
/** Set encryption key and iv
@param[in] key The encryption key to use
@param[in] key_len length of the encryption key
@param[in] iv The encryption iv to use */
void encryption_key(byte* key,
ulint key_len,
byte* iv)
{
m_encryption.m_key = key;
m_encryption.m_klen = key_len;
m_encryption.m_iv = iv;
}
/** Get the encryption algorithm.
@return the encryption algorithm */
Encryption encryption_algorithm() const
MY_ATTRIBUTE((warn_unused_result))
{
return(m_encryption);
}
/** @return true if the page should be encrypted. */
bool is_encrypted() const
MY_ATTRIBUTE((warn_unused_result))
{
return(m_encryption.m_type != Encryption::NONE);
}
/** Clear all encryption related flags */
void clear_encrypted()
{
m_encryption.m_key = NULL;
m_encryption.m_klen = 0;
m_encryption.m_iv = NULL;
m_encryption.m_type = Encryption::NONE;
}
/** Note that the IO is for double write recovery. */
void dblwr_recover()
{
@ -832,9 +581,6 @@ private:
/** Compression algorithm */
Compression m_compression;
/** Encryption algorithm */
Encryption m_encryption;
};
/* @} */

1
storage/innobase/include/sync0sync.h

@ -136,7 +136,6 @@ extern mysql_pfs_key_t index_online_log_key;
extern mysql_pfs_key_t dict_table_stats_key;
extern mysql_pfs_key_t trx_sys_rw_lock_key;
extern mysql_pfs_key_t hash_table_locks_key;
extern mysql_pfs_key_t master_key_id_mutex_key;
#endif /* UNIV_PFS_RWLOCK */
/** Prints info of the sync system.

1
storage/innobase/include/sync0types.h

@ -384,7 +384,6 @@ enum latch_id_t {
LATCH_ID_HASH_TABLE_RW_LOCK,
LATCH_ID_BUF_CHUNK_MAP_LATCH,
LATCH_ID_SYNC_DEBUG_MUTEX,
LATCH_ID_MASTER_KEY_ID_MUTEX,
LATCH_ID_SCRUB_STAT_MUTEX,
LATCH_ID_DEFRAGMENT_MUTEX,
LATCH_ID_BTR_DEFRAGMENT_MUTEX,

183
storage/innobase/log/log0recv.cc

@ -224,42 +224,6 @@ fil_name_process(
case FIL_LOAD_OK:
ut_ad(space != NULL);
#ifdef MYSQL_ENCRYPTION
/* For encrypted tablespace, set key and iv. */
if (FSP_FLAGS_GET_ENCRYPTION(space->flags)
&& recv_sys->encryption_list != NULL) {
dberr_t err;
encryption_list_t::iterator it;
for (it = recv_sys->encryption_list->begin();
it != recv_sys->encryption_list->end();
it++) {
if (it->space_id == space->id) {
err = fil_set_encryption(
space->id,
Encryption::AES,
it->key,
it->iv);
if (err != DB_SUCCESS) {
ib::error()
<< "Can't set"
" encryption"
" information"
" for"
" tablespace"
<< space->name
<< "!";
}
ut_free(it->key);
ut_free(it->iv);
it->key = NULL;
it->iv = NULL;
it->space_id = 0;
}
}
}
#endif /* MYSQL_ENCRYPTION */
if (f.space == NULL || f.space == space) {
f.name = fname.name;
f.space = space;
@ -682,7 +646,6 @@ recv_sys_init(
/* Call the constructor for recv_sys_t::dblwr member */
new (&recv_sys->dblwr) recv_dblwr_t();
recv_sys->encryption_list = NULL;
mutex_exit(&(recv_sys->mutex));
}
@ -732,28 +695,6 @@ recv_sys_debug_free(void)
os_event_set(recv_sys->flush_start);
}
if (recv_sys->encryption_list != NULL) {
encryption_list_t::iterator it;
for (it = recv_sys->encryption_list->begin();
it != recv_sys->encryption_list->end();
it++) {
if (it->key != NULL) {
ut_free(it->key);
it->key = NULL;
}
if (it->iv != NULL) {
ut_free(it->iv);
it->iv = NULL;
}
}
recv_sys->encryption_list->swap(*recv_sys->encryption_list);
UT_DELETE(recv_sys->encryption_list);
recv_sys->encryption_list = NULL;
}
mutex_exit(&(recv_sys->mutex));
}
@ -1101,116 +1042,6 @@ log_block_checksum_is_ok(
== log_block_calc_checksum(block));
}
#ifdef MYSQL_ENCRYPTION
/** Parse or process a write encryption info record.
@param[in] ptr redo log record
@param[in] end end of the redo log buffer
@param[in] space_id the tablespace ID
@return log record end, NULL if not a complete record */
static
byte*
fil_write_encryption_parse(
byte* ptr,
const byte* end,
ulint space_id)
{
fil_space_t* space;
ulint offset;
ulint len;
byte* key = NULL;
byte* iv = NULL;
bool is_new = false;
space = fil_space_get(space_id);
if (space == NULL) {
encryption_list_t::iterator it;
if (recv_sys->encryption_list == NULL) {
recv_sys->encryption_list =
UT_NEW_NOKEY(encryption_list_t());
}
for (it = recv_sys->encryption_list->begin();
it != recv_sys->encryption_list->end();
it++) {
if (it->space_id == space_id) {
key = it->key;
iv = it->iv;
}
}
if (key == NULL) {
key = static_cast<byte*>(ut_malloc_nokey(
ENCRYPTION_KEY_LEN));
iv = static_cast<byte*>(ut_malloc_nokey(
ENCRYPTION_KEY_LEN));
is_new = true;
}
} else {
key = space->encryption_key;
iv = space->encryption_iv;
}
offset = mach_read_from_2(ptr);
ptr += 2;
len = mach_read_from_2(ptr);
ptr += 2;
if (end < ptr + len) {
return(NULL);
}
if (offset >= UNIV_PAGE_SIZE
|| len + offset > UNIV_PAGE_SIZE
|| (len != ENCRYPTION_INFO_SIZE_V1
&& len != ENCRYPTION_INFO_SIZE_V2)) {
recv_sys->found_corrupt_log = TRUE;
return(NULL);
}
#ifdef UNIV_ENCRYPT_DEBUG
if (space) {
fprintf(stderr, "Got %lu from redo log:", space->id);
}
#endif
if (!fsp_header_decode_encryption_info(key,
iv,
ptr)) {
recv_sys->found_corrupt_log = TRUE;
ib::warn() << "Encryption information"
<< " in the redo log of space "
<< space_id << " is invalid";
}
ut_ad(len == ENCRYPTION_INFO_SIZE_V1
|| len == ENCRYPTION_INFO_SIZE_V2);
ptr += len;
if (space == NULL) {
if (is_new) {
recv_encryption_t info;
/* Add key and iv to list */
info.space_id = space_id;
info.key = key;
info.iv = iv;
recv_sys->encryption_list->push_back(info);
}
} else {
ut_ad(FSP_FLAGS_GET_ENCRYPTION(space->flags));
space->encryption_type = Encryption::AES;
space->encryption_klen = ENCRYPTION_KEY_LEN;
}
return(ptr);
}
#endif /* MYSQL_ENCRYPTION */
/** Try to parse a single log record body and also applies it if
specified.
@param[in] type redo log entry type
@ -1257,20 +1088,6 @@ recv_parse_or_apply_log_rec_body(
return(ptr + 8);
case MLOG_TRUNCATE:
return(truncate_t::parse_redo_entry(ptr, end_ptr, space_id));
case MLOG_WRITE_STRING:
/* For encrypted tablespace, we need to get the
encryption key information before the page 0 is recovered.
Otherwise, redo will not find the key to decrypt
the data pages. */
#ifdef MYSQL_ENCRYPTION
if (page_no == 0 && !is_system_tablespace(space_id)
&& !apply) {
return(fil_write_encryption_parse(ptr,
end_ptr,
space_id));
}
#endif
break;
default:
break;

901
storage/innobase/os/os0file.cc

@ -783,26 +783,6 @@ os_file_handle_error_no_exit(
const char* operation,
bool silent);
/** Decompress after a read and punch a hole in the file if it was a write
@param[in] type IO context
@param[in] fh Open file handle
@param[in,out] buf Buffer to transform
@param[in,out] scratch Scratch area for read decompression
@param[in] src_len Length of the buffer before compression
@param[in] len Compressed buffer length for write and size
of buf len for read
@return DB_SUCCESS or error code */
static
dberr_t
os_file_io_complete(
const IORequest&type,
os_file_t fh,
byte* buf,
byte* scratch,
ulint src_len,
ulint offset,
ulint len);
/** Does simulated AIO. This function should be called by an i/o-handler
thread.
@ -938,33 +918,7 @@ public:
@return DB_SUCCESS or error code. */
static dberr_t post_io_processing(Slot* slot);
/** Decompress after a read and punch a hole in the file if
it was a write */
static dberr_t io_complete(const Slot* slot)
{
ut_a(slot->offset > 0);
ut_a(slot->type.is_read() || !slot->skip_punch_hole);
return(os_file_io_complete(
slot->type, slot->file, slot->buf,
slot->compressed_page, slot->original_len,
static_cast<ulint>(slot->offset),
slot->len));
}
private:
/** Check whether the page was encrypted.
@param[in] slot The slot that contains the IO request
@return true if it was an encyrpted page */
static bool is_encrypted_page(const Slot* slot)
{
#ifdef MYSQL_ENCRYPTION
return(Encryption::is_encrypted_page(slot->buf));
#else
return (false);
#endif
}
/** Check whether the page was compressed.
@param[in] slot The slot that contains the IO request
@return true if it was a compressed page */
@ -1146,29 +1100,12 @@ AIOHandler::check_read(Slot* slot, ulint n_bytes)
#else
slot->n_bytes = static_cast<ulint>(n_bytes);
#endif /* _WIN32 */
err = io_complete(slot);
ut_a(err == DB_SUCCESS);
} else {
/* Read the next block in */
ut_ad(compressed_page_size(slot) >= n_bytes);
err = DB_FAIL;
}
} else if (is_encrypted_page(slot)) {
ut_a(slot->offset > 0);
slot->len = slot->original_len;
#ifdef _WIN32
slot->n_bytes = static_cast<DWORD>(n_bytes);
#else
slot->n_bytes = static_cast<ulint>(n_bytes);
#endif /* _WIN32 */
err = io_complete(slot);
ut_a(err == DB_SUCCESS);
} else {
err = DB_FAIL;
}
@ -1202,9 +1139,7 @@ AIOHandler::post_io_processing(Slot* slot)
&& slot->len == static_cast<ulint>(slot->n_bytes))) {
#ifdef MYSQL_COMPRESSION
if (!slot->type.is_log()
&& (is_compressed_page(slot)
|| is_encrypted_page(slot))) {
if (!slot->type.is_log() && is_compressed_page(slot)) {
ut_a(slot->offset > 0);
@ -1652,87 +1587,6 @@ os_file_read_string(
}
}
/** Decompress after a read and punch a hole in the file if it was a write
@param[in] type IO context
@param[in] fh Open file handle
@param[in,out] buf Buffer to transform
@param[in,out] scratch Scratch area for read decompression
@param[in] src_len Length of the buffer before compression
@param[in] len Used buffer length for write and output
buf len for read
@return DB_SUCCESS or error code */
static
dberr_t
os_file_io_complete(
const IORequest&type,
os_file_t fh,
byte* buf,
byte* scratch,
ulint src_len,
ulint offset,
ulint len)
{
#ifdef MYSQL_ENCRYPTION
/* We never compress/decompress the first page */
ut_a(offset > 0);
ut_ad(type.validate());
if (!type.is_compression_enabled()) {
return(DB_SUCCESS);
} else if (type.is_read()) {
dberr_t ret = DB_SUCCESS;
Encryption encryption(type.encryption_algorithm());
ut_ad(!type.is_log());
ret = encryption.decrypt(type, buf, src_len, scratch, len);
if (ret == DB_SUCCESS) {
return(os_file_decompress_page(
type.is_dblwr_recover(),
buf, scratch, len));
} else {
return(ret);
}
} else if (type.punch_hole()) {
ut_ad(len <= src_len);
ut_ad(!type.is_log());
ut_ad(type.is_write());
ut_ad(type.is_compressed());
/* Nothing to do. */
if (len == src_len) {
return(DB_SUCCESS);
}
#ifdef UNIV_DEBUG
const ulint block_size = type.block_size();
#endif /* UNIV_DEBUG */
/* We don't support multiple page sizes in the server
at the moment. */
ut_ad(src_len == srv_page_size);
/* Must be a multiple of the compression unit size. */
ut_ad((len % block_size) == 0);
ut_ad((offset % block_size) == 0);
ut_ad(len + block_size <= src_len);
offset += len;
return(os_file_punch_hole(fh, offset, src_len - len));
}
ut_ad(!type.is_log());
#endif /* MYSQL_ENCRYPTION */
return(DB_SUCCESS);
}
/** This function returns a new path name after replacing the basename
in an old path with a new basename. The old_path is a full path
name including the extension. The tablename is in the normal
@ -2109,51 +1963,6 @@ os_file_compress_page(
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/** Encrypt a page content when write it to disk.
@param[in] type IO flags
@param[out] buf buffer to read or write
@param[in,out] n number of bytes to read/write, starting from
offset
@return pointer to the encrypted page */
static
Block*
os_file_encrypt_page(
const IORequest& type,
void*& buf,
ulint* n)
{
byte* encrypted_page;
ulint encrypted_len = *n;
byte* buf_ptr;
Encryption encryption(type.encryption_algorithm());
ut_ad(!type.is_log());
ut_ad(type.is_write());
ut_ad(type.is_encrypted());
Block* block = os_alloc_block();
encrypted_page = static_cast<byte*>(
ut_align(block->m_ptr, UNIV_SECTOR_SIZE));
buf_ptr = encryption.encrypt(type,
reinterpret_cast<byte*>(buf), *n,
encrypted_page, &encrypted_len);
bool encrypted = buf_ptr != buf;
if (encrypted) {
buf = buf_ptr;
*n = encrypted_len;
}
return(block);
}
#endif /* MYSQL_ENCRYPTION */
#ifndef _WIN32
/** Do the read/write
@ -5501,23 +5310,6 @@ os_file_io(
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/* We do encryption after compression, since if we do encryption
before compression, the encrypted data will cause compression fail
or low compression rate. */
if (type.is_encrypted() && type.is_write()) {
/* We don't encrypt the first page of any file. */
Block* compressed_block = block;
ut_ad(offset > 0);
block = os_file_encrypt_page(type, buf, &n);
if (compressed_block != NULL) {
os_free_block(compressed_block);
}
}
#endif /* MYSQL_ENCRYPTION */
SyncFileIO sync_file_io(file, buf, n, offset);
for (ulint i = 0; i < NUM_RETRIES_ON_PARTIAL_IO; ++i) {
@ -5532,20 +5324,7 @@ os_file_io(
} else if ((ulint) n_bytes + bytes_returned == n) {
bytes_returned += n_bytes;
if (offset > 0
&& (type.is_compressed() || type.is_read())) {
*err = os_file_io_complete(
type, file,
reinterpret_cast<byte*>(buf),
compressed_page, original_n,
static_cast<ulint>(offset), n);
} else {
*err = DB_SUCCESS;
}
*err = DB_SUCCESS;
#ifdef MYSQL_COMPRESSION
if (block != NULL) {
os_free_block(block);
@ -7008,45 +6787,6 @@ AIO::reserve_slot(
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/* We do encryption after compression, since if we do encryption
before compression, the encrypted data will cause compression fail
or low compression rate. */
if (srv_use_native_aio
&& offset > 0
&& type.is_write()
&& type.is_encrypted()) {
ulint encrypted_len = slot->len;
Block* encrypted_block;
ut_ad(!type.is_log());
release();
void* src_buf = slot->buf;
encrypted_block = os_file_encrypt_page(
type,
src_buf,
&encrypted_len);
if (slot->buf_block != NULL) {
os_free_block(slot->buf_block);
}
slot->buf_block = encrypted_block;
slot->buf = static_cast<byte*>(src_buf);
slot->ptr = slot->buf;
#ifdef _WIN32
slot->len = static_cast<DWORD>(encrypted_len);
#else
slot->len = static_cast<ulint>(encrypted_len);
#endif /* _WIN32 */
acquire();
}
#endif /* MYSQL_ENCRYPTION */
#ifdef WIN_ASYNC_IO
{
OVERLAPPED* control;
@ -7713,13 +7453,6 @@ public:
}
}
/** Do the decompression of the pages read in */
void io_complete()
{
// Note: For non-compressed tables. Not required
// for correctness.
}
/** Mark the i/os done in slots */
void done()
{
@ -8064,8 +7797,6 @@ os_aio_simulated_handler(
srv_set_io_thread_op_info(global_segment, "file i/o done");
handler.io_complete();
array->acquire();
handler.done();
@ -8689,634 +8420,6 @@ os_file_decompress_page(
}
#endif /* MYSQL_COMPRESSION */
#ifdef MYSQL_ENCRYPTION
/**
@param[in] type The encryption type
@return the string representation */
const char*
Encryption::to_string(Type type)
{
switch(type) {
case NONE:
return("N");
case AES:
return("Y");
}
ut_ad(0);
return("<UNKNOWN>");
}
/** Generate random encryption value for key and iv.
@param[in,out] value Encryption value */
void Encryption::random_value(byte* value)
{
ut_ad(value != NULL);
my_rand_buffer(value, ENCRYPTION_KEY_LEN);
}
/** Create new master key for key rotation.
@param[in,out] master_key master key */
void
Encryption::create_master_key(byte** master_key)
{
#ifndef UNIV_INNOCHECKSUM
char* key_type = NULL;
size_t key_len;
char key_name[ENCRYPTION_MASTER_KEY_NAME_MAX_LEN];
int ret;
/* If uuid does not match with current server uuid,
set uuid as current server uuid. */
if (strcmp(uuid, server_uuid) != 0) {
memcpy(uuid, server_uuid, ENCRYPTION_SERVER_UUID_LEN);
}
memset(key_name, 0, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN);
/* Generate new master key */
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%s-%lu", ENCRYPTION_MASTER_KEY_PRIFIX,
uuid, master_key_id + 1);
/* We call key ring API to generate master key here. */
ret = my_key_generate(key_name, "AES",
NULL, ENCRYPTION_KEY_LEN);
/* We call key ring API to get master key here. */
ret = my_key_fetch(key_name, &key_type, NULL,
reinterpret_cast<void**>(master_key),
&key_len);
if (ret || *master_key == NULL) {
ib::error() << "Encryption can't find master key, please check"
" the keyring plugin is loaded.";
*master_key = NULL;
} else {
master_key_id++;
}
if (key_type) {
my_free(key_type);
}
#endif
}
/** Get master key by key id.
@param[in] master_key_id master key id
@param[in] srv_uuid uuid of server instance
@param[in,out] master_key master key */
void
Encryption::get_master_key(ulint master_key_id,
char* srv_uuid,
byte** master_key)
{
#ifndef UNIV_INNOCHECKSUM
char* key_type = NULL;
size_t key_len;
char key_name[ENCRYPTION_MASTER_KEY_NAME_MAX_LEN];
int ret;
memset(key_name, 0, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN);
if (srv_uuid != NULL) {
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%s-%lu", ENCRYPTION_MASTER_KEY_PRIFIX,
srv_uuid, master_key_id);
} else {
/* For compitable with 5.7.11, we need to get master key with
server id. */
memset(key_name, 0, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN);
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%lu-%lu", ENCRYPTION_MASTER_KEY_PRIFIX,
server_id, master_key_id);
}
/* We call key ring API to get master key here. */
ret = my_key_fetch(key_name, &key_type, NULL,
reinterpret_cast<void**>(master_key), &key_len);
if (key_type) {
my_free(key_type);
}
if (ret) {
*master_key = NULL;
ib::error() << "Encryption can't find master key, please check"
" the keyring plugin is loaded.";
}
#ifdef UNIV_ENCRYPT_DEBUG
if (!ret && *master_key) {
fprintf(stderr, "Fetched master key:%lu ", master_key_id);
ut_print_buf(stderr, *master_key, key_len);
fprintf(stderr, "\n");
}
#endif /* DEBUG_TDE */
#endif
}
/** Current master key id */
ulint Encryption::master_key_id = 0;
/** Current uuid of server instance */
char Encryption::uuid[ENCRYPTION_SERVER_UUID_LEN + 1] = {0};
/** Get current master key and master key id
@param[in,out] master_key_id master key id
@param[in,out] master_key master key
@param[in,out] version encryption information version */
void
Encryption::get_master_key(ulint* master_key_id,
byte** master_key,
Encryption::Version* version)
{
#ifndef UNIV_INNOCHECKSUM
char* key_type = NULL;
size_t key_len;
char key_name[ENCRYPTION_MASTER_KEY_NAME_MAX_LEN];
int ret;
memset(key_name, 0, ENCRYPTION_KEY_LEN);
*version = Encryption::ENCRYPTION_VERSION_2;
if (Encryption::master_key_id == 0) {
/* If m_master_key is 0, means there's no encrypted
tablespace, we need to generate the first master key,
and store it to key ring. */
memset(uuid, 0, ENCRYPTION_SERVER_UUID_LEN + 1);
memcpy(uuid, server_uuid, ENCRYPTION_SERVER_UUID_LEN);
/* Prepare the server uuid. */
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%s-1", ENCRYPTION_MASTER_KEY_PRIFIX,
uuid);
/* We call key ring API to generate master key here. */
ret = my_key_generate(key_name, "AES",
NULL, ENCRYPTION_KEY_LEN);
/* We call key ring API to get master key here. */
ret = my_key_fetch(key_name, &key_type, NULL,
reinterpret_cast<void**>(master_key),
&key_len);
if (!ret && *master_key != NULL) {
Encryption::master_key_id++;
*master_key_id = Encryption::master_key_id;
}
#ifdef UNIV_ENCRYPT_DEBUG
if (!ret && *master_key) {
fprintf(stderr, "Generated new master key:");
ut_print_buf(stderr, *master_key, key_len);
fprintf(stderr, "\n");
}
#endif
} else {
*master_key_id = Encryption::master_key_id;
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%s-%lu", ENCRYPTION_MASTER_KEY_PRIFIX,
uuid, *master_key_id);
/* We call key ring API to get master key here. */
ret = my_key_fetch(key_name, &key_type, NULL,
reinterpret_cast<void**>(master_key),
&key_len);
/* For compitable with 5.7.11, we need to try to get master key with
server id when get master key with server uuid failure. */
if (ret || *master_key == NULL) {
if (key_type) {
my_free(key_type);
}
memset(key_name, 0,
ENCRYPTION_MASTER_KEY_NAME_MAX_LEN);
ut_snprintf(key_name, ENCRYPTION_MASTER_KEY_NAME_MAX_LEN,
"%s-%lu-%lu", ENCRYPTION_MASTER_KEY_PRIFIX,
server_id, *master_key_id);
ret = my_key_fetch(key_name, &key_type, NULL,
reinterpret_cast<void**>(master_key),
&key_len);
*version = Encryption::ENCRYPTION_VERSION_1;
}
#ifdef UNIV_ENCRYPT_DEBUG
if (!ret && *master_key) {
fprintf(stderr, "Fetched master key:%lu ",
*master_key_id);
ut_print_buf(stderr, *master_key, key_len);
fprintf(stderr, "\n");
}
#endif
}
if (ret) {
*master_key = NULL;
ib::error() << "Encryption can't find master key, please check"
" the keyring plugin is loaded.";
}
if (key_type) {
my_free(key_type);
}
#endif
}
/** Check if page is encrypted page or not
@param[in] page page which need to check
@return true if it is a encrypted page */
bool
Encryption::is_encrypted_page(const byte* page)
{
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
return(page_type == FIL_PAGE_ENCRYPTED
|| page_type == FIL_PAGE_COMPRESSED_AND_ENCRYPTED
|| page_type == FIL_PAGE_ENCRYPTED_RTREE);
}
/** Encrypt the page data contents. Page type can't be
FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
FIL_PAGE_ENCRYPTED_RTREE.
@param[in] type IORequest
@param[in,out] src page data which need to encrypt
@param[in] src_len Size of the source in bytes
@param[in,out] dst destination area
@param[in,out] dst_len Size of the destination in bytes
@return buffer data, dst_len will have the length of the data */
byte*
Encryption::encrypt(
const IORequest& type,
byte* src,
ulint src_len,
byte* dst,
ulint* dst_len)
{
ulint len = 0;
ulint page_type = mach_read_from_2(src + FIL_PAGE_TYPE);
ulint data_len;
ulint main_len;
ulint remain_len;
byte remain_buf[MY_AES_BLOCK_SIZE * 2];
#ifdef UNIV_ENCRYPT_DEBUG
ulint space_id =
mach_read_from_4(src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint page_no = mach_read_from_4(src + FIL_PAGE_OFFSET);
fprintf(stderr, "Encrypting page:%lu.%lu len:%lu\n",
space_id, page_no, src_len);
#endif
/* Shouldn't encrypte an already encrypted page. */
ut_ad(page_type != FIL_PAGE_ENCRYPTED
&& page_type != FIL_PAGE_COMPRESSED_AND_ENCRYPTED
&& page_type != FIL_PAGE_ENCRYPTED_RTREE);
ut_ad(m_type != Encryption::NONE);
/* This is data size which need to encrypt. */
data_len = src_len - FIL_PAGE_DATA;
main_len = (data_len / MY_AES_BLOCK_SIZE) * MY_AES_BLOCK_SIZE;
remain_len = data_len - main_len;
/* Only encrypt the data + trailer, leave the header alone */
switch (m_type) {
case Encryption::NONE:
ut_error;
case Encryption::AES: {
lint elen;
ut_ad(m_klen == ENCRYPTION_KEY_LEN);
elen = my_aes_encrypt(
src + FIL_PAGE_DATA,
static_cast<uint32>(main_len),
dst + FIL_PAGE_DATA,
reinterpret_cast<unsigned char*>(m_key),
static_cast<uint32>(m_klen),
my_aes_256_cbc,
reinterpret_cast<unsigned char*>(m_iv),
false);
if (elen == MY_AES_BAD_DATA) {
ulint page_no =mach_read_from_4(
src + FIL_PAGE_OFFSET);
ulint space_id = mach_read_from_4(
src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
*dst_len = src_len;
#ifndef UNIV_INNOCHECKSUM
ib::warn()
<< " Can't encrypt data of page,"
<< " page no:" << page_no
<< " space id:" << space_id;
#else
fprintf(stderr, " Can't encrypt data of page,"
" page no:" ULINTPF
" space id:" ULINTPF,
page_no, space_id);
#endif /* !UNIV_INNOCHECKSUM */
return(src);
}
len = static_cast<ulint>(elen);
ut_ad(len == main_len);
/* Copy remain bytes and page tailer. */
memcpy(dst + FIL_PAGE_DATA + len,
src + FIL_PAGE_DATA + len,
src_len - FIL_PAGE_DATA - len);
/* Encrypt the remain bytes. */
if (remain_len != 0) {
remain_len = MY_AES_BLOCK_SIZE * 2;
elen = my_aes_encrypt(
dst + FIL_PAGE_DATA + data_len - remain_len,
static_cast<uint32>(remain_len),
remain_buf,
reinterpret_cast<unsigned char*>(m_key),
static_cast<uint32>(m_klen),
my_aes_256_cbc,
reinterpret_cast<unsigned char*>(m_iv),
false);
if (elen == MY_AES_BAD_DATA) {
ulint page_no =mach_read_from_4(
src + FIL_PAGE_OFFSET);
ulint space_id = mach_read_from_4(
src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
#ifndef UNIV_INNOCHECKSUM
ib::warn()
<< " Can't encrypt data of page,"
<< " page no:" << page_no
<< " space id:" << space_id;
#else
fprintf(stderr, " Can't encrypt data of page,"
" page no:" ULINTPF
" space id:" ULINTPF,
page_no, space_id);
#endif /* !UNIV_INNOCHECKSUM */
*dst_len = src_len;
return(src);
}
memcpy(dst + FIL_PAGE_DATA + data_len - remain_len,
remain_buf, remain_len);
}
break;
}
default:
ut_error;
}
/* Copy the header as is. */
memmove(dst, src, FIL_PAGE_DATA);
ut_ad(memcmp(src, dst, FIL_PAGE_DATA) == 0);
/* Add encryption control information. Required for decrypting. */
if (page_type == FIL_PAGE_COMPRESSED) {
/* If the page is compressed, we don't need to save the
original type, since it is done in compression already. */
mach_write_to_2(dst + FIL_PAGE_TYPE,
FIL_PAGE_COMPRESSED_AND_ENCRYPTED);
ut_ad(memcmp(src+FIL_PAGE_TYPE+2,
dst+FIL_PAGE_TYPE+2,
FIL_PAGE_DATA-FIL_PAGE_TYPE-2) == 0);
} else if (page_type == FIL_PAGE_RTREE) {
/* If the page is R-tree page, we need to save original
type. */
mach_write_to_2(dst + FIL_PAGE_TYPE, FIL_PAGE_ENCRYPTED_RTREE);
} else{
mach_write_to_2(dst + FIL_PAGE_TYPE, FIL_PAGE_ENCRYPTED);
mach_write_to_2(dst + FIL_PAGE_ORIGINAL_TYPE_V1, page_type);
}
#ifdef UNIV_ENCRYPT_DEBUG
#ifndef UNIV_INNOCHECKSUM
#if 0
byte* check_buf = static_cast<byte*>(ut_malloc_nokey(src_len));
byte* buf2 = static_cast<byte*>(ut_malloc_nokey(src_len));
memcpy(check_buf, dst, src_len);
dberr_t err = decrypt(type, check_buf, src_len, buf2, src_len);
if (err != DB_SUCCESS || memcmp(src + FIL_PAGE_DATA,
check_buf + FIL_PAGE_DATA,
src_len - FIL_PAGE_DATA) != 0) {
ut_print_buf(stderr, src, src_len);
ut_print_buf(stderr, check_buf, src_len);
ut_ad(0);
}
ut_free(buf2);
ut_free(check_buf);
#endif
fprintf(stderr, "Encrypted page:%lu.%lu\n", space_id, page_no);
#endif
#endif
*dst_len = src_len;
return(dst);
}
/** Decrypt the page data contents. Page type must be FIL_PAGE_ENCRYPTED,
if not then the source contents are left unchanged and DB_SUCCESS is returned.
@param[in] type IORequest
@param[in,out] src Data read from disk, decrypted data will be
copied to this page
@param[in] src_len source data length
@param[in,out] dst Scratch area to use for decryption
@param[in] dst_len Size of the scratch area in bytes
@return DB_SUCCESS or error code */
dberr_t
Encryption::decrypt(
const IORequest& type,
byte* src,
ulint src_len,
byte* dst,
ulint dst_len)
{
ulint data_len;
ulint main_len;
ulint remain_len;
ulint original_type;
ulint page_type;
byte remain_buf[MY_AES_BLOCK_SIZE * 2];
Block* block;
/* Do nothing if it's not an encrypted table. */
if (!is_encrypted_page(src)) {
return(DB_SUCCESS);
}
/* For compressed page, we need to get the compressed size
for decryption */
page_type = mach_read_from_2(src + FIL_PAGE_TYPE);
if (page_type == FIL_PAGE_COMPRESSED_AND_ENCRYPTED) {
src_len = static_cast<uint16_t>(
mach_read_from_2(src + FIL_PAGE_COMPRESS_SIZE_V1))
+ FIL_PAGE_DATA;
#ifndef UNIV_INNOCHECKSUM
src_len = ut_calc_align(src_len, type.block_size());
#endif
}
#ifdef UNIV_ENCRYPT_DEBUG
ulint space_id =
mach_read_from_4(src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint page_no = mach_read_from_4(src + FIL_PAGE_OFFSET);
fprintf(stderr, "Decrypting page:%lu.%lu len:%lu\n",
space_id, page_no, src_len);
#endif
original_type = static_cast<uint16_t>(
mach_read_from_2(src + FIL_PAGE_ORIGINAL_TYPE_V1));
byte* ptr = src + FIL_PAGE_DATA;
/* The caller doesn't know what to expect */
if (dst == NULL) {
block = os_alloc_block();
#ifdef UNIV_INNOCHECKSUM
dst = block;
#else
dst = block->m_ptr;
#endif /* UNIV_INNOCHECKSUM */
} else {
block = NULL;
}
data_len = src_len - FIL_PAGE_DATA;
main_len = (data_len / MY_AES_BLOCK_SIZE) * MY_AES_BLOCK_SIZE;
remain_len = data_len - main_len;
switch(m_type) {
case Encryption::AES: {
lint elen;
/* First decrypt the last 2 blocks data of data, since
data is no block aligned. */
if (remain_len != 0) {
ut_ad(m_klen == ENCRYPTION_KEY_LEN);
remain_len = MY_AES_BLOCK_SIZE * 2;
/* Copy the last 2 blocks. */
memcpy(remain_buf,
ptr + data_len - remain_len,
remain_len);
elen = my_aes_decrypt(
remain_buf,
static_cast<uint32>(remain_len),
dst + data_len - remain_len,
reinterpret_cast<unsigned char*>(m_key),
static_cast<uint32>(m_klen),
my_aes_256_cbc,
reinterpret_cast<unsigned char*>(m_iv),
false);
if (elen == MY_AES_BAD_DATA) {
if (block != NULL) {
os_free_block(block);
}
return(DB_IO_DECRYPT_FAIL);
}
/* Copy the other data bytes to temp area. */
memcpy(dst, ptr, data_len - remain_len);
} else {
ut_ad(data_len == main_len);
/* Copy the data bytes to temp area. */
memcpy(dst, ptr, data_len);
}
/* Then decrypt the main data */
elen = my_aes_decrypt(
dst,
static_cast<uint32>(main_len),
ptr,
reinterpret_cast<unsigned char*>(m_key),
static_cast<uint32>(m_klen),
my_aes_256_cbc,
reinterpret_cast<unsigned char*>(m_iv),
false);
if (elen == MY_AES_BAD_DATA) {
if (block != NULL) {
os_free_block(block);
}
return(DB_IO_DECRYPT_FAIL);
}
ut_ad(static_cast<ulint>(elen) == main_len);
/* Copy the remain bytes. */
memcpy(ptr + main_len, dst + main_len, data_len - main_len);
break;
}
default:
#if !defined(UNIV_INNOCHECKSUM)
ib::error()
<< "Encryption algorithm support missing: "
<< Encryption::to_string(m_type);
#else
fprintf(stderr, "Encryption algorithm support missing: %s\n",
Encryption::to_string(m_type));
#endif /* !UNIV_INNOCHECKSUM */
if (block != NULL) {
os_free_block(block);
}
return(DB_UNSUPPORTED);
}
/* Restore the original page type. If it's a compressed and
encrypted page, just reset it as compressed page type, since
we will do uncompress later. */
if (page_type == FIL_PAGE_ENCRYPTED) {
mach_write_to_2(src + FIL_PAGE_TYPE, original_type);
mach_write_to_2(src + FIL_PAGE_ORIGINAL_TYPE_V1, 0);
} else if (page_type == FIL_PAGE_ENCRYPTED_RTREE) {
mach_write_to_2(src + FIL_PAGE_TYPE, FIL_PAGE_RTREE);
} else {
ut_ad(page_type == FIL_PAGE_COMPRESSED_AND_ENCRYPTED);
mach_write_to_2(src + FIL_PAGE_TYPE, FIL_PAGE_COMPRESSED);
}
if (block != NULL) {
os_free_block(block);
}
#ifdef UNIV_ENCRYPT_DEBUG
fprintf(stderr, "Decrypted page:%lu.%lu\n", space_id, page_no);
#endif
DBUG_EXECUTE_IF("ib_crash_during_decrypt_page", DBUG_SUICIDE(););
return(DB_SUCCESS);
}
#endif /* MYSQL_ENCRYPTION */
/** Normalizes a directory path for the current OS:
On Windows, we convert '/' to '\', else we convert '\' to '/'.
@param[in,out] str A null-terminated directory and file path */

274
storage/innobase/row/row0import.cc

@ -124,8 +124,7 @@ struct row_import {
m_col_names(),
m_n_indexes(),
m_indexes(),
m_missing(true),
m_cfp_missing(true) { }
m_missing(true) {}
~row_import() UNIV_NOTHROW;
@ -220,9 +219,6 @@ struct row_import {
bool m_missing; /*!< true if a .cfg file was
found and was readable */
bool m_cfp_missing; /*!< true if a .cfp file was
found and was readable */
};
/** Use the page cursor to iterate over records in a block. */
@ -2182,9 +2178,6 @@ row_import_cleanup(
trx_commit_for_mysql(trx);
prebuilt->table->encryption_key = NULL;
prebuilt->table->encryption_iv = NULL;
row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx);
@ -3168,170 +3161,6 @@ row_import_read_cfg(
return(err);
}
#ifdef MYSQL_ENCRYPTION
/** Read the contents of the <tablespace>.cfp file.
@param[in] table table
@param[in] file file to read from
@param[in] thd session
@param[in] cfp contents of the .cfp file
@return DB_SUCCESS or error code. */
static
dberr_t
row_import_read_encryption_data(
dict_table_t* table,
FILE* file,
THD* thd,
row_import& import)
{
byte row[sizeof(ib_uint32_t)];
ulint key_size;
byte transfer_key[ENCRYPTION_KEY_LEN];
byte encryption_key[ENCRYPTION_KEY_LEN];
byte encryption_iv[ENCRYPTION_KEY_LEN];
lint elen;
if (fread(&row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
errno, strerror(errno),
"while reading encrypton key size.");
return(DB_IO_ERROR);
}
key_size = mach_read_from_4(row);
if (key_size != ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
errno, strerror(errno),
"while parsing encryption key size.");
return(DB_IO_ERROR);
}
/* Read the transfer key. */
if (fread(transfer_key, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while reading tranfer key.");
return(DB_IO_ERROR);
}
/* Read the encrypted key. */
if (fread(encryption_key, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while reading encryption key.");
return(DB_IO_ERROR);
}
/* Read the encrypted iv. */
if (fread(encryption_iv, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while reading encryption iv.");
return(DB_IO_ERROR);
}
table->encryption_key =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
table->encryption_iv =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
/* Decrypt tablespace key and iv. */
elen = my_aes_decrypt(
encryption_key,
ENCRYPTION_KEY_LEN,
table->encryption_key,
transfer_key,
ENCRYPTION_KEY_LEN,
my_aes_256_ecb, NULL, false);
if (elen == MY_AES_BAD_DATA) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
errno, strerror(errno),
"while decrypt encryption key.");
return(DB_IO_ERROR);
}
elen = my_aes_decrypt(
encryption_iv,
ENCRYPTION_KEY_LEN,
table->encryption_iv,
transfer_key,
ENCRYPTION_KEY_LEN,
my_aes_256_ecb, NULL, false);
if (elen == MY_AES_BAD_DATA) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
errno, strerror(errno),
"while decrypt encryption iv.");
return(DB_IO_ERROR);
}
return(DB_SUCCESS);
}
/** Read the contents of the <tablename>.cfp file.
@param[in] table table
@param[in] thd session
@param[in] cfp contents of the .cfp file
@return DB_SUCCESS or error code. */
static
dberr_t
row_import_read_cfp(
dict_table_t* table,
THD* thd,
row_import& import)
{
dberr_t err;
char name[OS_FILE_MAX_PATH];
/* Clear table encryption information. */
table->encryption_key = NULL;
table->encryption_iv = NULL;
srv_get_encryption_data_filename(table, name, sizeof(name));
FILE* file = fopen(name, "rb");
if (file == NULL) {
import.m_cfp_missing = true;
/* If there's no cfp file, we assume it's not an
encrpyted table. return directly. */
import.m_cfp_missing = true;
err = DB_SUCCESS;
} else {
import.m_cfp_missing = false;
err = row_import_read_encryption_data(table, file,
thd, import);
fclose(file);
}
return(err);
}
#endif /* MYSQL_ENCRYPTION */
/*****************************************************************//**
Update the <space, root page> of a table's indexes from the values
in the data dictionary.
@ -3699,42 +3528,7 @@ row_import_for_mysql(
rw_lock_s_unlock_gen(dict_operation_lock, 0);
}
/* Try to read encryption information. */
if (err == DB_SUCCESS) {
#ifdef MYSQL_ENCRYPTION
err = row_import_read_cfp(table, trx->mysql_thd, cfg);
/* If table is not set to encrypted, but the fsp flag
is not, then return error. */
if (!dict_table_is_encrypted(table)
&& space_flags != 0
&& FSP_FLAGS_GET_ENCRYPTION(space_flags)) {
ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Table is not marked as encrypted, but"
" the tablespace is marked as encrypted");
err = DB_ERROR;
return(row_import_error(prebuilt, trx, err));
}
/* If table is set to encrypted, but can't find
cfp file, then return error. */
if (cfg.m_cfp_missing== true
&& ((space_flags != 0
&& FSP_FLAGS_GET_ENCRYPTION(space_flags))
|| dict_table_is_encrypted(table))) {
ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Table is in an encrypted tablespace, but"
" can't find the encryption meta-data file"
" in importing");
err = DB_ERROR;
return(row_import_error(prebuilt, trx, err));
}
#endif /* MYSQL_ENCRYPTION */
} else {
if (err != DB_SUCCESS) {
return(row_import_error(prebuilt, trx, err));
}
@ -3757,22 +3551,6 @@ row_import_for_mysql(
DBUG_EXECUTE_IF("ib_import_reset_space_and_lsn_failure",
err = DB_TOO_MANY_CONCURRENT_TRXS;);
#ifdef MYSQL_ENCRYPTION
if (err == DB_IO_NO_ENCRYPT_TABLESPACE) {
char table_name[MAX_FULL_NAME_LEN + 1];
innobase_format_name(
table_name, sizeof(table_name),
table->name.m_name);
ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
"Encryption attribute is no matched");
return(row_import_cleanup(prebuilt, trx, err));
}
#endif /* MYSQL_ENCRYPTION */
if (err != DB_SUCCESS) {
char table_name[MAX_FULL_NAME_LEN + 1];
@ -3828,12 +3606,6 @@ row_import_for_mysql(
ulint fsp_flags = dict_tf_to_fsp_flags(table->flags, false);
#ifdef MYSQL_ENCRYPTION
if (table->encryption_key != NULL) {
fsp_flags |= FSP_FLAGS_MASK_ENCRYPTION;
}
#endif /* MYSQL_ENCRYPTION */
err = fil_ibd_open(
true, true, FIL_TYPE_IMPORT, table->space,
fsp_flags, table->name.m_name, filepath, table);
@ -3853,17 +3625,6 @@ row_import_for_mysql(
return(row_import_cleanup(prebuilt, trx, err));
}
#ifdef MYSQL_ENCRYPTION
/* For encrypted table, set encryption information. */
if (dict_table_is_encrypted(table)) {
err = fil_set_encryption(table->space,
Encryption::AES,
table->encryption_key,
table->encryption_iv);
}
#endif /* MYSQL_ENCRYPTION */
row_mysql_unlock_data_dictionary(trx);
ut_free(filepath);
@ -3961,37 +3722,6 @@ row_import_for_mysql(
ib::info() << "Phase IV - Flush complete";
fil_space_set_imported(prebuilt->table->space);
#ifdef MYSQL_ENCRYPTION
if (dict_table_is_encrypted(table)) {
fil_space_t* space;
mtr_t mtr;
byte encrypt_info[ENCRYPTION_INFO_SIZE_V2];
mtr_start(&mtr);
mtr.set_named_space(table->space);
space = mtr_x_lock_space(table->space, &mtr);
memset(encrypt_info, 0, ENCRYPTION_INFO_SIZE_V2);
if (!fsp_header_rotate_encryption(space,
encrypt_info,
&mtr)) {
mtr_commit(&mtr);
ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_FILE_NOT_FOUND,
filepath, err, ut_strerr(err));
ut_free(filepath);
row_mysql_unlock_data_dictionary(trx);
return(row_import_cleanup(prebuilt, trx, err));
}
mtr_commit(&mtr);
}
#endif /* MYSQL_ENCRYPTION */
/* The dictionary latches will be released in in row_import_cleanup()
after the transaction commit, for both success and error. */

58
storage/innobase/row/row0mysql.cc

@ -102,8 +102,6 @@ static ib_mutex_t row_drop_list_mutex;
/** Flag: has row_mysql_drop_list been initialized? */
static ibool row_mysql_drop_list_inited = FALSE;
extern ib_mutex_t master_key_id_mutex;
/** Magic table names for invoking various monitor threads */
/* @{ */
static const char S_innodb_monitor[] = "innodb_monitor";
@ -3275,33 +3273,6 @@ row_discard_tablespace(
return(err);
}
/* For encrypted table, before we discard the tablespace,
we need save the encryption information into table, otherwise,
this information will be lost in fil_discard_tablespace along
with fil_space_free(). */
if (dict_table_is_encrypted(table)) {
ut_ad(table->encryption_key == NULL
&& table->encryption_iv == NULL);
table->encryption_key =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
table->encryption_iv =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
fil_space_t* space = fil_space_get(table->space);
ut_ad(FSP_FLAGS_GET_ENCRYPTION(space->flags));
memcpy(table->encryption_key,
space->encryption_key,
ENCRYPTION_KEY_LEN);
memcpy(table->encryption_iv,
space->encryption_iv,
ENCRYPTION_KEY_LEN);
}
/* Discard the physical file that is used for the tablespace. */
err = fil_discard_tablespace(table->space);
@ -3614,7 +3585,6 @@ This deletes the fil_space_t if found and the file on disk.
@param[in] tablename Table name, same as the tablespace name
@param[in] filepath File path of tablespace to delete
@param[in] is_temp Is this a temporary table/tablespace
@param[in] is_encrypted Is this an encrypted table/tablespace
@param[in] trx Transaction handle
@return error code or DB_SUCCESS */
UNIV_INLINE
@ -3624,7 +3594,6 @@ row_drop_single_table_tablespace(
const char* tablename,
const char* filepath,
bool is_temp,
bool is_encrypted,
trx_t* trx)
{
dberr_t err = DB_SUCCESS;
@ -3632,7 +3601,7 @@ row_drop_single_table_tablespace(
/* This might be a temporary single-table tablespace if the table
is compressed and temporary. If so, don't spam the log when we
delete one of these or if we can't find the tablespace. */
bool print_msg = !is_temp && !is_encrypted;
bool print_msg = !is_temp;
/* If the tablespace is not in the cache, just delete the file. */
if (!fil_space_for_table_exists_in_mem(
@ -4117,7 +4086,6 @@ row_drop_table_for_mysql(
switch (err) {
ulint space_id;
bool is_temp;
bool is_encrypted;
bool ibd_file_missing;
bool is_discarded;
bool shared_tablespace;
@ -4127,7 +4095,6 @@ row_drop_table_for_mysql(
ibd_file_missing = table->ibd_file_missing;
is_discarded = dict_table_is_discarded(table);
is_temp = dict_table_is_temporary(table);
is_encrypted = dict_table_is_encrypted(table);
shared_tablespace = DICT_TF_HAS_SHARED_SPACE(table->flags);
/* If there is a temp path then the temp flag is set.
@ -4172,32 +4139,13 @@ row_drop_table_for_mysql(
nor system or shared general tablespaces. */
if (is_discarded || ibd_file_missing || shared_tablespace
|| is_system_tablespace(space_id)) {
/* For encrypted table, if ibd file can not be decrypt,
we also set ibd_file_missing. We still need to try to
remove the ibd file for this. */
if (is_discarded || !is_encrypted
|| !ibd_file_missing) {
break;
}
}
#ifdef MYSQL_ENCRYPTION
if (is_encrypted) {
/* Require the mutex to block key rotation. */
mutex_enter(&master_key_id_mutex);
break;
}
#endif /* MYSQL_ENCRYPTION */
/* We can now drop the single-table tablespace. */
err = row_drop_single_table_tablespace(
space_id, tablename, filepath,
is_temp, is_encrypted, trx);
#ifdef MYSQL_ENCRYPTION
if (is_encrypted) {
mutex_exit(&master_key_id_mutex);
}
#endif /* MYSQL_ENCRYPTION */
is_temp, trx);
break;
case DB_OUT_OF_FILE_SPACE:

238
storage/innobase/row/row0quiesce.cc

@ -480,210 +480,6 @@ row_quiesce_write_cfg(
return(err);
}
#ifdef MYSQL_ENCRYPTION
/** Write the transfer key to CFP file.
@param[in] table write the data for this table
@param[in] file file to write to
@param[in] thd session
@return DB_SUCCESS or error code. */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_quiesce_write_transfer_key(
const dict_table_t* table,
FILE* file,
THD* thd)
{
byte key_size[sizeof(ib_uint32_t)];
byte row[ENCRYPTION_KEY_LEN * 3];
byte* ptr = row;
byte* transfer_key = ptr;
lint elen;
ut_ad(table->encryption_key != NULL
&& table->encryption_iv != NULL);
/* Write the encryption key size. */
mach_write_to_4(key_size, ENCRYPTION_KEY_LEN);
if (fwrite(&key_size, 1, sizeof(key_size), file)
!= sizeof(key_size)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while writing key size.");
return(DB_IO_ERROR);
}
/* Generate and write the transfer key. */
Encryption::random_value(transfer_key);
if (fwrite(transfer_key, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while writing transfer key.");
return(DB_IO_ERROR);
}
ptr += ENCRYPTION_KEY_LEN;
/* Encrypt tablespace key. */
elen = my_aes_encrypt(
reinterpret_cast<unsigned char*>(table->encryption_key),
ENCRYPTION_KEY_LEN,
ptr,
reinterpret_cast<unsigned char*>(transfer_key),
ENCRYPTION_KEY_LEN,
my_aes_256_ecb,
NULL, false);
if (elen == MY_AES_BAD_DATA) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while encrypt tablespace key.");
return(DB_ERROR);
}
/* Write encrypted tablespace key */
if (fwrite(ptr, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while writing encrypted tablespace key.");
return(DB_IO_ERROR);
}
ptr += ENCRYPTION_KEY_LEN;
/* Encrypt tablespace iv. */
elen = my_aes_encrypt(
reinterpret_cast<unsigned char*>(table->encryption_iv),
ENCRYPTION_KEY_LEN,
ptr,
reinterpret_cast<unsigned char*>(transfer_key),
ENCRYPTION_KEY_LEN,
my_aes_256_ecb,
NULL, false);
if (elen == MY_AES_BAD_DATA) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while encrypt tablespace iv.");
return(DB_ERROR);
}
/* Write encrypted tablespace iv */
if (fwrite(ptr, 1, ENCRYPTION_KEY_LEN, file)
!= ENCRYPTION_KEY_LEN) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno),
"while writing encrypted tablespace iv.");
return(DB_IO_ERROR);
}
return(DB_SUCCESS);
}
/** Write the encryption data after quiesce.
@param[in] table write the data for this table
@param[in] thd session
@return DB_SUCCESS or error code */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_quiesce_write_cfp(
dict_table_t* table,
THD* thd)
{
dberr_t err;
char name[OS_FILE_MAX_PATH];
/* If table is not encrypted, return. */
if (!dict_table_is_encrypted(table)) {
return(DB_SUCCESS);
}
/* Get the encryption key and iv from space */
/* For encrypted table, before we discard the tablespace,
we need save the encryption information into table, otherwise,
this information will be lost in fil_discard_tablespace along
with fil_space_free(). */
if (table->encryption_key == NULL) {
table->encryption_key =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
table->encryption_iv =
static_cast<byte*>(mem_heap_alloc(table->heap,
ENCRYPTION_KEY_LEN));
fil_space_t* space = fil_space_get(table->space);
ut_ad(space != NULL && FSP_FLAGS_GET_ENCRYPTION(space->flags));
memcpy(table->encryption_key,
space->encryption_key,
ENCRYPTION_KEY_LEN);
memcpy(table->encryption_iv,
space->encryption_iv,
ENCRYPTION_KEY_LEN);
}
srv_get_encryption_data_filename(table, name, sizeof(name));
ib::info() << "Writing table encryption data to '" << name << "'";
FILE* file = fopen(name, "w+b");
if (file == NULL) {
ib_errf(thd, IB_LOG_LEVEL_WARN, ER_CANT_CREATE_FILE,
name, errno, strerror(errno));
err = DB_IO_ERROR;
} else {
err = row_quiesce_write_transfer_key(table, file, thd);
if (fflush(file) != 0) {
char msg[BUFSIZ];
ut_snprintf(msg, sizeof(msg), "%s flush() failed",
name);
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno), msg);
err = DB_IO_ERROR;
}
if (fclose(file) != 0) {
char msg[BUFSIZ];
ut_snprintf(msg, sizeof(msg), "%s flose() failed",
name);
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
errno, strerror(errno), msg);
err = DB_IO_ERROR;
}
}
/* Clean the encryption information */
table->encryption_key = NULL;
table->encryption_iv = NULL;
return(err);
}
#endif /* MYSQL_ENCRYPTION */
/*********************************************************************//**
Check whether a table has an FTS index defined on it.
@return true if an FTS index exists on the table */
@ -744,24 +540,9 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
extern ib_mutex_t master_key_id_mutex;
#ifdef MYSQL_ENCRYPTION
if (dict_table_is_encrypted(table)) {
/* Require the mutex to block key rotation. */
mutex_enter(&master_key_id_mutex);
}
#endif /* MYSQL_ENCRYPTION */
buf_LRU_flush_or_remove_pages(
table->space, BUF_REMOVE_FLUSH_WRITE, trx);
#ifdef MYSQL_ENCRYPTION
if (dict_table_is_encrypted(table)) {
mutex_exit(&master_key_id_mutex);
}
#endif /* MYSQL_ENCRYPTION */
if (trx_is_interrupted(trx)) {
ib::warn() << "Quiesce aborted!";
@ -771,12 +552,6 @@ row_quiesce_table_start(
ib::warn() << "There was an error writing to the"
" meta data file";
#ifdef MYSQL_ENCRYPTION
} else if (row_quiesce_write_cfp(table, trx->mysql_thd)
!= DB_SUCCESS) {
ib::warn() << "There was an error writing to the"
" encryption info file";
#endif /* MYSQL_ENCRYPTION */
} else {
ib::info() << "Table " << table->name
<< " flushed to disk";
@ -829,19 +604,6 @@ row_quiesce_table_complete(
ib::info() << "Deleting the meta-data file '" << cfg_name << "'";
if (dict_table_is_encrypted(table)) {
char cfp_name[OS_FILE_MAX_PATH];
srv_get_encryption_data_filename(table,
cfp_name,
sizeof(cfp_name));
os_file_delete_if_exists(innodb_data_file_key, cfp_name, NULL);
ib::info() << "Deleting the meta-data file '"
<< cfp_name << "'";
}
if (trx_purge_state() != PURGE_STATE_DISABLED) {
trx_purge_run();
}

44
storage/innobase/srv/srv0start.cc

@ -2289,17 +2289,6 @@ files_checked:
dict_check_tablespaces_and_store_max_id(validate);
}
#ifdef MYSQL_ENCRYPTION
/* Rotate the encryption key for recovery. It's because
server could crash in middle of key rotation. Some tablespace
didn't complete key rotation. Here, we will resume the
rotation. */
if (!srv_read_only_mode
&& srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
fil_encryption_rotate();
}
#endif /* MYSQL_ENCRYPTION */
/* Fix-up truncate of table if server crashed while truncate
was active. */
err = truncate_t::fixup_tables_in_non_system_tablespace();
@ -2970,36 +2959,3 @@ srv_get_meta_data_filename(
ut_free(path);
}
/** Get the encryption-data filename from the table name for a
single-table tablespace.
@param[in] table table object
@param[out] filename filename
@param[in] max_len filename max length */
void
srv_get_encryption_data_filename(
dict_table_t* table,
char* filename,
ulint max_len)
{
ulint len;
char* path;
/* Make sure the data_dir_path is set. */
dict_get_and_save_data_dir_path(table, false);
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
ut_a(table->data_dir_path);
path = fil_make_filepath(
table->data_dir_path, table->name.m_name, CFP, true);
} else {
path = fil_make_filepath(NULL, table->name.m_name, CFP, false);
}
ut_a(path);
len = ut_strlen(path);
ut_a(max_len >= len);
strcpy(filename, path);
ut_free(path);
}

2
storage/innobase/sync/sync0debug.cc

@ -1544,8 +1544,6 @@ sync_latch_meta_init()
LATCH_ADD(SYNC_DEBUG_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED);
LATCH_ADD(MASTER_KEY_ID_MUTEX, SYNC_NO_ORDER_CHECK, master_key_id_mutex_key);
/* JAN: TODO: Add PFS instrumentation */
LATCH_ADD(SCRUB_STAT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED);
LATCH_ADD(DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED);

1
storage/innobase/sync/sync0sync.cc

@ -98,7 +98,6 @@ mysql_pfs_key_t sync_array_mutex_key;
mysql_pfs_key_t thread_mutex_key;
mysql_pfs_key_t zip_pad_mutex_key;
mysql_pfs_key_t row_drop_list_mutex_key;
mysql_pfs_key_t master_key_id_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#ifdef UNIV_PFS_RWLOCK
mysql_pfs_key_t btr_search_latch_key;

4
storage/innobase/ut/ut0ut.cc

@ -759,10 +759,6 @@ ut_strerr(
return("Punch hole not supported by the file system");
case DB_IO_NO_PUNCH_HOLE_TABLESPACE:
return("Punch hole not supported by the tablespace");
case DB_IO_NO_ENCRYPT_TABLESPACE:
return("Page encryption not supported by the tablespace");
case DB_IO_DECRYPT_FAIL:
return("Page decryption failed after reading from disk");
case DB_IO_PARTIAL_FAILED:
return("Partial IO failed");
case DB_FORCED_ABORT:

Loading…
Cancel
Save