現象:mysqldump 匯出含存儲過程,匯入新庫後應用呼叫報 Access denied 或 The user specified as a definer does not exist。
mysqldump 會保留原 DEFINER (如 root@%) 與 SECURITY_TYPE = DEFINER。匯入目標庫若無該帳號,或應用帳號不匹配,執行時會以 DEFINER 權限檢查失敗。
-- 1. 檢視現有 procedure 定義
SHOW PROCEDURE STATUS WHERE Db = 'your_db';
-- 2. 批次修正 DEFINER 為應用帳號 (如 app_user@127.0.0.1)
UPDATE mysql.proc
SET definer = 'app_user@127.0.0.1',
security_type = 'INVOKER' -- 以呼叫者權限執行,不再依賴 DEFINER
WHERE db = 'your_db';
-- 3. 刷新權限
FLUSH PRIVILEGES;
| 模式 | 權限檢查對象 | 適用場景 |
|---|---|---|
| DEFINER (預設) | 建立者帳號 | 需集中控制、建立者權限高於呼叫者 |
| INVOKER | 呼叫者帳號 | 應用帳號已具備足夠權限、遷移後 DEFINER 不存在 |
mysqldump --routines --skip-definer db_name > dump.sql
-- 或
sed -i 's/DEFINER=`[^`]*`@`[^`]*` //g' dump.sql
最佳實踐:生產庫存儲過程一律用 INVOKER,配合專用應用帳號授權 EXECUTE。