注意(代码1592):自BINLOG_FORMAT = STATEMENT以来使用语句格式写入二进制日志的不安全语句。从另一个表中选择后,使用自动增量列写入表的语句是不安全的,因为检索行的顺序决定了将写入哪些行(如果有)。此订单无法预测,可能在主设备和从设备上有所不同。
我不明白上面的错误信息。以下是所涉及的陈述/表格。
mysql> show create table phppos_app_config;
+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_app_config | CREATE TABLE `phppos_app_config` (
`key` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`value` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> \W
Show warnings enabled.
mysql> CREATE TABLE IF NOT EXISTS `phppos_locations` (
-> `location_id` int(11) NOT NULL AUTO_INCREMENT,
-> `name` text COLLATE utf8_unicode_ci,
-> `address` text COLLATE utf8_unicode_ci,
-> `phone` text COLLATE utf8_unicode_ci,
-> `fax` text COLLATE utf8_unicode_ci,
-> `email` text COLLATE utf8_unicode_ci,
-> `receive_stock_alert` text COLLATE utf8_unicode_ci,
-> `stock_alert_email` text COLLATE utf8_unicode_ci,
-> `return_policy` text COLLATE utf8_unicode_ci,
-> `timezone` text COLLATE utf8_unicode_ci,
-> `mailchimp_api_key` text COLLATE utf8_unicode_ci,
-> `enable_credit_card_processing` text COLLATE utf8_unicode_ci,
-> `merchant_id` text COLLATE utf8_unicode_ci,
-> `merchant_password` text COLLATE utf8_unicode_ci,
-> `default_tax_1_rate` text COLLATE utf8_unicode_ci,
-> `default_tax_1_name` text COLLATE utf8_unicode_ci,
-> `default_tax_2_rate` text COLLATE utf8_unicode_ci,
-> `default_tax_2_name` text COLLATE utf8_unicode_ci,
-> `default_tax_2_cumulative` text COLLATE utf8_unicode_ci,
-> `deleted` int(1) DEFAULT '0',
-> PRIMARY KEY (`location_id`),
-> KEY `deleted` (`deleted`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
Query OK, 0 rows affected (0.02 sec)
mysql> -- -------------------------------------------------
mysql> -- Migrate app config to location ---
mysql> -- -------------------------------------------------
mysql>
mysql> INSERT INTO `phppos_locations` (`location_id`, `name`, `address`, `phone`, `fax`, `email`,
-> `receive_stock_alert`, `stock_alert_email`, `return_policy`, `timezone`, `mailchimp_api_key`,
-> `enable_credit_card_processing`, `merchant_id`, `merchant_password`, `default_tax_1_rate`,
-> `default_tax_1_name`,`default_tax_2_rate`, `default_tax_2_name`, `default_tax_2_cumulative`) VALUES(
-> 1,
-> 'Default',
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'address'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'phone'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'fax'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'email'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'receive_stock_alert'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'stock_alert_email'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'return_policy'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'timezone'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'mailchimp_api_key'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'enable_credit_card_processing'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'merchant_id'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'merchant_password'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'default_tax_1_rate'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'default_tax_1_name'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'default_tax_2_rate'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'default_tax_2_name'),
-> (SELECT `value` FROM phppos_app_config WHERE `key` = 'default_tax_2_cumulative')
-> );
Query OK, 1 row affected, 1 warning (0.00 sec)
Note (Code 1592): Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave.
答案 0 :(得分:23)
您可能熟悉two formats of binary logging,基于语句 - 它记录了修改主数据上的数据的实际查询,以便它们可以在从服务器上执行,并且基于行 - 在之前记录 - 和/或由查询更改的实际行数据的后映像,以便从属可以直接将这些更改应用于其数据...和混合模式,其中优化程序和存储引擎确定哪种格式是逐个查询的最佳格式。
当谈到MySQL Replication中语句的“安全性”时,我们指的是是否可以使用基于语句的格式正确复制语句及其效果。如果对于该陈述是正确的,我们将该陈述称为安全;否则,我们称之为不安全。
一般来说,如果声明是确定性的,则声明是安全的,如果不是,则声明是不安全的。
- http://dev.mysql.com/doc/refman/5.6/en/replication-rbr-safe-unsafe.html>
您正在执行的语句原则上是不安全的 ,因为您正在将INSERT ... SELECT
用于带有自动增量列的表中。如果在基于STATEMENT
的环境中使用了该常规表单的查询,并且SELECT
未在主服务器和从服务器上以相同顺序返回行,则行可以按不同的顺序选择,从而最终得到不同的自动增量值。
实际上,您执行的特定查询是确定性的,因为您只插入一行,并且您明确指定了自动增量值。我怀疑这是你混乱的原因。但是,您似乎仍在触发警告,因为您正在将INSERT ... SELECT
放入具有自动增量的表中,并且服务器似乎正在对查询应用广义的“不安全”确定作为原则,而不是精确。
将binlog_format
切换为MIXED
会使警告消失,因为服务器可以自行决定切换模式......并且不太可能产生负面影响。如果不是STATEMENT
一直是默认的事实(因为最初这是唯一可用的复制类型),我怀疑它们会在很久以前使MIXED
成为默认值...事实上,如果你熟悉二进制日志的内部结构,你可能会像我一样倾向于在所有事情上使用ROW
...它往往会为更加有用的二进制日志做出贡献故障排除并帮助您摆脱困境,因为DELETE
和UPDATE
上记录了“旧”行数据。