summaryrefslogtreecommitdiff
path: root/storage/innobase/handler
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/handler')
-rw-r--r--storage/innobase/handler/ha_innodb.cc93
-rw-r--r--storage/innobase/handler/ha_innodb.h9
-rw-r--r--storage/innobase/handler/handler0alter.cc6
-rw-r--r--storage/innobase/handler/i_s.cc112
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);