当前位置:   article > 正文

events_transactions_current表的写入读取和存储方式

events_transactions_current

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

总共有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;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

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;    
...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

但是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;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

其它信息比如表示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)
  • 1
  • 2
  • 3
  • 4
  • 5

函数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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

数据查询过程

下面来看下查询的过程:

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*)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过table_events_transactions_common::make_row(PFS_events_transactions *transaction)函数根据PSI_transaction_locker中的信息生成行数据返回给客户端,感兴趣的读者可以继续阅读函数table_events_transactions_common::make_row(PFS_events_transactions *transaction)。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/121840
推荐阅读
相关标签
  

闽ICP备14008679号