InnoDB的重做日志刷新策略对插入速度的影响

核心控制参数

InnoDB存储引擎通过innodb_flush_log_at_trx_commit参数控制重做日志刷新到磁盘的策略

查看参数值:

show variables like 'innodb_flush_log_at_trx_commit';

修改参数值:

set GLOBAL innodb_flush_log_at_trx_commit = 1;

三种刷新策略

策略一:参数值为0,表示事务提交时不强制一定要写入到重做日志,刷新到磁盘的时间控制有master thread控制,master thread会在每隔1秒进行同步刷新操作。

策略二:参数值为1,表示事务提交时必须将该事务的所有日志写入到磁盘中。

策略三:参数值为2,表示事务提交时将重做日志写入到重做日志文件,但仅仅是写入到文件系统的缓存中,不立刻进行同步刷新操作。

测试用例

创建表load_data表用来存储数据:

CREATE TABLE load_data (
    id INT UNSIGNED,
    data CHAR(100)
);

创建存储过程loadData用来加载数据:

CREATE PROCEDURE loadData(number INT UNSIGNED)
BEGIN
DECLARE i INT UNSIGNED DEFAULT 1;
DECLARE v CHAR(100) DEFAULT REPEAT ('t', 100); 
WHILE i <= number DO
INSERT INTO load_data SELECT i, v;
COMMIT;
SET i = i + 1;
END WHILE;
END;

插入100万条数据的速度比较

策略一的测试:

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 0     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> call loadData(1000000);
Query OK, 0 rows affected (38.84 sec)

策略二的测试(不能忍,都看了一集电视剧了):

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> call loadData(1000000);                              
Query OK, 0 rows affected (31 min 38.67 sec)

策略三的测试:

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.03 sec)

mysql> call loadData(1000000);                              
Query OK, 0 rows affected (1 min 34.67 sec)

各策略的优缺点

策略一:明显速度上比策略二快很多,因为少了很多刷新到磁盘的IO操作,这些IO操作的代价是很大的,很浪费时间,策略一在这点上省了不少的时间,但是代价就是可能会发生在最后一秒内事务丢失的情况,这样就不符合了事务的持久性。如果那一秒刚好接了1000万的单子,结果服务器死机了,找不回这条数据了,就只能呵呵了。

策略二:优点很明显,就是严重的符合了事务的持久性,每次都写入重做日志,当宕机情况出现的时候,可以准确的恢复。缺点也很明显,就是付出的时间代价很大。

策略三:利用缓存机制减少了不必要的IO操作,或者说是将多个IO操作合并成一个IO,提高了速率。缺点就是发生宕机的时候会丢失还没有从文件系统缓存刷新到重做日志的那一份数据。

总的来说,每种策略的存在都有其存在的道理。存在就是合理的,各种策略都有它应用的情景,只能了解了他们的情况,才能更好使用这些策略。


你可能感兴趣的:(InnoDB的重做日志刷新策略对插入速度的影响)