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

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

SpringBoot如何使用TraceId日志链路追踪

《SpringBoot如何使用TraceId日志链路追踪》文章介绍了如何使用TraceId进行日志链路追踪,通过在日志中添加TraceId关键字,可以将同一次业务调用链上的日志串起来,本文通过实例代码... 目录项目场景:实现步骤1、pom.XML 依赖2、整合logback,打印日志,logback-sp

使用@Slf4j注解,log.info()无法使用问题

《使用@Slf4j注解,log.info()无法使用问题》在使用Lombok的@Slf4j注解打印日志时遇到问题,通过降低Lombok版本(从1.18.x降至1.16.10)解决了问题... 目录@Slf4androidj注解,log.info()无法使用问题最后解决总结@Slf4j注解,log.info(

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训