binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
binlog不会记录SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改,但你可以通过查询通用日志来查看MySQL执行过的所有语句。
binlog是server层实现的。而undo log和redo log是innodb存储引擎层实现的。
影响binlog的参数:
binlog_cache_size:使用事务表存储引擎(如innodb存储引擎)时,所有未提交的binlog日志会被记录到一个缓存中去,等事务提交时再将缓存中的binlog写入到binlog文件中。缓存的大小由binlog_cache_size决定,默认大小为32K。
binlog_cache_size是基于session的,也就是说,当一个线程开始一个事务时,MySQL会自动分配一个大小为binlog_cache_size的缓存,因此该值的设置需要非常小心,不能设置过大。
当一个事务的记录大于设定的binlog_cache_size时,MySQL会把缓存中的日志写入一个临时文件中,因此该值又不能设的太小。
sync_binlog:sync_binlog=1,代表每次事务提交时就会刷新binlog到磁盘。sync_binlog=[N],代表每N个事务提交会进行一次binlog刷新。
以下来自MySQL官方文档:
For replication, the binary log on a master replication server provides a record of the data changes to be sent to slave servers. The master server sends the events contained in its binary log to its slaves, which execute those events to make the same data changes that were made on the master. See Section 17.2, Replication Implementation .
对于复制,主复制服务器上的二进制日志提供要发送到从服务器的数据更改的记录。主服务器将二进制日志中包含的事件发送给从服务器,从服务器执行这些事件以对主服务器进行相同的数据更改。参见17.2节,复制实现。
如图所示,主库有一个log dump线程,将binlog传给从库。从库有两个线程,一个I/O线程,一个SQL线程,I/O线程读取主库传过来的binlog内容并写入到relay log(中继日志),SQL线程从relay log里面读取内容,写入从库的数据库。
以下两段来自MySQL官方文档:
Certain data recovery operations require use of the binary log. After a backup has been restored, the events in the binary log that were recorded after the backup was made are re-executed. These events bring databases up to date from the point of the backup. See Section 7.5, Point-in-Time (Incremental) Recovery Using the Binary Log
某些数据恢复操作需要使用二进制日志。备份恢复后,将重新执行备份后记录的二进制日志中的事件。这些事件使数据库从备份时起保持最新。参见第7.5节,使用二进制日志的时间点(增量)恢复
Point-in-time recovery refers to recovery of data changes made since a given point in time. Typically, this type of recovery is performed after restoring a full backup that brings the server to its state as of the time the backup was made. (The full backup can be made in several ways, such as those listed in Section 7.2, Database Backup Methods .) Point-in-time recovery then brings the server up to date incrementally from the time of the full backup to a more recent time.
时间点恢复是指恢复自给定时间点以来所做的数据更改。通常,这种类型的恢复是在恢复完整备份之后执行的,该备份将服务器恢复到备份时的状态。(完全备份可以通过几种方式进行,例如第7.2节中列出的数据库备份方法。)时间点恢复将服务器从完全备份的时间增量地更新到最近的时间。
使用mysqldump备份时,只是对一段时间的数据进行全备,但是如果备份后突然发现数据库服务器故障,这个时候就要用到binlog的日志了。
参考:https://www.cnblogs.com/rjzheng/p/9721765.html
https://mp.weixin.qq.com/s?__biz=MzU3MDc3OTI1NA==&mid=2247485643&idx=8&sn=e8e27eb2ede59ce9809fa8fc2d10b800&chksm=fceb7bd2cb9cf2c44caa981a62895f6445d5af164af2c7b78f219e6b272d2fac15d36e3bf840&mpshare=1&scene=1&srcid=0128JiqpIl1J6P2ngHjd6OaD&sharer_sharetime=1580178635099&sharer_shareid=8f012a4343d344d99658ce94e8692951&key=1dba98cf68729bcf49f94f7c84b071ac17de6c46d1f0dc361d9578ce3fc434fb0a8b7412f9f163ff0841a8a4c9d8c35ba301272e530cce0db38523a42abc8a38a74d07bf369af7f7421bc52b97f7fa80&ascene=1&uin=MTE5OTMwODY3MQ%3D%3D&devicetype=Windows+7&version=6208006f&lang=zh_CN&exportkey=AZ%2FxJ1pWYrCvi2ux%2BgeaxaM%3D&pass_ticket=nZylyM3cFKEWFtq8xHf7P0sY38IvnPAzD4l2f9Z5NmEQjEaMYdzYKTodcHtRt4eB
redo log是innodb存储引擎层实现的,记录了哪个数据页的哪个位置做了什么样的修改。
在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是RedoLog已经持久化。系统可以根据RedoLog的内容,将所有数据恢复到最新的状态。
因此,有了redo log,当数据库发生宕机重启后,可通过redo log将未落盘的数据恢复,即保证已经提交的事务记录不会丢失。
参考:https://www.jianshu.com/p/4bcfffb27ed5
回滚日志,是innodb存储引擎层实现的
实现事务的原子性(回滚)、实现MVCC,上篇文章已讲述。
主要通过doublewrite、redo log以及binlog实现
实际上MySQL的真实数据写入分为两次写入,一次写入到一个称为DoubleWrite的地方,写成功之后再真实写入数据所在磁盘。为什么要写两次?这是因为MySQL数据页大小与磁盘一次原子操作大小不一致,有可能会出现部分写入的情况,比如默认InnoDB数据页大小为16K,而磁盘一次原子写入大小为512字节(扇区大小),这样一个数据页写入需要多次IO,这样一旦中间发生异常就会出现数据丢失。
工作流程
doublewrite由两部分组成,一部分为内存中的doublewrite buffer,其大小为2MB,另一部分是磁盘上共享表空间(ibdata x)中连续的128个页,即2个区(extent),大小也是2M。
1、当一系列机制触发数据缓冲池中的脏页刷新时,并不直接写入磁盘数据文件中,而是先拷贝至内存中的doublewrite buffer中;
2、接着从doublewrite buffer分两次写入磁盘共享表空间中(连续存储,顺序写,性能很高),每次写1MB;
3、待第二步完成后,再将doublewrite buffer中的脏页数据写入实际的各个表空间文件(离散写);(脏页数据固化后,即进行标记对应doublewrite数据可覆盖)
如果操作系统在将页写入磁盘的过程中发生崩溃,在恢复过程中,innodb存储引擎可以从共享表空间的doublewrite中找到该页的一个最近的副本,将其复制到表空间文件,再应用redo log,就完成了恢复过程。
因为有副本所以也不担心表空间中数据页是否损坏。
参考:https://www.cnblogs.com/geaozhang/p/7241744.html
http://hbasefly.com/2017/08/19/mysql-transaction/?jyfqjm=fvelj
哪怕断电,也能保证已提交的事务能持久化到磁盘
通过主从复制,保证从库的持久化
通过数据的增量恢复,保证将服务器从全备的时间点增量地更新到最近的时间点,使数据库状态保持最新。