MySQL Schema Apply / DDL Executor 安全策略
1. 文件目的
本文件整理第二階段 B 對 Schema Apply / DDL Executor 的安全策略。目標是在未來允許 Host 或工具執行資料庫 schema apply 前,先固定 gate、權限、備份、rollback、人工確認與停止線。
本文件只做安全策略設計,不實作 DDL executor、不執行 CREATE TABLE / ALTER TABLE / DROP、不修改資料庫、不修改 ConsoleHost 啟動流程、不新增 WebApi / ServiceHost,也不保存任何密碼或連線字串。
2. 目前狀態
| 項目 | 狀態 | 說明 |
|---|---|---|
| Schema Attribute | 已完成 | 可用 C# class 維護 table、column、index、comment。 |
| SQL Generator | 已完成 | 可產生 MySQL 5.6.2 相容 SQL preview。 |
| Schema Inspector | 已完成 | 可讀取 expected / current schema,真實 MySQL metadata inspect 已採 manual-only。 |
| Dry Run Planner | 已完成 | 可產生差異與 SQL preview,不執行 DDL。 |
| ConsoleHost DryRun 顯示 | 已完成 | 目前只顯示 preview 與警告。 |
| DDL Executor | 尚未實作 | 本文件先定義安全策略。 |
| 自動 Apply | 尚未允許 | 未確認前不得導入。 |
3. 核心原則
DryRun永遠是預設模式。Apply必須明確 gate,不得因設定檔存在就自動執行。- 正式 DB 與測試 DB 使用不同帳號權限。
- DDL 前必須輸出可人工審核的 plan。
- DDL 前必須記錄備份與 rollback 策略。
- DDL 失敗時不得吞 exception,需輸出 table、operation、SQL preview 與已遮蔽錯誤。
- 不得將密碼、token、connection string 寫入 repo、log、console 或文件。
- 對 MySQL 5.6.2 要保守處理,不能假設 DDL 可 transaction rollback。
4. 建議模式分級
| 模式 | 是否允許連 DB | 是否允許 DDL | 用途 |
|---|---|---|---|
DryRunOnly |
可選 | 否 | 預設模式,只產生差異與 SQL preview。 |
InspectOnly |
是 | 否 | 讀取 information_schema,不修改 DB。 |
ManualApplyPreview |
是 | 否 | 產生可審核 apply plan,等待人工確認。 |
ManualApply |
是 | 是,僅測試 DB | 使用者明確確認後才可執行。 |
ProductionApply |
是 | 是,但暫不建議 | 需另行設計審核、備份、維運窗口與 rollback。 |
第二階段 B 只建議完成 DryRunOnly、InspectOnly 與 ManualApplyPreview 策略;不建議直接開放 ProductionApply。
5. Apply Gate 草案
後續若進入實作,建議使用獨立 gate,不與 TaskStore / LogWriter gate 混用。
HS_MYSQL_SCHEMA_APPLY_ENABLED
HS_MYSQL_SCHEMA_APPLY_ALLOW_DDL
HS_MYSQL_SCHEMA_APPLY_TARGET
HS_MYSQL_SCHEMA_APPLY_REQUIRE_CONFIRMATION
HS_MYSQL_SCHEMA_APPLY_CONFIRMATION_TOKEN
HS_MYSQL_SCHEMA_APPLY_BACKUP_CONFIRMED
HS_MYSQL_SCHEMA_APPLY_ROLLBACK_PLAN_CONFIRMED
建議規則:
HS_MYSQL_SCHEMA_APPLY_ENABLED=true只表示允許產生 apply plan。HS_MYSQL_SCHEMA_APPLY_ALLOW_DDL=true才可執行 DDL。HS_MYSQL_SCHEMA_APPLY_TARGET=Test時才允許第二階段 PoC DDL。HS_MYSQL_SCHEMA_APPLY_TARGET=Production時,本階段仍應停止。HS_MYSQL_SCHEMA_APPLY_BACKUP_CONFIRMED=true前不得執行 DDL。HS_MYSQL_SCHEMA_APPLY_ROLLBACK_PLAN_CONFIRMED=true前不得執行 DDL。CONFIRMATION_TOKEN必須是本次 plan 產出的 hash 或人工確認字串,不得寫死。
6. 權限策略
| 帳號用途 | 建議權限 | 備註 |
|---|---|---|
| Inspect account | SELECT on information_schema / target schema metadata |
只讀 metadata。 |
| TaskStore test account | SELECT、INSERT、UPDATE、DELETE |
用於 manual-only DML 驗證。 |
| Apply test account | CREATE、ALTER、INDEX、必要時 DROP |
只限測試 DB,且需人工 gate。 |
| Production runtime account | 不應具備 DDL | 正式執行時避免誤 apply。 |
| Production apply account | 僅維運窗口使用 | 不應寫入 repo 或一般 host 設定。 |
7. Apply Plan 必要資訊
每次 apply 前必須先產生 plan,至少包含:
| 欄位 | 說明 |
|---|---|
PlanId |
本次 plan 識別碼。 |
GeneratedAt |
產生時間。 |
TargetDatabase |
目標 DB 名稱,host 需遮蔽。 |
SchemaVersion |
若未導入版本表,需標示 NotAvailable。 |
Operations |
新增 table、欄位、index、comment 等操作。 |
SqlPreview |
已遮蔽且可人工審查的 SQL。 |
DestructiveOperations |
是否包含 DROP、MODIFY、CHANGE、縮短欄位、改 nullable。 |
RequiresBackup |
是否需備份。 |
RollbackHint |
人工 rollback 提示。 |
PlanHash |
用於 confirmation token。 |
8. 高風險操作分類
| 操作 | 風險 | 第二階段建議 |
|---|---|---|
CREATE TABLE |
中 | 測試 DB 可 manual-only,正式 DB 暫不允許。 |
ADD COLUMN nullable |
中 | 需人工確認。 |
ADD COLUMN not null |
高 | 若無 default,可能失敗或影響既有資料。 |
ADD INDEX |
中到高 | 大表可能鎖表,需維運窗口。 |
MODIFY COLUMN |
高 | 可能截斷或轉型失敗。 |
CHANGE COLUMN |
高 | 可能破壞程式欄位對應。 |
DROP COLUMN |
極高 | 本階段不允許。 |
DROP TABLE |
極高 | 本階段不允許。 |
| 改 table charset / collation | 高 | 需另行評估。 |
9. MySQL 5.6.2 注意事項
- DDL 大多不是一般 transaction rollback 能保護的操作。
ALTER TABLE可能造成 table lock。TEXT欄位 index 需指定 prefix,不能直接任意加完整 index。datetime沒有 timezone,需要由應用層統一時間策略。COMMENT長度與字元集需保守處理。IF NOT EXISTS支援度需依實際 SQL 類型確認。- 大表 apply 前需先估計資料量與維運窗口。
10. Backup 與 Rollback 策略
執行 DDL 前至少要確認:
| 項目 | 必要性 | 說明 |
|---|---|---|
| schema dump | 必要 | 保存目前 table schema。 |
| data backup | 視操作而定 | 對 DROP / MODIFY / CHANGE 類操作必須有資料備份。 |
| rollback SQL | 必要 | 至少提供人工 rollback hint。 |
| 維運窗口 | 正式 DB 必要 | 避免操作中斷現場流程。 |
| 操作人 | 必要 | 紀錄誰確認 apply。 |
| plan hash | 必要 | 防止確認的 plan 與執行的 plan 不一致。 |
第二階段 B 可先完成策略與 plan 格式;正式 backup executor 與 rollback executor 不納入本階段。
11. Apply 執行停止線
以下任一條件成立,必須停止,不得執行 DDL:
- 目標不是測試 DB,且未另行取得正式 Apply 明確授權。
- 缺少 backup 確認。
- 缺少 rollback plan 確認。
- plan 包含
DROP TABLE或DROP COLUMN。 - plan 包含縮短欄位長度。
- plan 包含 not null 欄位且沒有 default / backfill 策略。
- plan hash 與 confirmation token 不一致。
- schema inspector 無法讀取目前 schema。
- SQL preview 含未遮蔽密碼、token、connection string。
- 工作樹或文件顯示目前 schema 規格未收斂。
12. 後續實作前確認項目
若要從策略進入程式實作,需先確認:
- 是否只做
ManualApplyPreview,不做真正 DDL。 - Apply plan model 放在哪個專案。
- DDL executor 是否獨立介面,是否 public。
- 是否需要
schema_migrations或schema_apply_historytable。 - 是否允許在測試 DB 建立 apply history table。
- confirmation token 來源與格式。
- ConsoleHost 是否只顯示 plan,不提供 apply。
- 是否要把正式 Apply 延到第三階段。
13. 建議測試策略
| 測試 | 目的 |
|---|---|
| Apply plan classification | 確認高風險操作會被標示。 |
| Gate disabled | 未開 gate 時只能 dry run。 |
| Production target block | 目標正式 DB 時停止。 |
| Missing backup block | 缺少 backup confirmation 時停止。 |
| Destructive operation block | DROP / MODIFY 等高風險操作需被擋下。 |
| Plan hash mismatch | 確認 token 不一致不得 apply。 |
| SQL preview redaction | 確認輸出不含敏感資訊。 |
14. 建議結論
第二階段 B 應先把 Schema Apply / DDL Executor 收斂為安全策略與 ManualApplyPreview 邊界,不建議直接進入真正 DDL executor。
若後續要實作,建議第一步只做 apply plan model 與高風險分類測試;真正執行 DDL 仍需使用者再次確認。