diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-08-14 11:09:06 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-08-14 16:25:18 +0300 |
commit | bfb6ea02321f963c2b5f5beb333283585d3d1be3 (patch) | |
tree | 1de9aa594dbefd0ce33301ec00833b442e9658af | |
parent | a80753594a37538a35df7c02ae80da624578dec4 (diff) | |
download | mariadb-git-bfb6ea02321f963c2b5f5beb333283585d3d1be3.tar.gz |
MDEV-8589: Non-default ENCRYPTION_KEY_ID is ignored upon reading a table
Analysis: Problem was that when a new tablespace is created a default
encryption info is also created and stored to the tablespace. Later a
new encryption information was created with correct key_id but that
does not affect on IV.
Fix: Push encryption mode and key_id to lower levels and create
correct encryption info when a new tablespace is created.
This fix does not contain test case because, currently incorrect
encryption key causes page corruption and a lot of error messages
to error log causing mtr to fail.
22 files changed, 154 insertions, 140 deletions
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 30523ff2af4..36a30cb75b7 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -309,7 +309,8 @@ dict_build_table_def_step( space, table->name, path, dict_tf_to_fsp_flags(table->flags), table->flags2, - FIL_IBD_FILE_INITIAL_SIZE); + FIL_IBD_FILE_INITIAL_SIZE, + node->mode, node->key_id); table->space = (unsigned int) space; @@ -934,8 +935,10 @@ tab_create_graph_create( dict_table_t* table, /*!< in: table to create, built as a memory data structure */ mem_heap_t* heap, /*!< in: heap where created */ - bool commit) /*!< in: true if the commit node should be + bool commit, /*!< in: true if the commit node should be added to the query graph */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { tab_node_t* node; @@ -948,6 +951,8 @@ tab_create_graph_create( node->state = TABLE_BUILD_TABLE_DEF; node->heap = mem_heap_create(256); + node->mode = mode; + node->key_id = key_id; node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables, heap); @@ -1042,7 +1047,6 @@ dict_create_table_step( /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ err = dict_build_table_def_step(thr, node); - if (err != DB_SUCCESS) { goto function_exit; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 7d8ce96ea3c..249e20da1bc 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2394,7 +2394,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; } } @@ -3331,9 +3333,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; @@ -3500,7 +3504,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; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 4351dc0b765..cc4a4f9f1a8 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1981,7 +1981,7 @@ fts_create_one_index_table( dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB, 4130048, 0); - error = row_create_table_for_mysql(new_table, trx, false); + error = row_create_table_for_mysql(new_table, trx, false, FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); if (error != DB_SUCCESS) { trx->error_state = error; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 398b303897f..4031ccd5b8f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10319,7 +10319,9 @@ create_table_def( is a zero length-string */ const char* remote_path, /*!< in: Remote path or zero length-string */ ulint flags, /*!< in: table flags */ - ulint flags2) /*!< in: table flags2 */ + ulint flags2, /*!< in: table flags2 */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { THD* thd = trx->mysql_thd; dict_table_t* table; @@ -10499,7 +10501,7 @@ err_col: fts_add_doc_id_column(table, heap); } - err = row_create_table_for_mysql(table, trx, false); + err = row_create_table_for_mysql(table, trx, false, mode, key_id); mem_heap_free(heap); @@ -11575,7 +11577,7 @@ ha_innobase::create( row_mysql_lock_data_dictionary(trx); error = create_table_def(trx, form, norm_name, temp_path, - remote_path, flags, flags2); + remote_path, flags, flags2, encrypt, key_id); if (error) { goto cleanup; } @@ -11735,48 +11737,6 @@ ha_innobase::create( DBUG_ASSERT(innobase_table != 0); - /* If user has requested that table should be encrypted or table - should remain as unencrypted store crypt data */ - if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) { - ulint maxsize=0; - ulint zip_size = fil_space_get_zip_size(innobase_table->space); - fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space); - fil_space_crypt_t* crypt_data; - - crypt_data = fil_space_create_crypt_data(encrypt, key_id); - crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); - crypt_data->encryption = encrypt; - - /* If there is old crypt data, copy IV */ - if (old_crypt_data) { - memcpy(crypt_data->iv, old_crypt_data->iv, sizeof(crypt_data->iv)); - } - - mtr_t mtr; - mtr_start(&mtr); - /* Get page 0*/ - ulint offset = 0; - buf_block_t* block = buf_page_get_gen(innobase_table->space, - zip_size, - offset, - RW_X_LATCH, - NULL, - BUF_GET, - __FILE__, __LINE__, - &mtr); - - /* Set up new crypt data */ - crypt_data = fil_space_set_crypt_data(innobase_table->space, crypt_data); - - /* Compute location to store crypt data */ - byte* frame = buf_block_get_frame(block); - - /* Write crypt data to page 0 */ - fil_space_write_crypt_data(innobase_table->space, frame, crypt_data->page0_offset, maxsize, &mtr); - - mtr_commit(&mtr); - } - innobase_copy_frm_flags_from_create_info(innobase_table, create_info); dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 4cb912cd023..3d6c0ecac32 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2791,6 +2791,7 @@ prepare_inplace_alter_table_dict( to rebuild the table with a temporary name. */ if (new_clustered) { + fil_space_crypt_t* crypt_data; const char* new_table_name = dict_mem_create_temporary_tablename( ctx->heap, @@ -2798,6 +2799,15 @@ prepare_inplace_alter_table_dict( ctx->new_table->id); ulint n_cols; dtuple_t* add_cols; + ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; + fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; + + crypt_data = fil_space_get_crypt_data(ctx->prebuilt->table->space); + + if (crypt_data) { + key_id = crypt_data->key_id; + mode = crypt_data->encryption; + } if (innobase_check_foreigns( ha_alter_info, altered_table, old_table, @@ -2929,7 +2939,7 @@ prepare_inplace_alter_table_dict( } error = row_create_table_for_mysql( - ctx->new_table, ctx->trx, false); + ctx->new_table, ctx->trx, false, mode, key_id); switch (error) { dict_table_t* temp_table; diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h index 67eab9058da..c40e5356ece 100644 --- a/storage/innobase/include/dict0crea.h +++ b/storage/innobase/include/dict0crea.h @@ -32,6 +32,7 @@ Created 1/8/1996 Heikki Tuuri #include "que0types.h" #include "row0types.h" #include "mtr0mtr.h" +#include "fil0crypt.h" /*********************************************************************//** Creates a table create graph. @@ -43,8 +44,10 @@ tab_create_graph_create( dict_table_t* table, /*!< in: table to create, built as a memory data structure */ mem_heap_t* heap, /*!< in: heap where created */ - bool commit);/*!< in: true if the commit node should be + bool commit, /*!< in: true if the commit node should be added to the query graph */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id);/*!< in: encryption key_id */ /*********************************************************************//** Creates an index create graph. @return own: index create node */ @@ -197,6 +200,8 @@ struct tab_node_t{ /* Local storage for this graph node */ ulint state; /*!< node execution state */ ulint col_no; /*!< next column definition to insert */ + ulint key_id; /*!< encryption key_id */ + fil_encryption_t mode; /*!< encryption mode */ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */ }; diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 6922a551f06..34452badc9f 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -66,17 +66,20 @@ struct key_struct struct fil_space_rotate_state_t { - time_t start_time; // time when rotation started - ulint active_threads; // active threads in space - ulint next_offset; // next "free" offset - ulint max_offset; // max offset needing to be rotated - uint min_key_version_found; // min key version found but not rotated - lsn_t end_lsn; // max lsn created when rotating this space - bool starting; // initial write of IV - bool flushing; // space is being flushed at end of rotate + time_t start_time; /*!< time when rotation started */ + ulint active_threads; /*!< active threads in space */ + ulint next_offset; /*!< next "free" offset */ + ulint max_offset; /*!< max offset needing to be rotated */ + uint min_key_version_found; /*!< min key version found but not + rotated */ + lsn_t end_lsn; /*!< max lsn created when rotating this + space */ + bool starting; /*!< initial write of IV */ + bool flushing; /*!< space is being flushed at end of rotate */ struct { - bool is_active; // is scrubbing active in this space - time_t last_scrub_completed; // when was last scrub completed + bool is_active; /*!< is scrubbing active in this space */ + time_t last_scrub_completed; /*!< when was last scrub + completed */ } scrubbing; }; diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index a3785292115..93ff999bcfe 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -774,6 +774,9 @@ char* fil_read_link_file( /*===============*/ const char* name); /*!< in: tablespace name */ + +#include "fil0crypt.h" + /*******************************************************************//** Creates a new single-table tablespace to a database directory of MySQL. Database directories are under the 'datadir' of MySQL. The datadir is the @@ -792,9 +795,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 */ __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************************//** diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 440001410f0..7fda64e21b7 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -35,6 +35,7 @@ Created 9/17/2000 Heikki Tuuri #include "row0types.h" #include "btr0pcur.h" #include "trx0types.h" +#include "fil0crypt.h" // Forward declaration struct SysIndexCallback; @@ -386,7 +387,9 @@ row_create_table_for_mysql( (will be freed, or on DB_SUCCESS added to the data dictionary cache) */ trx_t* trx, /*!< in/out: transaction */ - bool commit) /*!< in: if true, commit the transaction */ + bool commit, /*!< in: if true, commit the transaction */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Does an index creation operation for MySQL. TODO: currently failure diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index c87e1f8e247..da08939d78a 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -2019,7 +2019,8 @@ pars_create_table( column = static_cast<sym_node_t*>(que_node_get_next(column)); } - node = tab_create_graph_create(table, pars_sym_tab_global->heap, true); + node = tab_create_graph_create(table, pars_sym_tab_global->heap, true, + FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); table_sym->resolved = TRUE; table_sym->token_type = SYM_TABLE; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index cab7621a0d4..9ed14ffc9cb 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2211,7 +2211,9 @@ row_create_table_for_mysql( (will be freed, or on DB_SUCCESS added to the data dictionary cache) */ trx_t* trx, /*!< in/out: transaction */ - bool commit) /*!< in: if true, commit the transaction */ + bool commit, /*!< in: if true, commit the transaction */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { tab_node_t* node; mem_heap_t* heap; @@ -2324,7 +2326,7 @@ err_exit: ut_ad(strstr(table->name, "/FTS_") != NULL); } - node = tab_create_graph_create(table, heap, commit); + node = tab_create_graph_create(table, heap, commit, mode, key_id); thr = pars_complete_graph_for_exec(node, trx, heap); @@ -3461,10 +3463,19 @@ row_truncate_table_for_mysql( if (table->space && !DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) { /* Discard and create the single-table tablespace. */ + fil_space_crypt_t* crypt_data; ulint space = table->space; ulint flags = fil_space_get_flags(space); + ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; + fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; dict_get_and_save_data_dir_path(table, true); + crypt_data = fil_space_get_crypt_data(space); + + if (crypt_data) { + key_id = crypt_data->key_id; + mode = crypt_data->encryption; + } if (flags != ULINT_UNDEFINED && fil_discard_tablespace(space) == DB_SUCCESS) { @@ -3483,7 +3494,8 @@ row_truncate_table_for_mysql( space, table->name, table->data_dir_path, flags, table->flags2, - FIL_IBD_FILE_INITIAL_SIZE) + FIL_IBD_FILE_INITIAL_SIZE, + mode, key_id) != DB_SUCCESS) { dict_table_x_unlock_indexes(table); diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc index 30523ff2af4..36a30cb75b7 100644 --- a/storage/xtradb/dict/dict0crea.cc +++ b/storage/xtradb/dict/dict0crea.cc @@ -309,7 +309,8 @@ dict_build_table_def_step( space, table->name, path, dict_tf_to_fsp_flags(table->flags), table->flags2, - FIL_IBD_FILE_INITIAL_SIZE); + FIL_IBD_FILE_INITIAL_SIZE, + node->mode, node->key_id); table->space = (unsigned int) space; @@ -934,8 +935,10 @@ tab_create_graph_create( dict_table_t* table, /*!< in: table to create, built as a memory data structure */ mem_heap_t* heap, /*!< in: heap where created */ - bool commit) /*!< in: true if the commit node should be + bool commit, /*!< in: true if the commit node should be added to the query graph */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { tab_node_t* node; @@ -948,6 +951,8 @@ tab_create_graph_create( node->state = TABLE_BUILD_TABLE_DEF; node->heap = mem_heap_create(256); + node->mode = mode; + node->key_id = key_id; node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables, heap); @@ -1042,7 +1047,6 @@ dict_create_table_step( /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ err = dict_build_table_def_step(thr, node); - if (err != DB_SUCCESS) { goto function_exit; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 6d66fa64761..3fc9506a15a 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -2426,7 +2426,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; } } @@ -3365,9 +3367,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; @@ -3534,7 +3538,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; diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 5adda1fad6c..7a381f4ca05 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1981,7 +1981,7 @@ fts_create_one_index_table( dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB, 4130048, 0); - error = row_create_table_for_mysql(new_table, trx, false); + error = row_create_table_for_mysql(new_table, trx, false, FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); if (error != DB_SUCCESS) { trx->error_state = error; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 6ee8d397368..a7f5653c389 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -10832,7 +10832,9 @@ create_table_def( is a zero length-string */ const char* remote_path, /*!< in: Remote path or zero length-string */ ulint flags, /*!< in: table flags */ - ulint flags2) /*!< in: table flags2 */ + ulint flags2, /*!< in: table flags2 */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { THD* thd = trx->mysql_thd; dict_table_t* table; @@ -11013,7 +11015,7 @@ err_col: fts_add_doc_id_column(table, heap); } - err = row_create_table_for_mysql(table, trx, false); + err = row_create_table_for_mysql(table, trx, false, mode, key_id); mem_heap_free(heap); @@ -12094,7 +12096,7 @@ ha_innobase::create( row_mysql_lock_data_dictionary(trx); error = create_table_def(trx, form, norm_name, temp_path, - remote_path, flags, flags2); + remote_path, flags, flags2, encrypt, key_id); if (error) { goto cleanup; } @@ -12254,48 +12256,6 @@ ha_innobase::create( DBUG_ASSERT(innobase_table != 0); - /* If user has requested that table should be encrypted or table - should remain as unencrypted store crypt data */ - if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) { - ulint maxsize=0; - ulint zip_size = fil_space_get_zip_size(innobase_table->space); - fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space); - fil_space_crypt_t* crypt_data; - - crypt_data = fil_space_create_crypt_data(encrypt, key_id); - crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); - crypt_data->encryption = encrypt; - - /* If there is old crypt data, copy IV */ - if (old_crypt_data) { - memcpy(crypt_data->iv, old_crypt_data->iv, sizeof(crypt_data->iv)); - } - - mtr_t mtr; - mtr_start(&mtr); - /* Get page 0*/ - ulint offset = 0; - buf_block_t* block = buf_page_get_gen(innobase_table->space, - zip_size, - offset, - RW_X_LATCH, - NULL, - BUF_GET, - __FILE__, __LINE__, - &mtr); - - /* Set up new crypt data */ - crypt_data = fil_space_set_crypt_data(innobase_table->space, crypt_data); - - /* Compute location to store crypt data */ - byte* frame = buf_block_get_frame(block); - - /* Write crypt data to page 0 */ - fil_space_write_crypt_data(innobase_table->space, frame, crypt_data->page0_offset, maxsize, &mtr); - - mtr_commit(&mtr); - } - innobase_copy_frm_flags_from_create_info(innobase_table, create_info); dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index f791a4dcd2e..7f5ee15049e 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -2803,6 +2803,7 @@ prepare_inplace_alter_table_dict( to rebuild the table with a temporary name. */ if (new_clustered) { + fil_space_crypt_t* crypt_data; const char* new_table_name = dict_mem_create_temporary_tablename( ctx->heap, @@ -2810,6 +2811,15 @@ prepare_inplace_alter_table_dict( ctx->new_table->id); ulint n_cols; dtuple_t* add_cols; + ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; + fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; + + crypt_data = fil_space_get_crypt_data(ctx->prebuilt->table->space); + + if (crypt_data) { + key_id = crypt_data->key_id; + mode = crypt_data->encryption; + } if (innobase_check_foreigns( ha_alter_info, altered_table, old_table, @@ -2941,7 +2951,7 @@ prepare_inplace_alter_table_dict( } error = row_create_table_for_mysql( - ctx->new_table, ctx->trx, false); + ctx->new_table, ctx->trx, false, mode, key_id); switch (error) { dict_table_t* temp_table; diff --git a/storage/xtradb/include/dict0crea.h b/storage/xtradb/include/dict0crea.h index 67eab9058da..c40e5356ece 100644 --- a/storage/xtradb/include/dict0crea.h +++ b/storage/xtradb/include/dict0crea.h @@ -32,6 +32,7 @@ Created 1/8/1996 Heikki Tuuri #include "que0types.h" #include "row0types.h" #include "mtr0mtr.h" +#include "fil0crypt.h" /*********************************************************************//** Creates a table create graph. @@ -43,8 +44,10 @@ tab_create_graph_create( dict_table_t* table, /*!< in: table to create, built as a memory data structure */ mem_heap_t* heap, /*!< in: heap where created */ - bool commit);/*!< in: true if the commit node should be + bool commit, /*!< in: true if the commit node should be added to the query graph */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id);/*!< in: encryption key_id */ /*********************************************************************//** Creates an index create graph. @return own: index create node */ @@ -197,6 +200,8 @@ struct tab_node_t{ /* Local storage for this graph node */ ulint state; /*!< node execution state */ ulint col_no; /*!< next column definition to insert */ + ulint key_id; /*!< encryption key_id */ + fil_encryption_t mode; /*!< encryption mode */ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */ }; diff --git a/storage/xtradb/include/fil0crypt.h b/storage/xtradb/include/fil0crypt.h index 5936d43769d..4fd41d4b789 100644 --- a/storage/xtradb/include/fil0crypt.h +++ b/storage/xtradb/include/fil0crypt.h @@ -66,17 +66,20 @@ struct key_struct struct fil_space_rotate_state_t { - time_t start_time; // time when rotation started - ulint active_threads; // active threads in space - ulint next_offset; // next "free" offset - ulint max_offset; // max offset needing to be rotated - uint min_key_version_found; // min key version found but not rotated - lsn_t end_lsn; // max lsn created when rotating this space - bool starting; // initial write of IV - bool flushing; // space is being flushed at end of rotate + time_t start_time; /*!< time when rotation started */ + ulint active_threads; /*!< active threads in space */ + ulint next_offset; /*!< next "free" offset */ + ulint max_offset; /*!< max offset needing to be rotated */ + uint min_key_version_found; /*!< min key version found but not + rotated */ + lsn_t end_lsn; /*!< max lsn created when rotating this + space */ + bool starting; /*!< initial write of IV */ + bool flushing; /*!< space is being flushed at end of rotate */ struct { - bool is_active; // is scrubbing active in this space - time_t last_scrub_completed; // when was last scrub completed + bool is_active; /*!< is scrubbing active in this space */ + time_t last_scrub_completed; /*!< when was last scrub + completed */ } scrubbing; }; diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index cfada67ce14..66ceffbed26 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -769,6 +769,9 @@ char* fil_read_link_file( /*===============*/ const char* name); /*!< in: tablespace name */ + +#include "fil0crypt.h" + /*******************************************************************//** Creates a new single-table tablespace to a database directory of MySQL. Database directories are under the 'datadir' of MySQL. The datadir is the @@ -787,9 +790,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 */ __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************************//** diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index ab61459cae7..a0ff6cdad15 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -35,6 +35,7 @@ Created 9/17/2000 Heikki Tuuri #include "row0types.h" #include "btr0pcur.h" #include "trx0types.h" +#include "fil0crypt.h" // Forward declaration struct SysIndexCallback; @@ -386,7 +387,9 @@ row_create_table_for_mysql( (will be freed, or on DB_SUCCESS added to the data dictionary cache) */ trx_t* trx, /*!< in/out: transaction */ - bool commit) /*!< in: if true, commit the transaction */ + bool commit, /*!< in: if true, commit the transaction */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Does an index creation operation for MySQL. TODO: currently failure diff --git a/storage/xtradb/pars/pars0pars.cc b/storage/xtradb/pars/pars0pars.cc index c87e1f8e247..da08939d78a 100644 --- a/storage/xtradb/pars/pars0pars.cc +++ b/storage/xtradb/pars/pars0pars.cc @@ -2019,7 +2019,8 @@ pars_create_table( column = static_cast<sym_node_t*>(que_node_get_next(column)); } - node = tab_create_graph_create(table, pars_sym_tab_global->heap, true); + node = tab_create_graph_create(table, pars_sym_tab_global->heap, true, + FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); table_sym->resolved = TRUE; table_sym->token_type = SYM_TABLE; diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 4fc301111c9..efc5c568cd5 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -2232,7 +2232,9 @@ row_create_table_for_mysql( (will be freed, or on DB_SUCCESS added to the data dictionary cache) */ trx_t* trx, /*!< in/out: transaction */ - bool commit) /*!< in: if true, commit the transaction */ + bool commit, /*!< in: if true, commit the transaction */ + fil_encryption_t mode, /*!< in: encryption mode */ + ulint key_id) /*!< in: encryption key_id */ { tab_node_t* node; mem_heap_t* heap; @@ -2349,7 +2351,7 @@ err_exit: ut_ad(strstr(table->name, "/FTS_") != NULL); } - node = tab_create_graph_create(table, heap, commit); + node = tab_create_graph_create(table, heap, commit, mode, key_id); thr = pars_complete_graph_for_exec(node, trx, heap); @@ -3496,10 +3498,19 @@ row_truncate_table_for_mysql( if (table->space && !DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) { /* Discard and create the single-table tablespace. */ + fil_space_crypt_t* crypt_data; ulint space = table->space; ulint flags = fil_space_get_flags(space); + ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; + fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; dict_get_and_save_data_dir_path(table, true); + crypt_data = fil_space_get_crypt_data(space); + + if (crypt_data) { + key_id = crypt_data->key_id; + mode = crypt_data->encryption; + } if (flags != ULINT_UNDEFINED && fil_discard_tablespace(space) == DB_SUCCESS) { @@ -3518,7 +3529,8 @@ row_truncate_table_for_mysql( space, table->name, table->data_dir_path, flags, table->flags2, - FIL_IBD_FILE_INITIAL_SIZE) + FIL_IBD_FILE_INITIAL_SIZE, + mode, key_id) != DB_SUCCESS) { dict_table_x_unlock_indexes(table); |