:自增主鍵與序列改造全流程——AUTO_INCREMENT兼容、并發(fā)寫入與回退實(shí)戰(zhàn))
文章目錄每日一句正能量1. 背景與問題AUTO_INCREMENT遷移的核心是把“下一個(gè)ID由誰生成”遷過去2. 環(huán)境與數(shù)據(jù)先判斷是“簡(jiǎn)單自增”還是“分布式編號(hào)”2.1 為什么 auto_increment_increment/offset 必須檢查2.2 KingbaseES有兩條主流落地路線方案AIdentity方案BSequence Default3. 復(fù)現(xiàn)過程最容易踩的五個(gè)坑3.1 坑一導(dǎo)入3億歷史ID后目標(biāo)生成器仍從1開始3.2 坑二誤以為顯式插入歷史ID會(huì)自動(dòng)同步目標(biāo)生成器3.3 坑三把主鍵是否連續(xù)當(dāng)成驗(yàn)收指標(biāo)3.4 坑四只測(cè)試單條INSERT不測(cè)試批量主鍵回傳3.5 坑五源庫(kù)用多寫AUTO_INCREMENT目標(biāo)卻按單寫設(shè)計(jì)4. 方案實(shí)施一套可執(zhí)行的AUTO_INCREMENT遷移步驟4.1 第一步建立主鍵清單4.2 第二步處理 UNSIGNED4.3 第三步優(yōu)先Identity映射4.4 第四步Sequence兜底方案4.5 第五步全量導(dǎo)數(shù)保留原ID4.6 第六步增量同步仍然傳原ID4.7 第七步切流前二次校準(zhǔn)生成器4.8 第八步并發(fā)回歸單條 INSERT10/50/100并發(fā)回滾顯式歷史ID4.9 第九步批量INSERT單獨(dú)驗(yàn)證4.10 第十步ON DUPLICATE KEY UPDATE一起掃描5. 結(jié)果對(duì)比驗(yàn)收必須同時(shí)看數(shù)據(jù)、生成器和應(yīng)用5.1 歷史數(shù)據(jù)5.2 外鍵和業(yè)務(wù)引用5.3 生成器安全距離5.4 應(yīng)用主鍵回傳5.5 示例回歸結(jié)果模板5.6 性能指標(biāo)6. 風(fēng)險(xiǎn)與復(fù)盤自增主鍵最危險(xiǎn)的是“雙主同時(shí)生成”6.1 風(fēng)險(xiǎn)一切換窗口兩邊都在自動(dòng)生成ID6.2 風(fēng)險(xiǎn)二多庫(kù)分片ID被誤當(dāng)單庫(kù)AUTO_INCREMENT6.3 風(fēng)險(xiǎn)三Sequence CACHE造成空洞被誤判數(shù)據(jù)丟失6.4 風(fēng)險(xiǎn)四歷史高值異常6.5 風(fēng)險(xiǎn)五BIGINT UNSIGNED容量問題6.6 風(fēng)險(xiǎn)六LAST_INSERT_ID依賴被遺漏6.7 風(fēng)險(xiǎn)七Sequence權(quán)限遺漏回退方案回源之前也要重新校準(zhǔn)AUTO_INCREMENT最終復(fù)盤附錄 AMySQL源DDL附錄 BKingbaseES Identity方案附錄 CKingbaseES Sequence方案附錄 D最低回歸清單每日一句正能量“人生沒有標(biāo)準(zhǔn)答案敢于重新開始的人永遠(yuǎn)自帶光芒?!泵總€(gè)人都可以書寫自己的答案。而“重新開始”的能力是一個(gè)人生命力最璀璨的證明。跌倒后能爬起歸零后能重啟這種勇氣本身就是一種無法被忽視的光芒。主題AUTO_INCREMENT 兼容 / MySQL → KingbaseES / 互聯(lián)網(wǎng)業(yè)務(wù)遷移重點(diǎn)DDL 轉(zhuǎn)換、Identity/Sequence 選擇、歷史 ID 保留、并發(fā)寫入、主鍵回傳、回歸測(cè)試、數(shù)據(jù)校驗(yàn)與回退適用場(chǎng)景訂單、用戶、支付流水、內(nèi)容主表、互聯(lián)網(wǎng)業(yè)務(wù)單庫(kù)或分片庫(kù)遷移。1. 背景與問題AUTO_INCREMENT遷移的核心是把“下一個(gè)ID由誰生成”遷過去MySQL 互聯(lián)網(wǎng)業(yè)務(wù)里最常見的主鍵定義之一CREATETABLEbiz_order(order_idBIGINTNOTNULLAUTO_INCREMENT,...PRIMARYKEY(order_id));很多遷移方案會(huì)直接寫AUTO_INCREMENT → Identity然后認(rèn)為工作完成。但自增主鍵真正影響的不是一行 DDL而是一整條寫入鏈路INSERT不傳ID → 數(shù)據(jù)庫(kù)生成ID → 驅(qū)動(dòng)/ORM拿回ID → 子表/消息使用這個(gè)ID → CDC傳播 → 下一條記錄繼續(xù)生成對(duì)互聯(lián)網(wǎng)業(yè)務(wù)還可能存在auto_increment_increment auto_increment_offset 多主寫入 分庫(kù)分表 號(hào)段 雪花ID 外部ID服務(wù)因此遷移前必須先判斷源系統(tǒng)到底是在使用 MySQL 的“單實(shí)例 AUTO_INCREMENT”還是借用了 AUTO_INCREMENT 做多寫節(jié)點(diǎn)的號(hào)段隔離。MySQL 8.4 官方說明InnoDB 為 AUTO_INCREMENT 維護(hù)專門計(jì)數(shù)器不顯式提供值時(shí)由計(jì)數(shù)器產(chǎn)生新值。如果顯式插入的 ID 大于當(dāng)前計(jì)數(shù)器后續(xù)計(jì)數(shù)器會(huì)被推進(jìn)。MySQL 同時(shí)提供auto_increment_increment和auto_increment_offset可以用于多服務(wù)器生成互不沖突的自增值。所以遷移目標(biāo)必須覆蓋歷史ID不變 目標(biāo)新ID不沖突 應(yīng)用主鍵回傳正常 并發(fā)寫入安全 多寫架構(gòu)語義不丟失 異常時(shí)能回退2. 環(huán)境與數(shù)據(jù)先判斷是“簡(jiǎn)單自增”還是“分布式編號(hào)”示例環(huán)境源庫(kù)MySQL 8.0/8.4 InnoDB 目標(biāo)KingbaseES V9 業(yè)務(wù)互聯(lián)網(wǎng)訂單服務(wù) 單表數(shù)據(jù)約3億 日新增300萬 主鍵BIGINT AUTO_INCREMENT 寫入方式JDBC/MyBatis源表CREATETABLEbiz_order(order_idBIGINTNOTNULLAUTO_INCREMENT,customer_idBIGINTNOTNULL,order_noVARCHAR(64)NOTNULL,amountDECIMAL(18,2)NOTNULL,created_atDATETIME(6)NOTNULL,PRIMARYKEY(order_id),UNIQUEKEYuk_order_no(order_no));遷移前至少記錄當(dāng)前MAX(order_id) AUTO_INCREMENT當(dāng)前起點(diǎn) 數(shù)據(jù)類型是否UNSIGNED auto_increment_increment auto_increment_offset 主庫(kù)數(shù)量 是否多主寫 應(yīng)用如何取得新ID 是否有顯式插入ID邏輯2.1 為什么auto_increment_increment/offset必須檢查MySQL 官方文檔說明auto_increment_increment控制每次自增的步長(zhǎng)auto_increment_offset控制起始偏移。比如兩個(gè)寫節(jié)點(diǎn)節(jié)點(diǎn)Aoffset1, increment2 → 1,3,5,7... 節(jié)點(diǎn)Boffset2, increment2 → 2,4,6,8...如果這種架構(gòu)遷移到 KingbaseES 后簡(jiǎn)單變成所有節(jié)點(diǎn)共用一個(gè) START 1 INCREMENT 1雖然不會(huì)一定產(chǎn)生重復(fù)但源系統(tǒng)的分布式編號(hào)策略已經(jīng)改變。如果應(yīng)用或分片邏輯依賴id % 2判斷來源節(jié)點(diǎn)就會(huì)出現(xiàn)業(yè)務(wù)問題。因此要先做“主鍵架構(gòu)識(shí)別”。2.2 KingbaseES有兩條主流落地路線當(dāng)前 KingbaseES SQL 參考明確支持GENERATED ALWAYSASIDENTITYGENERATEDBYDEFAULTASIDENTITYIdentity 列會(huì)綁定一個(gè)隱式序列新插入行可以自動(dòng)獲得值。另外 KingbaseES 還提供獨(dú)立CREATESEQUENCE支持START WITH INCREMENT BY CACHE NO CYCLE NEXTVAL CURRVAL SETVAL因此最常用兩條路線方案AIdentityorder_idBIGINTGENERATEDBYDEFAULTASIDENTITY適合單寫服務(wù) 傳統(tǒng)AUTO_INCREMENT表 希望DDL簡(jiǎn)單方案BSequence DefaultCREATESEQUENCE biz_order_id_seq;order_idBIGINTDEFAULTNEXTVAL(biz_order_id_seq)適合需要顯式管理生成器 需要更清楚控制START/INCREMENT/CACHE 遷移工具對(duì)Identity支持一般3. 復(fù)現(xiàn)過程最容易踩的五個(gè)坑3.1 坑一導(dǎo)入3億歷史ID后目標(biāo)生成器仍從1開始源端MAX(order_id)386,120,008全量遷移order_id原值全部保留目標(biāo)數(shù)據(jù)檢查COUNT一致 MAX一致如果 Identity/Sequence 仍然從1開始切流后就有主鍵沖突風(fēng)險(xiǎn)。因此切換前必須滿足目標(biāo)NEXT VALUE 全局已使用MAX(id)這應(yīng)該是自動(dòng)化阻斷條件而不是檢查清單里“人工看一眼”。3.2 坑二誤以為顯式插入歷史ID會(huì)自動(dòng)同步目標(biāo)生成器MySQL 的行為很容易形成慣性。MySQL 官方示例說明如果向 AUTO_INCREMENT 列顯式寫一個(gè)較大的值例如100隨后自動(dòng)生成的值可以從101繼續(xù)。因此 DBA 容易形成“我已經(jīng)導(dǎo)入了歷史ID目標(biāo)自增肯定也知道最大值?!钡?KingbaseES 的 Identity 依賴隱式序列BY DEFAULT允許顯式歷史值優(yōu)先不代表遷移程序就可以省略生成器校準(zhǔn)。正確做法仍然是導(dǎo)完數(shù)據(jù) → SELECT MAX(id) → 檢查Identity/Sequence當(dāng)前狀態(tài) → 顯式RESTART/SETVAL/ALTER3.3 坑三把主鍵是否連續(xù)當(dāng)成驗(yàn)收指標(biāo)MySQL AUTO_INCREMENT 在事務(wù)回滾 并發(fā)插入 失敗插入 批量語句場(chǎng)景下并不應(yīng)該被當(dāng)作業(yè)務(wù)連續(xù)號(hào)碼。KingbaseES Sequence 也一樣。官方開發(fā)規(guī)范明確建議不要將商業(yè)邏輯建立在序列完全連續(xù)性上并說明增大 CACHE 可以減少爭(zhēng)用但會(huì)增加不連續(xù)的可能。所以驗(yàn)收重點(diǎn)是唯一 不會(huì)回退到已使用范圍 并發(fā)安全不是1001、1002、1003一個(gè)都不能少訂單號(hào)、發(fā)票號(hào)如果要求特定連續(xù)規(guī)則應(yīng)使用獨(dú)立業(yè)務(wù)編號(hào)機(jī)制。3.4 坑四只測(cè)試單條INSERT不測(cè)試批量主鍵回傳MySQL 生態(tài)中很多框架依賴LAST_INSERT_ID() getGeneratedKeys() useGeneratedKeysMySQL 官方文檔也明確提供LAST_INSERT_ID()/mysql_insert_id()獲取最近自動(dòng)生成的 AUTO_INCREMENT 值。遷到 KingbaseES 后數(shù)據(jù)庫(kù)生成 ID 沒問題不代表JDBC MyBatis JPA 批量INSERT都能用完全相同方式拿到主鍵。尤其批量插入INSERTINTO...VALUES(...),(...),(...);不能只假設(shè)拿到第一個(gè)ID → 后面的ID必然連續(xù)推導(dǎo)因?yàn)檫@種假設(shè)把“生成器連續(xù)性”當(dāng)成了應(yīng)用協(xié)議。應(yīng)該讓真實(shí)驅(qū)動(dòng)/ORM返回并驗(yàn)證每個(gè)生成主鍵。3.5 坑五源庫(kù)用多寫AUTO_INCREMENT目標(biāo)卻按單寫設(shè)計(jì)MySQL FAQ 明確說明MySQL 本身沒有通用 Sequence但可以通過auto_increment_increment auto_increment_offset在多服務(wù)器場(chǎng)景減少 AUTO_INCREMENT 沖突。如果源系統(tǒng)雙主 多源復(fù)制 多機(jī)房遷移時(shí)必須回答目標(biāo)還是多寫嗎如果目標(biāo)變成單主寫可以把主鍵生成收斂到單一 Sequence/Identity。如果目標(biāo)仍然需要多節(jié)點(diǎn)獨(dú)立生成ID則要重新設(shè)計(jì)不同START/OFFSET的Sequence 號(hào)段 全局ID服務(wù) 雪花ID不能只把源表 DDL 翻譯一下。4. 方案實(shí)施一套可執(zhí)行的AUTO_INCREMENT遷移步驟4.1 第一步建立主鍵清單建議 SQL 清單至少記錄schema table column type unsigned current_max_id auto_increment increment offset foreign_key_count write_qps id_generation_mode分類S1單庫(kù)單寫AUTO_INCREMENT S2多寫increment/offset S3分庫(kù)分表號(hào)段 S4外部ID/雪花 S5業(yè)務(wù)顯式賦ID優(yōu)先遷S1復(fù)雜度最低。4.2 第二步處理 UNSIGNEDMySQL 常見BIGINTUNSIGNEDAUTO_INCREMENT這不僅是自增問題也是數(shù)據(jù)類型范圍問題。目標(biāo) KingbaseES 如果采用有符號(hào)BIGINT必須檢查MAX(id)是否已經(jīng)超過目標(biāo)類型上限。大部分業(yè)務(wù)實(shí)際值遠(yuǎn)低于上限但遷移評(píng)估不能靠猜。必須MAX(id) 未來增長(zhǎng)年限做容量評(píng)估。4.3 第三步優(yōu)先Identity映射典型目標(biāo)CREATETABLEbiz_order(order_idBIGINTGENERATEDBYDEFAULTASIDENTITY(STARTWITH1INCREMENTBY1)PRIMARYKEY,customer_idBIGINTNOTNULL,order_noVARCHAR(64)NOTNULLUNIQUE,amountNUMERIC(18,2)NOTNULL,created_atTIMESTAMP(6)NOTNULL);為什么使用BY DEFAULT而不是遷移階段直接ALWAYSKingbaseES 官方語義是BY DEFAULT 用戶顯式提供值時(shí)用戶值優(yōu)先 ALWAYS 默認(rèn)強(qiáng)制使用生成值除非顯式覆蓋系統(tǒng)值遷移全量和增量都需要保留 MySQL 歷史 ID因此BY DEFAULT更方便。切換完成后是否調(diào)整更嚴(yán)格的寫入策略可以通過應(yīng)用層禁止傳ID 權(quán)限 SQL審計(jì)實(shí)現(xiàn)。4.4 第四步Sequence兜底方案如果想把生成器獨(dú)立出來CREATESEQUENCE biz_order_id_seqASBIGINTSTARTWITH386120009INCREMENTBY1CACHE100NOCYCLE;列order_idBIGINTDEFAULTNEXTVAL(biz_order_id_seq)KingbaseES 官方序列文檔明確支持START WITH、INCREMENT BY、CACHE、NO CYCLE并可通過nextval/currval/setval管理生成器。Sequence 方案的工程優(yōu)勢(shì)生成器獨(dú)立可見 參數(shù)更容易審計(jì) 多表/特殊生成策略可重用 遷移腳本容易校準(zhǔn)缺點(diǎn)DDL比Identity多一個(gè)對(duì)象 權(quán)限要單獨(dú)確認(rèn) 對(duì)象命名和生命周期要治理4.5 第五步全量導(dǎo)數(shù)保留原ID歷史訂單1 2 ... 386120008目標(biāo)必須仍然是1 2 ... 386120008不要重新生成。原因order_detail.order_id payment.order_id message業(yè)務(wù)鍵 數(shù)據(jù)倉(cāng)庫(kù)引用 日志關(guān)聯(lián)都可能已經(jīng)依賴原ID。如果重新編號(hào)就會(huì)把“主表遷移”變成“全鏈路主鍵重映射項(xiàng)目”。4.6 第六步增量同步仍然傳原ID全量遷移運(yùn)行幾個(gè)小時(shí)甚至幾天時(shí)MySQL 仍有新訂單寫入。CDC 增量INSERT order_id386120009目標(biāo)也要INSERT order_id386120009而不是由 KingbaseES 自己生成一個(gè) ID。遷移期MySQL是主鍵權(quán)威切流后KingbaseES才成為新的主鍵權(quán)威這個(gè)切換點(diǎn)必須明確。4.7 第七步切流前二次校準(zhǔn)生成器第一次全量導(dǎo)完MAX(id)386120008幾小時(shí)后 CDC 已經(jīng)追到386520100所以不能只在全量后校準(zhǔn)一次。切流正確順序停止源端新寫 ↓ 追平最后CDC ↓ 源目標(biāo)MAX(id)比對(duì) ↓ 目標(biāo)生成器再次校準(zhǔn) ↓ 驗(yàn)證NEXT VALUE安全 ↓ 開啟KingbaseES寫4.8 第八步并發(fā)回歸至少測(cè)試單條 INSERTINSERTINTObiz_order(customer_id,order_no,amount)VALUES(...);斷言生成ID非NULL 數(shù)據(jù)庫(kù)行ID 應(yīng)用拿到ID10/50/100并發(fā)檢查duplicate0 PK conflict0 generated ids unique回滾BEGIN INSERT ROLLBACK允許ID出現(xiàn)空洞但后續(xù)不得產(chǎn)生重復(fù)。顯式歷史ID分別插入比當(dāng)前MAX低 比當(dāng)前MAX高確認(rèn)遷移流程和后續(xù)校準(zhǔn)腳本都能正確處理。4.9 第九步批量INSERT單獨(dú)驗(yàn)證MySQL 應(yīng)用很喜歡INSERTINTOt(...)VALUES(...),(...),(...);遷移后至少驗(yàn)證生成多少個(gè)ID 驅(qū)動(dòng)返回多少個(gè) 順序是否對(duì)應(yīng)輸入行 批次部分失敗如何處理不要用first_id i推算后續(xù)主鍵作為正式設(shè)計(jì)。4.10 第十步ON DUPLICATE KEY UPDATE一起掃描互聯(lián)網(wǎng) MySQL 常見INSERT...ONDUPLICATEKEYUPDATE...MySQL 官方文檔說明它遇到 UNIQUE/PRIMARY KEY 沖突時(shí)可以轉(zhuǎn)為 UPDATE在含 AUTO_INCREMENT 的表上它還會(huì)影響自增值和LAST_INSERT_ID()相關(guān)行為。因此遷移自增主鍵時(shí)應(yīng)該順便掃描ON DUPLICATE KEY UPDATE REPLACE INTO INSERT IGNORE LAST_INSERT_ID這些都屬于“寫入語義”不能只改表結(jié)構(gòu)。5. 結(jié)果對(duì)比驗(yàn)收必須同時(shí)看數(shù)據(jù)、生成器和應(yīng)用5.1 歷史數(shù)據(jù)至少比較COUNT(*)MIN(id)MAX(id)COUNT(DISTINCTid)斷言COUNT COUNT(DISTINCT id)主鍵無重復(fù)。5.2 外鍵和業(yè)務(wù)引用例如SELECTCOUNT(*)FROMorder_detail dLEFTJOINbiz_order oONd.order_ido.order_idWHEREo.order_idISNULL;結(jié)果05.3 生成器安全距離遷移完成MAX(id)386520100目標(biāo)下一值必須386520100如果采用多節(jié)點(diǎn)號(hào)段還要驗(yàn)證所有節(jié)點(diǎn)未來生成空間互不沖突5.4 應(yīng)用主鍵回傳測(cè)試JDBC getGeneratedKeys MyBatis useGeneratedKeys JPA GeneratedValue 批量Insert 事務(wù)Insert必須斷言應(yīng)用對(duì)象ID 數(shù)據(jù)庫(kù)實(shí)際ID5.5 示例回歸結(jié)果模板用例MySQLKingbaseES結(jié)果單條自動(dòng)ID成功成功通過顯式歷史ID保留保留通過50并發(fā)無重復(fù)無重復(fù)通過ROLLBACK后繼續(xù)插入允許空洞允許空洞通過JDBC取主鍵正常正常通過批量Insert返回ID已驗(yàn)證返回通過這些是驗(yàn)收模板不是本文聲稱的真實(shí)生產(chǎn)結(jié)果。5.6 性能指標(biāo)自增遷移還應(yīng)該記錄Insert TPS P50/P95/P99 生成器等待 WAL 索引寫入 Sequence CACHE大小KingbaseES 官方開發(fā)規(guī)范建議適當(dāng)增大 Sequence CACHE 可以降低爭(zhēng)用但同時(shí)會(huì)增加序列不連續(xù)性?;ヂ?lián)網(wǎng)高并發(fā)業(yè)務(wù)可以測(cè)試CACHE 1 CACHE 20 CACHE 100 CACHE 300選擇性能和可接受空洞之間的平衡。再次強(qiáng)調(diào)主鍵唯一遠(yuǎn)比主鍵連續(xù)重要。6. 風(fēng)險(xiǎn)與復(fù)盤自增主鍵最危險(xiǎn)的是“雙主同時(shí)生成”6.1 風(fēng)險(xiǎn)一切換窗口兩邊都在自動(dòng)生成ID這是最大的風(fēng)險(xiǎn)。如果MySQL繼續(xù)AUTO_INCREMENT KingbaseES Identity也開放兩個(gè)庫(kù)可能在相同數(shù)值空間生成新ID。所以切換要保證同一個(gè)業(yè)務(wù)主鍵空間在任意時(shí)刻只能有一個(gè)權(quán)威生成器除非已經(jīng)設(shè)計(jì)了明確不沖突的號(hào)段。6.2 風(fēng)險(xiǎn)二多庫(kù)分片ID被誤當(dāng)單庫(kù)AUTO_INCREMENT比如db0 → 奇數(shù) db1 → 偶數(shù)或者每個(gè)分片從不同億級(jí)號(hào)段開始這些信息可能根本不在表 DDL 中而在MySQL系統(tǒng)變量 部署配置 中間件 應(yīng)用代碼遷移清單必須覆蓋數(shù)據(jù)庫(kù)外部。6.3 風(fēng)險(xiǎn)三Sequence CACHE造成空洞被誤判數(shù)據(jù)丟失KingbaseES 官方文檔說明緩存序列號(hào)能提升性能但實(shí)例異常關(guān)閉時(shí)緩存中尚未使用的值可能被跳過。這不是訂單丟失。真正的訂單完整性應(yīng)該通過業(yè)務(wù)唯一鍵 記錄數(shù) 狀態(tài) 消息鏈路判斷。不要用ID必須連續(xù)做數(shù)據(jù)完整性校驗(yàn)。6.4 風(fēng)險(xiǎn)四歷史高值異??赡芙^大多數(shù)id 4億但曾經(jīng)人工修復(fù)id9,000,000,000如果只按“正常增長(zhǎng)趨勢(shì)”設(shè)置目標(biāo)序列4億1最終仍會(huì)撞到歷史記錄。所以必須讀取真實(shí)MAX(id)6.5 風(fēng)險(xiǎn)五BIGINT UNSIGNED容量問題如果 MySQL 使用BIGINT UNSIGNED目標(biāo)類型范圍可能不同。即使當(dāng)前數(shù)據(jù)沒超過范圍也要評(píng)估未來3年/5年增長(zhǎng)不能等遷移后幾年才發(fā)現(xiàn)主鍵逼近上限。6.6 風(fēng)險(xiǎn)六LAST_INSERT_ID依賴被遺漏應(yīng)用可能直接執(zhí)行SELECTLAST_INSERT_ID();MySQL 官方說明LAST_INSERT_ID()對(duì)當(dāng)前連接生成的 AUTO_INCREMENT 值有明確語義。遷移后不能假設(shè)這個(gè)函數(shù)和連接態(tài)語義仍然完全一樣。更推薦應(yīng)用通過目標(biāo)驅(qū)動(dòng)支持的generated keys RETURNING獲取新主鍵并做真實(shí)連接池測(cè)試。6.7 風(fēng)險(xiǎn)七Sequence權(quán)限遺漏如果用Sequence Default應(yīng)用賬號(hào)除了表 INSERT 權(quán)限還需要確認(rèn)能夠正常訪問相關(guān)序列。這種權(quán)限問題往往在DBA賬號(hào)測(cè)試成功 生產(chǎn)應(yīng)用賬號(hào)失敗時(shí)才暴露。切換清單要使用真實(shí)應(yīng)用賬號(hào)執(zhí)行?;赝朔桨富卦粗耙惨匦滦?zhǔn)AUTO_INCREMENT假設(shè)MySQL最后ID 386520100切到 KingbaseES 后又寫了50000條最大 ID 已經(jīng)386570100現(xiàn)在因?yàn)閼?yīng)用兼容問題需要回退 MySQL。不能簡(jiǎn)單把連接串切回MySQL否則 MySQL 原計(jì)數(shù)器可能繼續(xù)從386520101生成而 KingbaseES 窗口期已經(jīng)使用了這些 ID。正確回退1. 停止KingbaseES新寫 2. 固化目標(biāo)最后ID和業(yè)務(wù)水位 3. 將目標(biāo)新增記錄反向同步MySQL并保留原ID 4. 校驗(yàn)兩端MAX(id) 5. 將MySQL AUTO_INCREMENT推進(jìn)到全局MAX(id)安全步長(zhǎng) 6. 恢復(fù)MySQL寫入口 7. KingbaseES轉(zhuǎn)為只讀排障回退原則和切流原則其實(shí)完全一致下一任主庫(kù)的主鍵生成器必須位于所有已使用ID之后。最終復(fù)盤MySQL 到 KingbaseES 的 AUTO_INCREMENT 遷移建議按五層處理第一層識(shí)別源編號(hào)架構(gòu) AUTO_INCREMENT / incrementoffset / 分片 / 外部ID 第二層選擇目標(biāo)生成器 Identity / Sequence / 外部ID服務(wù) 第三層保留歷史主鍵 全量 CDC 都顯式傳原ID 第四層校準(zhǔn)生成器 NEXT VALUE 全局MAX(id) 第五層回歸與回退 并發(fā)寫 主鍵回傳 雙端水位 回源校準(zhǔn)如果只記住一句話AUTO_INCREMENT 遷移不是把關(guān)鍵字換掉而是在遷移“誰擁有下一個(gè)唯一ID的生成權(quán)”。這個(gè)生成權(quán)只要在切換窗口中模糊一秒就可能留下后續(xù)非常難修復(fù)的主鍵沖突。附錄 AMySQL源DDLCREATETABLEbiz_order(order_idBIGINTNOTNULLAUTO_INCREMENT,customer_idBIGINTNOTNULL,order_noVARCHAR(64)NOTNULL,amountDECIMAL(18,2)NOTNULL,PRIMARYKEY(order_id));附錄 BKingbaseES Identity方案CREATETABLEbiz_order(order_idBIGINTGENERATEDBYDEFAULTASIDENTITY(STARTWITH1INCREMENTBY1)PRIMARYKEY,customer_idBIGINTNOTNULL,order_noVARCHAR(64)NOTNULL,amountNUMERIC(18,2)NOTNULL);附錄 CKingbaseES Sequence方案CREATESEQUENCE biz_order_id_seqASBIGINTSTARTWITH386520101INCREMENTBY1CACHE100NOCYCLE;CREATETABLEbiz_order(order_idBIGINTPRIMARYKEYDEFAULTNEXTVAL(biz_order_id_seq),...);附錄 D最低回歸清單[ ] AUTO_INCREMENT列已全部掃描 [ ] 當(dāng)前MAX(id)已記錄 [ ] increment/offset已記錄 [ ] UNSIGNED范圍已評(píng)估 [ ] 分庫(kù)分表/外部ID邏輯已識(shí)別 [ ] 全量導(dǎo)入保留原ID [ ] CDC保留原ID [ ] 目標(biāo)生成器已二次校準(zhǔn) [ ] 單條INSERT主鍵回傳通過 [ ] 批量INSERT主鍵回傳通過 [ ] 10/50/100并發(fā)無重復(fù) [ ] 回滾后寫入通過 [ ] 應(yīng)用真實(shí)賬號(hào)權(quán)限通過 [ ] 回退AUTO_INCREMENT校準(zhǔn)腳本已演練轉(zhuǎn)載自https://blog.csdn.net/u014727709/article/details/163728579歡迎 點(diǎn)贊?評(píng)論?收藏歡迎指正