赞
踩
events_transactions_current是performance_schema中记录事务状态信息的表,它除了可以记录普通事务以外,还可以记录MySQL中的XA事务。
表结构如下:
mysql> show create table performance_schema.events_transactions_current\G *************************** 1. row *************************** Table: events_transactions_current Create Table: CREATE TABLE `events_transactions_current` ( `THREAD_ID` bigint(20) unsigned NOT NULL, `EVENT_ID` bigint(20) unsigned NOT NULL, `END_EVENT_ID` bigint(20) unsigned DEFAULT NULL, `EVENT_NAME` varchar(128) NOT NULL, `STATE` enum('ACTIVE','COMMITTED','ROLLED BACK') DEFAULT NULL, `TRX_ID` bigint(20) unsigned DEFAULT NULL, `GTID` varchar(64) DEFAULT NULL, `XID_FORMAT_ID` int(11) DEFAULT NULL, `XID_GTRID` varchar(130) DEFAULT NULL, `XID_BQUAL` varchar(130) DEFAULT NULL, `XA_STATE` varchar(64) DEFAULT NULL, `SOURCE` varchar(64) DEFAULT NULL, `TIMER_START` bigint(20) unsigned DEFAULT NULL, `TIMER_END` bigint(20) unsigned DEFAULT NULL, `TIMER_WAIT` bigint(20) unsigned DEFAULT NULL, `ACCESS_MODE` enum('READ ONLY','READ WRITE') DEFAULT NULL, `ISOLATION_LEVEL` varchar(64) DEFAULT NULL, `AUTOCOMMIT` enum('YES','NO') NOT NULL, `NUMBER_OF_SAVEPOINTS` bigint(20) unsigned DEFAULT NULL, `NUMBER_OF_ROLLBACK_TO_SAVEPOINT` bigint(20) unsigned DEFAULT NULL, `NUMBER_OF_RELEASE_SAVEPOINT` bigint(20) unsigned DEFAULT NULL, `OBJECT_INSTANCE_BEGIN` bigint(20) unsigned DEFAULT NULL, `NESTING_EVENT_ID` bigint(20) unsigned DEFAULT NULL, `NESTING_EVENT_TYPE` enum('TRANSACTION','STATEMENT','STAGE','WAIT') DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
总共有24个字段。
此表对应performance_schema存储引擎的struct row_events_transactions,如下 :
/** A row of table_events_transactions_common. */ struct row_events_transactions { /** Column THREAD_ID. */ ulonglong m_thread_internal_id; /** Column EVENT_ID. */ ulonglong m_event_id; /** Column END_EVENT_ID. */ ulonglong m_end_event_id; /** Column NESTING_EVENT_ID. */ ulonglong m_nesting_event_id; /** Column NESTING_EVENT_TYPE. */ enum_event_type m_nesting_event_type; /** Column EVENT_NAME. */ const char *m_name; /** Length in bytes of @c m_name. */ uint m_name_length; /** Column TIMER_START. */ ulonglong m_timer_start; /** Column TIMER_END. */ ulonglong m_timer_end; /** Column TIMER_WAIT. */ ulonglong m_timer_wait; /** Column SOURCE. */ char m_source[COL_SOURCE_SIZE]; /** Length in bytes of @c m_source. */ uint m_source_length; /** InnoDB transaction id. */ ulonglong m_trxid; /** Transaction state. */ enum_transaction_state m_state; /** Global Transaction ID. */ char m_gtid[Gtid_specification::MAX_TEXT_LENGTH + 1]; /** GTID length in bytes*/ int m_gtid_length; /** XA transaction ID. */ PSI_xid m_xid; /** XA transaction state. */ enum_xa_transaction_state m_xa_state; /** True if XA transaction. */ bool m_xa; /** True if autocommit transaction. */ bool m_autocommit; /** Isolation level. */ enum_isolation_level m_isolation_level; /** True if read-only, read-write otherwise. */ bool m_read_only; /** Column NUMBER_OF_SAVEPOINTS. */ ulonglong m_savepoint_count; /** Column NUMBER_OF_ROLLBACK_TO_SAVEPOINT. */ ulonglong m_rollback_to_savepoint_count; /** Column NUMBER_OF_RELEASE_SAVEPOINT. */ ulonglong m_release_savepoint_count; };
row_events_transactions的信息由每一个客户端线程独立维护,如下:
class THD :public MDL_context_owner,
public Query_arena,
public Open_tables_state
{
...
/** Current transaction instrumentation. */
PSI_transaction_locker *m_transaction_psi;
...
}
但是m_transaction_psi只记录了如下信息,并没有覆盖到row_events_transactions的所有信息,:
/** A transaction record. */ struct PFS_events_transactions : public PFS_events { /** Source identifier, mapped from internal format. */ rpl_sid m_sid; /** InnoDB transaction ID. */ ulonglong m_trxid; /** Status */ enum_transaction_state m_state; /** Global Transaction ID specifier. */ Gtid_specification m_gtid_spec; /** True if XA transaction. */ my_bool m_xa; /** XA transaction ID. */ PSI_xid m_xid; /** XA status */ enum_xa_transaction_state m_xa_state; /** Transaction isolation level. */ enum_isolation_level m_isolation_level; /** True if read-only transaction, otherwise read-write. */ my_bool m_read_only; /** True if autocommit transaction. */ my_bool m_autocommit; /** Total number of savepoints. */ ulonglong m_savepoint_count; /** Number of rollback_to_savepoint. */ ulonglong m_rollback_to_savepoint_count; /** Number of release_savepoint. */ ulonglong m_release_savepoint_count; };
其它信息比如表示m_timer_end是在由用户查询此表时计算的。
当我们开启监控时,需要对m_transaction_psi进行写入,其过程如下:
...
Sql_cmd_xa_start::execute(THD*)
Sql_cmd_xa_start::trans_xa_start(THD*)
inline_mysql_set_transaction_xid(PSI_transaction_locker*, void const*, int)
::pfs_set_transaction_xid_v1(PSI_transaction_locker *, const void *, int)
函数pfs_set_transaction_xid_v1的主要作用是写入事务的xid,实现如下:
void pfs_set_transaction_xid_v1(PSI_transaction_locker *locker, const void *xid, int xa_state) { PSI_transaction_locker_state *state= reinterpret_cast<PSI_transaction_locker_state*> (locker); DBUG_ASSERT(state != NULL); if (state->m_flags & STATE_FLAG_EVENT) { PFS_events_transactions *pfs= reinterpret_cast<PFS_events_transactions*> (state->m_transaction); DBUG_ASSERT(pfs != NULL); DBUG_ASSERT(xid != NULL); pfs->m_xid= *(PSI_xid *)xid; pfs->m_xa_state= (enum_xa_transaction_state)xa_state; pfs->m_xa= true; } return; }
下面来看下查询的过程:
handle_query(THD*, LEX*, Query_result*, unsigned long long, unsigned long long)
...
handler::ha_rnd_next(unsigned char*)
ha_perfschema::rnd_next(unsigned char*)
table_events_transactions_current::rnd_next()
table_events_transactions_common::make_row(PFS_events_transactions*)
通过table_events_transactions_common::make_row(PFS_events_transactions *transaction)函数根据PSI_transaction_locker中的信息生成行数据返回给客户端,感兴趣的读者可以继续阅读函数table_events_transactions_common::make_row(PFS_events_transactions *transaction)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。