MariaDB 5.5 / MySQL 5.5 主庫錯誤日誌大量出現:
[Warning] Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
Statement is unsafe because it uses a system function that may return a different value on the slave.
Statement: INSERT INTO t_user(userId, userName) VALUES(UUID(), 'FunYoung')
UUID(),產生新值,導致主從數據不一致。NOW()、RAND()、SYSDATE() 等)。新版本在 ROW/MIXED 模式下自動處理非確定性函數,或直接將 UUID() 標記為安全。若環境允許升級,此為最徹底方案。
-- 動態生效(重啟失效)
SET GLOBAL binlog_format = 'ROW';
-- 或 MIXED:非確定語句自動切 ROW
SET GLOBAL binlog_format = 'MIXED';
-- 永久生效,編輯 my.cnf
[mysqld]
binlog_format = ROW
影響:ROW 格式體積較大,網絡/磁碟開銷增加;MIXED 為折中。
將 UUID 生成邏輯下沉到應用代碼(Java UUID.randomUUID()、PHP uniqid()、Go github.com/google/uuid 等),SQL 僅插入已生成的字串:
INSERT INTO t_user(userId, userName) VALUES('a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'FunYoung');
優勢:
-- 主庫執行
INSERT INTO t_user(userId, userName) VALUES(UUID(), 'test');
-- 從庫檢查
SELECT * FROM t_user WHERE userName='test';
-- 對比 userId 是否一致
| 場景 | 推薦方案 |
|---|---|
| 可升級 DB 版本 | 升級至 5.6+/MariaDB 10.2+,保持 STATEMENT |
| 不可升級、低寫入量 | 改 binlog_format=MIXED |
| 高併發、強一致性要求 | 應用層生成 UUID + ROW 格式 |