前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ent M2M模型在pxc集群中的一个大坑

ent M2M模型在pxc集群中的一个大坑

作者头像
天地一小儒
发布2023-10-16 16:21:59
1740
发布2023-10-16 16:21:59
举报
文章被收录于专栏:信且诚心之动

ent M2M模型在pxc集群中的一个大坑

事故简要分析

PXC集群3个节点,在插入数据时,如果使用数据库自己生成的主键,一般顺序为1,4,7,10…

这里就是坑的源头,在ent底层代码中,在做M2M模型插入时,会先插入两个模型,再插入中间表。即,假设M2M模型为group和user(https://entgo.io/docs/schema-edges#m2m-two-types),这里数据库会产生3张表,users, groups 和 user_groups,其中user_groups存放userid和groupid,这样就组成了一个多对多模型。

事故复原

假设先插入一个group,再插入一堆user,而在使用ent的CreateBulk插入user时,问题就发生了,我们在测试环境永远无法复现出问题,而只要一上生产环境,问题必然出现。原因就在于测试环境使用单节点mysql,生产环境使用的pxc集群!

先看插入代码:

代码语言:javascript
复制
// Add Group
hub := client.Group.
        Create().
        SetName("GitHub").
        SaveX(ctx)

// Add Users
bulk := make([]*User, len(users))
for i, user:= range users {
            bulk[i] = client.User.
        Create().
        SetAge(30).
        SetName("a8m").
        AddGroups(hub)
}
_, err = client.User.CreateBulk(bulk...).Save(ctx)
if err != nil {
    return errors.Wrap(err, "User.CreateBulk") // pxc集群必然报错
}

源码分析

.Save()中调用了BatchCreate,又跳转nodes

Untitled.png

nodes中主要两行代码是batchInsert和batchAddM2M,直观理解就是,先插入users,在插入user_groups,而插入user_groups时需要拿到所有users的id,由于我们是在一个事务里完成的,因此实际数据并未真正插入,因此ent做了一个看起来没问题的骚操作。

Untitled 1.png

从batchInsert到c.insertLastIDs

Untitled 2.png

重点来了,MySQL数据库id的处理结果是插入一条,剩下的数据加1,这是理想情况。比如插入时,第一条user的id是4,那剩下的id就是5,6,7,8,9…,但实际上,pxc集群处理时并不是这样,因此造成插入users时,id实际是4,7,10,13…,因此最终执行M2M插入操作时报错:add m2m edge for table

Untitled 3.png

正确的应该是1,4 1,7。于是报错:Error 1452: FOREIGN KEY constraint failed

Untitled 4.png

解决方式

PXC集群下

  • 能不用M2M就不用M2M。M2M改O2M;
  • 必须使用M2M时,不使用CreateBulk。该批量为单条;
  • 必须使用CreateBulk时,手动指定id。自行使用分布式id。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ent M2M模型在pxc集群中的一个大坑
  • 事故简要分析
  • 事故复原
    • 先看插入代码:
      • 源码分析
      • 解决方式
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档