当前位置: 首页 > news >正文

MySQL高可用改造之数据库开发规范(大事务与数据一致性篇)

文章目录

    • 一、前言
    • 二、延迟的原因
    • 三、大事务处理规范
      • 3.1. 删除类操作优化设计
      • 3.2. 大事务通用拆分原则
    • 四、数据一致性核对规范
      • 4.1. 主从变更记录识别方法
    • 五、小结

一、前言

MySQL 高可用架构中最基础、最为核心的内容:MySQL 复制(Replication),数据库复制本质上就是数据同步。MySQL 数据库是基于二进制日志(binary log)进行数据增量同步,而二进制日志记录了所有对于MySQL 数据库的修改操作。

很多时候我们会发现,MySQL 的主从复制会存在主从数据延迟的问题,甚至会导致读写分离架构设计在业务层出现较为严重的问题,比如迟迟无法读取到主库已经插入的数据。

所以本文,我们就如何从数据库设计避免这个令人头疼的问题。

二、延迟的原因

MySQL 复制基于的二进制日志是一种逻辑日志,其写入的是每个事务中已变更的每条记录的前项、后项。有了每条记录的变化内容,用户可以方便地通过分析 MySQL 的二进制日志内容。逻辑日志简单易懂,方便数据之间的同步,但它的缺点是:事务不能太大,否则会导致二进制日志非常大,一个大事务的提交会非常慢。

假设有个 DELETE 删除操作,删除当月数据,由于数据量可能有 1 亿条记录,可能会产生 100G 的二进制日志,则这条 SQL 在提交时需要等待 100G 的二进制日志写入磁盘,如果二进制日志磁盘每秒写入速度为 100M/秒,至少要等待 1000 秒才能完成这个事务的提交。

三、大事务处理规范

核心原则:避免大事务(单次操作涉及大量数据或长时间持有锁),以降低提交延迟、减少主从复制延迟风险,并提升系统整体并发能力。

3.1. 删除类操作优化设计

(1)优先采用物理拆分替代逻辑删除

  • 适用场景:针对流水表、日志表等历史数据定期清理需求。
  • 规范要求:
    • 设计阶段将此类表按时间维度分表(如按月分表)或分区(如按天/月分区),例如:
    -- 分表示例:按月分表(logs_202401、logs_202402...)CREATE TABLE logs_202401 (...); CREATE TABLE logs_202402 (...);-- 分区表示例:按月份范围分区CREATE TABLE logs (id INT,log_time DATETIME,...) PARTITION BY RANGE (YEAR(log_time)*100 + MONTH(log_time)) (PARTITION p202401 VALUES LESS THAN (202402),PARTITION p202402 VALUES LESS THAN (202403),...);
  • 删除操作直接通过 DROP TABLE(分表)或 ALTER TABLE … DROP PARTITION(分区)实现,二进制日志(binlog)仅记录一条元数据操作,写入速度快且不占用大量日志空间。

      -- 分表删除:直接删除整月表(瞬时完成)DROP TABLE logs_202312;-- 分区删除:移除指定月份分区(高效且可快速回收空间)ALTER TABLE logs DROP PARTITION p202312;
    

(2)未分表/分区时的拆分策略(应急方案)

  • 若因历史原因无法分表/分区,需通过小事务分批删除替代单条大事务 DELETE:

    • 拆分方法:添加 LIMIT 子句限制单次删除条数(如每次1000条),结合时间范围条件逐步清理。
      -- 示例:每次删除2024年1月内1000条记录,循环执行直至完成DELETE FROM logs WHERE log_time BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59'LIMIT 1000;
  • 优势:

    • 单次事务量小,减少锁持有时间(避免长时间阻塞其他会话)。
    • 降低二进制日志(binlog)体积,避免因大事务日志过大导致主从同步延迟。
    • 支持并发执行:可通过多线程/多连接分片删除不同时间范围或ID段的数据(需确保无重叠),提升清理效率。

