<<MySQL的1000个疑问>> 系列二:你的MySQL 二进制文件安全吗?
2011-12-01 15:43
381 查看
二进制文件是什么
二进制文件就是类似于mysql-bin.000001,mysql-bin.000002这样的文件。在my.cnf配置log-bin指定二进制文件位置与名称及开启二进制文件。
二进制文件的作用
我想大家都知道二进制文件的好处,主从数据同步,数据恢复都需要用到二进制文件。开启它会对性能一定影响,官网给的数据是影响1%,不过考虑到主从结构以及非常重要的数据恢复,这点影响完全有必要承受。
二进制文件的工作方式
我这里不对日志内部结构做说明,因为这涉及到日志格式。这里我只说明它的基本工作思路。也就是数据是怎么写到日志里面去的。
首先,MySQL会针对每一个事务,向二进制文件写入这条SQL。从库就可以利用这条SQL,在从库上执行来达到与主库数据同步的效果。在事务还没有提交commit之前,这条SQL会先被写入到二进制缓存里,就是binlog-cache.其大小由binlog_cache_size参数设置。在事务提交之后,再把二进制缓存里的数据写到二进制文件中。大体的工作方式就是这样。
二进制文件的危害
但问题来了,把二进制缓存里的数据写到二进制文件中,因为操作系统有Buffer的原因,其实这时数据并没有真正落地,也就是没有真正写入到日志中。如果这个时候断电,数据就会丢失。那么这种情况就会造成,数据库的数据与二进制文件里的数据无法对应,到时候从库通过执行二进制文件中的SQL就会与主库数据不同步。那么有没有解决办法?有,有个参数sync_binlog.这个参数表示,当执行多少条事务之后,将操作系统中的缓冲写刷新到磁盘。一般将值设为0,或者1。
sync_binlog = 0,完全由操作系统来负责将Buffer刷新到磁盘。
sync_binlog = 1,每次事务提交后就同步到磁盘。这种方式最安全,保证事务不会丢失。
这样做就能保证绝对安全吗?
NO。上文我提到Innodb的日志缓冲。将innodb_log_at_trx_commit=1,每次事务提交就将日志缓冲的数据刷新到日志文件中。那么现在,我们就至少知道,在事务提交后,需要做两个操作,一个是将二进制文件缓存刷新到磁盘上的二进制文件,另一个就是日志缓冲。那么有没有可能出现,这两个操作一个被执行了,而另一个没有被执行的情况呢?有,肯定有。如果二进制文件缓存刷写成功之后,突然MySQL进程崩溃,事务日志缓冲没有被刷写到磁盘上的日志文件,那么下次重启后,因为二进制文件存在最后一条SQL,而由于日志缓冲丢失,数据库中数据并没有被修改,那么就造成数据不一致。那有没有解决办法?有,肯定有。让这两个操作处于一个事务里面,要么同时成功,要么都失败。这样一来,问题就解决了。 MySQL提供了这个参数设置innodb_support_xa。将innodb_support_xa=1,就能保证这两个操作处在一个事务里。问题也就解决了。
二进制文件就是类似于mysql-bin.000001,mysql-bin.000002这样的文件。在my.cnf配置log-bin指定二进制文件位置与名称及开启二进制文件。
二进制文件的作用
我想大家都知道二进制文件的好处,主从数据同步,数据恢复都需要用到二进制文件。开启它会对性能一定影响,官网给的数据是影响1%,不过考虑到主从结构以及非常重要的数据恢复,这点影响完全有必要承受。
二进制文件的工作方式
我这里不对日志内部结构做说明,因为这涉及到日志格式。这里我只说明它的基本工作思路。也就是数据是怎么写到日志里面去的。
首先,MySQL会针对每一个事务,向二进制文件写入这条SQL。从库就可以利用这条SQL,在从库上执行来达到与主库数据同步的效果。在事务还没有提交commit之前,这条SQL会先被写入到二进制缓存里,就是binlog-cache.其大小由binlog_cache_size参数设置。在事务提交之后,再把二进制缓存里的数据写到二进制文件中。大体的工作方式就是这样。
二进制文件的危害
但问题来了,把二进制缓存里的数据写到二进制文件中,因为操作系统有Buffer的原因,其实这时数据并没有真正落地,也就是没有真正写入到日志中。如果这个时候断电,数据就会丢失。那么这种情况就会造成,数据库的数据与二进制文件里的数据无法对应,到时候从库通过执行二进制文件中的SQL就会与主库数据不同步。那么有没有解决办法?有,有个参数sync_binlog.这个参数表示,当执行多少条事务之后,将操作系统中的缓冲写刷新到磁盘。一般将值设为0,或者1。
sync_binlog = 0,完全由操作系统来负责将Buffer刷新到磁盘。
sync_binlog = 1,每次事务提交后就同步到磁盘。这种方式最安全,保证事务不会丢失。
这样做就能保证绝对安全吗?
NO。上文我提到Innodb的日志缓冲。将innodb_log_at_trx_commit=1,每次事务提交就将日志缓冲的数据刷新到日志文件中。那么现在,我们就至少知道,在事务提交后,需要做两个操作,一个是将二进制文件缓存刷新到磁盘上的二进制文件,另一个就是日志缓冲。那么有没有可能出现,这两个操作一个被执行了,而另一个没有被执行的情况呢?有,肯定有。如果二进制文件缓存刷写成功之后,突然MySQL进程崩溃,事务日志缓冲没有被刷写到磁盘上的日志文件,那么下次重启后,因为二进制文件存在最后一条SQL,而由于日志缓冲丢失,数据库中数据并没有被修改,那么就造成数据不一致。那有没有解决办法?有,肯定有。让这两个操作处于一个事务里面,要么同时成功,要么都失败。这样一来,问题就解决了。 MySQL提供了这个参数设置innodb_support_xa。将innodb_support_xa=1,就能保证这两个操作处在一个事务里。问题也就解决了。
相关文章推荐
- <<MySQL的1000个疑问>> 系列一:你的innodb 日志缓冲安全吗?
- <<Magento2 命令行安装及演示数据>>系列
- 文件读写操作之一 <二进制读写操作> fwrite与fread
- spring配置文件中的<value></value>
- Spring配置文件中使用ref local与ref bean的区别. 在ApplicationResources.properties文件中,使用<ref bean>与<ref local>方法如下
- <<醒了自悟>>系列-bozo---虫不知---Don't know what you don't know
- <style><script> css和js文件引入
- Android 源码系列之<三>从安全的角度深入理解BroadcastReceiver(下)
- <<深入理解mariadb和mysql>>之mysql执行计划分析学习记录
- c3p0 xml配置文件模版 [html] view plain copy <c3p0-config> <default-config> <property name=
- mysql mybatis xml配置文件<property name="url" value="" />
- Spring配置文件中使用ref local与ref bean的区别. 在ApplicationResources.properties文件中,使用<ref bean>与<ref local>方法如下
- <p><span style="font-size:14px">近期须要批量将PNM格式的文件转换成GIF文件。我尝试了例如以下的图像转换工具:</span></p>
- <<深入理解mariadb和mysql>>之mysql优化学习记录
- <<醒了自悟>>系列--Go On... OR Stop...
- Android 源码系列之<二>从安全的角度深入理解BroadcastReceiver(上)
- <<读书笔记>>系列--VB2005-菜根谭
- <<C++ design patterns and Derivatives Pricing>> 学习系列 CH1-对蒙特卡洛基本理解
- 对<<寒江独钓---Windows内核安全编程>>中第3章<<串口过滤>>的改进
- 实时开发框架Meteor 实际应用系列<一>---文件的上传和下载