专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

MySQL不会丢失数据的秘密,就藏在它的7种日志里

  进入正题前先简单看看MySQL的逻辑架构,相信我用的着。
  MySQL逻辑架构
  MySQL的逻辑架构大致可以分为三层: 第一层:处理客户端连接、授权认证,安全校验等。 第二层:服务器 server 层,负责对SQL解释、分析、优化、执行操作引擎等。第三层:存储引擎,负责MySQL中数据的存储和提取。
  我们要知道MySQL的服务器层是不管理事务的,事务是由存储引擎实现的,而MySQL中支持事务的存储引擎又属 InnoDB 使用的最为广泛,所以后续文中提到的存储引擎都以InnoDB 为主。
  MySQL数据更新流程
  记住!   记住!   记住!  上边这张图,她是MySQL更新数据的基础流程,其中包括 redo log 、bin log 、undo log 三种日志间的大致关系,好了闲话少说直奔主题。redo log(重做日志)
  redo log 属于MySQL存储引擎InnoDB 的事务日志。
  MySQL的数据是存放在磁盘中的,每次读写数据都需做磁盘IO操作,如果并发场景下性能就会很差。为此MySQL提供了一个优化手段,引入缓存 Buffer Pool 。这个缓存中包含了磁盘中部分数据页(page )的映射,以此来缓解数据库的磁盘压力。
  当从数据库读数据时,首先从缓存中读取,如果缓存中没有,则从磁盘读取后放入缓存;当向数据库写入数据时,先向缓存写入,此时缓存中的数据页数据变更,这个数据页称为 脏页 , Buffer Pool 中修改完数据后会按照设定的更新策略,定期刷到磁盘中,这个过程称为刷脏页。MySQL宕机
  如果刷脏页还未完成,可MySQL由于某些原因宕机重启,此时 Buffer Pool 中修改的数据还没有及时的刷到磁盘中,就会导致数据丢失,无法保证事务的持久性。
  为了解决这个问题引入了 redo log ,redo Log如其名侧重于重做!它记录的是数据库中每个页的修改,而不是某一行或某几行修改成怎样,可以用来恢复提交后的物理数据页,且只能恢复到最后一次提交的位置。
  redo log 用到了WAL (Write-Ahead Logging)技术,这个技术的核心就在于修改记录前,一定要先写日志,并保证日志先落盘,才能算事务提交完成。
  有了redo log再修改数据时,InnoDB引擎会把更新记录先写在redo log中,在修改 Buffer Pool 中的数据,当提交事务时,调用fsync 把redo log刷入磁盘。至于缓存中更新的数据文件何时刷入磁盘,则由后台线程异步处理。
  注意 :此时redo log的事务状态是 prepare ,还未真正提交成功,要等bin log 日志写入磁盘完成才会变更为commit ,事务才算真正提交完成。
  这样一来即使刷脏页之前MySQL意外宕机也没关系,只要在重启时解析redo log中的更改记录进行重放,重新刷盘即可。 大小固定
  redo log采用固定大小,循环写入的格式,当redo log写满之后,重新从头开始如此循环写,形成一个环状。
  那为什么要如此设计呢?
  因为redo log记录的是数据页上的修改,如果 Buffer Pool 中数据页已经刷磁盘后,那这些记录就失效了,新日志会将这些失效的记录进行覆盖擦除。
  上图中的 write pos 表示redo log当前记录的日志序列号LSN (log sequence number),写入还未刷盘,循环往后递增;check point 表示redo log中的修改记录已刷入磁盘后的LSN,循环往后递增,这个LSN之前的数据已经全落盘。
  write pos 到check point 之间的部分是redo log空余的部分(绿色),用来记录新的日志;check point 到write pos 之间是redo log已经记录的数据页修改数据,此时数据页还未刷回磁盘的部分。当write pos 追上check point 时,会先推动check point 向前移动,空出位置(刷盘)再记录新的日志。
  注意 :redo log日志满了,在擦除之前,需要确保这些要被擦除记录对应在内存中的数据页都已经刷到磁盘中了。擦除旧记录腾出新空间这段期间,是不能再接收新的更新请求的,此刻MySQL的性能会下降。所以在并发量大的情况下,合理调整redo log的文件大小非常重要。 crash-safe
  因为redo log的存在使得 Innodb 引擎具有了crash-safe 的能力,即MySQL宕机重启,系统会自动去检查redo log,将修改还未写入磁盘的数据从redo log恢复到MySQL中。
  MySQL启动时,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。会先检查数据页中的 LSN ,如果这个 LSN 小于 redo log 中的LSN,即write pos 位置,说明在redo log 上记录着数据页上尚未完成的操作,接着就会从最近的一个check point 出发,开始同步数据。
  简单理解,比如:redo log的 LSN 是500,数据页的LSN 是300,表明重启前有部分数据未完全刷入到磁盘中,那么系统则将redo log中LSN 序号300到500的记录进行重放刷盘。
  undo log(回滚日志)
  undo log 也是属于MySQL存储引擎InnoDB的事务日志。
  undo log 属于逻辑日志,如其名主要起到回滚的作用,它是保证事务原子性的关键。记录的是数据修改前的状态,在数据修改的流程中,同时会记录一条与当前操作相反的逻辑日志到undo log 中。
  我们举个栗子:假如更新ID=1记录的name字段,name原始数据为小富,现改name为程序员内点事
  事务执行 update X set name = 程序员内点事 where id =1 语句时,先会在undo log 中记录一条相反逻辑的update X set name = 小富 where id =1 记录,这样当某些原因导致服务异常事务失败,就可以借助undo log 将数据回滚到事务执行前的状态,保证事务的完整性。
  那可能有人会问:同一个事物内的一条记录被多次修改,那是不是每次都要把数据修改前的状态都写入 undo log 呢?
  答案是不会的!
  undo log 只负责记录事务开始前要修改数据的原始版本,当我们再次对这行数据进行修改,所产生的修改记录会写入到redo log ,undo log 负责完成回滚,redo log 负责完成前滚。回滚
  未提交的事务,即事务未执行 commit 。但该事务内修改的脏页中,可能有一部分脏块已经刷盘。如果此时数据库实例宕机重启,就需要用回滚来将先前那部分已经刷盘的脏块从磁盘上撤销。前滚
  未完全提交的事务,即事务已经执行 commit ,但该事务内修改的脏页中只有一部分数据被刷盘,另外一部分还在buffer pool 缓存上,如果此时数据库实例宕机重启,就需要用前滚来完成未完全提交的事务。将先前那部分由于宕机在内存上的未来得及刷盘数据,从redo log 中恢复出来并刷入磁盘。
  数据库实例恢复时,先做前滚,后做回滚。
  如果你仔细看过了上边的  MySQL数据更新流程图  就会发现,undo log 、redo log 、bin log 三种日志都是在刷脏页之前就已经刷到磁盘了的,相互协作最大限度保证了用户提交的数据不丢失。bin log(归档日志)
  bin log 是一种数据库Server层(和什么引擎无关),以二进制形式存储在磁盘中的逻辑日志。bin log 记录了数据库所有DDL 和DML 操作(不包含 SELECT  和 SHOW 等命令,因为这类操作对数据本身并没有修改)。
  默认情况下,二进制日志功能是关闭的。可以通过以下命令查看二进制日志是否开启: mysql> SHOW VARIABLES LIKE "log_bin"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin       | OFF   | +---------------+-------+
  bin log 也被叫做归档日志 ,因为它不会像redo log 那样循环写擦除之前的记录,而是会一直记录日志。一个bin log 日志文件默认最大容量1G (也可以通过max_binlog_size 参数修改),单个日志超过最大值,则会新创建一个文件继续写。mysql> show binary logs; +-----------------+-----------+ | Log_name        | File_size | +-----------------+-----------+ | mysq-bin.000001 |      8687 | | mysq-bin.000002 |      1445 | | mysq-bin.000003 |      3966 | | mysq-bin.000004 |       177 | | mysq-bin.000005 |      6405 | | mysq-bin.000006 |       177 | | mysq-bin.000007 |       154 | | mysq-bin.000008 |       154 |
  bin log 日志的内容格式其实就是执行SQL命令的反向逻辑,这点和undo log 有点类似。一般来说开启bin log 都会给日志文件设置过期时间(expire_logs_days 参数,默认永久保存),要不然日志的体量会非常庞大。mysql> show variables like "expire_logs_days"; +------------------+-------+ | Variable_name    | Value | +------------------+-------+ | expire_logs_days | 0     | +------------------+-------+ 1 row in set  mysql> SET GLOBAL expire_logs_days=30; Query OK, 0 rows affected
  bin log 主要应用于MySQL主从模式(master-slave )中,主从节点间的数据同步;以及基于时间点的数据还原。主从同步
  通过下图MySQL的主从复制过程,来了解下 bin log 在主从模式下的应用。
  用户在主库 master 执行DDL 和DML 操作,修改记录顺序写入bin log ;从库 slave 的I/O线程连接上Master,并请求读取指定位置position 的日志内容;Master 收到从库slave 请求后,将指定位置position 之后的日志内容,和主库bin log文件的名称以及在日志中的位置推送给从库;slave的I/O线程接收到数据后,将接收到的日志内容依次写入到 relay log 文件最末端,并将读取到的主库bin log文件名和位置position 记录到master-info 文件中,以便在下一次读取用;slave的SQL线程检测到 relay log 中内容更新后,读取日志并解析成可执行的SQL语句,这样就实现了主从库的数据一致;基于时间点还原
  我们看到 bin log 也可以做数据的恢复,而redo log 也可以,那它们有什么区别?层次不同:redo log 是InnoDB存储引擎实现的,bin log 是MySQL的服务器层实现的,但MySQL数据库中的任何存储引擎对于数据库的更改都会产生bin log。 作用不同:redo log 用于碰撞恢复( crash recovery ),保证MySQL宕机也不会影响持久性;bin log 用于时间点恢复(point-in-time recovery ),保证服务器可以基于时间点恢复数据和主从复制。内容不同:redo log 是物理日志,内容基于磁盘的页 Page ;bin log的内容是二进制,可以根据binlog_format 参数自行设置。写入方式不同:redo log 采用循环写的方式记录;binlog 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上。 刷盘时机不同:bin log在事务提交时写入;redo log 在事务开始时即开始写入。
  bin log 与 redo log 功能并不冲突而是起到相辅相成的作用,需要二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。 relay log(中继日志)
  relay log 日志文件具有与bin log 日志文件相同的格式,从上边MySQL主从复制的流程可以看出,relay log 起到一个中转的作用,slave 先从主库master 读取二进制日志数据,写入从库本地,后续再异步由SQL线程 读取解析relay log 为对应的SQL命令执行。slow query log
  慢查询日志( slow query log ): 用来记录在 MySQL 中执行时间超过指定时间的查询语句,在 SQL 优化过程中会经常使用到。通过慢查询日志,我们可以查找出哪些查询语句的执行效率低,耗时严重。
  出于性能方面的考虑,一般只有在排查慢SQL、调试参数时才会开启,默认情况下,慢查询日志功能是关闭的。可以通过以下命令查看是否开启慢查询日志: mysql> SHOW VARIABLES LIKE "slow_query%"; +---------------------+--------------------------------------------------------+ | Variable_name       | Value                                                  | +---------------------+--------------------------------------------------------+ | slow_query_log      | OFF                                                    | | slow_query_log_file | /usr/local/mysql/data/iZ2zebfzaequ90bdlz820sZ-slow.log | +---------------------+--------------------------------------------------------+
  通过如下命令开启慢查询日志后,我发现  iZ2zebfzaequ90bdlz820sZ-slow.log  日志文件里并没有内容啊,可能因为我执行的 SQL 都比较简单没有超过指定时间。mysql>  SET GLOBAL slow_query_log=ON; Query OK, 0 rows affected
  上边提到超过  指定时间  的查询语句才算是慢查询,那么这个时间阈值又是多少嘞?我们通过 long_query_time  参数来查看一下,发现默认是 10 秒。mysql> SHOW VARIABLES LIKE "long_query_time"; +-----------------+-----------+ | Variable_name   | Value     | +-----------------+-----------+ | long_query_time | 10.000000 | +-----------------+-----------+
  这里我们将  long_query_time  参数改小为 0.001秒再次执行查询SQL,看看慢查询日志里是否有变化。mysql> SET GLOBAL long_query_time=0.001; Query OK, 0 rows affected
  果然再执行 SQL 的时,执行时间大于 0.001秒,发现慢查询日志开始记录了。
  慢查询日志 general query log
  一般查询日志( general query log ):用来记录用户的所有操作,包括客户端何时连接了服务器、客户端发送的所有SQL 以及其他事件,比如 MySQL  服务启动和关闭等等。MySQL 服务器会按照它接收到语句的先后顺序写入日志文件。
  由于一般查询日志记录的内容过于详细,开启后 Log 文件的体量会非常庞大,所以出于对性能的考虑,默认情况下,该日志功能是关闭的,通常会在排查故障需获得详细日志的时候才会临时开启。
  我们可以通过以下命令查看一般查询日志是否开启,命令如下: mysql> show variables like "general_log"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | general_log   | OFF   | +---------------+-------+
  下边开启一般查询日志并查看日志存放的位置。 mysql> SET GLOBAL general_log=on; Query OK, 0 rows affected mysql> show variables like "general_log_file"; +------------------+---------------------------------------------------+ | Variable_name    | Value                                             | +------------------+---------------------------------------------------+ | general_log_file | /usr/local/mysql/data/iZ2zebfzaequ90bdlz820sZ.log | +------------------+---------------------------------------------------+
  执行一条查询 SQL 看看日志内容的变化。 mysql> select * from t_config; +---------------------+------------+---------------------+---------------------+ | id                  | remark     | create_time         | last_modify_time    | +---------------------+------------+---------------------+---------------------+ | 1325741604307734530 | 我是广播表 | 2020-11-09 18:06:44 | 2020-11-09 18:06:44 | +---------------------+------------+---------------------+---------------------+
  我们看到日志内容详细的记录了所有执行的命令、SQL、SQL的解析过程、数据库设置等等。
  一般查询日志 error log
  错误日志( error log ): 应该是 MySQL 中最好理解的一种日志,主要记录 MySQL 服务器每次启动和停止的时间以及诊断和出错信息。
  默认情况下,该日志功能是开启的,通过如下命令查找错误日志文件的存放路径。 mysql> SHOW VARIABLES LIKE "log_error"; +---------------+----------------------------------------------------------------+ | Variable_name | Value                                                          | +---------------+----------------------------------------------------------------+ | log_error     | /usr/local/mysql/data/LAPTOP-UHQ6V8KP.err | +---------------+----------------------------------------------------------------+
  注意 :错误日志中记录的可并非全是错误信息,像 MySQL 如何启动  InnoDB  的表空间文件、如何初始化自己的存储引擎,初始化 buffer pool  等等,这些也记录在错误日志文件中。
  总结
  MySQL作为我们工作中最常接触的中间件,熟练使用只算是入门,如果要在简历写上一笔精通,还需要深入了解其内部工作原理,而这7种日志也只是深入学习过程中的一个起点,学无止境,兄嘚干就完了!

