写点什么

使用 MTK 迁移 Mysql 源库后主键自增列导致数据无法插入问题

  • 2023-01-17
    中国香港
  • 本文字数:1626 字

    阅读完需:约 5 分钟

使用MTK迁移Mysql源库后主键自增列导致数据无法插入问题

本文分享自华为云社区《使用MTK迁移Mysql源库后主键自增列导致数据无法插入问题》,作者:Gauss 松鼠会。

故障背景


用户使用 Mogdb 2.0.1 版本进行业务上线测试,发现在插入数据时,应用日志中提示 primary key 冲突,用户自查业务 SQL 没有问题,接到通知后,招手处理故障。 


故障描述及根源分析


通过对用户数据表的检查,发现在 id 列上有一个 primary key,并且制定了一个序列器作为自增主键的代替。初步怀疑是 id 中的值,已经超过了序列器的最大值,导致了故障的发生。 分别检查序列器和表.id 字段的最大值,发现果然 max(id)为 474,序列器最大值刚刚 44。


file_manage=> \d file_table                                   Table "file_manage.file_table"   Column     |            Type             |                        Modifiers                        ---------------+-----------------------------+---------------------------------------------------------id            | bigint                      | not null default nextval('file_table_id_seq'::regclass)type_id       | bigint                      | column_name   | character varying(32)       | default NULL::character varyingfile_id       | character varying(64)       | default NULL::character varyingfile_name     | character varying(100)      | default NULL::character varyingcategory_type | integer                     | default 0pieces_id     | bigint                      | flag          | smallint                    | default (0)::smallintdel_flag      | smallint                    | default (0)::smallintcreate_time   | timestamp without time zone | default pg_systimestamp()update_time   | timestamp without time zone | default pg_systimestamp()
file_manage=> \d file_table_id_seq Sequence "file_manage.file_table_id_seq" Column | Type | Value ---------------+---------+---------------------sequence_name | name | file_table_id_seqlast_value | bigint | 44start_value | bigint | 1increment_by | bigint | 1max_value | bigint | 9223372036854775807min_value | bigint | 1cache_value | bigint | 1log_cnt | bigint | 32is_cycled | boolean | fis_called | boolean | tuuid | bigint | 0Owned by: file_manage.file_table.id
复制代码




同时查看报错的 id 对应值是否在 file_table 表中是否存在:


file_manage=> select count(*) from file_table where id=43;count -------    1(1 row)
file_manage=> select count(*) from file_table where id=44;count ------- 1(1 row)
复制代码



由此,基本上可以确定故障原因在于表中主键列已经保存了一定数量的值,在操作过程中,序列器并没有进行累加,导致序列器 nextval 已经远远小于主节列值,从而引发主键冲突。咨询用户后,用户确实使用过 insert into 语句为数据表插入了部分测试数据库上的数据。

故障处理流程


使用语句重新为序列器重置 currval


file_manage=> select setval('file_table_id_seq',(select max(id) from file_table));setval --------   474(1 row)
复制代码


通知用户重新启动应用进行测试,故障现象消失。故障总结分析本次故障的成因是通过 MTK 进行数据数据迁移时,如果源库是 MySQL,MTK 会通过判断 MySQL 数据表是否存在自增主键,如果存在泽辉建立一个序列器模拟 MySQL 自增主键效果。 但是如果在此类表上进行手动 gs_dump 或者 insert into 操作时,由于在操作过程中指定了主键列的值,并不会推搞序列器的 currval,最会导致在正常的数据增删改之后,出现类似主键冲突的问题。 对应的处理办法是需要在数据插入后,手动进行序列器的 currval 的重置,指向当前主键最大值。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
使用MTK迁移Mysql源库后主键自增列导致数据无法插入问题_数据库_华为云开发者联盟_InfoQ写作社区