8.5.2 Optimizing InnoDB Transaction Management 优化InnoDB事务管理
优化InnoDB 事务处理, 找到完美的平衡在性能开销和服务器负载之间。比如,
一个应用可能会遇到性能问题,如果它提交每秒数千次, 不同的性能问题如果它每2-3个小时提交一次。
默认MySQL 设置 AUTOCOMMIT=1 能利用性能局限性。在实践中,几个相关的DML 操作到一个事务,通过
设置AUTOCOMMIT=0 或者一个START TRANSACTION 语句,在做出改变后 执行COMMIT语句。
InnoDB 必须flush log 到磁盘在每次事务提交的时候,如果transaction 模式更改为database.
当每个改变后跟着commit(默认自动提交), 存储设备的I/O吞吐量.
另外的,对于事务只有单个的SELECT 语句组成,打开自动提交有助于InnoDB 来识别只读的事务,优化它们。
避免在insert,update或者delete大量记录后执行回滚,如果一个大的事务会放缓服务器的性能,
回滚会让问题变得更糟,回滚可能比正常的DML操作时间时间花费多几倍。 杀死数据库进程没有帮助,
因为服务器启动会再次回滚。
To minimize the chance of this issue occurring:
1.增加buffer pool的大小,让所有的DML改变都能被cache 相比立即写到磁盘
2.设置innodb_change_buffering=all(默认就是all) ,更新和删除操作会被buffered ,除inserts之外
- 考虑在大的DML操作,周期性的执行COMMIT,可能把一个单独的delete或者update 打散成多个语句来操作较少的数据行。
一旦失控的回顾发生,增加buffer_pool ,回滚变的CPU-bound and runs fast,
或者kill the server ,重启设置 innodb_force_recovery=3
这个问题在MySQL 5.5和更高的版本是不突出的, 因为默认的innodb_change_buffering=all,
允许更新和删除操作被cache在内存, 使它们更快的运行在第一个地方,回滚也变得更快。
确保使用这个参数时,长时间运行事务得进程有很多的inserts,updates或者deletes.
如果你承受当crash 发生时 最新提交的事务丢失,可以设置innodb_flush_log_at_trx_commit =0.
InnoDB 会flush日志1秒一次, 尽管flush 不是强制的,或者set the value of innodb_support_xa to 0
当记录被修改或者删除, 该记录和相关的undo logs 不是物理的立即删除,
甚至在事务提交后。 旧的undo数据是保存的直到事务开始的事务或者并发完成,
因此这些事务可以访问先前修改或者删除的记录。因此,长时间运行的事务可以防止InnoDB
清楚数据,被一个不同的事务修改的。
当长事务修改或者删除记录, 其他的事务使用READ COMMITED和 REPEATABLE READ 隔离级别
需要做更多的工作来重构老的数据(undo),如果读取相同的行。