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

相关文章

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

SpringBoot日志配置SLF4J和Logback的方法实现

《SpringBoot日志配置SLF4J和Logback的方法实现》日志记录是不可或缺的一部分,本文主要介绍了SpringBoot日志配置SLF4J和Logback的方法实现,文中通过示例代码介绍的非... 目录一、前言二、案例一:初识日志三、案例二:使用Lombok输出日志四、案例三:配置Logback一

golang 日志log与logrus示例详解

《golang日志log与logrus示例详解》log是Go语言标准库中一个简单的日志库,本文给大家介绍golang日志log与logrus示例详解,感兴趣的朋友一起看看吧... 目录一、Go 标准库 log 详解1. 功能特点2. 常用函数3. 示例代码4. 优势和局限二、第三方库 logrus 详解1.

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步

SQL Server清除日志文件ERRORLOG和删除tempdb.mdf

《SQLServer清除日志文件ERRORLOG和删除tempdb.mdf》数据库再使用一段时间后,日志文件会增大,特别是在磁盘容量不足的情况下,更是需要缩减,以下为缩减方法:如果可以停止SQLSe... 目录缩减 ERRORLOG 文件(停止服务后)停止 SQL Server 服务:找到错误日志文件:删除

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES