精华内容
下载资源
问答
  • mysql binlog redolog undolog 日志概念说明binlogbinlog使用场景binlog刷盘时机binlog日志格式redo log为什么需要redo logredo log基本概念redo log记录形式redo log与binlog区别undo log 日志是 mysql 数据库的...

    日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。作为开发,我们重点需要关注的是二进制日志( binlog )和事务日志(包括
    redo logundo log ),本文接下来会详细介绍这三种日志。

    概念说明

    • 逻辑日志:可以简单理解为记录的就是sql语句 。
    • 物理日志mysql 数据最终是保存在数据页中的,物理日志记录的就是数据页变更 。
    • cash safe :即在 InnoDB 存储引擎中,事务提交过程中任何阶段,MySQL突然奔溃,重启后都能保证事务的完整性,已提交的数据不会丢失,未提交完整的数据会自动进行回滚。 MySQL 的 crash-safe 原理解析

    binlog

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

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

    binlog使用场景

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

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

    binlog刷盘时机

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

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

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

    binlog日志格式

    binlog 日志有三种格式,分别为 STATMENTROWMIXED

    MySQL 5.7.7 之前,默认的格式是 STATEMENTMySQL 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:基于STATMENTROW 两种模式的混合复制( mixed-based replication, MBR ),一般的复制使用 STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog
      binlog三种日志格式可参考:二进制日志

    redo log

    为什么需要redo log

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

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

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

    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中,过程如下:

    img

    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

    img

    redo log记录形式

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

    img

    同时我们很容易得知, 在innodb中,既有redo log 需要刷盘,还有 数据页 也需要刷盘, redo log存在的意义主要就是降低对 数据页 刷盘的要求 ** 。在上图中, write pos 表示 redo log 当前记录的 LSN (逻辑序列号)位置, check point 表示 数据页更改记录 刷盘后对应 redo log 所处的 LSN(逻辑序列号)位置。write poscheck point 之间的部分是 redo log 空着的部分,用于记录新的记录;check pointwrite pos 之间是 redo log 待落盘的数据页更改记录。当 write pos追上 check point 时,会先推动 check point 向前移动,空出位置再记录新的日志。

    启动 innodb 的时候,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。因为 redo log记录的是数据页的物理变化,因此恢复的时候速度比逻辑日志(如 binlog )要快很多。重启 innodb 时,首先会检查磁盘中数据页的 LSN ,如果数据页的 LSN 小于日志中的 LSN ,则会从 checkpoint 开始恢复。还有一种情况,在宕机前正处于
    checkpoint 的刷盘过程,且数据页的刷盘进度超过了日志页的刷盘进度,此时会出现数据页中记录的 LSN 大于日志中的 LSN
    ,这时超出日志进度的部分将不会重做,因为这本身就表示已经做过的事情,无需再重做。

    redo log与binlog区别

    redo log binlog
    文件大小 redo log 的大小是固定的。 binlog 可通过配置参数 max_binlog_size 设置每个binlog 文件的大小。
    实现方式 redo logInnoDB 引擎层实现的,并不是所有引擎都有。 binlogServer 层实现的,所有引擎都可以使用 binlog 日志
    记录方式 redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 binlog通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上
    适用场景 redo log 适用于崩溃恢复(crash-safe) binlog 适用于主从复制和数据恢复
    日志类型 物理日志 逻辑日志

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

    undo log

    数据库事务四大特性中有一个是 原子性 ,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。实际上, 原子性 底层就是通过 undo log 实现的。undo log 主要记录了数据的逻辑变化,比如一条 INSERT 语句,对应一条 DELETEundo log ,对于每个 UPDATE 语句,对应一条相反的 UPDATEundo log ,(不包活select)这样在发生错误时,就能回滚到事务之前的数据状态。在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,属于逻辑日志。同时, undo log 也是 MVCC(多版本并发控制)实现的关键。

    更新操作的流程

    以下面sql为例,总结一下一个更新操作的流程,这是一个简化的过程,name原值是qingshan;
    update user set name = 'penyuyan' where id = 1;

    更新操作流程(redo log + bin log)

    在这里插入图片描述

    • 1.先从内存或者磁盘拿到这条数据
    • 2.把name改成盆鱼宴,然后调用存储的API接口,将这行数据写入内存,同时记录redo log. 这时redo log进入prepare阶段, 然后告诉执行器,执行完成了, 可以随时提交。
    • 3.执行器收到通知后记录binlog。
    • 4.然后调用存储引擎接口,设置redo log为commit状态。更新完成。

    更新操作流程(redo log + undo log)

    • 1.事务开始,内存(buffer pool)或磁盘(data file)取到这条数据,返回给server的执行器;
    • 2.Server的执行器修改这一行数据的值为penyuyan;
    • 3.记录name=qingshan到undo log;
    • 4.记录name=penyuyan到redo log;
    • 5.调用存储引擎接口,在内存(buffer pool)中修改name=penyuyan;
    • 6.事务提交。

    转载:

    MySQL 三种日志

    什么是crash-safe能力?什么是两阶段提交?
    MySQL 的 crash-safe 原理解析

    展开全文
  • Redo log Undo Log Bin log 作用 数据写入到mysql数据页的临时存储空间,磁盘上存储 事务回滚和MVCC 主从复制 类型 物理日志 逻辑日志 逻辑日志 幂等性 无幂等性 无幂等性 ...
      Redo log Undo Log Bin log
    作用 数据写入到mysql数据页的临时存储空间,磁盘上存储 事务回滚和MVCC 主从复制
    类型 物理日志 逻辑日志 逻辑日志
      幂等性 无幂等性 无幂等性
      有buffer 未知 有buffer
      事务结束时Buffer提交到磁盘 事务进行过程中每一个操作都提交 事务结束时提交

     

    展开全文
  • CPU与Mem,Mem与Disk一级一级的速度差别,使得我们不断寻找可以提高速度的方式;例如,页面速度的提高:使用squid、...oracle 从i到g都在不断优化(之间是回滚段到回滚表空间),对redoundo日志的利用越来越高。但my...

    CPU与Mem,Mem与Disk一级一级的速度差别,使得我们不断寻找可以提高速度

    的方式;例如,页面速度的提高:使用squid、varnish、nginx cache等页面

    缓存提高页面的访问速度,使用memcache等数据缓存提高应用层访问速度。

    数据库怎么减少离散磁盘读写,提高数据访问速度。oracle 从i到g都在不断

    优化(之间是回滚段到回滚表空间),对redo和undo日志的利用越来越高。但

    mysql中事务类型innodb存储引擎的具体情况是怎样呢?

    在对付用户每次有导致数据变更的请求中,Innodb引擎把数据和索引都载入到

    内存中的缓冲池(buffer pool)中,如果每次修改数据和索引都需要更新到磁盘,

    必定会大大增加I/O请求,而且因为每次更新的位置都是随机的,磁头需要频繁定

    位导致效率低,数据暂放在内存中,也一定程度的提高了读的速度。所以Innodb

    每处理完一个请求(Transaction)后只添加一条日志log,另外有一个线程负责智

    能地读取日志文件并批量更新到磁盘上,实现最高效的磁盘写入。(^-^听着听着

    像看到Oracle的一些影子吧,因为本人以前是弄Oracle所以现在简单mysql都联想

    到oracle的架构体系,其实个人认为每个数据原理上是差不多。)

    innodb既然利用Mem buffer提高相应的速度,那当然也会带来数据不一致,术语为

    脏数据,Mysql称之为dirty page。发生过程:当事务(Transaction)需要修改某条

    记录(row)时,InnoDB需要将该数据所在的page从disk读到buffer pool中,事务

    提交后,InnoDB修改page中的记录(row)。这时buffer pool中的page就已经和disk

    中的不一样了,mem中的数据称为脏数据(dirty page)。Dirty page等待flush到disk上。

    知道mysql中术语的dirty page(我认为这个dirty page放在哪个缓存工具层面上

    都适合)。

    dirty page既然是在Buffer pool中,那么如果系统突然断电Dirty page中的数据

    修改是否会丢失?答案是肯定的,buffer pool中的数据并不是永久性。

    系统故障造成数据库不一致的原因有两个:

    1.未完成事务对数据库的更新可能已写入数据库。

    2.已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库。

    在这里我们先说恢复的一般方法:

    (1)正向扫描日志文件(从头到尾),找出故障发生前已经提交的事务(存在begin transaction

    和commit记录),将其标识记入重做(redo)队列。同时找出故障发生时未完成的事务

    (只有begin transaction,没commit),将其标识记入(undo)队列

    (2)对undo队列的各事务进行撤销处理。进行undo的处理方法是,反向扫描日志文件,对每个undo

    事务的更新操作执行反操作,即将日志记录中“更新前的值”写入数据库。

    (3)对重做日志中的各事务进行重做操作。进行redo的处理方法是,正向扫描日志,对每个redo事务

    重新执行日志文件登记操作。即将日志中“更新后的值”写入数据库。

    以上三个步骤放于四海皆行。

    但mysql为了防止buffer pool数据掉失,在日常的操作中也建立了redo和undo这两个日志,记录相关

    的信息,redo log在每次事务commit的时候,就立刻将事务更改操作记录到redo log。所以即使buffer

    pool中的dirty page在断电时丢失,InnoDB在启动时,仍然会根据redo log和undo log中的记录完成数据恢复。

    具体操作是:

    110105120703.jpg

    redo log 也不能无限制放任不断增长,dirty page什么时候flush到disk上?

    1. The redo log, which is organized as a ring buffer, is full. To free up some space we will write

    out dirty pages in redo log order so that we can advance the trailing pointer of the redo log ring

    buffer an make some room.

    redo log是一个环(ring)结构,当redo空间占满时,将会将部分dirty page flush到disk上,然后释放部分redo log。

    This situation is called an Innodb_log_wait and will be registered in the status counter of the same name.

    这种情况称为Innodb_log_wait,会被记录在Mysql status 中。

    2. InnoDB requires a free page from the InnoDB buffer pool but cannot find one. Usually we can free a page in

    the buffer pool by giving up a page that is not marked dirty. When a page is not marked dirty its contents

    can be reloaded from disk at any time and so we can safely give it up in memory. But when the buffer pool

    holds only dirty pages this is impossible and we actually have to flush dirty pages to disk before we can

    free them up for other uses.

    当需要在Buffer pool分配一个page,但是找不到这样的一个page,因为所有的page都是被标注为dirty

    This situation is called Innodb_buffer_pool_wait_free and will be registered in a status counter of the

    same name. InnoDB tries to avoid this situation: Whenever more than innodb_max_dirty_pages_pct percent many

    pages are marked dirty a checkpoint is forced and dirty pges will be written.

    这种情况称为Innodb_buffer_pool_wait_free,并将会记录到Innodb_buffer_pool_wait_free Mysql的系统变量中。

    一般地,可以可以通过启动参数innodb_max_dirty_pages_pct控制这种情况,当buffer pool中的

    dirty page到达这个比例的时候,将会强制设定一个checkpoint,并把dirty page flush到disk中。

    3. InnoDB feels idle and will write out batches of 64 pages each to disk once a second.

    检测到系统空闲的时候,会flush,每次64 pages。

    This is normal and will not be specifically registered (but will of course bump Innodb_pages_written like everything else).

    以上三种情况涉及的主要两个参数为:innodb_flush_log_at_trx_commit、 innodb_max_dirty_pages_pct;

    可通过状态参数:Innodb_log_wait、Innodb_buffer_pool_wait_free进行查询

    innodb_flush_log_at_trx_commit

    默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时。

    特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM

    表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘,

    所以一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也

    可能会丢失事务的数据。而值2只会在整个操作系统挂了时才可能丢数据。

    innodb_max_dirty_pages_pct

    his is an integer in the range from 0 to 100. The default value is 90.

    The main thread in InnoDB tries to write pages from the buffer pool so that the

    percentage of dirty (not yet written) pages will not exceed this value.

    具体映射到Mysql的图示

    110105120839.jpg

    PS:这图也解答了网页中“Mysql 有undo relog log?” 这样的提问了

    展开全文
  • binlog redolog undolog

    2020-07-25 23:44:18
    innodb事务日志包括的redo logundo logredo log是物理日志,记录的是数据页的物理修改,它保证了事务的持久性。 redo log分为两部分:一个是内存中的日志缓冲(redo log buffer),该部分日志是容易丢失的。二是...

    bin log

    bin log是位于MySQL服务层,记录所有数据库表结构和表数据修改的二进制日志。

    redo log

    innodb事务日志包括的redo log 和 undo log。redo log是物理日志,记录的是数据页的物理修改,它保证了事务的持久性。

    redo log分为两部分:一个是内存中的日志缓冲(redo log buffer),该部分日志是容易丢失的。二是磁盘上的重做日志文件(redo log file),该部分是持久的。事务在提交时,必须先将该事物的所有事务日志写入到磁盘上的redo log和undo log中进行持久化。

    当发生数据修改时,innodb引擎会先将记录写到redo log buffer中,并更新内存中的数据,此时更新就算是完成了。redo log buffer中的日志会写到os buffer中,os buffer会异步的调用fsync写入到磁盘。

    redo log是固定大小的,是循环写。

    有了redo log之后,innodb就可以保证即使数据库发生异常重启,之前的记录也不会丢失。

    undo log

    undo log用来回滚行记录到某个版本和MVCC,保证了事务的原子性。undo log一般是逻辑日志,根据每行记录进行记录。

    在数据发生修改的时候,不仅记录了redo log,还记录了undo log,如果因为某些原因导致事务失败或回滚了,可以借助undo log进行回滚。

    undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

    redo log和bin log区别

    • 作用不同:bin log可以用来恢复数据,搭建主从。redo log用来异常宕机后恢复。
    • 层次不同:bin log是服务层产生的,不管什么存储引擎对数据修改都会产生bin log。redo log是innodb引擎的,只记录该引擎的数据的修改。
    • 内容不同:bin log记录的是逻辑性的语句。redo log记录的是数据页的修改。
    • 写入时机不同:bin log只在每次事务提交的时候一次性写入缓存中的日志文件。redo log在数据准备修改前写入内存中的redo log中,然后才对内存中的数据执行修改操作。而且保证在发出事务提交指令时,先向内存中的redo log写入日志,写入完成后才提交动作。
    • 写入方式不同:bin log追加写,redo log循环写。

    mysql二阶段提交

    事务commit分为parpare和commit两个阶段

    • 第一阶段:innodb prepare, write/sync redo log
    • 第二阶段:1. write/sync bin log 2. innodb commit
    展开全文
  • mysql redolog undolog binlog

    2020-06-12 10:58:36
    innodb事务日志包括redo logundo logredo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作。 undo log不是redo log的逆向过程,其实它们都算是用来恢复的日志:1.redo log通常是物理日志,记录...
  • redo log redo log是基于磁盘数据结构记录的日志,用于在db崩溃时恢复由未完成的事务写入的正确数据。在正常操作期间,redo log会对SQL语句或低级API调用产生的更改表数据的请求进行编码。在意外关闭之前没有完成...
  • mysql中的redolog undolog

    2019-11-08 20:14:57
    1 redolog保证了事务的一致性,持久性。在mysql服务启动时,就会给redolog分配一块连续的存储空间,各个事务共享这块存储空间,各个事务的redolog日志根据语句的执行...2 undolog保证了事务的原子性,它记录了数据操...
  • 阅读目录(Content)1 undo1.1 undo是啥1.2 undo参数1.3 undo空间管理2 redo2.1 redo是啥2.2 redo 参数2.3 redo 空间管理3 undoredo如何记录事务3.1 Undo + Redo事务的简化过程3.2  IO影响3.3 恢复   ...
  • Mysql Redolog Undolog Binlog

    2020-01-01 16:30:34
    https://yq.aliyun.com/articles/592937 https://www.cnblogs.com/wy123/p/8365234.html
  • 作为开发,我们重点需要关注的是二进制日志(binlog)和事务日志(包括redo logundo log),本文接下来会详细介绍这三种日志。 binlog binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在...
  • undolog的执行逻辑可以理解为: 当 delete 一条记录时,undolog 记录一条对应的 insert 语句 当 insert 一条记录时,undolog 记录一条对应的 delete 语句 当 update 一条记录时,undolog 记录一条对应的返 update...
  • Mysq日志 binlog redolog undolog

    千次阅读 2017-12-27 15:07:26
    // 当记录存在表里的时候, 该表是 mysql.general_log 原本就有 不用创建 // 当日志记录到文件时, 需要设置文件的路径 set global general_log_file='/var/lib/mysql/420.log'; show variables like "general_log_...
  • 说说MySQL中的Redo log Undo log都在干啥

    千次阅读 2019-10-04 15:15:42
    在数据库系统中,既有存放数据的文件... MySQL中的日志文件,有这么两类常常讨论到:undo日志与redo日志。 1 undo 1.1 undo是啥 undo日志用于存放数据修改被修改前的值,假设修改 tba 表中 id=2的行数据,把Name...
  • 在数据库系统中,既有存放... MySQL中的日志文件,有这么两类常常讨论到:undo日志与redo日志。 1 undo 1.1 undo是啥 undo日志用于存放数据被修改前的记录,假设修改 tba 表中 id=2的行数据,把Name='B' 修改为Na...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,015
精华内容 806
关键字:

redologundolog