首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 錯誤處理:ERROR 1665 (HY000) — BINLOG_FORMAT=STATEMENT 與 READ COMMITTED 隔離級別衝突解決

     編輯:MySQL 綜合教學

InnoDB 在 READ COMMITTED 或 READ UNCOMMITTED 隔離級別下,必須使用 ROW 或 MIXED 格式的 Binlog,否則執行寫入語句報錯 ERROR 1665 (HY000)。本文解析衝突機制、給出無需重啟的動態修復方案。

一、報錯現場

ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log
since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine
limited to row-based logging. InnoDB is limited to row-logging when transaction
isolation level is READ COMMITTED or READ UNCOMMITTED.

二、根因機制

  • READ COMMITTED 隔離級別下,InnoDB 使用 **Next-Key Lock 退化為 Record Lock**,同一語句多次執行可能看到不同快照(Phantom Read)。
  • STATEMENT 格式 Binlog 記錄 SQL 文本,主從重放時若快照不同會導致數據不一致。
  • 為保證主從一致性,InnoDB **強制要求** 隔離級別 ≤ READ COMMITTED 時 Binlog 格式為 ROW 或 MIXED。

三、動態修復(無需重啟)

SET GLOBAL binlog_format = 'MIXED';
-- 或
SET GLOBAL binlog_format = 'ROW';
  • 新會話立即生效,舊會話保持原格式直到重連。
  • MIXED:MySQL 自動判斷,安全語句用 STATEMENT,不安全(如 UUID、NOW()、UDF、READ COMMITTED 下的 InnoDB)自動切 ROW,兼顧性能與安全,**推薦生產默認值**。

四、持久化配置

# /etc/my.cnf [mysqld]
binlog_format = MIXED
# 重啟後生效

五、隔離級別與 Binlog 格式兼容矩陣

隔離級別允許的 Binlog 格式推薦
REPEATABLE READ (默認)STATEMENT / ROW / MIXEDMIXED
READ COMMITTEDROW / MIXEDROW 或 MIXED
READ UNCOMMITTEDROW / MIXEDROW
SERIALIZABLESTATEMENT / ROW / MIXEDMIXED

六、避坑提示

  1. 修改 binlog_format 為 ROW 會顯著增加 Binlog 體積(全行映像),需配合 expire_logs_days、max_binlog_size 盤容量規劃。
  2. 若業務強依賴 STATEMENT 格式(如異構同步工具解析),只能升級隔離級別至 REPEATABLE READ,但會增加鎖爭用,需壓測評估。
  3. SESSION 級別也可設:SET SESSION binlog_format = 'ROW'; 供特定遷移任務臨時使用。

核心原則:**隔離級別與 Binlog 格式必須匹配**,MIXED 是 99% 場景的「銀彈」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved