[MySQLソース]:トランザクションコミットのInnoDB Prepare
2876 ワード
MySQL 5.6 InnoDB Prepareの流れは以下の通りです.
innodb_flush_log_at_trx_commitパラメータは、trx_flush_log_if_needed_low関数では0:redoをリフレッシュしないことを示し、何もしない1:redoをリフレッシュし、ログをディスクにリフレッシュする2:redoをリフレッシュするが、落盤はオペレーティングシステムによって制御される
5.6 InnoDB Prepareに比べて5.7が最適化され、Innodb Prepareフェーズではflushログは再利用されず、flush redoをbinlog flushフェーズに調整してredologのグループコミットを実現
[MySQLソース]:2 PCでのトランザクションコミットの概要
innobase_xa_prepare // InnoDB Prepare
trx_prepare_for_mysql // Prepare
{
trx->op_info = "preparing"; // preparing
trx_prepare(trx); //// Prepare
trx_undo_set_state_at_prepare() // undo Prepare
undo->state = TRX_UNDO_PREPARED;
undo->xid = trx->xid;
trx->state = TRX_STATE_PREPARED //
trx_flush_log_if_needed(lsn, trx); // redo
{
trx->op_info = "flushing log";
trx_flush_log_if_needed_low(lsn); // lsn redo
log_write_up_to() // redo
trx->op_info = "";
}
trx->op_info = ""; // ""
}
innodb_flush_log_at_trx_commitパラメータは、trx_flush_log_if_needed_low関数では0:redoをリフレッシュしないことを示し、何もしない1:redoをリフレッシュし、ログをディスクにリフレッシュする2:redoをリフレッシュするが、落盤はオペレーティングシステムによって制御される
trx_flush_log_if_needed_low(
/*========================*/
lsn_t lsn) /*!< in: lsn up to which logs are to be
flushed. */
{
switch (srv_flush_log_at_trx_commit) {
case 0: // 0
/* Do nothing */
break;
case 1: // 1 ,flush redo
/* Write the log and optionally flush it to disk */
log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
srv_unix_file_flush_method != SRV_UNIX_NOSYNC);
break;
case 2: // 2 ,flush redo,
/* Write the log but do not flush it to disk */
log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
break;
default:
ut_error;
}
}
5.6 InnoDB Prepareに比べて5.7が最適化され、Innodb Prepareフェーズではflushログは再利用されず、flush redoをbinlog flushフェーズに調整してredologのグループコミットを実現
if (prepare_trx
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* We were instructed to prepare the whole transaction, or
this is an SQL statement end and autocommit is on */
ut_ad(trx_is_registered_for_2pc(trx));
dberr_t err = trx_prepare_for_mysql(trx);
ut_ad(err == DB_SUCCESS || err == DB_FORCED_ABORT);
if (err == DB_FORCED_ABORT) {
innobase_rollback(hton, thd, prepare_trx);
return(convert_error_code_to_mysql(
DB_FORCED_ABORT, 0, thd));
}
} else {
/* We just mark the SQL statement ended and do not do a
transaction prepare */
/* If we had reserved the auto-inc lock for some
table in this SQL statement we release it now */
lock_unlock_table_autoinc(trx);
/* Store the current undo_no of the transaction so that we
know where to roll back if we have to roll back the next
SQL statement */
trx_mark_sql_stat_end(trx);
}
[MySQLソース]:2 PCでのトランザクションコミットの概要