MySQL 源码解读 -- 事务结构

basic structure

1
2
3
4
5
6
enum enum_tx_isolation : int {
ISO_READ_UNCOMMITTED,
ISO_READ_COMMITTED,
ISO_REPEATABLE_READ,
ISO_SERIALIZABLE
};

Attachable_trx

1
2
3
4
5
6
7
8
class Attachable_trx {
THD *m_thd;
enum_reset_lex m_reset_lex; //RESET_LEX, DO_NOT_RESET_LEX
Attachable_trx *m_prev_attachable_trx;
Transaction_state m_trx_state; /// Transaction state data.
};


Transaction_state

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
55
56
57
58
59
60
61
62
63
64
65
66
struct Transaction_state {
Transaction_state();
THD::Transaction_state::Transaction_state()
: m_query_tables_list(new Query_tables_list()),
m_ha_data(PSI_NOT_INSTRUMENTED, m_ha_data.initial_capacity) {}
~Transaction_state();
void backup(THD *thd);
void restore(THD *thd);

/// SQL-command.
enum_sql_command m_sql_command;

Query_tables_list *m_query_tables_list;

/// Open-tables state.
Open_tables_backup m_open_tables_state;

/// SQL_MODE.
sql_mode_t m_sql_mode;

/// Transaction isolation level. RU/RC/RR/Serialization
enum_tx_isolation m_tx_isolation;

/// Ha_data array.
Prealloced_array<Ha_data, PREALLOC_NUM_HA> m_ha_data;

/// Transaction_ctx instance.
Transaction_ctx *m_trx;

/// Transaction read-only state.
bool m_tx_read_only;

/// THD options.
ulonglong m_thd_option_bits;

/// Current transaction instrumentation.
PSI_transaction_locker *m_transaction_psi;

/// Server status flags.
uint m_server_status;

/// THD::in_lock_tables value.
bool m_in_lock_tables;

/**
Current time zone (i.e. @@session.time_zone) usage indicator.

Saving it allows data-dictionary code to read timestamp values
as datetimes from system tables without disturbing user's statement.
TODO: We need to change DD code not to use @@session.time_zone at all and
stick to UTC for internal storage of timestamps in DD objects.
*/
bool m_time_zone_used;

/**
Transaction rollback request flag.

InnoDB can try to access table definition while rolling back regular
transaction. So we need to be able to start attachable transaction
without being affected by, and affecting, the rollback state of regular
transaction.
*/
bool m_transaction_rollback_request;

PPI_transaction *m_ppi_transaction;
}

Transaction_ctx

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
class Transaction_ctx {
SAVEPOINT *m_savepoints;
THD_TRANS m_scope_info[2];

XID_STATE m_xid_state;

MEM_ROOT m_mem_root; // Transaction-life memory allocation pool

struct {
bool enabled; // see ha_enable_transaction()
bool xid_written; // The session wrote an XID
bool real_commit; // Is this a "real" commit?
bool commit_low; // see MYSQL_BIN_LOG::ordered_commit
bool run_hooks; // Call the after_commit hook
#ifndef DBUG_OFF
bool ready_preempt; // internal in MYSQL_BIN_LOG::ordered_commit
#endif
} m_flags;
/* Binlog-specific logical timestamps. */
/*
Store for the transaction's commit parent sequence_number.
The value specifies this transaction dependency with a "parent"
transaction.
The member is assigned, when the transaction is about to commit
in binlog to a value of the last committed transaction's sequence_number.
This and last_committed as numbers are kept ever incremented
regardless of binary logs being rotated or when transaction
is logged in multiple pieces.
However the logger to the binary log may convert them
according to its specification.
*/
int64 last_committed;
/*
The transaction's private logical timestamp assigned at the
transaction prepare phase. The timestamp enumerates transactions
in the binary log. The value is gained through incrementing (stepping) a
global clock.
Eventually the value is considered to increase max_committed_transaction
system clock when the transaction has committed.
*/
int64 sequence_number;

Rpl_transaction_ctx m_rpl_transaction_ctx;
Rpl_transaction_write_set_ctx m_transaction_write_set_ctx;
bool trans_begin_hook_invoked;
}

Transaction_ro

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

class Transaction_ro {
public:
Transaction_ro(THD *thd, enum_tx_isolation isolation)
: otx(thd, TL_READ), m_thd(thd), m_kill_immunizer(thd) {
thd->begin_attachable_ro_transaction();
thd->tx_isolation = isolation;
}

~Transaction_ro() { m_thd->end_attachable_transaction(); }

Open_dictionary_tables_ctx otx;

private:
THD *m_thd;

DD_kill_immunizer m_kill_immunizer;
};

class Open_dictionary_tables_ctx {
THD *m_thd;
thr_lock_type m_lock_type;
bool m_ignore_global_read_lock;
typedef std::map<String_type, Raw_table *> Object_table_map;
Object_table_map m_tables;
}