MySQL:日志知识点盘点

本篇内容包括:binlog(二进制日志)、redo log 以及 undo log

一、binlog(二进制日志)

binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。

  • 逻辑日志:可以简单理解为记录的就是sql语句。
  • 物理日志:因为mysql数据最终是保存在数据页中的,物理日志记录的就是数据页变更。

binlog是通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。

1、binlog使用场景

在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。

  • 主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
  • 数据恢复:通过使用mysqlbinlog工具来恢复数据。

2、binlog刷盘时机

对于InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中,那么biglog是什么时候刷到磁盘中的呢?mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:

  • 0:不去强制要求,由系统自行判断何时写入磁盘;
  • 1:每次commit的时候都要将binlog写入磁盘;
  • N:每N个事务,才会将binlog写入磁盘。

从上面可以看出,sync_binlog最安全的是设置是1,这也是MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

3、inlog日志格式

binlog日志有三种格式,分别为STATMENT、ROW和MIXED。

在 MySQL 5.7.7之前,默认的格式是STATEMENT,MySQL 5.7.7之后,默认值是ROW。日志格式通过binlog-format指定。

  • STATMENT:基于SQL语句的复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog中。
    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO, 从而提高了性能;
    • 缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、slepp()等。
  • ROW:基于行的复制(row-based replication, RBR),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了。
    • 优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题;
    • 缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨
  • MIXED:基于STATMENT和ROW两种模式的混合复制(mixed-based replication, MBR),一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog

二、redo log

1、为什么需要redo log

我们都知道,事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么mysql是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:

  • 因为Innodb是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!
  • 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差!

因此mysql设计了redo log,具体来说就是只记录事务对数据页做了哪些修改,这样就能完美地解决性能问题了(相对而言文件更小并且是顺序IO)。

搜索Java知音公众号,回复“后端面试”,送你一份Java面试题宝典

2、redo log基本概念

redo log包括两部分:一个是内存中的日志缓冲(redo log buffer),另一个是磁盘上的日志文件(redo log file)。mysql每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。这种先写日志,再写磁盘的技术就是MySQL里经常说到的WAL(Write-Ahead Logging) 技术。

在计算机操作系统中,用户空间(user space)下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer写入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中。

3、redo log记录形式

前面说过,redo log实际上记录数据页的变更,而这种变更记录是没必要全部保存,因此redo log实现上采用了大小固定,循环写入的方式,当写到结尾时,会回到开头循环写日志。

同时我们很容易得知,在innodb中,既有redo log需要刷盘,还有数据页也需要刷盘,redo log存在的意义主要就是降低对数据页刷盘的要求。在上图中,write pos表示redo log当前记录的LSN(逻辑序列号)位置,check point表示数据页更改记录刷盘后对应redo log所处的LSN(逻辑序列号)位置。

write pos到check point之间的部分是redo log空着的部分,用于记录新的记录;check point到write pos之间是redo log待落盘的数据页更改记录。当write pos追上check point时,会先推动check point向前移动,空出位置再记录新的日志。

启动innodb的时候,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。因为redo log记录的是数据页的物理变化,因此恢复的时候速度比逻辑日志(如binlog)要快很多。

重启 innodb 时,首先会检查磁盘中数据页的LSN,如果数据页的LSN小于日志中的LSN,则会从checkpoint开始恢复。

还有一种情况,在宕机前正处于checkpoint的刷盘过程,且数据页的刷盘进度超过了日志页的刷盘进度,此时会出现数据页中记录的LSN大于日志中的LSN,这时超出日志进度的部分将不会重做,因为这本身就表示已经做过的事情,无需再重做。

4、redo log与binlog区别

由binlog和redo log的区别可知:binlog日志只用于归档,只依靠binlog是没有crash-safe能力的。但只有redo log也不行,因为redo log是InnoDB特有的,且日志上的记录落盘后会被覆盖掉。因此需要binlog和redo log二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。


三、undo log

数据库事务四大特性中有一个是原子性,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。

实际上,原子性底层就是通过undo log实现的。undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/535512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROWNUM的使用

一个伪列看起来像是一个表中的列,但实际上并不保存在表中。你可以查询, 但是不能插入,修改和删除其中的值。一个伪列也类似于一个没有参数的函 数。但是在典型情况下,在结果集中可以为每一行返回相同的值,而伪列通 常为…

MySQL:主从相关知识点盘点

本篇内容包括:MySQL 主从复制简介、主从复制的原理以及主从搭建 一、MySQL 主从复制简介 在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能,一般都会采用**「主从复制」**。 比如:在复杂的业务系统中&#x…

oracle导出expdp

expdp/impdp 是 oracle 10g 版本后推出的服务器端工具--数据泵,作用是为了将数据库中的逻辑对象,比如表、用户、全库、表空间进 行导入,导出 命令解析 ATTACH ATTACH [[schema_name.]job_name] schema_name 表示用户名,job_name 表示导出的作…

oracle导入impdp

expdp/impdp 是 oracle 10g 版本后推出的服务器端工具--数据泵,作用是为了将数据库中的逻辑对象,比如表、用户、全库、表空间进 行导入,导出REMAP_DATAFILE 该选项用于将源数据文件名转变为目标数据文件名, 在不同平台之间搬移表空间时可能需…

