diff options
Diffstat (limited to 'storage/innobase/handler')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 93 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.h | 9 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 6 | ||||
-rw-r--r-- | storage/innobase/handler/i_s.cc | 112 |
4 files changed, 150 insertions, 70 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 79056f949ba..869864e303c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1184,6 +1184,9 @@ static SHOW_VAR innodb_status_variables[]= { {"encryption_rotation_estimated_iops", (char*) &export_vars.innodb_encryption_rotation_estimated_iops, SHOW_LONG}, + {"encryption_key_rotation_list_length", + (char*)&export_vars.innodb_key_rotation_list_length, + SHOW_LONGLONG}, /* scrubing */ {"scrub_background_page_reorganizations", @@ -1936,6 +1939,15 @@ thd_has_edited_nontrans_tables( return((ibool) thd_non_transactional_update(thd)); } +/* Return high resolution timestamp for the start of the current query */ +UNIV_INTERN +unsigned long long +thd_query_start_micro( + const THD* thd) /*!< in: thread handle */ +{ + return thd_start_utime(thd); +} + /******************************************************************//** Returns true if the thread is executing a SELECT statement. @return true if thd is executing SELECT */ @@ -12402,7 +12414,7 @@ create_table_info_t::check_table_options() enum row_type row_format = m_form->s->row_type; ha_table_option_struct *options= m_form->s->option_struct; fil_encryption_t encrypt = (fil_encryption_t)options->encryption; - bool should_encrypt = (encrypt == FIL_SPACE_ENCRYPTION_ON); + bool should_encrypt = (encrypt == FIL_ENCRYPTION_ON); /* Currently we do not support encryption for spatial indexes thus do not allow creating table with forced @@ -12418,7 +12430,7 @@ create_table_info_t::check_table_options() } } - if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT && !m_allow_file_per_table) { + if (encrypt != FIL_ENCRYPTION_DEFAULT && !m_allow_file_per_table) { push_warning( m_thd, Sql_condition::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, @@ -12426,7 +12438,7 @@ create_table_info_t::check_table_options() return "ENCRYPTED"; } - if (encrypt == FIL_SPACE_ENCRYPTION_OFF && srv_encrypt_tables == 2) { + if (encrypt == FIL_ENCRYPTION_OFF && srv_encrypt_tables == 2) { push_warning( m_thd, Sql_condition::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, @@ -12507,8 +12519,8 @@ create_table_info_t::check_table_options() } /* If encryption is set up make sure that used key_id is found */ - if (encrypt == FIL_SPACE_ENCRYPTION_ON || - (encrypt == FIL_SPACE_ENCRYPTION_DEFAULT && srv_encrypt_tables)) { + if (encrypt == FIL_ENCRYPTION_ON || + (encrypt == FIL_ENCRYPTION_DEFAULT && srv_encrypt_tables)) { if (!encryption_key_id_exists((unsigned int)options->encryption_key_id)) { push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, @@ -12521,7 +12533,7 @@ create_table_info_t::check_table_options() } /* Ignore nondefault key_id if encryption is set off */ - if (encrypt == FIL_SPACE_ENCRYPTION_OFF && + if (encrypt == FIL_ENCRYPTION_OFF && options->encryption_key_id != THDVAR(m_thd, default_encryption_key_id)) { push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, @@ -12534,7 +12546,7 @@ create_table_info_t::check_table_options() /* If default encryption is used make sure that used kay is found from key file. */ - if (encrypt == FIL_SPACE_ENCRYPTION_DEFAULT && + if (encrypt == FIL_ENCRYPTION_DEFAULT && !srv_encrypt_tables && options->encryption_key_id != FIL_DEFAULT_ENCRYPTION_KEY) { if (!encryption_key_id_exists((unsigned int)options->encryption_key_id)) { @@ -20290,22 +20302,24 @@ wsrep_innobase_kill_one_trx( if (!thd) { DBUG_PRINT("wsrep", ("no thd for conflicting lock")); - WSREP_WARN("no THD for trx: %lu", (ulong) victim_trx->id); + WSREP_WARN("no THD for trx: " TRX_ID_FMT, victim_trx->id); DBUG_RETURN(1); } if (!bf_thd) { DBUG_PRINT("wsrep", ("no BF thd for conflicting lock")); - WSREP_WARN("no BF THD for trx: %lu", (bf_trx) ? (ulong) bf_trx->id : (ulong) 0); + WSREP_WARN("no BF THD for trx: " TRX_ID_FMT, + bf_trx ? bf_trx->id : 0); DBUG_RETURN(1); } WSREP_LOG_CONFLICT(bf_thd, thd, TRUE); - WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %llu", + WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: " + TRX_ID_FMT, signal, (long long)bf_seqno, thd_get_thread_id(thd), - (ulonglong) victim_trx->id); + victim_trx->id); WSREP_DEBUG("Aborting query: %s", (thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void"); @@ -20322,15 +20336,15 @@ wsrep_innobase_kill_one_trx( if (wsrep_thd_query_state(thd) == QUERY_EXITING) { - WSREP_DEBUG("kill trx EXITING for %llu", - (ulonglong) victim_trx->id); + WSREP_DEBUG("kill trx EXITING for " TRX_ID_FMT, + victim_trx->id); wsrep_thd_UNLOCK(thd); DBUG_RETURN(0); } if (wsrep_thd_exec_mode(thd) != LOCAL_STATE) { - WSREP_DEBUG("withdraw for BF trx: %llu, state: %d", - (longlong) victim_trx->id, + WSREP_DEBUG("withdraw for BF trx: " TRX_ID_FMT ", state: %d", + victim_trx->id, wsrep_thd_get_conflict_state(thd)); } @@ -20339,8 +20353,8 @@ wsrep_innobase_kill_one_trx( wsrep_thd_set_conflict_state(thd, MUST_ABORT); break; case MUST_ABORT: - WSREP_DEBUG("victim %llu in MUST ABORT state", - (longlong) victim_trx->id); + WSREP_DEBUG("victim " TRX_ID_FMT " in MUST ABORT state", + victim_trx->id); wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); DBUG_RETURN(0); @@ -20348,9 +20362,8 @@ wsrep_innobase_kill_one_trx( case ABORTED: case ABORTING: // fall through default: - WSREP_DEBUG("victim %llu in state %d", - (longlong) victim_trx->id, - wsrep_thd_get_conflict_state(thd)); + WSREP_DEBUG("victim " TRX_ID_FMT " in state %d", + victim_trx->id, wsrep_thd_get_conflict_state(thd)); wsrep_thd_UNLOCK(thd); DBUG_RETURN(0); break; @@ -20362,8 +20375,8 @@ wsrep_innobase_kill_one_trx( WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu", - (longlong) victim_trx->id); + WSREP_DEBUG("kill trx QUERY_COMMITTING for " TRX_ID_FMT, + victim_trx->id); if (wsrep_thd_exec_mode(thd) == REPL_RECV) { wsrep_abort_slave_trx(bf_seqno, @@ -20377,8 +20390,9 @@ wsrep_innobase_kill_one_trx( switch (rcode) { case WSREP_WARNING: - WSREP_DEBUG("cancel commit warning: %llu", - (ulonglong) victim_trx->id); + WSREP_DEBUG("cancel commit warning: " + TRX_ID_FMT, + victim_trx->id); wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); DBUG_RETURN(1); @@ -20387,9 +20401,9 @@ wsrep_innobase_kill_one_trx( break; default: WSREP_ERROR( - "cancel commit bad exit: %d %llu", - rcode, - (ulonglong) victim_trx->id); + "cancel commit bad exit: %d " + TRX_ID_FMT, + rcode, victim_trx->id); /* unable to interrupt, must abort */ /* note: kill_mysql() will block, if we cannot. * kill the lock holder first. @@ -20405,8 +20419,8 @@ wsrep_innobase_kill_one_trx( /* it is possible that victim trx is itself waiting for some * other lock. We need to cancel this waiting */ - WSREP_DEBUG("kill trx QUERY_EXEC for %llu", - (ulonglong) victim_trx->id); + WSREP_DEBUG("kill trx QUERY_EXEC for " TRX_ID_FMT, + victim_trx->id); victim_trx->lock.was_chosen_as_deadlock_victim= TRUE; @@ -20443,7 +20457,7 @@ wsrep_innobase_kill_one_trx( break; case QUERY_IDLE: { - WSREP_DEBUG("kill IDLE for %llu", (ulonglong) victim_trx->id); + WSREP_DEBUG("kill IDLE for " TRX_ID_FMT, victim_trx->id); if (wsrep_thd_exec_mode(thd) == REPL_RECV) { WSREP_DEBUG("kill BF IDLE, seqno: %lld", @@ -21749,10 +21763,11 @@ static MYSQL_SYSVAR_UINT(encryption_rotate_key_age, PLUGIN_VAR_RQCMDARG, "Key rotation - re-encrypt in background " "all pages that were encrypted with a key that " - "many (or more) versions behind", + "many (or more) versions behind. Value 0 indicates " + "that key rotation is disabled.", NULL, innodb_encryption_rotate_key_age_update, - srv_fil_crypt_rotate_key_age, 0, UINT_MAX32, 0); + 1, 0, UINT_MAX32, 0); static MYSQL_SYSVAR_UINT(encryption_rotation_iops, srv_n_fil_crypt_iops, PLUGIN_VAR_RQCMDARG, @@ -22992,8 +23007,9 @@ innodb_encrypt_tables_validate( for update function */ struct st_mysql_value* value) /*!< in: incoming string */ { - if (check_sysvar_enum(thd, var, save, value)) + if (check_sysvar_enum(thd, var, save, value)) { return 1; + } ulong encrypt_tables = *(ulong*)save; @@ -23005,6 +23021,17 @@ innodb_encrypt_tables_validate( "encryption plugin is not available"); return 1; } + + if (!srv_fil_crypt_rotate_key_age) { + const char *msg = (encrypt_tables ? "enable" : "disable"); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_UNSUPPORTED, + "InnoDB: cannot %s encryption, " + "innodb_encryption_rotate_key_age=0" + " i.e. key rotation disabled", msg); + return 1; + } + return 0; } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 49eb150036b..463717ee6b2 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -549,6 +549,14 @@ int thd_slave_thread(const MYSQL_THD thd); @retval 1 the user thread is running a non-transactional update */ int thd_non_transactional_update(const MYSQL_THD thd); +/** Get high resolution timestamp for the current query start time. +The timestamp is not anchored to any specific point in time, +but can be used for comparison. +@param thd user thread +@retval timestamp in microseconds precision +*/ +unsigned long long thd_start_utime(const MYSQL_THD thd); + /** Get the user thread's binary logging format @param thd user thread @return Value to be used as index into the binlog_format_names array */ @@ -1022,4 +1030,3 @@ ib_push_frm_error( TABLE* table, /*!< in: MySQL table */ ulint n_keys, /*!< in: InnoDB #keys */ bool push_warning); /*!< in: print warning ? */ - diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 82fa4b724f4..fd61db9725d 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4532,9 +4532,11 @@ prepare_inplace_alter_table_dict( ulint space_id = 0; ulint z = 0; ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; - fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; + fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT; - crypt_data = fil_space_get_crypt_data(ctx->prebuilt->table->space); + fil_space_t* space = fil_space_acquire(ctx->prebuilt->table->space); + crypt_data = space->crypt_data; + fil_space_release(space); if (crypt_data) { key_id = crypt_data->key_id; diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index dd43a52ae66..6bf16573efd 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -8560,22 +8560,31 @@ static ST_FIELD_INFO innodb_tablespaces_encryption_fields_info[] = STRUCT_FLD(old_name, ""), STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, +#define TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING 9 + {STRUCT_FLD(field_name, "ROTATING_OR_FLUSHING"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + END_OF_ST_FIELD_INFO }; /**********************************************************************//** Function to fill INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION -with information collected by scanning SYS_TABLESPACES table and then use -fil_space() +with information collected by scanning SYS_TABLESPACES table. +@param[in] thd thread handle +@param[in] space Tablespace +@param[in] table_to_fill I_S table to fill @return 0 on success */ static int i_s_dict_fill_tablespaces_encryption( -/*==========================*/ - THD* thd, /*!< in: thread */ - ulint space, /*!< in: space ID */ - const char* name, /*!< in: tablespace name */ - TABLE* table_to_fill) /*!< in/out: fill this table */ + THD* thd, + fil_space_t* space, + TABLE* table_to_fill) { Field** fields; struct fil_space_crypt_status_t status; @@ -8585,10 +8594,11 @@ i_s_dict_fill_tablespaces_encryption( fields = table_to_fill->field; fil_space_crypt_get_status(space, &status); - OK(fields[TABLESPACES_ENCRYPTION_SPACE]->store(space)); + + OK(fields[TABLESPACES_ENCRYPTION_SPACE]->store(space->id)); OK(field_store_string(fields[TABLESPACES_ENCRYPTION_NAME], - name)); + space->name)); OK(fields[TABLESPACES_ENCRYPTION_ENCRYPTION_SCHEME]->store( status.scheme)); @@ -8600,6 +8610,9 @@ i_s_dict_fill_tablespaces_encryption( status.current_key_version)); OK(fields[TABLESPACES_ENCRYPTION_CURRENT_KEY_ID]->store( status.key_id)); + OK(fields[TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING]->store( + (status.rotating || status.flushing) ? 1 : 0)); + if (status.rotating) { fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER]->set_notnull(); OK(fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER]->store( @@ -8613,6 +8626,7 @@ i_s_dict_fill_tablespaces_encryption( fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_MAX_PAGE_NUMBER] ->set_null(); } + OK(schema_table_store_record(thd, table_to_fill)); DBUG_RETURN(0); @@ -8652,30 +8666,36 @@ i_s_tablespaces_encryption_fill_table( while (rec) { const char* err_msg; - ulint space; + ulint space_id; const char* name; ulint flags; /* Extract necessary information from a SYS_TABLESPACES row */ err_msg = dict_process_sys_tablespaces( - heap, rec, &space, &name, &flags); + heap, rec, &space_id, &name, &flags); mtr_commit(&mtr); mutex_exit(&dict_sys->mutex); - if (space == 0) { + if (space_id == 0) { found_space_0 = true; } - if (!err_msg) { + fil_space_t* space = fil_space_acquire_silent(space_id); + + if (!err_msg && space) { i_s_dict_fill_tablespaces_encryption( - thd, space, name, tables->table); + thd, space, tables->table); } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", err_msg); } + if (space) { + fil_space_release(space); + } + mem_heap_empty(heap); /* Get the next record */ @@ -8691,10 +8711,13 @@ i_s_tablespaces_encryption_fill_table( if (found_space_0 == false) { /* space 0 does for what ever unknown reason not show up * in iteration above, add it manually */ - ulint space = 0; - const char* name = NULL; + + fil_space_t* space = fil_space_acquire_silent(0); + i_s_dict_fill_tablespaces_encryption( - thd, space, name, tables->table); + thd, space, tables->table); + + fil_space_release(space); } DBUG_RETURN(0); @@ -8845,22 +8868,32 @@ static ST_FIELD_INFO innodb_tablespaces_scrubbing_fields_info[] = STRUCT_FLD(old_name, ""), STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, +#define TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING 9 + {STRUCT_FLD(field_name, "ROTATING_OR_FLUSHING"), + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + END_OF_ST_FIELD_INFO }; /**********************************************************************//** Function to fill INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING -with information collected by scanning SYS_TABLESPACES table and then use -fil_space() +with information collected by scanning SYS_TABLESPACES table and +fil_space. +@param[in] thd Thread handle +@param[in] space Tablespace +@param[in] table_to_fill I_S table @return 0 on success */ static int i_s_dict_fill_tablespaces_scrubbing( -/*==========================*/ - THD* thd, /*!< in: thread */ - ulint space, /*!< in: space ID */ - const char* name, /*!< in: tablespace name */ - TABLE* table_to_fill) /*!< in/out: fill this table */ + THD* thd, + fil_space_t* space, + TABLE* table_to_fill) { Field** fields; struct fil_space_scrub_status_t status; @@ -8870,10 +8903,11 @@ i_s_dict_fill_tablespaces_scrubbing( fields = table_to_fill->field; fil_space_get_scrub_status(space, &status); - OK(fields[TABLESPACES_SCRUBBING_SPACE]->store(space)); + + OK(fields[TABLESPACES_SCRUBBING_SPACE]->store(space->id)); OK(field_store_string(fields[TABLESPACES_SCRUBBING_NAME], - name)); + space->name)); OK(fields[TABLESPACES_SCRUBBING_COMPRESSED]->store( status.compressed ? 1 : 0)); @@ -8893,6 +8927,7 @@ i_s_dict_fill_tablespaces_scrubbing( TABLESPACES_SCRUBBING_CURRENT_SCRUB_ACTIVE_THREADS, TABLESPACES_SCRUBBING_CURRENT_SCRUB_PAGE_NUMBER, TABLESPACES_SCRUBBING_CURRENT_SCRUB_MAX_PAGE_NUMBER }; + if (status.scrubbing) { for (uint i = 0; i < array_elements(field_numbers); i++) { fields[field_numbers[i]]->set_notnull(); @@ -8912,6 +8947,7 @@ i_s_dict_fill_tablespaces_scrubbing( fields[field_numbers[i]]->set_null(); } } + OK(schema_table_store_record(thd, table_to_fill)); DBUG_RETURN(0); @@ -8951,30 +8987,36 @@ i_s_tablespaces_scrubbing_fill_table( while (rec) { const char* err_msg; - ulint space; + ulint space_id; const char* name; ulint flags; /* Extract necessary information from a SYS_TABLESPACES row */ err_msg = dict_process_sys_tablespaces( - heap, rec, &space, &name, &flags); + heap, rec, &space_id, &name, &flags); mtr_commit(&mtr); mutex_exit(&dict_sys->mutex); - if (space == 0) { + if (space_id == 0) { found_space_0 = true; } - if (!err_msg) { + fil_space_t* space = fil_space_acquire_silent(space_id); + + if (!err_msg && space) { i_s_dict_fill_tablespaces_scrubbing( - thd, space, name, tables->table); + thd, space, tables->table); } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", err_msg); } + if (space) { + fil_space_release(space); + } + mem_heap_empty(heap); /* Get the next record */ @@ -8990,10 +9032,12 @@ i_s_tablespaces_scrubbing_fill_table( if (found_space_0 == false) { /* space 0 does for what ever unknown reason not show up * in iteration above, add it manually */ - ulint space = 0; - const char* name = NULL; + fil_space_t* space = fil_space_acquire_silent(0); + i_s_dict_fill_tablespaces_scrubbing( - thd, space, name, tables->table); + thd, space, tables->table); + + fil_space_release(space); } DBUG_RETURN(0); |