Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seata 1.8.0版本 使用DM数据库报错Before image size is not equaled to after image size, probably because you updated the primary keys #6960

Open
skippyb1 opened this issue Oct 29, 2024 · 7 comments

Comments

@skippyb1
Copy link

skippyb1 commented Oct 29, 2024

Ⅰ. Issue Description

seata 1.8.0版本 使用DM数据库报错Before image size is not equaled to after image size, probably because you updated the primary keys

Ⅱ. Describe what happened
If there is an exception, please attach the exception trace:
image

当建立联合索引的字段中存在主键字段时会把索引的indexType设置为IndexType.PRIMARY 导致生成的afterImageSql错误
错误代码位置
72919fcbebd6343dd6428cd24e771f0

Just paste your stack trace here!
Ⅲ. Describe what you expected to happen
能够正常执行

Ⅳ. How to reproduce it (as minimally and precisely as possible)
可参考:#3946

Minimal yet complete reproducer code (or URL to code):

Ⅴ. Anything else we need to know?
Ⅵ. Environment:
JDK version : 1.8
Others: seata1.8.0

@lin1005q
Copy link

@iquanzhan

@funky-eyes
Copy link
Contributor

把你的表结构和sql发出来看下,以及buildBeforeImageSQL和buildAfterImageSQL 帮忙看下是什么样的。debug UpdateExecutor这个类
Please share your table structure and SQL, as well as the buildBeforeImageSQL and buildAfterImageSQL methods. I need to take a look at them. Additionally, debug the UpdateExecutor class.

@skippyb1
Copy link
Author

建表语句
CREATE TABLE PIPELINE.FLOW_TEMPLATE (
TEMPLATE_ID VARCHAR(108) NOT NULL,
TEMPLATE_NAME VARCHAR(300),
CREATE_DATE DATE,
STATUS CHAR(1),
TEMPLATE_INFO TEXT,
PROJECT_ID VARCHAR(24000),
TEMPLATE_TAG VARCHAR(48),
VERSION_ROLE VARCHAR(12000),
CONSTRAINT CONS134227764 PRIMARY KEY (TEMPLATE_ID)
);
CREATE UNIQUE INDEX INDEX33568088 ON PIPELINE.FLOW_TEMPLATE (TEMPLATE_ID);
CREATE INDEX MSG_U_FT ON PIPELINE.FLOW_TEMPLATE (STATUS,TEMPLATE_ID,TEMPLATE_NAME,TEMPLATE_TAG);

执行的语句
update flow_template
set template_name = 'xxxxx',
create_date = '2023-04-23',
status = '2'
where template_id = 'xxxx'

beforeImageSql
SELECT STATUS , TEMPLATE_NAME , TEMPLATE_TAG , TEMPLATE_ID, template_name, create_date, status FROM flow_template WHERE template_id = ? FOR UPDATE

afterImageSql
SELECT STATUS , TEMPLATE_NAME , TEMPLATE_TAG , TEMPLATE_ID, template_name, create_date, status FROM flow_template WHERE (STATUS,TEMPLATE_NAME,TEMPLATE_TAG,TEMPLATE_ID) in ( (?,?,?,?) )

@skippyb1
Copy link
Author

UpdateExecutor截图
1730363539881

@skippyb1
Copy link
Author

信息补充
status字段原始值是1 更新语句是要改成2 status也在索引中

@funky-eyes
Copy link
Contributor

收到,我们先看下谢谢
Received, let's take a look first, thank you.

@ygg100
Copy link

ygg100 commented Dec 14, 2024

@funky-eyes @skippyb1
seata 1.8.0版本 AT模式

我这边遇到类似的情况,联合主键(id,create_date),create_date为date和datetime都会报错,create_date作为分区。
当删除(逻辑删除其实是update)1条的时候可以成功。
当删除数量达到2条或以上,并且第一次请求,则会报:
Before image size is not equaled to after image size, probably because you updated the primary keys.
当第二次再次请求则会成功,相隔时间不长(1分钟内)。

表结构:
CREATE TABLE fm_bill_splt (
id varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'ID',
create_date date NOT NULL DEFAULT (curdate()) COMMENT '创建日期',
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
create_by varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人ID',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
update_by varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '更新人ID',
is_deleted tinyint DEFAULT '0' COMMENT '删除区分',
PRIMARY KEY (id,create_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
/*!50100 PARTITION BY RANGE (year(create_date))
(PARTITION p0 VALUES LESS THAN (2020) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (2021) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2022) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (2023) ENGINE = InnoDB,
PARTITION p4 VALUES LESS THAN (2024) ENGINE = InnoDB,
PARTITION p5 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

UPDATE fm_bill_splt SET update_by = ?, update_time = ?, is_deleted = 1 WHERE id = ? AND is_deleted = 0

beforeImageSql:
SELECT
id,
create_date,
update_by,
update_time,
is_deleted
FROM
fm_bill_splt
WHERE
( id = ? AND is_deleted = 0 )
OR ( id = ? AND is_deleted = 0 ) FOR UPDATE ;

afterImageSql
SELECT
id,
create_date,
update_by,
update_time,
is_deleted
FROM
fm_bill_splt
WHERE
( id, create_date ) IN (
(?,?),(?,?));

截图:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants