百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

读书笔记14-mysql中的日志知识点总结

toyiye 2024-06-21 12:14 8 浏览 0 评论

1.mysql是怎么保证数据不丢的?

结论是:只要redo logbinlog保证持久化 到磁盘 就能保证mysql异常重启后,数据可恢复

1.1 binlog的写入机制

binlog写入逻辑: 事务执行过程中,先把日志写到 binlog cache事务提交时,再把binlog cache 写到binlog文件中,binlog cache的大小由 binlog_cache_size参数控制,binlog cache是由每个线程独享的,如里一个线程中的binlog cache被写满,就需要暂存到磁盘中,如下图

图中的write 指的就是把日志文件写入到文件系统的 page cache,fsync 是将数据持久化到磁盘的操作

参数sync_binlog控制 writefsync的写入时机

  1. sync_binlog=0时,表示每次提交事务都只写write ,不fsync;
  2. sync_binlog=1时,表示每次提交事务都会执行fsync;
  3. sync_binlog=N(N>1)时,表示每次提交事务都write,但是累积N个事务后才fsync

在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成0,比较常见的是将其设置成100~1000中的某个数值,如果设置为N,如果主机发生异常重启,会丢失最近N个事务的binlog日志

1.2 redo log 写入机制

在innodb中,参数innodb_flush_log_at_trx_commit用来控制 redo log的写入策略

  1. 设置为0时,表示每次事务提交时,都只是把redo log 留在 redo log buffer中;
  2. 设置为1时,表示每次事务提交时都将redo log 直接持久化到磁盘
  3. 设置为2时,表示每次事务提交时都只是把redo log写到page cache中

innodb有一个后台线程,每隔一秒,就会把 redo log buffer中的日志,调用write写的文件系统中的page cache,然后调用 fsync持久化到磁盘,在这过程中,一个没有提交的事务也有可能会被持久化到磁盘中

1.2.1 redo log 主动写盘时机

  1. 一种是 redo log buffer占用的空间即将达到innodb_log_buffer_size 一半的时候,后台线程会主动写盘,这里的写盘是write 不会调用fsync
  2. 一种是并行的事务提交时,顺带将这个事务的redo log buffer持久化到磁盘

1.2.2 组提交

为了优化io性能,在刷盘时会用到组提交机制,一次组提交里面,组员越多,节约磁盘iops的效果越好

如果想提升binlog组提交的效果,可以通过设置 binlog_group_commit_sync_delay 和binlog_group_commit_sync_no_delay_count参数控制

  1. binlog_group_commit_sync_delay 参数,表示延迟多少微秒后才调用 fsync;
  2. binlog_group_commit_sync_no_delay_count 参数,表示累积多少次以后才调用 fsync。

这两个条件是或的关系,只要有一个满足条件就会调用fsync

2. mysql是怎么保证主备一致的

2.1 主备基本原理

说明:

备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:

在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及 要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。

在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。

主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog, 发给 B。

备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)。

sql_thread 读取中转日志,解析出日志里的命令,并执行。

2.2 binlog的三种格式

  1. statement,此种模式下,binlog记录的是sql原文,如果sql中包括函数,索引的时候,在从库执行时,可能会出现主备库不一致的情况
  2. row,此种模式下,binlog记录的是真实影响到的行记录,在从库执行时,不会出现不一致情况,但是会导致binlog日志文件过大
  3. mixed,此种模式下 ,属于一个折中方案,在些格式下,mysql会自已判断这条sql 是否可能引起主备不一致情况,如果可能就用row模式,否则就用statement格式

2.3 利用binlog进行数据恢复

使用 mysqlbinlog 解析 binlog文件 ,找到要恢复的数据,进行数据恢复

常用的方法

show master status 查看使用的 binlog文件和 pos_position位置

使用 mysqlbinlog --start-position=binlog_position /var/lib/mysql/mysql-bin.000001 > /path/to/sql | mysql -u your_username -p your_database_name 进行数据恢复

2.4 双主结构下的循环复制问题

业务逻辑在节点 A 上更新了一条语句,然后再把生成的 binlog 发给节点 B,节点 B 执行 完这条更新语句后也会生成 binlog。(我建议你把参数 log_slave_updates 设置为 on, 表示备库执行 relay log 后生成 binlog)。

3 mysql是怎么保证高可用的

在保证高可用的前提下,可能会有主备延迟的产生,有如下几种情况

  1. 在一些部署条件下,可能备服务器上的机器性能要差些,如里是这种情况,可以加装多台从服务器来缓解压力
  2. 大事务执行,也会带来主备延迟,解决办法,尽量减少大事务的发生,比较分批删除大量数据,或者在业务低峰期执行大事务
  3. 对大表执行ddl操作,也会导致主备延迟的产生,解决办法:尽量避免
  4. 备库的并行复制能力低也有可能导致主备延迟

