【MySQL】聊聊数据库是如何保证数据不丢的

对于一个存储系统来说,其中比较关键的核心组件包含,网络、存储模型、持久化、数据结构等。而数据如何保证不丢失,对于不同的存储系统来说,比如Redis采用AOF和RDB的方式进行混合使用,而MySQL采用日志进行保证。也就是redo\undo\bin log。本篇就聊聊数据库是如何进行不丢失的。

总体流程

对于数据不丢失,其实就是针对更新语句(update\delete\insert)的操作流程,其中主要靠redo log保证恢复事务,undo log 回滚事务。

bin log的写入机制

binlog在事务执行过程中,把日志写到binlog cache中,等事务提交的时候,再把binlog cache写到binlog中。而操作的维度就是一个事务。

系统给binlog cache分配了一片内存,每个线程一个。binlog_cache_size 控制单个线程内binlog cache所占内存的大小,超过之后,就暂存到磁盘中。

事务提交的时候,执行器把binlog cache里的完整事务写入到binlog中。并清空binlog cache

每个线程都有自己的binlog cache,但是对于bin log来说共用的。

  • write:把日志文件binlog cache写入到binlog files中,也就是paeg cache中,因为是内存操作,所以速度比较快。
  • fsync: 将数据从page cache写入到本次磁盘中,这个比较费时,所以可能是影响IOPS的一个因素。

决定执行write和fsync由sync_binlog参数决定。

  • sync_binlog=0 每次提交事务只write,不fsync
  • sync_binlog=1 提交事务的时候都fsync
  • sync_binlog>1 提交事务的只write ,但是积累到N个事务才fsync。其实就是批处理。

其实就是在性能和可用性之间进行权衡,在时机中,一般都是设置成100-1000中的某个值。但是当系统发生宕机的时候,可能丢失N个事务的binlog 日志。

redo log的写入机制

redo log是先写入redo log buffer-> page cache -> 磁盘

从而就对应三种写入状态

写入时机

  • 存储在redo log buffer中,其实就是MySQL进程内存中。红色部分
  • 写到磁盘write,但是没有持久化(fsync) 文件系统的page cache里面,黄色部分
  • 持久化到磁盘里,就是hard disk,绿色部分。

InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,控制写入策略。

  • 0 : 事务提交时,只把redo log留在redo log buffer中。
  • 1 : 事务提交时,redo log 持久化到磁盘
  • 2 : 事务提交时,redo log 写到page cache中。

如图5就是将定时将脏页进行刷新操作。而对于bin log来说,是依靠每次事务提交的时候进行刷盘。

InnoDB由一个后台线程,间隔1S把redo log buffer中的日志,调用write写到文件系统的page cache,调用fscyn持久化到磁盘中。

所以这里可能存在一种情况,可能一个事务执行过程中,也可能被定时后台线程持久化到磁盘中。

刷盘时机

  • 定时1S刷盘操作
  • redo log buffer达到 innodb_log_buffer_size 一半的空间。只写write
  • 每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘
  • mysql正常关闭的时候。

组提交机制(group commit)

日志逻辑序列号 log sequence number LSN 对应redo log的一个个写入点,每次写入长度为length的redo log LSN的值就会加上length。

图中有三个事务trx1、trx2、trx3 分别是50、120、160。

当trx1 第一个到达,提交的时候就会把2 3也一起进行提交fsync。所以一组提交的事务越多IOPS的效果越好。其实就是批处理的概念,一次多处理,而不是分批处理。比如批量插入SQL等,Kafka的批处理消息等。

WAL其实就只依赖于两个方面,redo log 和 bin log 都是顺序写,磁盘的顺序写比随机写快,另外一个是组提交,大幅度降低磁盘的IOPS消耗。

相关推荐
进击的荆棘26 分钟前
MySQL——数据库基础
数据库·mysql
Decay__27 分钟前
22_MySQL 运维自动化平台 —— 部署编排 + 监控 + 巡检 + 告警 + 工单闭环一体化
运维·数据库·sql·mysql·架构
FungLeo1 小时前
成为全栈·基础补充·数据库索引:为什么加了索引还是慢
mysql·postgresql·sqlite·sql优化·数据库索引·成为全栈
codeejun1 小时前
每日一Go·MySQL-11、覆盖索引 & 回表原理
javascript·数据库·mysql
CoderYanger2 小时前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)
java·数据库·spring·面试·职场和发展·java-ee·mybatis
XLYcmy2 小时前
信息检索报告数字经济赋能城市低碳治理的路径研究——基于“传统数据库 + 生成式人工智能”双轮驱动的检索实践 检索实施与结果分析 Web of Science
数据库·ai·llm·prompt·ssci·deepseek·wos
Decay__2 小时前
21_MySQL 优化案例集 —— 慢 SQL 优化、索引重构与参数调整收益对比
运维·数据库·sql·mysql·架构
挖掘狂人3 小时前
MySQL 深分页优化:limit 100000, 10 慢在哪,怎么救
后端·sql·mysql
codigger3 小时前
MySQL 深分页优化:limit 100000, 10 慢在哪,怎么救
数据库·sql·mysql·程序员
麦壳饼3 小时前
SonnetDB 5.0 正式发布:增强 SQL 与事务,开放九模型 MCP 读写
数据库·人工智能·sql·sonnetdb