摘要:用戶使用Mogdb 2.0.1版本進行業務上線測試,發現在插入數據時,應用日誌中提示primary key衝突,用戶自查業務SQL沒有問題,接到通知後,招手處理故障。 本文分享自華為雲社區《使用MTK遷移Mysql源庫後主鍵自增列導致數據無法插入問題》,作者:Gauss松鼠會。 故障背景 用戶 ...
摘要:用戶使用Mogdb 2.0.1版本進行業務上線測試,發現在插入數據時,應用日誌中提示primary key衝突,用戶自查業務SQL沒有問題,接到通知後,招手處理故障。
本文分享自華為雲社區《使用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 varying file_id | character varying(64) | default NULL::character varying file_name | character varying(100) | default NULL::character varying category_type | integer | default 0 pieces_id | bigint | flag | smallint | default (0)::smallint del_flag | smallint | default (0)::smallint create_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_seq last_value | bigint | 44 start_value | bigint | 1 increment_by | bigint | 1 max_value | bigint | 9223372036854775807 min_value | bigint | 1 cache_value | bigint | 1 log_cnt | bigint | 32 is_cycled | boolean | f is_called | boolean | t uuid | bigint | 0 Owned 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的重置,指向當前主鍵最大值。