S23赛季更新时间确定,赛季皮肤给到程咬金,元芳喜提限定皮肤文在下小飞解说小飞出品,必是精品。大家好,我是每天都会更新游戏资讯的小飞。前言S22赛季即将结束,但还有很多玩家还没上王者,这里我推荐玩中路和发育路位置上分比较快,今天就来聊聊S2钻石消耗活动即将开启,纯白花嫁返场,多款史诗皮肤限时打折文小飞解说小飞出品,必是精品,大家好,我是每天都会更新游戏资讯的小飞。王者荣耀官方每次会在赛季中旬会开启钻石消耗活动,本赛季的时间已经过半,相信3月末将会开启钻石消耗活动,3月143款皮肤返场,狂铁特工战影免费获得,辅助配传说皮肤吗狂铁特工战影狂铁这款皮肤被官方贴上活动专属皮肤,仔细的小伙伴会发现上几次高级梦境都是出那几个英雄,几乎好多玩家都拥有里面三款皮肤,而且狂铁这个皮肤的特效也不属于史诗皮肤,所以很大概碎片商店更新内容爆料,露娜新皮肤特效曝光,品质堪比史诗文白猫解说白猫出品,必是精品,大家好我是每天都会更新游戏资讯的白猫。王者荣耀是一款非常火爆的游戏,里面的英雄数量也是非常多,而英雄皮肤更是做的精致,很多皮肤都是买的,碎片商店是零充宝藏主播!被誉为国服猴第一人,青帝到底是怎么理解猴子的?最近虎牙青帝火了起来,原因就是因为他用猴子打野在巅峰赛打上了前十。要知道现在是赛季初,各大技术主播纷纷上场秀操作,其中不乏有北慕,微凉和韩涵这样的实力打野主播。但青帝只使用一个猴子孙悟空皮肤返场,钻石消耗活动开启,瑶传说皮肤封面曝光文小飞解说小飞出品,必是精品,大家好我是每天都会更新游戏资讯的小飞。前言每个赛季中旬,王者荣耀都会更新一些福利活动,不出意外的话距离S24赛季开启还有30多天,这就意味着王者荣耀将9号迎来更新,皮肤两下三返场,特工战影烂大街,水晶留给新皮肤文白猫解说白猫出品,必是精品,大家好我是每天都会更新游戏资讯的白猫解说。前言王者荣耀每次更新都会出现一些新的主题和新的活动,露娜的六元新皮肤上架英雄的调整王者都出现了小的更新。今天3月即将上线皮肤,露娜桂冠女神皮肤,西施,杨玉环新皮肤优化文小飞解说小飞出品,必是精品,大家好,我是每天都会更新游戏资讯的小飞。前言2月即将结束,3月即将开始,在2月份因春节原因,王者荣耀出了很多皮肤还包括一些返场皮肤,那么今天就来聊聊3王者联动西游记皮肤官宣,猴子喜提新传说皮肤,狼狗有望得新皮肤文子飞解说大家好,我是每天都会更新游戏资讯的子飞。前言就在今天王者荣耀与86版的西游记首次联动,这次的官宣视频里面师徒四人西天取经,这就表明王者官方会在这四人中联动皮肤。王者荣耀作电玩小子星元皮肤特效曝光,蒙犽端午节皮肤预热被网友疯狂吐槽文栀子飞解说小飞出品,必是精品,大家好,我是每天都会更新游戏资讯的小飞。前言鲁班的电玩小子第一个星元皮肤出自s22战令进阶版,而官方又为电玩小子设计了两款星元皮肤,和一个电子鲨鱼武王者荣耀孙悟空新皮肤特效曝光,出场动画经典还原首周532点券文王者先知菌001大家好,我是每天都会更新游戏资讯的先知菌。前言孙悟空作为峡谷里元老级英雄,也是拥有九款皮肤的英雄,这次孙悟空第十款新皮肤特效曝光,这款新皮肤是王者荣耀与86版西游
8个月过去,赛博朋克2077现在怎么样,值得一玩吗?要问2020年全球游戏玩家最期待的游戏,赛博朋克2077一定位列榜首。记得在去年12月发售前,网上铺天盖地的都是2077的醒目黄颜色。现在8个月过去了,游戏在8。18号也迎来了新的恒大汽车!戴雷新东家定了又一名汽车大佬加入!记者获悉,汽车界的明星职业经理人戴雷(DanielKirchert)已正式入职恒大汽车并担任常务副总裁。汽车经理人戴雷戴雷出生于德国,在汽车行业拥有19年经验,车主访谈从Mustang到Shelby,年轻的我经历了什么对于很多Mustang的车主来说,买一辆Mustang只是圆梦的开始,而后续的改装才是他们的漫漫长路,今天车界慢慢弹迎来了这样一位Mustang年轻车主小陆,他的Mustang改成剧情注水不讲瓜德网友喊话河南车主张女士再不检测可要弃剧了近期,官方相继发布几起特斯拉相关事故的调查结果,加之河南车主温先生自爆言论不断,大瓜一波三折然而相比事故发生时的媒体报道的热度,这些来自官方权威的真相结果,似乎并没有引起太大的关注这是奥迪的未来?GrandSphere概念车预告图发布未来汽车是什么样?每个汽车厂商有每个汽车厂商的想法,比如奥迪,近日就发布了代表奥迪未来的概念车GrandSphere。从目前的曝光的照片上看,这款车的设计感非常的圆润,和如今奥迪家马超到底经历了什么,为何成为对抗路垫底英雄?神威返场还有必要吗?峡谷英雄千千万,而我独爱小卤蛋,大家好我是逍遥学长。马超到底经历了什么,为何成为对抗路垫底英雄?神威返场还有必要吗?不知不觉中王者荣耀s24赛季就已经过去一大半了,大概下个月月底就魔兽世界TBCP2术士生存指南,金团打工仔,团本天花板术士一直以来都是被玩家们称为了DPS的天花板,但是因为操作难度相对来说比较大一些所以职业密度会比法师小很多,并且在输出能力上一般都会超越法师,不过自从奥法这个玩法出现以来似乎在WC魔兽世界TBC等级不足没办法赚G?野外打怪,收益更高很多玩家们在游戏中十分羡慕那些排骨人,可以将自己所热爱的一切变成了自己的工作,并且一些排骨人每天靠打游戏就在魔兽世界中搬砖月入都不低,并且还能每天享受着游戏。但是很多玩家们却在游戏魔兽世界TBC拍卖行部分价格虚高?谨防黑心团长,小心工作室前几天更新一期内容,大致是讲拍卖行中存在部分价格虚高的产品,而造成这些产品价格虚高的主要原因来自于一些玩家们进行恶意设置价格,然后就会使得一些插件中给出的建议价格出现了虚高,但是很魔兽世界TBC凤凰最值得入手?别被金团骗了,虚空鳐才是首选说起坐骑这可能是玩家们心中难以磨灭的痛,坐骑系统一直以来被称为魔兽世界游戏中系统回收G币最多的一个设定,并且几乎每个玩家都会被系统掠夺走大量的G币,以70级的骑术为例,一般正常的玩魔兽世界TBC时光徽章新高,工作室背锅,排骨人是原罪?最近很多人都在讨论说目前魔兽世界怀旧服TBC中的时光徽章价格屡破新高,一个月之前的时光徽章价格普遍都维持在1600G币一个,并且有时候还会低于1500G币,但是短短几天时间时光徽章
友情链接:快好知快生活快百科快传网中准网文好找聚热点快软件