diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2016-09-22 05:56:34 +0000 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2017-05-05 20:36:07 +0300 |
commit | 84e1971128156b366ac1f2e8476a8001008e36c7 (patch) | |
tree | 2520727c28a124c00d4bfe5e74ccf1cbc701b111 /storage/innobase/handler/i_s.cc | |
parent | bd0b21d22cd76a0f52fde3942721cc2331d4be46 (diff) | |
download | mariadb-git-84e1971128156b366ac1f2e8476a8001008e36c7.tar.gz |
IB: 0.2 part I
* SYS_VTQ internal InnoDB table;
* I_S.INNODB_SYS_VTQ table;
* vers_notify_vtq(): add record to SYS_VTQ on versioned DML;
* SYS_VTQ columns filled: TRX_ID, BEGIN_TS.
Diffstat (limited to 'storage/innobase/handler/i_s.cc')
-rw-r--r-- | storage/innobase/handler/i_s.cc | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 6bf16573efd..d53f4fe9df2 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -347,6 +347,54 @@ field_store_ulint( # define I_S_AHI 0 /* Omit the IS_HASHED column */ #endif +/*******************************************************************//** +Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field. +If the value is UINT64_UNDEFINED then the field it set to NULL. +@return 0 on success */ +int +field_store_ullong( +/*==============*/ + Field* field, /*!< in/out: target field for storage */ + ullong n) /*!< in: value to store */ +{ + int ret; + + if (n != UINT64_UNDEFINED) { + ret = field->store(n, 1); + field->set_notnull(); + } else { + ret = 0; /* success */ + field->set_null(); + } + + return(ret); +} + +/*******************************************************************//** +Auxiliary function to store packed timestamp value in MYSQL_TYPE_DATETIME field. +If the value is ULINT_UNDEFINED then the field it set to NULL. +@return 0 on success */ +int +field_store_packed_ts( +/*==============*/ +Field* field, /*!< in/out: target field for storage */ +ullong n) /*!< in: value to store */ +{ + int ret; + MYSQL_TIME tmp; + + if (n != UINT64_UNDEFINED) { + unpack_time(n, &tmp); + ret = field->store_time(&tmp); + field->set_notnull(); + } else { + ret = 0; /* success */ + field->set_null(); + } + + return(ret); +} + /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */ static ST_FIELD_INFO innodb_trx_fields_info[] = { @@ -9608,3 +9656,236 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits = STRUCT_FLD(version_info, INNODB_VERSION_STR), STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), }; + + +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_vtq */ +static ST_FIELD_INFO innodb_vtq_fields_info[] = +{ +#define SYS_VTQ_TRX_ID 0 + { STRUCT_FLD(field_name, "trx_id"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE) }, + +#define SYS_VTQ_BEGIN_TS 1 + { STRUCT_FLD(field_name, "begin_ts"), + STRUCT_FLD(field_length, 6), + STRUCT_FLD(field_type, MYSQL_TYPE_TIMESTAMP), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE) }, + +#define SYS_VTQ_COMMIT_TS 2 + { STRUCT_FLD(field_name, "commit_ts"), + STRUCT_FLD(field_length, 6), + STRUCT_FLD(field_type, MYSQL_TYPE_TIMESTAMP), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE) }, + +#define SYS_VTQ_CONCURR_TRX 3 + { STRUCT_FLD(field_name, "concurr_trx"), + STRUCT_FLD(field_length, 120), + STRUCT_FLD(field_type, MYSQL_TYPE_MEDIUM_BLOB), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE) }, + + END_OF_ST_FIELD_INFO +}; + +/**********************************************************************//** +Function to fill INFORMATION_SCHEMA.INNODB_SYS_VTQ with information +collected by scanning SYS_VTQ table. +@return 0 on success */ +static +int +i_s_dict_fill_vtq( +/*========================*/ + THD* thd, /*!< in: thread */ + ullong col_trx_id, /*!< in: table fields */ + ullong col_begin_ts, + ullong col_commit_ts, + ullong col_concurr_trx, + TABLE* table_to_fill) /*!< in/out: fill this table */ +{ + Field** fields; + + DBUG_ENTER("i_s_dict_fill_vtq"); + fields = table_to_fill->field; + + OK(field_store_ullong(fields[SYS_VTQ_TRX_ID], col_trx_id)); + OK(field_store_packed_ts(fields[SYS_VTQ_BEGIN_TS], col_begin_ts)); + OK(field_store_packed_ts(fields[SYS_VTQ_COMMIT_TS], col_commit_ts)); + OK(field_store_ullong(fields[SYS_VTQ_CONCURR_TRX], col_concurr_trx)); + + OK(schema_table_store_record(thd, table_to_fill)); + + DBUG_RETURN(0); +} + +/*******************************************************************//** +Function to populate INFORMATION_SCHEMA.INNODB_SYS_VTQ table. +Loop through each record in SYS_VTQ, and extract the column +information and fill the INFORMATION_SCHEMA.INNODB_SYS_VTQ table. +@return 0 on success */ + +static const int I_S_SYS_VTQ_LIMIT = 1000; // maximum number of records in I_S.INNODB_SYS_VTQ + +static +int +i_s_sys_vtq_fill_table( +/*=========================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + Item* ) /*!< in: condition (not used) */ +{ + btr_pcur_t pcur; + const rec_t* rec; + mem_heap_t* heap; + mtr_t mtr; + int err = 0; + + DBUG_ENTER("i_s_sys_vtq_fill_table"); + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); + + /* deny access to user without PROCESS_ACL privilege */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + heap = mem_heap_create(1000); + mutex_enter(&dict_sys->mutex); + mtr_start(&mtr); + + rec = dict_startscan_system(&pcur, &mtr, SYS_VTQ); + + for (int i = 0; rec && i < I_S_SYS_VTQ_LIMIT; ++i) { + const char* err_msg; + ullong col_trx_id; + ullong col_begin_ts; + ullong col_commit_ts; + ullong col_concurr_trx; + + /* Extract necessary information from a SYS_VTQ row */ + err_msg = dict_process_sys_vtq( + heap, + rec, + &col_trx_id, + &col_begin_ts, + &col_commit_ts, + &col_concurr_trx); + + mtr_commit(&mtr); + mutex_exit(&dict_sys->mutex); + + if (!err_msg) { + err = i_s_dict_fill_vtq( + thd, + col_trx_id, + col_begin_ts, + col_commit_ts, + col_concurr_trx, + tables->table); + } else { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_CANT_FIND_SYSTEM_REC, "%s", + err_msg); + err = 1; + } + + if (err) + break; + + mem_heap_empty(heap); + + /* Get the next record */ + mutex_enter(&dict_sys->mutex); + mtr_start(&mtr); + rec = dict_getnext_system(&pcur, &mtr); + } + + if (!err) { + mtr_commit(&mtr); + mutex_exit(&dict_sys->mutex); + } + mem_heap_free(heap); + + DBUG_RETURN(err); +} + +/*******************************************************************//** +Bind the dynamic table INFORMATION_SCHEMA.innodb_vtq +@return 0 on success */ +static +int +innodb_vtq_init( +/*===================*/ +void* p) /*!< in/out: table schema object */ +{ + ST_SCHEMA_TABLE* schema; + + DBUG_ENTER("innodb_vtq_init"); + + schema = (ST_SCHEMA_TABLE*) p; + + schema->fields_info = innodb_vtq_fields_info; + schema->fill_table = i_s_sys_vtq_fill_table; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_maria_plugin i_s_innodb_vtq = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_VTQ"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB Versioning Transaction Query table"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_vtq_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* Maria extension */ + STRUCT_FLD(version_info, INNODB_VERSION_STR), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_GAMMA), +}; |