加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

Mysql的日志文件的理解

发布时间:2023-01-05 05:31:39 所属栏目:MsSql教程 来源:未知
导读: MySQL的日志文件有,redo log、undo log、binlog、errorlog、slow query log、还有general log和relay log等7大日志文件
binlog
binlog:以二进制的形式保存在磁盘的日志,记录了所有的DDL

MySQL的日志文件有,redo log、undo log、binlog、errorlog、slow query log、还有general log和relay log等7大日志文件

binlog

binlog:以二进制的形式保存在磁盘的日志,记录了所有的DDL和DML修改命令(增删改)的逆向操作,不记录查询命令。delete语句记录成insert命令,update命令记录成update执行的前后的版本信息,insert记录成delete和insert本身的信息。

Binlog什么时候写入日志?

Binlog对任何修改语句,也就是一个事务,事务是不允许拆开的,不论有多大,必须一次性写入,事务在执行的时候,先把日志写到binlog cache中,也就是内存中,事务提交的时候再把binlog cache写到binlog磁盘中。当然binlog刷入磁盘是由参数syn_binlog控制的,设置为Nmssql数据库日志,表示每N次事务提交,会刷入一次磁盘,如果设置为0,表示只会写入内存cache中,默认为1,也就是事务安全模式。大于1就有可能出现失误丢失问题。

binlog主要用于主从同步和数据恢复

Binlog的数据恢复和同步,本质上是靠binlog position也就是点位,从哪里开始同步,相当于redis的偏移量offset,知道这个位置就可以做复制同步操作了。以下是主从数据复制过程。

Redo日志

Redo日志是存储引擎innodb生成的日志文件,主要为了保障数据的可靠性,是存储引擎层的日志。与binlog是数据库层面的不同,redo log 是物理日志,记录的是在?具体?某个数据页上做了什么修改,binlog 是逻辑日志,记录的是这个语句的原始逻辑。MySQL作为一个存储系统,为了保证数据的可靠性,必须得存入磁盘,但是,为了兼顾写入速度又必须绕过实时写入磁盘的这个巨耗时的IO操作,所以引入基于内存的缓冲池,如何避免数据先写入缓存中,然后再以某种方式刷新到磁盘,存在的宕机导致的缓冲池中的数据丢失的问题,为了解决数据丢失问题,redo log应运而生。

Mysql的事务持久化是通过Redo日志实现的

在执行事务过程中,会不断地产生 redo log,这些 redo log 会先定入 redo log buffer中,然后再将 redo log buffer 中的数据以某些方式顺序地写入到磁盘(各个操作的redo log 汇总到 redo log buffer,再由 redo log buffer 统一写磁盘,就能做到顺序写了),redo log buffer 的刷新到磁盘的速度由参数 innodb_flush_log_at_trx_commit 参数控制,可取的值有:0、1、2。0是线程周期性任务刷新,1 是事务 每commit 一次,先写入redo log buffer ,与此同时执行写入disk。2 将代表redo log 日志数据,在事务执行的时候先写redo log buffer中,然后待一定时机再异步写入 disk,所以即使在事务成功提交后并不能保证数据一定落到磁盘上了。

对数据丢失很敏感,设置为1,数据保障写入磁盘但性能较差。对数据不太敏感可以设置为0或2,性能较好。但可能会丢失1秒的数据。

redo log写入磁盘时,是按512个字节(一个磁盘扇区大小)写入的,扇区是写入的最小单位,因此可以保证写入是必定成功的,不需要 double write buffer,程序产生的数据都是先在内存里面,然后从内存里面持久化到磁盘的。

分析不同时刻发生故障的情景

mysql> update T set c=c+1 where ID=2;

根据索引取得 ID=2 这一行这行的 c 值加1更新到内存写入 redo log(处于 prepare 阶段)写 binlog提交事务(处于 commit 状态)

Mysql的事务采用两阶段提交,那为什么要采用两阶段提交呢?是为了让 binlog 和 redo log 之间的逻辑一致。

我们假设一下上面的 update 语句在执行的每个时刻,MySQL 崩溃了,看一下两个日志间的逻辑是如何保持一致的。

undo log

undo log又称为回滚日志,用来记录数据修改前的备份,当有取消的操作或者执行过程突然中断的等情景的时候,对执行而未提交的数据进行恢复。undo log就是为了回滚而生,会记录逆向操作也就是修改前的数据,插入的数据的回滚就是删除一条数据,删除记录就是把这些记录插入进来就可,修改了一条记录就要把修改前的记录存下来回滚的时候直接成旧值就行了。select 语句没有undo日志,因为没有对数据的修改。

undo log的写入时机

在修改数据之前写入undo日志,先于redo日志,redo日志是在缓存冲修改后记录的,binlog是在commit之后记录的。对于insert操作,undo记录的是插入行的主键,redo记录的是行插入位置的物理地址,对于delete操作,undo是将记录标记为delete mark,将系统列写入undo,将主键和所有索引列写入undo。对于update操作分为三种,一种是没有修改聚集索引键值,undo主要是将系统列写入,将主键列写入,将当前update列的前镜像写入,然后将修改后行记录的回滚指向undo记录。第二种是没有修改聚集索引键值但是列长度变化了,不过记录的位置没有变化,这对于undo是没有影响的。第三种是修改了聚集索引键值,这种会导致新纪录跟原纪录不在同一位置,所以这里undo也不能in place update了,首先对原纪录进行delete mark操作然后写入undo,然后对新纪录进行insert操作然后写入undo。

undo日志在MVCC的作用

mvcc通过事务版本号进行mvcc,系统维护一个系统版本号,进行插入操作的时候就把插入记录的系统列事务id设置为当前系统版本号;对于删除操作,则是将记录标记为delete mark,并将事务id改为当前系统版本号;对于更新操作,则是同时保持旧记录和新纪录;对于查询操作则是根据当前系统版本号和查询行的事务id来判断记录是否可读。那么具体是怎么进行操作的呢。

主要是几个规则,一个是旧数据存储在undo中,再通过rollback ptr回溯查找历史版本。比如说update操作,对于不修改主键索引键值的update操作,更新后的行记录事务id存储修改时的系统版本号,然后将被更新的行记录写进undo中,并将更新后行记录rollback ptr指向这个undo记录,那么当一个正在进行的事务需要读取该进行了更新的记录,这个事务的版本号比更新后的行记录事务id要小,那么肯定是不能读取更新后的记录,就需要通过回滚指针前往undo读取更新前记录,直到满足条件为止。

relay log

relay log也称为中继日志,一般情况下,它在MySQL主从同步读写分离集群的从节点才开启。主节点一般不需要这个日志。从节点从主节点复制的数据会先写入relay日志,由从节点的sql线程发现日志新增,生成sql命令写入本地。

error log

error log,错误日志,记录了 MySQL Server 每次启动和关闭的详细信息以及运行过程中所有较为严重的警告和错误信息。

show query log

show query log,慢查询日志,MySQL慢查询日志记录下所有执行超过long_query_time时间的SQL语句,帮你找到执行慢的SQL,方便我们对这些SQL进行优化。

general log

开启general log会将所有到达MySQL Server的SQL语句记录下来。一般不会开启开功能,因为log的量会非常庞大。

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章