MySQL“写缓冲“优化策略

概要

前文讲过MySQL的缓冲池buffer-pool,我们知道缓冲池是用于加速数据访问速度的。那么当发生写操作时,也需要更新缓冲池中缓存的数据,这也是在任何缓存架构体系下需要实现的机制。

简单的更新缓存套路:

1、持久化数据
2、让缓存失效

  • 以上操作没有考虑缓存(Cache)和持久层(Repository)的整体事务的问题。
  • 如果你需要强一致性,你需要使用“两阶段提交协议”——prepare, commit/rollback,比如Java 7 的XAResource,还有MySQL 5.7的 XA Transaction,有些cache也支持XA,比如EhCache。
    当然,XA这样的强一致性的玩法会导致性能下降。

回到mysql中的实现:

缓存命中

1、先修改缓冲池中的页(内存)
2、顺序写入redo log (磁盘)

  • 当读取时,会命中缓冲池中的页,直接返回缓存数据
  • 当缓冲池数据通过LRU算法被淘汰时,“脏页”会被刷回磁盘
  • 当数据库崩溃(内存丢失),从redo log中恢复数据

内存页与磁盘数据不一致时,内存页也叫做“脏页”,mysql采用定期刷盘,降低磁盘IO,提升mysql性能。

缓存不命中

1、先从磁盘加载数据到缓冲池(磁盘io)
2、修改缓冲池中的页(内存)
3、写入redo log(磁盘)

总结:
当缓存不命中时,会比缓存命中多一次磁盘io,为了优化这次io,mysql做了以下优化(InnoDB引擎)。

写缓冲优化

1、当缓存不命中时,不从磁盘加载数据,而是在内存(写缓冲池)中记录写操作
2、写入redo log(磁盘)

  • 当发生读操作时,(缓存不命中),从磁盘加载数据
  • 从内存中(写缓冲池)读取写操作
  • 根据写操作恢复索引页,放到缓冲池

写缓冲池并不是银弹

  • 当如果索引设置了唯一(unique)属性,在进行修改操作时,InnoDB必须进行唯一性检查。
    这个时候不能单单只在写缓冲池记录写操作,还需要检索所有的页检测唯一性,那么磁盘IO就不可避免了。

  • 可以看到我们采用写缓冲池的这种方式是为了优化磁盘IO,那最适合的场景应该是写多读少的情况下。

设置写缓冲池大小

在生产应用中,如果可以调整写缓冲池占缓冲池大小比例
1、查看比例

show variables like '%innodb_change_buffer_max_size%';

2、设置哪些操作触发写缓冲

show variables like '%innodb_change_buffering%';

可以设置成all/none/inserts/deletes等。

猜你喜欢

转载自blog.csdn.net/BBinChina/article/details/123860361