本文主要是介绍Warning: 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
向数据库中插入时报
Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
具体类似如下:
- Warning: (1592, u’Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an
AUTO_INCREMENT
column. Inserted values cannot be logged correctly.’)
self._do_get_result()
原因分析: 出现这个问题的原因是 MySQL做了主-从同步后,从库对于一些特殊的字段作同步时不能安全的保证数据与主库一致,如字段id的AUTO_INCREMENT属性、使用sysdate()日期函数等。
- [Warning] Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
INSERT... SELECT... ON DUPLICATE KEY UPDATE
is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are updated. This order cannot be predicted and may differ on master and the slave. Statement:INSERT INTO table_name
原因分析: 要插入的表table_name上有2个唯一键。则使用 INSERT… ON DUPLICATE KEY UPDATE ,且当前数据库binlog_format是statement格式,这种sql语句就会报unsafe。
使用一下sql进行查询当前binlog_format模式:
SELECT @@global.binlog_format;
解决办法:
1…不使用特殊属性,如不要在语句中使用函数。不要定义自增字段。这种方法一般不太现实。
2. 修改数据库配置。不使用语句级的日志复制,改成行级ROW或混合方式MIXED。
分别在主-从库my.cnf配置以下语句: binlog_format = 'MIXED'
或者binlog_format = 'ROW'
, 重启主-从 各库使配置生效。
或者登陆mysql,直接使用语句进行修改:
mysql> SET GLOBAL binlog_format=MIXED;
解决方法就是上面,接下来,对binlog_format的不同取值进行介绍,可以略过。
mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
- STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
- 使用以下函数的语句也无法被复制:
- LOAD_FILE()
- UUID()
- USER()
- FOUND_ROWS()
- SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)
- 同时在INSERT …SELECT 会产生比 RBR 更多的行级锁
- ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中会让日志暴涨。- MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的变更。
这篇关于Warning: 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!