binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。
binlog是通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。
binlog使用场景
项目 在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。
MySQL主从同步原理
binlog的内容
上面说了,binlog是一种逻辑日志,可以简单得理解为sql语句,但是实际上还包含着执行的sql语句的反向逻辑。delete对应着delete本身以及反向的insert信息;update包含着对应的update执行前后数据行的相关信息;insert包含自身的insert以及对应的delete信息。
binlog的格式
binlog共有三种格式,分别是statement、row以及mixed。MySQL 5.7.7版本之前默认使用的是statement,MySQL 5.7.7之后默认使用的是row。日志的格式可以通过my.ini配置文件中的binlog-format来修改。
(1)statement:基于sql语句的复制(statement-based replication,SBR),每一条修改数据的sql语句都会记录到binlog中。
(2)row:基于行记录的复制(row-based replication,RBR),不记录sql语句上下文相关信息,而是记录哪条记录被修改的细节。
(3)mixed:根据上面所说的,statement和row各有优缺点,因此出现了mixed这个版本,将这二者进行混合。一般情况下使用statement格式来进行保存,当遇到statement无法解决时,切换为row格式来进行保存。
特别地,上面说了,新版本(MySQL 5.7.7之后)默认使用的row格式,这里的row也做了相应的优化,在遇到alter table这个操作时采用statement格式进行记录,其余操作仍然使用row格式。
binlog刷盘时机
对于InnoDB存储引擎来说,只有在事务提交的时候才会记录binlog,此时记录还在内存中,MySQL通过sync_binlog来控制binlog的刷盘时机,取值范围为0-N:
从上面可以看出,sync_binlog最安全的是设置是1,这也是MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。
binlog的物理文件大小
在my.ini配置文件中,可以通过max_binlog_size来配置binlog的大小。当日志量超过binlog文件的大小时,系统会重新生成一个新的文件来继续保存文件。当一个事务比较大时,或者是当日志越来越多的时候,此时占据的物理空间太大怎么办?MySQL提供了一种自动删除的机制,还是在my.ini配置文件中,可以通过配置expire_logs_days这个参数来解决,单位为天。当这个参数为0,表示永不删除;为N时,表示第N天后自动删除。
redolog是InnoDB引擎专有的日志系统。主要是用来实现事务的持久性以及实现crash-safe功能。redolog属于物理日志,记录的是sql语句执行之后数据页上的具体修改内容。
我们都知道,当MySQL运行的时候,会将数据从磁盘中加载到内存当中。当执行sql语句对数据进行修改时,修改后的内容其实都只是暂时保存到内存当中,如果此时断电或者出现其他情况,这些修改就会丢失。因而,当修改完数据之后,MySQL会寻找机会将这些内存中的记录刷回到磁盘当中。但这就出现一个性能问题,主要有两个方面:
InnoDB中是以页为数据单位与磁盘进行交互的,而一个事务很可能只是修改了一个页上的几个字节,如果将一个完整的数据页刷回磁盘当中,浪费资源;
一个事务可能涉及到多个数据页,这些数据页只是逻辑上连续,在物理上并不连续,使用随机IO性能太差;
因此,MySQL设计了redolog来记录事务对数据页具体做了哪些修改,之后将redolog再刷回磁盘当中。你可能会有疑惑,本来就是想减少io,这不又加上一次io么?InnoDB的设计者在设计之初就已经考虑到了这些。redolog文件一般都比较小,且在刷回磁盘的过程中是顺序io,相比于随机io来说,性能更好。
redo log基本概念
redolog由两部分组成,一个是内存中的日志缓存redo log buffer,一个是磁盘中的日志文件redo log file。当每次对数据记录进行修改的时候,都会将这些修改内容先写入redo log buffer中,后续等待合适的时机将内存中的修改刷回到redo log file中。这种先写日志,再写磁盘的技术就是WAL(Write-Ahead Logging)技术。需要注意的是redolog比数据页先刷回磁盘,聚簇索引,二级索引,undo页面的修改,均需要记录redolog。
在计算机操作系统中,用户空间(user space)下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer写入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中,过程如下:
mysql支持三种将redo log buffer写入redo log file的时机,可以通过innodb_flush_log_at_trx_commit参数配置,各参数值含义如下:
参数值 | 含义 |
---|---|
0(延迟写) | 事务提交时不会将redo log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到redo log file中。也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。 |
1(实时写,实时刷) | 事务每次提交都会将redo log buffer中的日志写入os buffer并调用fsync()刷到redo log file中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。 |
2(实时写,延迟刷) | 每次提交都仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到redo log file。 |
redo log记录形式 | |
redolog采用固定大小,循环写入的格式,当redolog写满之后,会重新从头开始写。为什么这么设计呢? | |
redo log存在的意义主要就是降低对数据页刷盘的要求。redolog记录了数据页上的修改,但是当数据页也刷回到磁盘后,这些记录就失去作用了。因此当MySQL判断之前的redolog已经失去作用之后,新数据会将这些失效的数据进行覆盖。那如何判断该不该进行覆盖呢? | |
上图是redo log file的示意图,write pos表示redolog当前记录的日志序列号LSN(log sequence number)。当数据页也已经刷回磁盘之后,会更新redo log file中的LSN,表示到这个LSN之前的数据已经落盘,这个LSN就是check point。write pos到check point之间的部分是redolog空余的部分,用于记录新的记录;check point到write pos之间是redolog已经记录的数据页修改部分,但此时数据页还未刷回磁盘的部分。当write pos追上check point时,会先推动check point向前移动,空出位置再记录新的日志。 |
启动innodb的时候,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。恢复时,会先检查数据页中的LSN,如果这个LSN小于redolog中的LSN,即write pos位置,说明在redolog上记录着数据页上尚未完成的操作,接着就会从最近的一个check point出发,开始同步数据。
那有没有可能数据页中的LSN大于redolog中的LSN呢?答案是当然可能。出现这种情况时,这时超出redolog的部分将不会重做,因为这本身就表示已经做过的事情,无需再重做。
redo log与binlog区别
redo log | binlog | |
---|---|---|
文件大小 | redo log的大小是固定的。 | binlog可通过配置参数max_binlog_size设置每个binlog文件的大小。 |
实现方式 | redo log是InnoDB引擎层实现的,并不是所有引擎都有。 | binlog是Server层实现的,所有引擎都可以使用 binlog日志 |
记录方式 | redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 | binlog 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上 |
适用场景 | redo log适用于崩溃恢复(crash-safe) | binlog适用于主从复制和数据恢复 |
由binlog和redo log的区别可知:binlog日志只用于归档,只依靠binlog是没有crash-safe能力的。但只有redo log也不行,因为redo log是InnoDB特有的,且日志上的记录落盘后会被覆盖掉。因此需要binlog和redo log二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。
两阶段提交
上面简单介绍了redolog和binlog,在对数据进行修改时,他们都会对这些修改进行保存落地,只是一个是物理日志,一个是逻辑日志。那他俩具体在修改过程中是如何执行的呢?
假设现在有一条update语句要执行,update from table_name set c=c+1 where id=2,执行流程如下:
示意图如下所示:
这种将redolog的写入拆分成prepare和commit两个步骤的过程称之为两阶段提交。
redolog 和binlog都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。如果不使用两阶段提交,而是先写其中一个再写另外一个可能会带来一些问题。
此时还是使用update来举例。假设当前id=2,有一个字段c=0,分别分析以下情况:
先写redolog再写binlog
假设先写redolog,当redolog写完,但是binlog还未写完的时候,此时MySQL突然出现异常导致重启。由于之前redolog已经写完,系统重启后,修改的记录仍然存在,所以恢复后这一行 c 的值是 1。但由于系统重启,binlog中并未有这条记录。之后备份日志的时候,存起来的binlog里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的binlog丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。
先写binlog再写redolog
假如先写binlog,然后写redolog的时候系统重启。重启之后,redolog中没有对c进行修改的记录,此时c的值还是0。但是 binlog里面已经记录了“把 c 从 0 改成 1”这个日志。所以,在之后用 binlog来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。
因此,综上所述,如果是先写某一个日志再写另一个日志,就会出现数据库的状态与使用binlog恢复出来的库的状态不一致的情况。
undolog主要用来记录某条行记录被修改之前的状态,记录的是修改前的数据。这样的话,当事务进行回滚时,就可以通过undolog将记录恢复到事务开始前的样子。事务的原子性和持久性也是依靠undolog来实现的。undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。同时,在进行数据恢复的时候,与binlog,redolog结合使用,保证了数据恢复的正确性。
undolog的作用流程如下所示:
需要注意的是,与redolog一样,undolog也是要先于数据页刷回到磁盘当中。在恢复数据时,如果undolog是完整的,可以根据undolog来回滚事务。
在一个事务当中,可能会对同一条数据进行多次修改,那么是不是每一次修改前的记录都要记录到undolog中呢?这样的话,会导致undolog日志量太大,此时redolog就要上场了。在一个事务当中,如果是对同一条记录进行修改,undolog只会记录事务开始前的原始记录,当再次对这条记录进行修改时,redolog会记录后续的变化。在数据恢复时,redolog完成前滚,undolog完成回滚,二者相互协调完成数据的恢复。过程如下所示:
还有一个功能就是MVCC多版本控制链了,这个请参考这篇文章
MySQL之MVCC实现原理
binlog,redolog和undolog是MySQL中最重要的三个日志,在进行数据恢复时,三者进行协调合作,保证数据恢复的正确性。
文章浏览阅读68次。我是参考 http://www.ibm.com/developerworks/cn/linux/l-ganglia-nagios-1/ 这篇文章搭建的ganglia,部分内容页引自这篇文章,与原文不同之处用红色标出,操作系统是CentOS 5.7 x86_64。安装 Ganglia先决条件假定您已经设置了 yum 库,安装先决条件在很大程度上应当十分简单。类...
文章浏览阅读7k次。Magics RP是比利时Materialise公司开发的、完全针对3D打印工序特征的软件,其目前最新版本为19.01。Magics为处理STL文件提供了理想的、完美的解决方案,具有功能强大、易用、高效等优点,是从事3D打印行业必不可少的软件。在3D打印行业,Magics常用于零件摆放、模型修复、添加支撑、切片等环节。 由于STL文件结构简单,没有几何拓扑_magics导入零件 stp
文章浏览阅读1.7k次。《转载》Oracle官方站:Oracle中文官网metalink.oracle.comOracle官方知识库,需要付费帐号登陆tahiti.oracle.comsearch and download documentation for Oracle's server productsOracle11gR1Online DocumentationOracle10gR2 Online Docu
文章浏览阅读872次,点赞22次,收藏26次。毫米波雷达是一种利用毫米波段电磁波来探测目标的雷达系统。它具有体积小、重量轻、功耗低、分辨率高、抗干扰能力强等优点,广泛应用于汽车、航空、航天、军事等领域。毫米波雷达的工作原理是:雷达发射机发射毫米波电磁波,电磁波遇到目标后反射,反射波被雷达接收机接收,并根据反射波的强度、频率和相位等信息来确定目标的位置、速度和姿态。毫米波雷达的接收发射信号主要包括以下几个步骤:发射信号毫米波雷达发射机产生毫米波电磁波,并通过天线发射出去。发射信号的频率、功率和波形等参数由雷达系统的设计要求决定。信号传播。_毫米波雷达仿真
文章浏览阅读6.4k次,点赞6次,收藏8次。for循环循环特定的次数,用end表示循环快结束。示例如下:注意n可以从1取到10,总共循环10次。while循环只要条件为真,就一直循环,用end表示循环快结束。示例如下:该程序中,设置n初值为10,然后进入while循环中。m为产生不大于n的一个随机数,当产生的随机数m和n相等时,退出循环。否则把n加1,再次循环。运行结果如下:if end条件控制if后面要和一个布尔表达式,后面再跟一个或者多个语句分割,就是一个if..end语句。运行如下:i_matlab设计问题if,while,for都包含的例题
文章浏览阅读159次。1、交通灯实例<!DOCTYPE html><html><head> <title>js04-1</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href=&qu_原生js怎么写
文章浏览阅读4.9k次,点赞4次,收藏11次。IDEA中快捷创建SpringBoot主启动类的方法的设置,自动同步同类名的参数_idea本地启动spring配置主类
文章浏览阅读2.7w次,点赞14次,收藏40次。主页面布局(main_activity.xml) LinearLayout 里面加一个Button,注意这里的LinearLayout要有orientation<?xml version="1.0" encoding="utf-8"?><LinearLayout ="http://schemas.android.com/apk..._android字符串动态生成view id
文章浏览阅读459次。2、设置合并优先级。选择字段,设置优先级。无需优先级,可以吧文字清空,则会根据与地块有相同信息字段的值来合并。[arcgis插件]尖锐角检查/批量处理工具,支持arcgis10.2-10.8版本。7、仅仅检查选中的地块:先选中地块再执行流程。5、处理流程设置:1 处理,2 切割,3 合并。6、顺便检查选择检查狭长面、自相交、重复节点。4、存在尖锐角并且面积小于这个面积阈值,则无需切割,直接合并。可以选择shp数据、GDB或者MDB的矢量面图层。年度变更,又是尖锐角,死磕尖锐角,就不信搞不定它。_arcgis如何查尖锐角
文章浏览阅读5k次。说明:1.BlackBerry_App_Descriptor.xml设置程序为Auto-run on startup,Do not display the application icon on the BlackBerry home screen2.手机开机后自动运行 BackgroundApplication3.主程序BackgroundApplication的main中,执行BackgroundThread.waitForSingleton().start();启动后台线程4.BackgroundTh_黑莓手机guid
文章浏览阅读9.9k次。oracle中查找执行效率低下的SQLkt431128 发布于 9个月前,共有 0 条评论v$sqltext:存储的是完整的SQL,SQL被分割v$sqlarea:存储的SQL 和一些相关的信息,比如累计的执行次数,逻辑读,物理读等统计信息(统计)v$sql:内存共享SQL区域中已经解析的SQL语句。(即时) select opname, ta_oracle 怎么抓取执行慢的sql
文章浏览阅读3k次。每当我遇到Unicode时,都没有用.我在Linux上,我从Windows获得这些文件:$file *file1: UTF-8 Unicode textfile2: ISO-8859 textfile3: ISO-8859 text在我发现文件有不同的编码之前,没有任何工作.我希望让我的生活变得轻松,并将它们全部放在相同的格式中:iconv -f UTF-8 -t ISO-8859 file1 &..._iso-8859 text