3.2. 大事务通用拆分原则

  • 核心要求:单次事务操作的数据量需控制在合理范围内(建议单事务影响行数≤1万条,具体根据业务负载调整)。

  • 典型场景:

    • 批量数据插入/更新/删除时,通过循环或分片拆分为多个小事务(如每次处理1000~5000条)。
    • 避免在事务中执行耗时操作(如网络请求、复杂计算),减少锁持有时间。
  • 示例(批量更新拆分):

    -- 原始大事务(风险高):一次性更新10万条记录
    -- UPDATE orders SET status = 'completed' WHERE create_time < '2024-01-01';-- 拆分后小事务(推荐):每次更新5000条
    UPDATE orders 
    SET status = 'completed' 
    WHERE create_time < '2024-01-01' 
    LIMIT 5000;-- 循环执行直至受影响行数为0(可通过程序控制)
    

四、数据一致性核对规范

4.1. 主从变更记录识别方法

  • 设计要求:所有业务表必须包含 last_modify_date 字段(或类似的时间戳字段,如 update_time),用于记录每条数据的最后修改时间(建议默认值为 CURRENT_TIMESTAMP,并通过触发器或应用逻辑保证更新时自动维护)。
  CREATE TABLE example (id INT PRIMARY KEY,data VARCHAR(255),last_modify_date DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
  • 核对流程:

    1. 定位变更记录:通过 last_modify_date 过滤出主库上最近一段时间内(如最近1小时/1天)被修改的数据。
    -- 示例:查询主库上2024-06-01 00:00:00后更新的所有记录SELECT * FROM example WHERE last_modify_date >= '2024-06-01 00:00:00';
  1. 逐条比对:将主库查询结果与从库对应表的数据进行字段级比对(可通过程序脚本实现),确认关键字段(如业务状态、金额等)是否一致。
  2. 异常处理:若发现不一致,需记录差异详情并触发告警,由运维或开发人员排查原因(如主从延迟、业务逻辑错误等)。

五、小结

通过以上规范,可有效控制大事务风险,保障MySQL数据库高可用架构的性能、可用性与数据一致性。

http://www.lryc.cn/news/617975.html

相关文章:

  • C++方向知识汇总(三)
  • Git 常用命令总结
  • 泰国文字识别技术:从精准识别字符向深度理解语义的方向不断进化
  • 日本VPS内存溢出了如何优化
  • 数据变而界面僵:Vue/React/Angular渲染失效解析与修复指南
  • 稠密检索:基于神经嵌入的高效语义搜索范式
  • 【LeetCode 热题 100】(七)链表
  • 数据结构——树(02构造二叉树,代码练习)
  • 【网络基础】深入理解 TCP/IP 协议体系
  • 无人机航拍数据集|第11期 无人机人员行为目标检测YOLO数据集1868张yolov11/yolov8/yolov5可训练
  • libwebsockets 服务端获取过代理的真实连接IP
  • [4.2-1] NCCL新版本的register如何实现的?
  • AI(领域)应用落地技术决策指南:从双路径架构到系统性实施
  • Oracle 23AI 稳定执行计划:SQL Profile
  • 训练苹果风格Emoji生成模型的技术方案
  • Docker-09.Docker基础-Dockerfile语法
  • 数据上云有什么好处?企业数据如何上云?
  • Flutter Provider 状态管理全面解析与实战应用:从入门到精通
  • priority_queue(优先级队列)和仿函数
  • 关于linux系统编程2——IO编程
  • 内网依赖管理新思路:Nexus与CPolar的协同实践
  • redis常见的性能问题
  • Redis 数据倾斜
  • day072-代码检查工具-Sonar与maven私服-Nexus
  • Qt 5.14.2安装教程
  • 基于Qt Property Browser的通用属性系统:Any类与向量/颜色属性的完美结合
  • 学习嵌入式第二十五天
  • QT QVersionNumber 比较版本号大小
  • office卸载不干净?Office356卸载不干净,office强力卸载软件下载
  • MySQL 索引(重点)