3.1主备切换对应的策略

  1. 可靠性优先
  2. 判断备库 B 现在的 seconds_behind_master,如果小于某个值(比如 5 秒)继续下一 步,否则持续重试这一步;
  3. 把主库 A 改成只读状态,即把 readonly 设置为 true;
  4. 判断备库 B 的 seconds_behind_master 的值,直到这个值变成 0 为止;
  5. 把备库 B 改成可读写状态,也就是把 readonly 设置为 false;
  6. 把业务请求切到备库 B。
  7. 可以看到,这个切换流程中是有不可用时间的。因为在步骤 2 之后,主库 A 和备库 B 都处 于 readonly 状态,也就是说这时系统处于不可写状态,直到步骤 5 完成后才能恢复。 在这个不可用状态中,比较耗费时间的是步骤 3,可能需要耗费好几秒的时间。这也是为什 么需要在步骤 1 先做判断,确保 seconds_behind_master 的值足够小。 试想如果一开始主备延迟就长达 30 分钟,而不先做判断直接切换的话,系统的不可用时间 就会长达 30 分钟,这种情况一般业务都是不可接受的。 当然,系统的不可用时间,是由这个数据可靠性优先的策略决定的。你也可以选择可用性优 先的策略,来把这个不可用时间几乎降为 0。
  8. 可用性优化

  1. 步骤 2 中,主库 A 执行完 insert 语句,插入了一行数据(4,4),之后开始进行主备切 换。
  2. 步骤 3 中,由于主备之间有 5 秒的延迟,所以备库 B 还没来得及应用“插入 c=4”这个 中转日志,就开始接收客户端“插入 c=5”的命令。
  3. 步骤 4 中,备库 B 插入了一行数据(4,5),并且把这个 binlog 发给主库 A。
  4. 步骤 5 中,备库 B 执行“插入 c=4”这个中转日志,插入了一行数据(5,4)。而直接 在备库 B 执行的“插入 c=5”这个语句,传到主库 A,就插入了一行新数据(5,5)

最后的结果就是,主库 A 和备库 B 上出现了两行不一致的数据。可以看到,这个数据不一 致,是由可用性优先流程导致的。

那么,如果我还是用可用性优先策略,但设置 binlog_format=row,情况又会怎样呢? 因为 row 格式在记录 binlog 的时候,会记录新插入的行的所有字段值,所以最后只会有 一行不一致。而且,两边的主备同步的应用线程会报错 duplicate key error 并停止。也就 是说,这种情况下,备库 B 的 (5,4) 和主库 A 的 (5,5) 这两行数据,都不会被对方执行。

在实际应用中,建议还是以可靠性策略优先为主,毕竟数据完整性更重要

4. 主备切换的方法

当主库出现问题时,把从库切换为主库的方式有如下几种

4.1基于位点的主备切换

语句如下:

 CHANGE MASTER TO 
 MASTER_HOST=$host_name 
 MASTER_PORT=$port 
 MASTER_USER=$user_name 
 MASTER_PASSWORD=$password 
 MASTER_LOG_FILE=$master_log_name 
 MASTER_LOG_POS=$master_log_pos 

这条命令有这么 6 个参数: MASTER_HOST、MASTER_PORT、MASTER_USER 和 MASTER_PASSWORD 四个参 数,分别代表了主库 A’的 IP、端口、用户名和密码。 最后两个参数 MASTER_LOG_FILE 和 MASTER_LOG_POS 表示,要从主库的 master_log_name 文件的 master_log_pos 这个位置的日志继续同步。而这个位置就是 我们所说的同步位点,也就是主库对应的文件名和日志偏移量。可以通过 show master status来查找

可能遇到的问题: 会遇到主键冲突的问题

解决办法:

主动跳过一个事务。跳过命令的写法是: set global sql_slave_skip_counter=1; start slave;

通过设置 slave_skip_errors 参数,直接设置跳过指定的错误。在执行主备切换时,有这么两类错误,是经常会遇到的: 1062 错误是插入数据时唯一键冲突; 1032 错误是删除数据时找不到行。

因此,我们可以把 slave_skip_errors 设置为 “1032,1062”,这样中间碰到这两个错误时 就直接跳过。

4.2 基于 GTID进行主备切换 (全局事务id)

在 GTID 模式下,备库 B 要设置为新主库 A’的从库的语法如下:

 CHANGE MASTER TO
 MASTER_HOST=$host_name 
 MASTER_PORT=$port 
 MASTER_USER=$user_name 
 MASTER_PASSWORD=$password 
 master_auto_position=1 

其中,master_auto_position=1 就表示这个主备关系使用的是 GTID 协议。可以看到,前 面让我们头疼不已的 MASTER_LOG_FILE 和 MASTER_LOG_POS 参数,已经不需要指定 了。

取binlog 的逻辑是

  1. 实例 B 指定主库 A’,基于主备协议建立连接。
  2. 实例 B 把 set_b 发给主库 A’。
  3. 实例 A’算出 set_a 与 set_b 的差集,也就是所有存在于 set_a,但是不存在于 set_b 的 GTID 的集合,判断 A’本地是否包含了这个差集需要的所有 binlog 事务。 a. 如果不包含,表示 A’已经把实例 B 需要的 binlog 给删掉了,直接返回错误; b. 如果确认全部包含,A’从自己的 binlog 文件里面,找出第一个不在 set_b 的事务, 发给 B;
  4. 之后就从这个事务开始,往后读文件,按顺序取 binlog 发给 B 去执行。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码