事务结构 struct trx_t
写在前面
InnoDB是MySQL的一个存储引擎,支持事务,支持非堵塞的一致性读,物理存储结构是Page,每个事务都有回滚日志,重做日志,事务还会有死锁检测,各种各样不同的锁等等等等
翻看innodb的源码,发现数下来开启一个事务的时候,InnoDB需要处理63个变量,变量类型纷繁复杂,结构体,自定义的数据类型等等。
这次整理,我翻看了不少同行们写的博客,包括InnoDB官方博客,有一个心得是不同人的翻译不一样,尽管是官方写的博客,也会因为一些篇幅问题,减掉了一些细节的介绍。这次的整理,我特意保留了原来的英文备注,然后加上自己的理解进去。
MySQL的源码文件很多,InnoDB也不少,不过我觉得事务的结构体代码还是要理解透的,透了才能理解透事务的实现细节,更加深入认识数据库系统为了保证数据的一致性,做了多少事情....
文件地址
文件地址
storage/innobase/include/trx0trx.h
变量1 magic_n
变量类型 ulint #define ulint unsigned long
变量2 mutex
变量类型 ib_mutex_t
mutex的代码备注
Mutex protecting the fields state and lock (except some fields of lock, which are protected by lock_sys->mutex) Mutex保护字段的状态和锁定(除了某些锁定字段,由lock_sys-> mutex保护)
ib_mutex_t对应的结构体
/** InnoDB mutex */
struct ib_mutex_t {
os_event_t event; /*!< Used by sync0arr.cc for the wait queue */
volatile lock_word_t lock_word; /*!< lock_word is the target
of the atomic test-and-set instruction when
atomic operations are enabled. */
这里面又有另外一个结构体 os_event_t
/** An asynchronous signal sent between threads */
struct os_event {
#ifdef __WIN__
HANDLE handle; /*!< kernel event object, slow,
used on older Windows */
#endif
os_fast_mutex_t os_mutex; /*!< this mutex protects the next
fields */
ibool is_set; /*!< this is TRUE when the event is
in the signaled state, i.e., a thread
does not stop if it tries to wait for
this event */
ib_int64_t signal_count; /*!< this is incremented each time
the event becomes signaled */
os_cond_t cond_var; /*!< condition variable is used in
waiting for the event */
UT_LIST_NODE_T(os_event_t) os_event_list;
/*!< list of all created events */
};
变量3 state
变量类型 trx_state_t 变量备注
事务状态TRX_STATE_NOT_STARTED TRX_STATE_ACTIVE TRX_STATE_PREPARED TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED)
结构体trx_state_t的源码
/** Transaction states (trx_t::state) */
enum trx_state_t {
TRX_STATE_NOT_STARTED,
TRX_STATE_ACTIVE,
TRX_STATE_PREPARED, /* Support for 2PC/XA */
TRX_STATE_COMMITTED_IN_MEMORY
};
变量4 lock
变量类型 trx_lock_t
变量备注
Information about the transaction locks and state. Protected by trx->mutex or lock_sys->mutex or both 事务锁和状态有关的信息。 受trx-> mutex或lock_sys-> mutex或两者保护
trx_lock_t的结构体定义
struct trx_lock_t {
ulint n_active_thrs; /*!< number of active query threads */
trx_que_t que_state; /*!< valid when trx->state
== TRX_STATE_ACTIVE: TRX_QUE_RUNNING,
TRX_QUE_LOCK_WAIT, ... */
lock_t* wait_lock; /*!< if trx execution state is
TRX_QUE_LOCK_WAIT, this points to
the lock request, otherwise this is
NULL; set to non-NULL when holding
both trx->mutex and lock_sys->mutex;
set to NULL when holding
lock_sys->mutex; readers should
hold lock_sys->mutex, except when
they are holding trx->mutex and
wait_lock==NULL */
ib_uint64_t deadlock_mark; /*!< A mark field that is initialized
to and checked against lock_mark_counter
by lock_deadlock_recursive(). */
ibool was_chosen_as_deadlock_victim;
/*!< when the transaction decides to
wait for a lock, it sets this to FALSE;
if another transaction chooses this
transaction as a victim in deadlock
resolution, it sets this to TRUE.
Protected by trx->mutex. */
time_t wait_started; /*!< lock wait started at this time,
protected only by lock_sys->mutex */
que_thr_t* wait_thr; /*!< query thread belonging to this
trx that is in QUE_THR_LOCK_WAIT
state. For threads suspended in a
lock wait, this is protected by
lock_sys->mutex. Otherwise, this may
only be modified by the thread that is
serving the running transaction. */
mem_heap_t* lock_heap; /*!< memory heap for trx_locks;
protected by lock_sys->mutex */
UT_LIST_BASE_NODE_T(lock_t)
trx_locks; /*!< locks requested
by the transaction;
insertions are protected by trx->mutex
and lock_sys->mutex; removals are
protected by lock_sys->mutex */
ib_vector_t* table_locks; /*!< All table locks requested by this
transaction, including AUTOINC locks */
ibool cancel; /*!< TRUE if the transaction is being
rolled back either via deadlock
detection or due to lock timeout. The
caller has to acquire the trx_t::mutex
in order to cancel the locks. In
lock_trx_table_locks_remove() we
check for this cancel of a transaction's
locks and avoid reacquiring the trx
mutex to prevent recursive deadlocks.
Protected by both the lock sys mutex
and the trx_t::mutex. */
};
变量5 is_recovered
变量类型 ulint 变量备注
0=normal transaction, 1=recovered, must be rolled back, protected by trx_sys->mutex when trx->in_rw_trx_list holds 0 =正常事务,1 =恢复,必须回滚,当trx-> in_rw_trx_list保持时由trx_sys-> mutex保护
变量6 op_info
变量类型 const char*
变量7 isolation_level
变量类型 ulint 变量备注 READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE
变量8 is_registered:1
变量类型 unsigned 变量备注
MySQL has a transaction coordinator to coordinate two phase commit between multiple storage engines and the binary log. When an engine participates in a transaction, it's responsible for registering itself using the trans_register_ha() API. This flag is set to 1 after the transaction has been registered with the coordinator using the XA API, and is set to 0 after commit or rollback
MySQL有一个事务协调器来协调多个存储引擎和二进制日志之间的两阶段提交,它负责使用trans_register_ha()API注册自己.
在事务已使用XA API向协调器注册后,此标志设置为1,并在提交或回滚后设置为0
变量9 check_unique_secondary
变量类型 ulint
变量备注
通常为TRUE,但是如果用户想要通过抑制对二级索引的唯一键检查来加快插入,当我们决定是否可以为它们使用插入缓冲区时,我们设置这个FALSE
变量10 support_xa
变量类型 ulint
变量备注 normally we do the XA two-phase commit steps, but by setting this to FALSE, one can save CPU time and about 150 bytes in the undo log size as then we skip XA steps
通常我们做XA两阶段提交步骤,但通过设置为FALSE,可以节省CPU时间和大约150字节的undo日志大小,然后我们跳过XA步骤
变量11 flush_log_later
变量类型 ulint
变量备注
In 2PC, we hold the prepare_commit mutex across both phases. In that case, we defer flush of the logs to disk until after we release the mutex
在两阶段提交,我们持有两个阶段的prepare_commit互斥体。 在这种情况下,我们推迟刷新日志到磁盘,直到我们释放互斥体。
变量12 must_flush_log_later
变量类型 ulint
变量备注
this flag is set to TRUE in trx_commit() if flush_log_later was TRUE, and there were modifications by the transaction; in that case we must flush the log in trx_commit_complete_for_mysql()
此标志在trx_commit()中设置为TRUE,如果flush_log_later为TRUE,并且事务进行了修改; 在这种情况下,我们必须通过trx_commit_complete_for_mysql()刷新日志
变量13 duplicates
变量类型 ulint
变量备注 TRX_DUP_IGNORE | TRX_DUP_REPLACE
变量14 has_search_latch
变量类型 ulint
变量备注
TRUE if this trx has latched the search system latch in S-mode 如果此trx已在S模式下锁定搜索系统锁存器,则为TRUE
变量15 search_latch_timeout
变量类型 ulint
变量备注
If we notice that someone is waiting for our S-lock on the search latch to be released, we wait in row0sel.cc for BTR_SEA_TIMEOUT new searches until we try to keep the search latch again over calls from MySQL; this is intended to reduce contention on the search latch
如果我们注意到有事务在等待我们的S锁锁定被释放,我们在row0sel.cc中等待BTR_SEA_TIMEOUT新的搜索,直到我们尝试保持搜索锁定再次超过来自MySQL的调用; 这旨在减少对搜索锁存器的争用
变量16 dict_operation
变量类型 trx_dict_op_t
变量备注
主要是三种状态 没有修改表结构=0 改表=1 修改索引=2
/** Type of data dictionary operation */
enum trx_dict_op_t {
/** The transaction is not modifying the data dictionary. */
TRX_DICT_OP_NONE = 0,
/** The transaction is creating a table or an index, or
dropping a table. The table must be dropped in crash
recovery. This and TRX_DICT_OP_NONE are the only possible
operation modes in crash recovery. */
TRX_DICT_OP_TABLE = 1,
/** The transaction is creating or dropping an index in an
existing table. In crash recovery, the data dictionary
must be locked, but the table must not be dropped. */
TRX_DICT_OP_INDEX = 2
};
变量17 declared_to_be_inside_innodb
变量 ulint
备注
this is TRUE if we have declared this transaction in srv_conc_enter_innodb to be inside the InnoDB engine 如果我们已经在srv_conc_enter_innodb中声明这个事务在InnoDB引擎中,那么这是TRUE
变量18 n_tickets_to_enter_innodb
变量类型 ulint
变量备注
< this can be > 0 only when declared_to_... is TRUE; when we come to srv_conc_innodb_enter, if the value here is > 0, we decrement this by 1
<这可以> 0只有当declared_to_be_inside_innodb _…为TRUE 当我们来到srv_conc_innodb_enter,如果这里的值> 0,我们将其减1
变量19 dict_operation_lock_mode
变量类型 ulint
变量备注
0, RW_S_LATCH, or RW_X_LATCH: the latch mode trx currently holds on dict_operation_lock. Protected by dict_operation_lock 0,RW_S_LATCH或RW_X_LATCH:锁存模式trx当前持有dict_operation_lock。 受dict_operation_lock保护
变量20 no
变量类型 trx_id_t
storage/innobase/include/univ.i
typedef ib_uint64_t ib_id_t;
storage/innobase/include/trx0types.h
/** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */
typedef ib_id_t trx_id_t;
变量备注
transaction serialization number: max trx id shortly before the transaction is moved to COMMITTED_IN_MEMORY state. Protected by trx_sys_t::mutex when trx->in_rw_trx_list. Initially set to TRX_ID_MAX
事务序列号:事务被移动到COMMITTED_IN_MEMORY状态之前不久的max trx id。 当trx-> in_rw_trx_list时,由trx_sys_t :: mutex保护。 最初设置为TRX_ID_MAX
变量21 start_time
变量类型 time_t
变量备注 time the trx state last time became TRX_STATE_ACTIVE
trx状态变为TRX_STATE_ACTIVE的上一次时间(开始时间)
变量22 id
变量类型 trx_id_t
变量备注 transaction id 事务id
变量23 XID
变量类型 XID
sql/handler.h
typedef struct xid_t XID;
xid_t是一个结构体,代码太多,这里就不贴了
变量备注 X/Open XA transaction identification to identify a transaction branch 打开分布式事务的标识,以便区分事务分支
变量24 commit_lsn
变量类型
/* Type used for all log sequence number storage and arithmetics */
typedef ib_uint64_t lsn_t;
变量备注
lsn at the time of the commit lsn提交的时间
变量25 table_id
变量类型 table_id_t
变量备注 Table to drop iff dict_operation == TRX_DICT_OP_TABLE, or 0
变量26 mysql_thd
变量类型 THD* 这是一个超级大的结构体,详情需要看代码
变量备注
MySQL thread handle corresponding to this trx, or NULL 对应这个trx的MySQL线程句柄,或NULL
变量27 mysql_log_file_name
变量类型 const char*
变量备注
if MySQL binlog is used, this field contains a pointer to the latest file name; this is NULL if binlog is not used
如果使用MySQL binlog,此字段包含指向最新文件名的指针; 如果不使用binlog,则为NULL
变量28 mysql_log_offset
变量类型 ib_int64_t
变量备注
if MySQL binlog is used, this field contains the end offset of the binlog entry
如果使用MySQL binlog,则此字段包含binlog条目的结束偏移量
变量29 n_mysql_tables_in_use
变量类型 ulint
变量备注 number of Innobase tables used in the processing of the current SQL statement in MySQL
MySQL中处理当前SQL语句时使用的Innobase表的数量
变量30 mysql_n_tables_locked
变量类型 ulint
变量备注
how many tables the current SQL statement uses, except those in consistent read
变量31 trx_list
变量类型 UT_LIST_NODE_T(trx_t)
#define UT_LIST_NODE_T(TYPE) \
struct { \
TYPE* prev; /*!< pointer to the previous node, \
NULL if start of list */ \
TYPE* next; /*!< pointer to next node, NULL if end of list */\
}
变量备注
list of transactions; protected by trx_sys->mutex. The same node is used for both trx_sys_t::ro_trx_list and trx_sys_t::rw_trx_list
事务列表:受trx_sys->mutex保护。 同样的节点用于trx_sys_t :: ro_trx_list和trx_sys_t :: rw_trx_list
变量32 mysql_trx_list
变量类型 UT_LIST_NODE_T(trx_t)
变量备注
list of transactions created for MySQL; protected by trx_sys->mutex
变量33 error_state
变量类型 dberr_t
变量备注
0 if no error, otherwise error number; NOTE That ONLY the thread doing the transaction is allowed to set this field: this is NOT protected by any mutex
错误码 注意只有执行事务的线程才允许设置此字段 这不受任何互斥保护
变量34 dict_index_t*error_info
变量类型 const
变量备注
if the error number indicates a duplicate key error, a pointer to the problematic index is stored here 如果错误号表示重复键错误,则在此存储指向有问题索引的指针
变量35 error_key_num
变量类型 ulint
变量备注
if the index creation fails to a duplicate key error, a mysql key number of that index is stored here
如果索引创建失败,重复的键错误,该索引的mysql键号存储在这里
变量36 sess
变量类型 sess_t*
/* The session handle. This data structure is only used by purge and is
not really necessary. We should get rid of it. */
struct sess_t{
ulint state; /*!< state of the session */
trx_t* trx; /*!< transaction object permanently
assigned for the session: the
transaction instance designated by the
trx id changes, but the memory
structure is preserved */
UT_LIST_BASE_NODE_T(que_t)
graphs; /*!< query graphs belonging to this
session */
};
变量备注
session of the trx, NULL if none
变量37 graph
变量类型que_t*
变量备注
query currently run in the session, or NULL if none; NOTE that the query belongs to the session, and it can survive over a transaction commit, if it is a stored procedure with a COMMIT WORK statement, for instance
查询当前在运行中的会话,如果没有则为NULL 注意,查询属于会话,并且它可以通过事务提交存活,如果它是具有COMMIT WORK语句的存储过程,例如
变量38 global_read_view_heap
变量类型 mem_heap_t*
/* A memory heap is a nonempty linear list of memory blocks */
typedef mem_block_t mem_heap_t;
/* A block of a memory heap consists of the info structure
followed by an area of memory */
typedef struct mem_block_info_t mem_block_t;
mem_block_info_t又是一个复杂的结构体
变量备注
memory heap for the global read view 内存堆的全局读取视图
变量39 global_read_view
变量类型 read_view_t* 又是一个比较复杂的结构体
一致的读取视图关联到事务或NULL
变量40 read_view
变量类型 read_view_t* 变量备注
consistent read view used in the transaction or NULL, this read view if defined can be normal read view associated to a transaction (i.e. same as global_read_view) or read view associated to a cursor
一致的读取视图用于事务或NULL,此读取视图如果定义可以是与事务相关联的正常读取视图(即与global_read_view相同)或与光标相关联的读取视图
变量41 trx_savepoints
变量类型 UT_LIST_BASE_NODE_T(trx_named_savept_t)
变量备注 savepoints set with SAVEPOINT ..., oldest first 使用SAVEPOINT设置保存点的列表 ...,最旧的放在最前面
变量42 undo_mutex
变量类型 ib_mutex_t
变量备注 mutex protecting the fields in this section (down to undo_no_arr), EXCEPT last_sql_stat_start, which can be accessed only when we know that there cannot be any activity in the undo logs!
互斥体保护此部分中的字段(向下到undo_no_arr),除了 last_sql_stat_start,只有当我们知道在撤销日志中不能有任何活动时才可以访问它们!
变量43 undo_no
变量类型undo_no_t
/** Undo number */
typedef ib_id_t undo_no_t;
变量备注
next undo log record number to assign; since the undo log is private for a transaction, this is a simple ascending sequence with no gaps; thus it represents the number of modified/inserted rows in a transaction
分配下一个撤销日志记录号; 因为撤销日志对于事务是私有的,这是一个没有间隙的简单升序序列; 因此它表示事务中修改/插入行的数量。
变量44 last_sql_stat_start
变量类型 trx_savept_t
变量备注 undo_no when the last sql statement was started: in case of an error, trx is rolled back down to this undo number; see note at undo_mutex
当最后一个sql语句启动时,分配undo_no:在出现错误的情况下,trx被回滚到这个撤销号; 请参见undo_mutex中的注释
变量45 rseg
变量类型 trx_rseg_t* 这又是一个比较复杂的结构体,但segement其实是和Page绑定在一起的, 变量备注
rollback segment assigned to the transaction, or NULL if not assigned yet
回滚段分配给事务,如果尚未分配,则为NULL
变量46 insert_undo
变量类型 trx_undo_t*
变量备注
pointer to the insert undo log, or NULL if no inserts performed yet
指向插入undo日志的指针,如果尚未执行插入,则为NULL
变量47 update_undo
变量类型 trx_undo_t*
变量备注 pointer to the update undo log, or NULL if no update performed yet
变量48 roll_limit
变量类型 undo_no_t
变量备注 least undo number to undo during a rollback
事务回滚的时候,最小的回滚数
变量49 pages_undone
变量类型 ulint
变量备注 number of undo log pages undone since the last undo log truncation
自上次撤消日志截断以来撤销日志页面的数量
变量50 undo_no_arr
变量类型 trx_undo_arr_t*
变量备注 array of undo numbers of undo log records which are currently processed by a rollback operation
撤消日志记录的撤销编号数组,这些撤消日志记录当前由回滚操作处理
变量51 n_autoinc_rows
变量类型ulint
变量备注 no. of AUTO-INC rows required for an SQL statement. This is useful for multi-row INSERTs
SQL语句所需的AUTO-INC行的数量。 这对于多行INSERT非常有用
变量52 autoinc_locks
变量类型 ib_vector_t*
变量备注
AUTOINC locks held by this transaction. Note that these are also in the lock list trx_locks. This vector needs to be freed explicitly when the trx instance is destroyed. Protected by lock_sys->mutex
此事务持有的AUTOINC锁。 注意,这些也在锁定列表trx_locks中。 当trx实例被销毁时,这个向量需要被明确地释放。 受lock_sys-> mutex保护
变量53 read_only
变量类型 ibool
变量备注 TRUE if transaction is flagged as a READ-ONLY transaction. if !auto_commit || will_lock > 0 then it will added to the list trx_sys_t::ro_trx_list. A read only transaction will not be assigned an UNDO log. Non-locking auto-commit read-only transaction will not be on either list
如果事务标记为READ-ONLY事务,则为TRUE。 if!auto_commit || will_lock> 0,那么它将被添加到列表trx_sys_t :: ro_trx_list。 只读事务将不会被分配UNDO日志。 非锁定自动提交只读事务将不在任一列表上
变量54 auto_commit
变量类型 ibool
变量备注 TRUE if it is an autocommit
变量55 will_lock
变量类型 ulint
变量备注
Will acquire some locks. Increment each time we determine that a lock will be acquired by the MySQL layer
标记会获得一些锁。 每次我们确定需要获取锁的时候,将被MySQL层获取时递增
变量56 ddl
变量类型 bool
变量备注 true if it is a transaction that is being started for a DDL operation
如果它是为DDL操作启动的事务,则为true
变量57 fts_trx
变量类型 fts_trx_t*
变量类型 FTS information, or NULL if transaction hasn't modified tables with FTS indexes (yet)
FTS信息,如果事务尚未修改具有FTS索引的表(尚未),则为NULL;
变量58 fts_next_doc_id
变量类型 doc_id_t
变量备注
The document id used for updates 用于更新的文档ID
变量59 flush_tables
变量类型 ulint
变量备注 if "covering" the FLUSH TABLES",count of tables being flushed
如果“覆盖”FLUSH TABLES“,则表的计数被刷新
变量60 api_trx
变量类型 bool
变量备注 trx started by InnoDB API
变量61 api_auto_commit
变量类型 bool
变量备注 automatic commit
变量62 read_write
变量类型 bool
变量备注 if read and write operation
变量63 detailed_error[256]
变量类型char
变量备注 detailed error message for last error, or empty