
用 ECS 自建 MySQL 跑小應用到底圖什么圖便宜、圖可控。可在我把應用遷到瑤池數據庫 RDS MySQL 之后回頭看這筆賬其實沒算對——不是 RDS 太貴而是自建的隱性成本被嚴重低估了。這篇文章就把我從自建 MySQL 遷移到瑤池 RDS 的完整過程記錄下來包括方案怎么選、mysqldump 怎么用、切換當天怎么處理、以及遷完之后的賬單對比給同樣在 ECS 上自己維護數據庫的朋友一個可以直接參考的實戰樣本。先說下背景應用不大高峰并發幾十數據量不到 5GBMySQL 版本 8.0原先是應用和數據庫擠在同一臺 2核4G ECS 上。這種配置在個人項目和小團隊里非常典型也是我寫這篇的前提。如果你也是類似規模這篇文章會很有用如果你的庫有幾百 GB 甚至更大遷移思路可以參考但工具選型得調整我會在第二章說明白。1. 自建 MySQL 的隱形賬單為什么小應用也扛不住1.1 那臺“便宜”的 ECS拆開算并不便宜很多朋友自建數據庫的初衷是省錢反正 ECS 都要買MySQL 是開源的裝上去就能用何必多花一份 RDS 的錢這個邏輯乍看沒問題但你得把賬單拆開看。我當初的配置是一臺 2核4G ECS40G ESSD 云盤包年折算下來大概每月 250 元左右云盤單獨計費40G 大概 20 元/月快照如果開了一個月再多個 5-10 元。如果還買了固定公網帶寬又是額外一筆。這還只是“應用和數據庫共用一臺機器”的情況。問題在于小應用跑著跑著會長大。當數據庫和 Web 服務搶 CPU、搶內存、搶磁盤 IO 的時候你只有兩個選擇一是忍著接受高峰期頁面卡頓二是給數據庫單獨買一臺 ECS。如果單獨買一臺同規格的機器成本直接翻倍一個月就是 500-600 元往上走。到了這個階段“自建省錢”的論點基本就不成立了。我見過不少團隊嘴上說自建省錢實際上數據庫服務器和應用服務器分開買了兩臺加起來一個月五六百元還只是裸算 ECS 和云盤費用后面那些隱性成本根本沒算進去。1.2 除了月賬單更大的成本是運維精力顯性賬單只是冰山一角真正把自建 MySQL 成本推高的是運維精力這部分在小團隊里往往被忽略因為沒人給“自己的時間”定價。先說基礎維護MySQL 8.0 的補丁版本更新頻繁每次升級都要先備份、再替換二進制、然后跑一輪測試安全補丁更要上心暴露在公網上的 3306 端口如果被掃到輕則被爆破重則數據被加密勒索。你還要處理 binlog 無限增長、臨時表空間膨脹、慢查詢堆積這些日常問題。我印象很深的一次半夜兩點磁盤報警爬起來一看binlog 文件占滿了 40G 云盤中的三分之一。那一刻我真的在認真思考人生。再說備份和恢復。自建 MySQL 的常規操作是寫個 crontab 定時 mysqldump但有多少人真的定期演練過恢復流程我坦白說遷移前我一次完整的恢復演練都沒做過全靠“應該沒問題吧”撐著。真到數據損壞那天你面對的是一臺可能已經寫了幾小時新數據的實例如果沒有 binlog 增量備份丟幾小時數據幾乎是必然的。最后是故障處理能力。ECS 自建的 MySQL 是單點ECS 宿主機故障、云盤故障、內核 bug任何一個都能讓你從睡夢中爬起來。自己搭主從又涉及半同步復制、腦裂處理、故障切換腳本小團隊基本沒有精力維護。這些成本很難精確到元但真實存在。1.3 觸發我遷移的三個真實信號真正讓我下決心遷移的是三個問題同時出現第一磁盤報警越來越頻繁。binlog 占空間、慢查詢日志占空間、臨時排序文件也占空間40G 云盤怎么清都不夠用擴容又要停機操作。第二我發現自己長期活在“備份恐懼”里。每次要動數據庫結構第一反應是手動導一份 SQL 文件存到本地因為我不確定自動備份任務到底有沒有在正常工作更不確定那份備份能不能恢復。第三MySQL 版本升級的需求來了。應用需要用到 8.0 的新特性而自建升級意味著再一次完整走一遍備份、升級、回滾預案的流程周期至少一個晚上還不敢保證一次成功。這三個信號疊加在一起讓我認真評估了瑤池數據庫 RDS MySQL。對比之后發現RDS 自帶的自動備份、一鍵升級、監控告警恰好就是我在自建場景里一直想做但又沒做好的事。于是遷移這事就正式排上了日程。2. 遷移路線怎么定全量導出還是 DTS以及 RDS 規格選擇2.1 兩種遷移路徑的適用邊界先把結論放在前面小數據量、可接受短停服的場景直接用 mysqldump 全量導出導入就夠了數據量大、幾乎不能停服的場景用數據傳輸服務 DTS 做全量加增量同步。這兩種方案我在評估時都測過各有適用邊界。mysqldump 全量方案的邏輯很簡單在業務低峰期停服導出全量數據導入 RDS切換連接串啟動應用。優點是工具通用、流程透明、每一步都可控缺點是需要一個停服窗口窗口長短取決于數據量和導入速度。DTS 全量加增量方案的邏輯是先做一次全量遷移再通過解析源庫 binlog 持續同步增量數據等到兩邊追平后手動切換。優點是停服時間能壓縮到分鐘級甚至業務無感缺點是需要源庫開啟 binlog 且格式為 ROW需要額外創建遷移賬號并授權對表結構、主鍵、字符集也有一些兼容性要求。以我的場景為例數據量不到 5GB業務形態是內部工具加小 C 端應用凌晨兩點基本沒有流量停服 5-10 分鐘完全可接受。所以我選了 mysqldump 全量方案省去 DTS 的配置成本和 binlog 相關的前置改造。如果你的庫超過幾十 GB或者業務 7x24 小時都有寫入DTS 方案值得優先考慮。2.2 RDS 規格選型基礎版與高可用版的取舍瑤池數據庫 RDS MySQL 在購買時面對的第一個選擇題就是“基礎版”還是“高可用版”。這兩個詞的差異簡單說基礎版是單節點架構只有一個數據庫實例勝在便宜適合開發測試環境或對可用性要求不高的場景高可用版是一主一備架構主庫故障時自動切換到備庫RPO 和 RTO 都有保障適合生產環境價格大概是同規格基礎版的一倍左右。我當時糾結了很久最終還是選了基礎版 2核4G。原因是第一應用本身對分鐘級故障可以容忍真有故障大不了重啟服務第二預算有限能省則省第三瑤池 RDS 后續可以升級到高可用版不用重新遷移數據相當于給自己留了后悔藥。這里有一個值得注意的點升配容易降配難如果你的業務處在增長期建議一開始就按半年后的預期規格來買別省那點錢后面又折騰一次遷移。存儲方面小應用建議從 100G 起步。別按當前用量買RDS 的存儲擴容雖然可以在線操作但擴容過程會產生額外的 IO 開銷和費用而且磁盤使用率超過 80% 之后性能下降會比較明顯。100G 對小應用來說既不會太浪費又留下了足夠的緩沖空間。2.3 地域、VPC 內網與白名單準備RDS 選地域的原則就一條和你的 ECS 在同一個地域最好在同一個 VPC 內。這樣應用連數據庫走內網不走公網既能省下公網流量費延遲也更低。我在實操中踩過一個坑創建完 RDS 實例后控制臺默認白名單是空的應用連數據庫直接超時。原因很常見——我只在 RDS 控制臺加了 ECS 的公網 IP沒有加內網 IP。ECS 和 RDS 同 VPC 互通時走的是內網源 IP 是 ECS 的內網地址所以白名單里必須放行 ECS 的內網 IP比如 172.16.0.0/16 這個網段下的具體 IP。如果你不確定 ECS 的內網 IP 是多少ECS 控制臺實例詳情頁里能看到。賬號權限方面我建議分兩個賬號一個高權限賬號用來管理 DDL一個業務賬號只給 SELECT、INSERT、UPDATE、DELETE 權限。不要圖省事讓業務代碼去連高權限賬號一旦代碼注入或被拖庫損失會大得多。RDS 控制臺創建賬號時能精細控制權限這個能力自建 MySQL 里要手動 GRANT體驗完全不同。3. 遷移實操記錄從 mysqldump 到行數校驗的完整流程3.1 盤點庫表、字符集與權限遷移前一定要先盤點這一步直接決定后面導入流程順不順利。我是用下面幾條 SQL 來摸底的-- 統計各表行數注意InnoDB 的 table_rows 是估算值僅用來了解量級 SELECT table_name, table_rows, data_length, index_length FROM information_schema.tables WHERE table_schema appdb ORDER BY data_length DESC; -- 查看庫的默認字符集和排序規則 SELECT default_character_set_name, default_collation_name FROM information_schema.schemata WHERE schema_name appdb;把庫里的表、數據量、字符集摸清之后還要確認幾類容易被忽略的對象是否有觸發器、存儲過程、函數、事件調度器。這些對象在業務代碼里往往隱藏得很深如果漏導應用可能運行幾天后才暴露出某個定時任務沒有執行。可以在源庫執行-- 查看所有觸發器 SHOW TRIGGERS; -- 查看所有事件調度器 SELECT event_name, status, execute_at FROM information_schema.events; -- 查看所有存儲過程和函數 SELECT routine_name, routine_type FROM information_schema.routines WHERE routine_schema appdb;盤點完這些我心里就有底了這個庫有 3 個觸發器、2 個存儲過程、1 個事件調度器字符集是 utf8mb4 / utf8mb4_unicode_ci。注意這個排序規則的細節后面導入時會用到。3.2 mysqldump 參數解讀與一次權限報錯盤點完成后我在源庫創建了一個專用的備份賬號然后執行導出命令mysqldump \ -h 源庫內網IP -P 3306 \ -u backup_user -p \ --single-transaction \ --routines \ --events \ --triggers \ --set-gtid-purgedOFF \ --default-character-setutf8mb4 \ --max-allowed-packet256M \ --databases appdb appdb.sql逐行解釋幾個關鍵參數因為不少教程要么不給參數要么給一堆沒用的--single-transaction基于 InnoDB 的 MVCC 機制在一個事務里做一致性快照導出過程中不鎖表業務可以繼續寫入。這是 8.0 自建庫導出最推薦的參數沒有之一。--routines、--events、--triggers分別導出存儲過程/函數、事件調度器、觸發器。不加這三個參數你會丟東西。--set-gtid-purgedOFF如果源庫開啟了 GTID導出文件里會帶上SET GLOBAL.GTID_PURGED語句導入到 RDS 時可能因為 GTID 狀態不匹配而報錯。這個參數把它關掉避免不必要的兼容性問題。--max-allowed-packet256M防止某些大字段或大批量插入語句在導出/導入時超過默認包大小限制觸發Got a packet bigger than max_allowed_packet bytes的錯誤。--databases appdb帶上庫名導出文件里會包含CREATE DATABASE和USE appdb語句導入時更方便。這里我遇到了一次權限報錯ERROR 1227 (42000): Access denied; you need (at least one of) the PROCESS privilege(s) for this operation。原因是--single-transaction需要 PROCESS 權限來查看當前事務而我創建的備份賬號只有 SELECT 和 SHOW VIEW。解決辦法是在源庫執行GRANT SELECT, SHOW VIEW, TRIGGER, EVENT, PROCESS ON *.* TO backup_user%; FLUSH PRIVILEGES;注意PROCESS是全局權限不能只授給某個庫所以這里必須用*.*。這套權限組合是 mysqldump 做一致性導出的典型最小權限集值得記下來。3.3 導入 RDS 時的兼容性處理先在瑤池 RDS 控制臺創建目標庫和目標賬號。這里有個細節RDS 控制臺創建數據庫時會讓選字符集和排序規則一定要選和源庫一致的utf8mb4和utf8mb4_unicode_ci。如果默認選了utf8mb4_0900_ai_ci雖然大部分情況下沒問題但索引排序和某些字符的等價判斷結果會變最穩妥的做法是和源庫保持一致。導出的 SQL 文件里每條 CREATE TABLE 都帶有原來的字符集和排序規則信息理論上導入時會自動覆蓋庫級別設置。但保險起見我建議先只導入結構檢查沒有問題再導數據。操作方式是把導出文件里的 INSERT 語句去掉或者分兩步導出。實際上我更推薦這樣操作第一步用--no-data先導一份純結構文件導入 RDS 后用SHOW CREATE TABLE抽查幾張核心表確認結構沒問題再導入包含數據的完整文件。多花兩步能省去導入到一半才發現字符集對不上的痛苦。導入命令很簡單mysql \ -h RDS內網地址 -P 3306 \ -u rds_user -p \ --default-character-setutf8mb4 \ appdb.sql導入過程中遇到的真實報錯和大家分享兩個第一個是存儲過程相關的ERROR 1419 (HY000): You do not have the SUPER privilege and binary logging is enabled。這是因為 RDS 賬號默認沒有 SUPER 權限而創建存儲過程時如果數據庫開了 binlog會要求賬號有 SUPER 或SET_USER_ID權限。解決辦法是在 RDS 控制臺將參數組里的log_bin_trust_function_creators設置為 ON。注意這個參數在 RDS 控制臺可以改改完不需要重啟。第二個是導入文件里的DEFINER問題。如果你之前的表、視圖或存儲過程定義了特定歸屬者導出文件里會包含DEFINER語句導入到 RDS 時如果這個歸屬者不存在就會報ERROR 1449 (HY000): The user specified as a definer does not exist。處理辦法很簡單導出后用 sed 把文件里的 DEFINER 都替換掉sed -i s/DEFINER[^*]*\*/\*/g appdb.sql這條命令會把DEFINER和后面的一段內容替換成空的讓導入時使用當前賬號作為歸屬者。對我這種小應用足夠用如果場景復雜還是建議在源庫就把歸屬者統一管理清楚。3.4 一致性校驗行數、最大 ID 與抽樣數據導入完成后不能只看“命令執行成功”就以為萬事大吉。我用的是三種校驗方法組合起來基本能覆蓋數據完整性的檢查。第一種是逐表行數對比。小應用表不多我寫了個簡單的 Python 腳本分別連源庫和目標庫逐表執行SELECT COUNT(*)然后對比。注意這里不能用information_schema.tables的table_rows字段因為 InnoDB 的這是一個估算值不是精確行數。這個腳本很快5GB 的庫大概幾分鐘能跑完。第二種是自增主鍵最大值對比。對于有自增主鍵的表直接對比MAX(id)如果有主從復制或導入過程中有寫入這個值能快速暴露問題。命令如下SELECT MAX(id) FROM 核心表名;第三種是抽樣數據校驗。我挑了幾張數據比較敏感的表用MD5或CHECKSUM對抽樣行做校驗。比如對比某張訂單表的最近 1000 條記錄是否一致SELECT MD5(CONCAT_WS(|, id, user_id, amount, created_at)) FROM 訂單表 ORDER BY id DESC LIMIT 1000;兩邊執行同樣的查詢對比結果是否一致。這個方法的原理是如果兩邊的數據有任何細微差異MD5 值大概率會不同。三種校驗都通過后我對數據完整性基本放心了進入切換環節。4. 切換當天停服窗口、驗證清單與回滾預案4.1 如何把停服窗口壓到 5 分鐘我把切換安排在凌晨兩點這個時段我的應用幾乎沒有任何寫入。整體流程是先停應用服務再導出最后一次增量數據導入 RDS最后把應用連接串切到 RDS 并重啟。為什么停服后還要再導一次增量因為在第 3 章那次全量導出之后到正式切換之前業務可能已經有了新的寫入。為了解決這個窗口我在切換當天重新執行了一次完整的 mysqldump 導出導入。由于數據量小全量導出一遍只需要兩三分鐘這比做增量同步要簡單得多。具體時間線大概是02:00停應用服務入口切到維護頁02:01在源庫執行最后一次 mysqldump導出到本地02:03把 SQL 文件導入 RDS02:06修改應用配置文件里的數據庫連接地址從 ECS 內網 IP 改成 RDS 的內網域名02:07啟動應用觀察日志和接口02:15確認無異常撤下維護頁。整個過程不到 15 分鐘其中真正影響業務的只有 7 分鐘。這是小應用遷移的主場優勢不需要搞復雜的 DTS 增量不需要寫同步腳本一次全量導出足夠。如果你的應用有兩臺以上 ECS配置文件改起來會麻煩一些建議提前把所有機器的連接串都準備好切換時逐臺發布。更規范的做法是先把新連接串作為環境變量配置好切換時只改環境變量指向應用不用動。4.2 切換后的驗證清單切換完成后我有一份自己總結的驗證清單照著走一遍能覆蓋絕大多數問題應用健康檢查接口是否返回正常核心業務鏈路是否通注冊、登錄、下單、支付回調等每個都實際點一遍定時任務是否執行我在第 3 章提到過源庫有一個事件調度器如果 RDS 的event_scheduler參數默認是 OFF這個任務會靜默失效。這是一個非常隱蔽的坑建議拿一張有定時任務的表看切換后有沒有新數據寫入慢查詢日志和錯誤日志有沒有異常RDS 控制臺直接看自建時還得自己配監控這里省了不少事連接數是否符合預期RDS 默認的max_connections可能比你自建時調得低如果應用連接池沒有限制最大連接數有可能直接把連接數打滿核心頁面的響應時間對比遷移前的基準值確認沒有明顯劣化。驗證時有一個技巧先把維護頁撤下但保持數據庫側的應用賬號只讀等確認所有頁面正常后再放開寫權限。不過我這個做法只適合小應用內部切換時用對外業務還是按“快速切換、快速驗證”的節奏來畢竟只讀窗口拉太長會影響用戶體驗。4.3 回滾預案舊庫保留多久、怎么留切換前我做的唯一一件“浪費”但極其重要的事就是沒有動舊庫。舊 ECS 上的 MySQL 保持原樣沒有停、沒有刪、沒有把磁盤清空只是應用不再連它了。一旦新環境出現問題且短期無法解決回滾只需要兩步把應用連接串改回舊 ECS 內網 IP重啟應用。因為舊庫一直開著數據還在切換時刻的最終狀態。這里有一個細節切換之后新庫會產生新寫入所以回滾時這些新數據需要想辦法同步回舊庫。我的處理辦法是一旦確定需要回滾立刻停應用把新庫的最新數據用 mysqldump 導出一份再導入舊庫然后恢復應用連接。這本質上和正向遷移是同一個流程只是方向反了。以我的經驗真正需要回滾的情況很少。大部分問題在驗證清單階段就能發現并解決。但“用不上”的預案不代表不值得準備心理層面的安心價值很大。舊庫我保留了兩周確定新環境穩定后才關閉在 6.3 節我會詳細說保留周期怎么定。5. 遷移后的成本對比月賬單與隱性成本5.1 同規格下的兩張賬單先說結論我的實際月賬單遷移后沒有變貴基本持平但數據庫的可用性、備份能力、監控能力全面提升了一個檔次。直接貼我自己的賬單對比所有價格按包年折算或實際扣費記錄地域是某二線城市可用區僅供參考不同地域和不同的活動折扣會有出入。如下表成本項自建 MySQL遷移前遷移到瑤池 RDS 后應用 ECS 2核4G約 250 元/月縮配到 1核2G約 120 元/月數據庫承載與應用共用同一臺 ECS隱性搶資源RDS 基礎版 2核4G約 260 元/月云盤/存儲40G ESSD約 20 元/月RDS 存儲 100G包含在 RDS 費用套餐內未單獨計費快照/備份手動 mysqldump未計費但無保障RDS 自動備份備份存儲容量在免費額度內未產生額外費用公網帶寬固定帶寬約 100 元/月走內網訪問數據庫這項無需重復購買合計約 370-390 元/月約 380 元/月這里有一個容易被忽略的點遷移后我把應用 ECS 從 2核4G 縮到了 1核2G。因為數據庫搬走之后應用本身的負載用 1核2G 完全夠用。如果不縮配總成本反而會上升。這也是不少團隊遷到 RDS 后感覺“變貴了”的原因——他們保留了原來的 ECS 規格又額外掏了一份 RDS 的錢兩邊都付了。如果你原來就是“應用一臺機器、數據庫一臺機器”的自建模式那遷移到 RDS 后大概率是直接省錢的。因為 RDS 基礎版的費用通常低于一臺同規格專門跑數據庫的 ECS 費用而且省掉了快照、備份、監控等額外配置的成本。5.2 備份、監控、安全這些看不見的差異賬單之外的對比才是自建和 RDS 差距最大的地方。自建時我備份靠 crontab 里的 mysqldump 腳本且不說腳本本身也可能掛掉關鍵是沒人保證恢復過程沒問題。RDS 的自動備份是平臺能力控制臺能看到備份記錄還能隨時用備份創建新的臨時實例來驗證數據。監控方面自建時我得額外部署一套監控系統看 CPU、內存、磁盤、連接數、慢查詢。RDS 控制臺把這些全內置了還能設置告警規則磁盤使用率超過閾值就往釘釘或短信推。遷移后第一天我就把慢查詢、磁盤、CPU、連接數的告警全部配好這種“有人在看著”的感覺自建時代真的沒有。安全方面RDS 自帶白名單、SSL 加密、SQL 注入檢測、透明數據加密等能力。這些功能如果在自建環境實現需要部署額外組件成本和工作量都不小。對小團隊來說這些安全能力用不用是另一回事但有和沒有是完全不同的風險級別。把這些隱性成本量化一下假設一次數據庫故障耗時 2 小時按開發者時薪 100 元計直接成本 200 元業務中斷的損失另算。RDS 高可用版能把故障概率顯著降低基礎版雖然單節點但也有自動重建能力和數據冗余保障。對于小應用這筆賬算下來RDS 的價值已經不是“方便”而是“用一份合理費用買了一份可靠”。5.3 觀察一個月基礎版夠不夠用遷移完成后的一個月我做了持續觀察。結果是這樣CPU 使用率業務高峰時基本在 30%-50% 之間2核4G 對當前負載來說算比較寬裕連接數方面應用連接池最大配置 50RDS 默認max_connections幾百個完全夠用磁盤使用率因為從 40G 換到 100G加上 binlog 清理策略更好長期維持在低水位。基礎版的唯一短板是高可用性如果底層出現故障RDS 會嘗試重建實例過程中可能有幾分鐘不可用。對我不算什么大問題但如果你做的是電商交易、支付這類對連續性敏感的業務建議直接上高可用版別拿基礎版賭運氣。另外我注意到瑤池 RDS 控制臺里可以一鍵變配從基礎版升到高可用版或者調整規格不需要重新遷移數據。這是自建 MySQL 最頭疼的地方——想升級架構就得量數據、開窗口、做演練。RDS 把這個過程壓縮到了控制臺操作而且變配過程中業務影響很小。這一點的價值只有經歷過自建升級的人才能真正體會。6. 遷移后的收尾事項別急著釋放舊機器6.1 參數與連接池配置切換到 RDS 之后有幾個參數我建議根據應用情況調整不要直接用默認值跑生產。第一個是event_scheduler。RDS 的默認值可能是 OFF你的定時任務如果依賴 MySQL Event必須把它打開否則任務靜默失效。RDS 控制臺參數組里可以改改完立即生效。第二個是slow_query_log和long_query_time。RDS 自帶慢查詢日志但默認不一定開了記錄閾值。建議把long_query_time設為 1 秒這樣連到 RDS 后業務代碼里那些隱藏的慢 SQL 能被及時抓到而不是等用戶反饋卡頓之后再去翻日志。第三個是應用連接池。自建 MySQL 時你可能習慣了把連接串寫成jdbc:mysql://內網IP:3306/appdb遷移后要改成 RDS 給的內網域名。同時把connectTimeout、socketTimeout配置清楚避免網絡波動時應用線程長時間掛起。連接池的最大連接數不要盲目調大RDS 的連接數上限是有限資源連接池撐爆實例連接數反而會導致整個應用不可用。我在遷移后順手做了一件事把所有 SQL 里依賴數據庫本地時間的邏輯改成顯式指定時區。原因很簡單ECS 自建和 RDS 的默認時區可能不同如果業務代碼用NOW()或者CURRENT_TIMESTAMP又依賴特定時區遷移后很可能出現時間偏差。RDS 控制臺可以設置默認時區為中國標準時間但如果你的應用是多地域訪問建議統一在連接串里指定serverTimezoneAsia/Shanghai。6.2 備份策略與真實恢復演練RDS 的備份策略默認是開啟的但你怎么設置窗口和保留周期也很重要。自動備份時間窗口建議放在業務低峰期比如凌晨。備份保留周期小應用設置 7 天足夠如果磁盤費用也不高可以保留 15 天到 30 天看你的數據需求和成本預算。重點想說的是恢復演練。自建時代最大的隱患就是“備份了但沒驗證過”遷移到 RDS 之后這個隱患終于能輕松消滅了。RDS 控制臺支持用備份創建一個臨時實例你可以在這個臨時實例上執行幾條關鍵查詢或者直接跑一遍業務初始化腳本確認備份數據是可用的。整個過程不需要搭建額外環境也不需要準備新機器。我當時做了一次演練從當天自動備份里克隆了一個臨時實例然后在上面執行了SELECT COUNT(*)檢查核心表又跑了一個查詢腳本確認備份數據能正常支撐應用啟動。這個演練在自建時代至少要半小時起步在 RDS 控制臺上幾分鐘就完成了。從那之后我對“備份可用”這件事是真的放心了。6.3 舊 ECS 的保留周期與歸檔舊庫和舊 ECS 的處置我的建議是“留兩周想清楚再釋放”。第一周保留舊 MySQL 實例運行。這樣如果新環境出現嚴重問題隨時可以回滾。這一周內應用已經完全不依賴舊庫了所以不需要維護它但也不要順手刪掉數據文件。第二周如果業務運行平穩可以把舊 MySQL 服務停掉但 ECS 不要立刻釋放。這一步的目的是讓團隊消化和沉淀把自建時代的配置、腳本、積累的 SQL 診斷經驗整理成文檔把原來的 ECS 縮配或改作他用。我實際操作時把舊 ECS 上的 MySQL 服務停了但保留了數據盤萬一之后要做數據分析還能直接查舊庫。第二周結束后我的做法是把舊 ECS 釋放但釋放前做了一件事把舊庫的最后一份完整導出文件保存到了對象存儲里作為最終歸檔。這樣即便以后發現遷移丟了什么還有一個最終的兜底存在成本幾乎為零。還有一個細節值得提整個遷移過程中我把所有命令、參數、賬號權限、報錯信息都記錄到了一個文檔里。一開始只是為了方便自己排查后來發現這套“遷移 SOP”非常有用——身邊有朋友要遷移時直接發文檔過去他照著走一遍就能完成省去了重讀命令文檔和踩一遍同樣坑的時間。如果你也要遷強烈建議從第一天就開始記錄別等遷完了再回憶。最后再分享一個小技巧遷移后的一到兩周一定把慢查詢和錯誤日志的告警開著。自建 MySQL 時代的很多 SQL 寫法可能在非嚴格模式下勉強能跑到了 RDS 默認參數更嚴格的 8.0 版本下就會暴露問題。比如某些聚合查詢、隱式類型轉換、排序規則不一致造成的索引失效都是遷完后才慢慢浮現的。開著告警你才能第一時間發現這些隱藏的兼容性問題。