Seata 2.x 系列【10】回滚日志表 undo_log

2024-03-14 17:12
文章标签 日志 系列 log seata 回滚 undo

本文主要是介绍Seata 2.x 系列【10】回滚日志表 undo_log,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有道无术,术尚可求,有术无道,止于术。

本系列Seata 版本 2.0.0

本系列Spring Boot 版本 3.2.0

本系列Spring Cloud 版本 2023.0.0

源码地址:https://gitee.com/pearl-organization/study-seata-demo

文章目录

    • 1. 概述
    • 2. 表语句
    • 3. 配置项
    • 4. 回滚信息
      • 4.1 内容
      • 4.2 序列化/反序列化
      • 4.3 压缩

1. 概述

AT模式中,需要在参与全局事务的数据库中,添加一个undo_log表,类似于Mysql数据库中的undo log事务回滚日志表,在事务没提交之前,记录分支事务更新前的数据到日志表中,当全局事务需要回滚时,TC发出回滚命令,RM收到后使用undo log进行回退,并删除日志。

2. 表语句

undo_log建表语句如下:

-- seata_account.undo_log definitionCREATE TABLE `undo_log` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',`branch_id` bigint NOT NULL COMMENT '分支事务ID',`xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '全局事务唯一标识',`context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '上下文',`rollback_info` longblob NOT NULL COMMENT '回滚信息',`log_status` int NOT NULL COMMENT '状态,0正常,1全局已完成(防悬挂)',`log_created` datetime NOT NULL COMMENT '创建时间',`log_modified` datetime NOT NULL COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='AT模式回滚日志表';

各字段详细说明如下:

字段名说明
id主键ID
branch_id分支事务ID,比如:99302990136558270
xid全局事务唯一标识,比如:192.168.58.1:8091:99302990136558268Seata 服务端地址+全局事务ID
context回滚信息序列化和压缩格式,serializer=fastjson&compressorType=NONE,表示使用fastjson序列化,没有采用压缩
rollback_info回滚信息
log_status日志状态,0正常,1全局已完成 (防悬挂)
log_created创建时间
log_modified修改时间

3. 配置项

Server端关于undo log的配置项:

server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000

配置说明:

配置项描述备注
server.undo.logSaveDays保留天数默认 7 天,清理log_status=1和未正常清理的记录
server.undo.logDeletePeriod清理线程间隔时间默认 8640000024小时),单位毫秒

Client端关于undo log的配置项:

client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k

配置说明:

配置项描述备注版本说明
client.undo.dataValidation二阶段回滚镜像校验默认 true 开启false 关闭
client.undo.logSerialization序列化方式默认 jackson
client.undo.logTable自定义表名默认 undo_log
client.undo.onlyCareUpdateColumns只生成被更新列的镜像默认 true
client.undo.compress.enable压缩开关默认 true1.4.1 版本新增
client.undo.compress.type压缩算法 默认 zip,可选 NONE(不压缩)、GZIPZIPSEVENZBZIP2LZ4DEFLATERZSTD1.4.1 版本新增
client.undo.compress.threshold压缩阈值默认值 64k,压缩开关开启且 undo log 大小超过阈值时才进行压缩1.4.1 版本新增

4. 回滚信息

4.1 内容

RM执行分支事务后,开始构建回滚日志,其中最重要的就是回滚信息rollback_info字段,记录了数据修改前后镜像

例如调用库存服务扣减时,undo_log表生成的rollback_info信息如下:
在这里插入图片描述
rollback_info信息对应的类为BranchUndoLog,经过序列化后,在数据库以longblob格式存储:

public class BranchUndoLog implements Serializable {private static final long serialVersionUID = -101750721633603671L;// 全局事务标识private String xid;// 分支事务IDprivate long branchId;// undo log 信息private List<SQLUndoLog> sqlUndoLogs;
}

undo log 信息对应的类为SQLUndoLog

public class SQLUndoLog implements Serializable {private static final long serialVersionUID = -4160065043902060730L;// SQL 类型private SQLType sqlType;// 表名private String tableName;// 操作前数据镜像private TableRecords beforeImage;// 操作后数据镜像private TableRecords afterImage;
}

前置镜像中,会记录该条数据被修改前的主键ID、被修改的字段及值:
在这里插入图片描述
后置镜像中,会记录该条数据被修改后的主键ID、被修改的字段及值:
在这里插入图片描述
当全局事务需要回滚时,RM会根据事务ID查询到回滚信息(反序列化),根据前后镜像将数据还原到被修改前的状态,然后进行日志删除和事务提交,并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC

注意: 详细的执行流程,会在后续源码分析篇介绍。

4.2 序列化/反序列化

回滚信息在进行存储、查询时,涉及到序列化反序列化Seata 提供了UndoLogParser 接口处理回滚日志的序列化和反序列化:

public interface UndoLogParser {// 序列化类型名称,比如fastjsonString getName();// 获取默认的内容=》{}byte[] getDefaultContent();// 序列化BranchUndoLog 对象 byte[] encode(BranchUndoLog var1);// 反序列化BranchUndoLog 对象 BranchUndoLog decode(byte[] var1);
}

UndoLogParser 接口的实现类就对应了Seata 提供的序列化方式:
在这里插入图片描述
简要说明:

  • FastjsonUndoLogParserFastjson
  • JacksonUndoLogParserJackson
  • KryoUndoLogParserKryo
  • ProtostuffUndoLogParserProtostuff

推荐使用默认的jackson即可,其他方式可能还需要额外引入对应的包,并通过以下配置项进行修改:

client.undo.logSerialization=jackson
client.undo.logSerialization=fastjson
client.undo.logSerialization=kryo
client.undo.logSerialization=protostuff

4.3 压缩

在上面我们只修改了库存表的一个存库值,回滚信息的内容已经很多,如果是批量插入、更新、删除等操作,其影响的行数可能会比较多,将会拼接成一个大的字段插入到数据库中,会带来以下问题:

  • 超出数据库单次操作的最大写入限制,比如MySQLmax_allowed_package参数
  • 较大的数据量带来的网络IO和数据库磁盘IO开销比较大

Seata 1.4.1 版在框架层面提供了undo log数据压缩功能,通进一步提高Seata在处理数据量较大的时候的性能,同时也提供了对应的开关和相对合理的默认值,既方便用户进行开箱即用,也方便用户根据实际需求进行一定的调整,使得对应的功能更适合实际使用场景。

实现思路如下图所示:
在这里插入图片描述
默认配置项如下说示:

# 是否开启undo_log压缩,默认为true
seata.client.undo.compress.enable=true
# 压缩器类型,默认为zip,一般建议都是zip
seata.client.undo.compress.type=zip
# 启动压缩的阈值,默认为64k
seata.client.undo.compress.threshold=64k

这篇关于Seata 2.x 系列【10】回滚日志表 undo_log的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/809114

相关文章

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

java -jar example.jar 产生的日志输出到指定文件的方法

《java-jarexample.jar产生的日志输出到指定文件的方法》这篇文章给大家介绍java-jarexample.jar产生的日志输出到指定文件的方法,本文给大家介绍的非常详细,对大家的... 目录怎么让 Java -jar example.jar 产生的日志输出到指定文件一、方法1:使用重定向1、

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

nginx配置错误日志的实现步骤

《nginx配置错误日志的实现步骤》配置nginx代理过程中,如果出现错误,需要看日志,可以把nginx日志配置出来,以便快速定位日志问题,下面就来介绍一下nginx配置错误日志的实现步骤,感兴趣的可... 目录前言nginx配置错误日志总结前言在配置nginx代理过程中,如果出现错误,需要看日志,可以把

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.