当前位置:网站首页>关系型数据库-MySQL:二进制日志(binlog)
关系型数据库-MySQL:二进制日志(binlog)
2022-08-04 05:26:00 【focus_lyh】
文章目录
一、作用
作用:记录所有变更类操作。
应用场景:
假如每天晚上12点进行一次数据库备份,此处不考虑数据量,备份时间等其他因素,那么在本次备份完成后到下次备份开始前的这段时间段中,如果数据库服务崩溃了,我们应该怎样恢复呢?
如果我们只依靠上一次的数据库备份进行恢复,那么我们最多只能恢复到上一个12点时的数据,但是12点以后的数据则会丢失,所以,我们还需要依靠二进制日志(binlog),我们先用上一次的备份将数据库恢复至最近一次12点时的样子,再利用binlog,将12点之后的所有操作”重放”一遍,由于上次备份之时到数据库崩溃之时之间的所有操作完完全全的重新执行了一遍,所以我们可以将数据库中的数据恢复至崩溃之时的样子,而不至于丢失数据,这就是binlog用于恢复时的作用。
思考一个新的问题,假设在执行某条修改数据库的语句时,用到了user()函数,那么当我们执行这条语句时,语句根据当前用户的信息修改了数据库,然后这条语句将被记录到binlog中,但是,语句被记录在binlog中时,并没有记录当前用户的信息,而是记录了”user()”这个函数本身的几个字符,当我们根据binlog再次重放这条语句时,如果重放这条语句的用户与这条语句被记录时所使用的用户不同,那么语句执行后的结果就不同,这样就导致根据binlog重放操作时,并不能得到与我们预想的完全一致的数据,这种情况在数据恢复时是不允许的,在主从复制时也不是我们期望看到的,所以,为了能够完全的还原日志被记录时的操作,我们应该记录对应语句到底修改了哪些行,并且记录对应语句对这些行进行了哪些修改,只有这样,才能保证我们在重放binlog时,执行的操作与记录日志时的操作是完全一致的,这样是安全了,但是,我们设想一下,如果我们执行了一条update语句,这条update语句涉及到10000行数据的修改,那么,我们就需要将这条sql涉及到的10000行数据修改都记录到binlog中,以便重放二进制日志时,能够还原当时的操作,这样与只记录一条update语句来说,记录的信息量就大的多了,这样想想,这两种记录方式还是各有优势的。当然,到底是让binlog以记录语句的模式进行记录,还是以记录数据修改的模式进行记录,可以通过配置binlog的记录模式来实现:statement、row、mixed。
statement模式:记录对数据库做出修改的语句,比如,update A set test=’test’,如果使用statement模式,那么这条update语句将会被记录到二进制日志中,使用statement模式时,优点是binlog日志量少,IO压力小,性能较高,缺点是为了能够尽量的完全一致的还原操作,除了记录语句本身以外,可能还需要记录一些相关的信息,而且,在使用一些特定的函数时,并不能保证恢复操作与记录时完全一致。
row模式(推荐):记录对数据库做出修改的语句所影响到的数据行以及这些行的修改,比如,update A set test=’test’,如果使用row模式,那么这条update语句所影响到的行所对应的修改,将会记录到binlog中,比如,A表中有1000条数据,那么当执行这条update语句以后,由于1000条数据都会被修改,所以会有1000行数据被记录到二进制日志中,以及它们是怎样被修改的,使用row模式时,优点是能够完全的还原或者复制日志被记录时的操作,缺点是记录日志量较大,IO压力大,性能消耗较大。
mixed模式:混合使用上述两种模式,一般的语句使用statment方式进行保存,如果遇到一些特殊的函数,则使用row模式进行记录,这种记录方式被称之为mixed,看上去这种方式似乎比较美好,但是在生产环境中,为了保险起见,一般会使用row模式。
管理员可以使用 binlog_format 变量设置二进制日志的记录方式,为了使配置永久生效,我们可以在 my.cnf 配置文件中加入如下配置,使用row模式记录 binlog:
binlog_format=row
二、二进制日志相关参数
log_bin
此变量用于控制是否开启二进制日志,而且这是一个只读变量,什么意思呢?默认情况下,启动数据库以后,在当前数据库连接中查看此变量的值,此变量值可能为 OFF,表示不记录二进制日志,如果想要记录二进制日志,只需将此值设置为二进制日志的文件名即可,但是需要注意的是,我们无法在当前会话中使用 set 命令设置 log_bin 的值,因为它是一个只读变量,我们只能通过修改 my.cnf 的方式,设置 log_bin 的值,假设,我们编辑 my.cnf 文件,设置 log_bin 的值为 mybinlog,那么,在mysql的数据目录中,将会自动生成一个以 mybinlog 为文件名前缀的二进制日志文件,如果想要再次禁用 binlog,只需要将log_bin这一行配置从 my.cnf 文件中注释即可,或者将其删除,重启 mysql 服务后,再次查看 log_bin 的值,其值为 OFF,注意,不要直接在 my.cnf 文件中将 log_bin 的值设置为 ON 或者 OFF ,如果这样做,你将会看到以 ON 或者 OFF 为文件名前缀的二进制日志文件。换句话说,如果 my.cnf 配置文件中没有 log_bin 的配置,则表示未开启二进制日志,如果 my.cnf 中存在 log_bin 的配置,那么则表示开启了二进制日志,同时二进制日志文件的名称将会以 log_bin 对应的值为文件名前缀,同时,二进制日志文件的后缀名会进行自动编号,每次日志滚动后,后缀名编号自动加1。sql_log_bin
此变量用于标识当前会话中的操作是否会被记录于二进制日志,此变量值设置为 ON,则表示在当前数据库连接中,对数据库进行修改的语句将会被记录到 binlog 中,此变量值设置为 OFF,则表示在当前数据库连接中,对数据库进行的修改的语句将不会被记录到 binlog 中,在主从复制结构中,这些语句由于没有被 binlog 记录,所以也不会同步到从节点中。换句话说,即使在my.cnf 配置文件中设置了 log_bin 的值,当前会话中,如果 sql_log_bin 的值设置为OFF,当前会话的操作也不会记录在二进制日志中。而且需要注意的是,sql_log_bin 是一个会话界别的变量,只能在当前会话中使用 set sql_log_bin 命令进行设置,不能使用 set global sql_log_bin 命令进行设置,因为它是会话级别的变量,而且 sql_log_bin 也不能配置在 my.cnf 文件中,否则可能会无法启动 mysql。binlog_format
此变量的值决定了二进制日志的记录方式,可以设置为 statement、row、mixed,分别表示以语句的形式记录二进制日志,以数据修改的形式记录二进制日志,以混合的方式记录二进制日志,安全保险起见,推荐使用row的方式记录。max_binlog_size
设置单个二进制日志文件的最大大小,以字节为单位,超过此值大小,则二进制日志文件会自动滚动,比如设置为500M为524288000。sync_binlog
还记的事务日志的相关文章吗?当把 innodb_flush_log_at_trx_commit 设置为1的时候,表示事务提交时,事务日志立马从内存刷写到磁盘中的事务日志文件中,而 sync_binlog 对于二进制日志的作用,就像 innodb_flush_log_at_trx_commit 对于事务日志的作用,由于二进制日志一开始存在于内存(binlog_cache)中,如果将 sync_binlog 设置为1,则表示每1次事务提交之后,都会立即将内存中的二进制日志立即同步到磁盘中的二进制日志文件中,如果将 sync_binlog 设置为0,则表示当事务提交之后,mysql 不会立即将内存中的 binlog 刷写到磁盘中的 binlog 日志文件中,而是由文件系统决定什么时候刷写,这可能取决于文件系统的缓存机制,当此值设置为 0 时,一旦操作系统宕机,那么将丢失未从内存中同步到磁盘中的 binlog,所以,当此值设置为 0 时,安全性最差,但是性能最高,当此值设置为 1 时,安全性最高,性能最差,除了将此值设置为 0 或 1,还能设置为N,假设将此值设置为3,则表示每3次事务提交后,将 binlog 从内存刷写到磁盘一次,值设置的越大,有可能丢失的日志数据将会越多,当然,性能会越好,在追求安全的情况下,推荐设置为1,但是听说,此值设置为0和设置为1时在性能上的差距还是比较明显的,如果设置为0或N,最好为操作系统准备带有备用电源的缓存。
边栏推荐
猜你喜欢
7.15 Day21---MySQL----索引
npm报错Beginning October 4, 2021, all connections to the npm registry - including for package installa
7.16 Day22---MYSQL(Dao模式封装JDBC)
基于C语言的学生信息管理系统_(更新版)_(附源码和安装包)_课程设计_**往事随風**的博客
解决JDBC在web工程中无法获取配置文件
Delphi-C端有趣的菜单操作界面设计
webrtc中视频采集实现分析(一) 采集及图像处理接口封装
4.3 基于注解的声明式事务和基于XML的声明式事务
Can‘t connect to MySQL server on ‘localhost3306‘ (10061) 简洁明了的解决方法
webrtc中的任务队列TaskQueue
随机推荐
The cost of automated testing is high and the effect is poor, so what is the significance of automated testing?
【JS】js给对象动态添加、设置、删除属性名和属性值
实现登录密码混合动态因子,且动态因子隐式
Cannot read properties of null (reading ‘insertBefore‘)
npm init [email protected] 构建项目报错SyntaxError: Unexpected token ‘.‘解决办法
Handling List
12. Paging plugin
大龄程序员的心理建设
Embedded system driver primary [3] - _IO model in character device driver foundation
EntityComponentSystemSamples学习笔记
thymeleaf中onclick事件动态传递参数问题
登录页面js手写
跨域问题的解决
webtrc 中VideoAdapter类中的作用及局限
力扣:96.不同的二叉搜索树
动态规划总括
8.03 Day34---BaseMapper query statement usage
【Matlab仿真】:一带电量为q的电荷以速度v运动,求运动电荷产生磁感应强度
php实现telnet访问端口
代码重构:面向单元测试