介绍 BufferPool 之前,先抛出一个问题,每次更新,新增,删除的动作,都会去写磁盘吗?如果是,那样效率会不会很低,如果不是,怎么保证数据不会丢失?
不会实时写入磁盘
如果每次对数据的操作都要实时同步到硬盘中,那么将要产生大量的IO,并且是随机IO,因为无法保证这写被写入的数据是在磁盘的相邻区域。随机IO的性能是非常差的。当然不能实时的写入磁盘,而是暂时把这些数据保存到一块内存区域中,等积累到一定大小或者一定时间后,再统一写入磁盘。这个时间是不确定的,由操作系统决定。这个内存区域就是MySQL 中的BuffrPoll,可以理解为缓存。
数据不会丢失
既然数据是先放到内存中的,然后定期的写入磁盘,如果在数据还没有写入磁盘,服务器断电了怎么办?那样数据不就丢了吗?还怎么保证持久性呢?
redo log
答案是redo log, 在我们执行一个事务时,redo log 会记录事务中所有的写操作,和bin_log 是一样的,只有事务中的写操作成功被记录到redo log中,该事务才能被提交。客户端才会认为这个事务正常执行了。redo log 是一个日志文件,写操作是实时被记录到该文件中的,如果在BufferPoll
中的数据没有写入磁盘而发生了故障,等下次服务器恢复时,就会先从redo log中加载数据到Buffer,然后在合适的时机写入磁盘。
同样都是实时写入磁盘,为什么redo log 可以接受呢? 因为写入log时,是顺序IO,提前分配一块磁盘空间,顺序追加就行了。顺序IO比磁盘IO效率高很多
顺序IO和随机IO
顺序IO是指读写操作的访问地址连续。在顺序IO访问中,HDD所需的磁道搜索时间显着减少,因为读/写磁头可以以最小的移动访问下一个块。数据备份和日志记录等业务是顺序IO业务。
随机IO是指读写操作时间连续,但访问地址不连续,随机分布在磁盘的地址空间中。产生随机IO的业务有OLTP服务,SQL,即时消息服务等。
redo log 和bin log
redo log是在引擎层, bin_log 是在 server 层,和引擎无关
redo log 是为了保证数据的持久性,不丢失,配合 BufferPoll发挥作用
bin log 是为了恢复数据使用