oracle高水位线

ORACLE在逻辑存储上分4个粒度: 表空间, 段, 区 和 块. 1.1 块: 是粒度最小的存储单位,现在标准的块大小是8K,ORACLE每一次I/O操作也是按块来操作的,也就是说当ORACLE从数据文件读数据时,是读取多少个块,而不是多少行. 每一个Block里可以包含多个row. 1.2 区:…

oracle检查点

检 查 点 概述 ■l当修改数据时,需要首先将数据读入内存中(Buffer Cache),修改数据的同时,Oracle会记录重做信息(Redo)用于恢复。因 为有了重做信息的存在,Oracle不需要在提交时…

文献翻译:Java theory and practice: Fixing the Java Memory Model, Part 2

Java theory and practice: Fixing the Java Memory Model, Part 2 译:Java 理论与实践:修复 Java 内存模型,第 2 部分 翻译自:http://www.ibm.com/developerworks/library/j-jtp03304/(原文写于2004年3月&#xff0…

oracle的buffercache

LRU空闲或者干净的链,可以从这里找到未修改的数据LRUW脏链,一个脏块同时挂到了lruw和检查点队列,LRUW分冷端和热端,冷端即为更新频率较低的一端,热端为更新频率较高的一端,dbwn写入数据文件时从冷端开始写入…

oracle的undo

Undo段中区的状态free expiredinactiveactive 显示UNDO区信息 SELECT extent_ id, bytes, status FROM dba_ _undo_ _extentsWHERE segment_ name SYSSMU1S ; 图解一一个事务的操作流程 Undo段的组成:段头、回滚块 事务ID …

SQLPlus命令详细说明

SQLPlus命令详细说明 2011-10-19 17:23:01 分类: Oracle 1. 执行一个SQL脚本文件 SQL>start file_name SQL> file_name 2. 对当前的输入进行编辑 SQL>edit 3. 重新运行上一次运行的sql语句 SQL>/ 4. 将显示的内容输出到指定文件 SQL> S…

oracle的EMCTL

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。 C:\Users\Administrator>emctl start dbconsole Environment variable ORACLE_UNQNAME not defined. Please set ORACLE_UNQNAME to da tabase unique name. C:\Users\Administ…

RHEL7 修改SSH默认端口

1.查询seliunx [roottest10597 ~]# getenforce Enforcing [roottest10597 ~]# semanage port -l|grep ssh ssh_port_t tcp 222.设置selinux端口 [roottest10597 ~]# semanage port -a -t ssh_port_t -p tcp 10022 [roottest10597 ~]# semanage …

oracle预定义异常

NO_DATA_FOUND:执行查询无数据、引用一个末初使化的表、通过UTL_FILE包调用到尾的文件TOO_MANY_ROWS:采用SELECT INTO语句,但返回的记录超过了1条DUP_VAL_ON_INDEX:插入或者更新语句,与唯一索引相冲突TIMEOUT_ON_RESOURCE:等待资源…

常用系统函数oracle

单行函数日期函数ADD_MONTHS(date, n):用于从一个日期值增加或减少一些月份 MONTHS_BETWEEN(date1, date2):判断两个日期之间相差的月份 LAST_DAY(date): 函数返回包含日期的月份的最后一天 ROUND(date[,fmt]): 将日期d按照fmt指定的格式舍入,fmt为字符串 TRU…

oracle游标

游标(cursor )是一个私有的SQL工作区域,是一个指向上下文区的句柄或指针,位于内存中的 "临时表"。 游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某…

找出占用cpu最高的线程

ps -eo %cpu,pid |sort -n -k1 -r | head -n 1| awk {print $2}| xargs top -b -n1 -Hp | grep COMMAND -A1 |tail -n 1 |awk {print $1}| xargs printf 0x%x ➊ 在命令行输入top,然后shiftp查看占用CPU最高的进程,记下进程号 ➋ 在命令行输入top -Hp…

系统学习SpringFramework:Spring 概述

本篇内容包括:Spring/SpringFrame 概述、Spring IOC 和 AOP 概述、Spring 全家桶内容概述(包括:Spring Boot、Spring Cloud、Spring Cloud data flow …)等内容! 一、Spring/SpringFrame 概述 Spring 是一个生态体系&…

存储过程与函数oracle

存储在数据库中供所有用户程序调用的子程序叫做存储过程,存储函数。 存储过程是在大型数据库系统中,用PL/SQL语言编写的能完成一定处理功能的存储在数据库字典中的程序,它是一个命名的 PL/SQL 块,经编译后存储在数据库中&#xff…

系统学习SpringFramework:Spring IOC

本篇内容包括:IOC 和 DI 的概念、Spring 容器,即 BenaFactory 与 AplicationConext 等 IOC 相关内容。 一、IOC 和 DI 的概念 1、IOC IoC(Inversion of control )即“控制反转”,它是一种设计思想而非一个技术实现。…

彻底卸载oracle

linux删除Oracle安装目录下的所有文件和文件夹即可。windows 1.关闭oracle所有的服务。可以在windows的服务管理器中关闭 2.打开注册表:regedit 打开路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ 删除该路径下的所有以oracle开始的服务…