在啟用 Binlog 的 MySQL 實例上創建存儲函數/觸發器/事件時,常遇報錯:ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled。本文解析底層邏輯,提供生產安全的配置方案與代碼規範。
UUID()、RAND()、修改數據)在主庫執行一次,從庫重放可能產生不同結果 → 數據不一致log_bin_trust_function_creatorsCREATE FUNCTION calculate_bonus(base_salary DECIMAL(10,2), performance_score INT)
RETURNS DECIMAL(10,2)
DETERMINISTIC -- 相同輸入必產生相同輸出
NO SQL -- 不包含 SQL 語句(純計算)
-- READS SQL DATA -- 僅讀取數據,不修改
-- MODIFIES SQL DATA -- 修改數據(極少用,需 SUPER 權限)
BEGIN
DECLARE bonus DECIMAL(10,2);
IF performance_score >= 90 THEN
SET bonus = base_salary * 0.2;
ELSEIF performance_score >= 70 THEN
SET bonus = base_salary * 0.1;
ELSE
SET bonus = 0;
END IF;
RETURN bonus;
END;
| 特徵 | 含義 | Binlog 記錄方式 | 適用場景 |
|---|---|---|---|
| DETERMINISTIC | 確定性:相同參數必返相同結果 | 記錄函數調用語句 | 純計算、工具函數 |
| NO SQL | 無 SQL:不執行任何 SQL | 不記錄(視為內建函數) | 數學運算、字串處理 |
| READS SQL DATA | 讀數據:含 SELECT,無 DML/DDL | 記錄函數調用,從庫重執行 SELECT | 查詢封裝、報表計算 |
| MODIFIES SQL DATA | 改數據:含 INSERT/UPDATE/DELETE | 記錄函數內部每條 SQL | 極少用,需謹慎評估 |