summaryrefslogtreecommitdiff
path: root/storage/xtradb/fil/fil0fil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/fil/fil0fil.cc')
-rw-r--r--storage/xtradb/fil/fil0fil.cc168
1 files changed, 109 insertions, 59 deletions
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 11fb999d529..dde309f4234 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -460,7 +460,7 @@ fil_space_get_latch(
/*******************************************************************//**
Returns the type of a file space.
-@return FIL_TABLESPACE or FIL_LOG */
+@return ULINT_UNDEFINED, or FIL_TABLESPACE or FIL_LOG */
UNIV_INTERN
ulint
fil_space_get_type(
@@ -468,6 +468,7 @@ fil_space_get_type(
ulint id) /*!< in: space id */
{
fil_space_t* space;
+ ulint type = ULINT_UNDEFINED;
ut_ad(fil_system);
@@ -475,11 +476,13 @@ fil_space_get_type(
space = fil_space_get_by_id(id);
- ut_a(space);
-
mutex_exit(&fil_system->mutex);
- return(space->purpose);
+ if (space) {
+ type = space->purpose;
+ }
+
+ return(type);
}
#endif /* !UNIV_HOTBACKUP */
@@ -2012,8 +2015,6 @@ fil_read_first_page(
lsn values in data files */
lsn_t* max_flushed_lsn, /*!< out: max of flushed
lsn values in data files */
- ulint orig_space_id, /*!< in: original file space
- id */
fil_space_crypt_t** crypt_data) /*< out: crypt data */
{
byte* buf;
@@ -2022,6 +2023,7 @@ fil_read_first_page(
const char* check_msg = NULL;
fil_space_crypt_t* cdata;
+
buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
/* Align the memory for a possible read from a raw device */
@@ -2052,6 +2054,10 @@ fil_read_first_page(
fsp_flags_get_zip_size(*flags), NULL);
cdata = fil_space_read_crypt_data(space, page, offset);
+ if (crypt_data) {
+ *crypt_data = cdata;
+ }
+
/* If file space is encrypted we need to have at least some
encryption service available where to get keys */
if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) ||
@@ -2059,16 +2065,14 @@ fil_read_first_page(
cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
if (!encryption_key_id_exists(cdata->key_id)) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Tablespace id %ld encrypted but encryption service"
- " not available. Can't continue opening tablespace.\n",
- space);
- ut_error;
- }
- }
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Tablespace id %ld is encrypted but encryption service"
+ " or used key_id %u is not available. Can't continue opening tablespace.",
+ space, cdata->key_id);
- if (crypt_data) {
- *crypt_data = cdata;
+ return ("table encrypted but encryption service not available.");
+
+ }
}
ut_free(buf);
@@ -2425,7 +2429,9 @@ fil_op_log_parse_or_replay(
if (fil_create_new_single_table_tablespace(
space_id, name, path, flags,
DICT_TF2_USE_TABLESPACE,
- FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
+ FIL_IBD_FILE_INITIAL_SIZE,
+ FIL_SPACE_ENCRYPTION_DEFAULT,
+ FIL_DEFAULT_ENCRYPTION_KEY) != DB_SUCCESS) {
ut_error;
}
}
@@ -3364,9 +3370,11 @@ fil_create_new_single_table_tablespace(
const char* dir_path, /*!< in: NULL or a dir path */
ulint flags, /*!< in: tablespace flags */
ulint flags2, /*!< in: table flags2 */
- ulint size) /*!< in: the initial size of the
+ ulint size, /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
+ fil_encryption_t mode, /*!< in: encryption mode */
+ ulint key_id) /*!< in: encryption key_id */
{
os_file_t file;
ibool ret;
@@ -3533,7 +3541,7 @@ fil_create_new_single_table_tablespace(
}
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
- fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY));
+ fil_space_create_crypt_data(mode, key_id));
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
err = DB_ERROR;
@@ -3650,7 +3658,8 @@ fil_open_single_table_tablespace(
ulint flags, /*!< in: tablespace flags */
const char* tablename, /*!< in: table name in the
databasename/tablename format */
- const char* path_in) /*!< in: tablespace filepath */
+ const char* path_in, /*!< in: tablespace filepath */
+ dict_table_t* table) /*!< in: table */
{
dberr_t err = DB_SUCCESS;
bool dict_filepath_same_as_default = false;
@@ -3761,9 +3770,13 @@ fil_open_single_table_tablespace(
if (def.success) {
def.check_msg = fil_read_first_page(
def.file, FALSE, &def.flags, &def.id,
- &def.lsn, &def.lsn, id, &def.crypt_data);
+ &def.lsn, &def.lsn, &def.crypt_data);
def.valid = !def.check_msg;
+ if (table) {
+ table->crypt_data = def.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3783,9 +3796,13 @@ fil_open_single_table_tablespace(
if (remote.success) {
remote.check_msg = fil_read_first_page(
remote.file, FALSE, &remote.flags, &remote.id,
- &remote.lsn, &remote.lsn, id, &remote.crypt_data);
+ &remote.lsn, &remote.lsn, &remote.crypt_data);
remote.valid = !remote.check_msg;
+ if (table) {
+ table->crypt_data = remote.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3806,9 +3823,13 @@ fil_open_single_table_tablespace(
if (dict.success) {
dict.check_msg = fil_read_first_page(
dict.file, FALSE, &dict.flags, &dict.id,
- &dict.lsn, &dict.lsn, id, &dict.crypt_data);
+ &dict.lsn, &dict.lsn, &dict.crypt_data);
dict.valid = !dict.check_msg;
+ if (table) {
+ table->crypt_data = dict.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3990,7 +4011,9 @@ cleanup_and_exit:
mem_free(remote.filepath);
}
if (remote.crypt_data && remote.crypt_data != crypt_data) {
- fil_space_destroy_crypt_data(&remote.crypt_data);
+ if (err == DB_SUCCESS) {
+ fil_space_destroy_crypt_data(&remote.crypt_data);
+ }
}
if (dict.success) {
os_file_close(dict.file);
@@ -4005,7 +4028,9 @@ cleanup_and_exit:
os_file_close(def.file);
}
if (def.crypt_data && def.crypt_data != crypt_data) {
- fil_space_destroy_crypt_data(&def.crypt_data);
+ if (err == DB_SUCCESS) {
+ fil_space_destroy_crypt_data(&def.crypt_data);
+ }
}
mem_free(def.filepath);
@@ -4225,7 +4250,7 @@ check_first_page:
fsp->success = TRUE;
if (const char* check_msg = fil_read_first_page(
fsp->file, FALSE, &fsp->flags, &fsp->id,
- &fsp->lsn, &fsp->lsn, ULINT_UNDEFINED, &fsp->crypt_data)) {
+ &fsp->lsn, &fsp->lsn, &fsp->crypt_data)) {
ib_logf(IB_LOG_LEVEL_ERROR,
"%s in tablespace %s (table %s)",
check_msg, fsp->filepath, tablename);
@@ -5923,9 +5948,9 @@ _fil_io(
if (!ret) {
return(DB_OUT_OF_FILE_SPACE);
- } else {
- return(DB_SUCCESS);
}
+
+ return(DB_SUCCESS);
}
#ifndef UNIV_HOTBACKUP
@@ -6450,8 +6475,17 @@ fil_iterate(
ut_ad(!(n_bytes % iter.page_size));
byte* readptr = io_buffer;
- if (iter.crypt_data != NULL) {
+ byte* writeptr = io_buffer;
+ bool encrypted = false;
+
+ /* Use additional crypt io buffer if tablespace is encrypted */
+ if ((iter.crypt_data != NULL && iter.crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
+ (srv_encrypt_tables &&
+ iter.crypt_data && iter.crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
+
+ encrypted = true;
readptr = iter.crypt_io_buffer;
+ writeptr = iter.crypt_io_buffer;
}
if (!os_file_read(iter.file, readptr, offset, (ulint) n_bytes)) {
@@ -6464,24 +6498,36 @@ fil_iterate(
bool updated = false;
os_offset_t page_off = offset;
ulint n_pages_read = (ulint) n_bytes / iter.page_size;
+ bool decrypted = false;
for (ulint i = 0; i < n_pages_read; ++i) {
+ ulint size = iter.page_size;
+ dberr_t err = DB_SUCCESS;
+
+ /* If tablespace is encrypted, we need to decrypt
+ the page. */
+ if (encrypted) {
+ decrypted = fil_space_decrypt(
+ iter.crypt_data,
+ io_buffer + i * size, //dst
+ iter.page_size,
+ readptr + i * size, // src
+ &err); // src
+
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
- if (iter.crypt_data != NULL) {
- bool decrypted = fil_space_decrypt(
- iter.crypt_data,
- readptr + i * iter.page_size, // src
- iter.page_size,
- io_buffer + i * iter.page_size); // dst
if (decrypted) {
- /* write back unencrypted page */
updated = true;
+ } else {
+ /* TODO: remove unnecessary memcpy's */
+ memcpy(io_buffer + i * size, readptr + i * size, size);
}
}
buf_block_set_file_page(block, space_id, page_no++);
- dberr_t err;
if ((err = callback(page_off, block)) != DB_SUCCESS) {
@@ -6495,6 +6541,32 @@ fil_iterate(
buf_block_set_state(block, BUF_BLOCK_NOT_USED);
buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE);
+ /* If tablespace is encrypted, encrypt page before we
+ write it back. Note that we should not encrypt the
+ buffer that is in buffer pool. */
+ if (decrypted && encrypted) {
+ unsigned char *src = io_buffer + (i * size);
+ unsigned char *dst = writeptr + (i * size);
+ ulint space = mach_read_from_4(
+ src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ ulint offset = mach_read_from_4(src + FIL_PAGE_OFFSET);
+ ib_uint64_t lsn = mach_read_from_8(src + FIL_PAGE_LSN);
+
+ byte* tmp = fil_encrypt_buf(
+ iter.crypt_data,
+ space,
+ offset,
+ lsn,
+ src,
+ iter.page_size == UNIV_PAGE_SIZE ? 0 : iter.page_size,
+ dst);
+
+ if (tmp == src) {
+ /* TODO: remove unnecessary memcpy's */
+ memcpy(writeptr, src, size);
+ }
+ }
+
page_off += iter.page_size;
block->frame += iter.page_size;
}
@@ -6502,7 +6574,7 @@ fil_iterate(
/* A page was updated in the set, write back to disk. */
if (updated
&& !os_file_write(
- iter.filepath, iter.file, io_buffer,
+ iter.filepath, iter.file, writeptr,
offset, (ulint) n_bytes)) {
ib_logf(IB_LOG_LEVEL_ERROR, "os_file_write() failed");
@@ -6664,28 +6736,6 @@ fil_tablespace_iterate(
mem_free(io_buffer);
if (iter.crypt_data != NULL) {
- /* clear crypt data from page 0 and write it back */
- os_file_read(file, page, 0, UNIV_PAGE_SIZE);
- fil_space_clear_crypt_data(page, crypt_data_offset);
- lsn_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
- if (callback.get_zip_size() == 0) {
- buf_flush_init_for_writing(
- page, 0, lsn);
- } else {
- buf_flush_update_zip_checksum(
- page, callback.get_zip_size(), lsn);
- }
-
- if (!os_file_write(
- iter.filepath, iter.file, page,
- 0, iter.page_size)) {
-
- ib_logf(IB_LOG_LEVEL_ERROR,
- "os_file_write() failed");
-
- return(DB_IO_ERROR);
- }
-
mem_free(crypt_io_buffer);
iter.crypt_io_buffer = NULL;
fil_space_destroy_crypt_data(&iter.crypt_data);