如我们所知
“替换”与“插入”完全一样,但如果表中的旧行与主键或唯一索引的新行的值相同,则在插入新行之前删除旧行。
当我使用一个没有删除权限的帐户执行替换进入时,它会提醒我删除权限。
但是,当我使用mysqlbinlog查看binlog中的内容时,它使我感到困惑。
一个例子如下:
binlog_format=row
root:test> show create table t3\G
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE `t3` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) DEFAULT NULL,
`c2` varchar(20) DEFAULT NULL,
`c3` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uidx_c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 15 | 5 | bb | NULL |
+----+------+------+------+
5 rows in set (0.01 sec)案例1:
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 15 | 5 | bb | NULL |
+----+------+------+------+
5 rows in set (0.01 sec)
root:test>
root:test> replace into t3 (c1,c2,c3) values(5,'bb',3);
Query OK, 2 rows affected (0.01 sec)
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 16 | 5 | bb | 3 |
+----+------+------+------+
5 rows in set (0.00 sec)mysqlbinlog显示如下:
# at 15126
#161019 15:04:14 server id 22100 end_log_pos 15190 CRC32 0x9bab83d9 Update_rows: table id 234 flags: STMT_END_F
### UPDATE `test`.`t3`
### WHERE
### @1=15
### @2=5
### @3='bb'
### @4=NULL
### SET
### @1=16
### @2=5
### @3='bb'
### @4=3
# at 15190
#161019 15:04:14 server id 22100 end_log_pos 15221 CRC32 0x70a88be3 Xid = 177
COMMIT/*!*/;mysqlbinlog不显示“删除”和“插入”。
案例2: auto_increment=17
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 16 | 5 | bb | 3 |
+----+------+------+------+
5 rows in set (0.00 sec)
root:test> replace into t3 (id,c1,c2,c3) values(17,5,'bb',3);
Query OK, 2 rows affected (0.01 sec)
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 17 | 5 | bb | 3 |
+----+------+------+------+
5 rows in set (0.00 sec)mysqlbinlog显示如下:
# at 15408
#161019 15:13:18 server id 22100 end_log_pos 15476 CRC32 0xe200a811 Update_rows: table id 234 flags: STMT_END_F
### UPDATE `test`.`t3`
### WHERE
### @1=16
### @2=5
### @3='bb'
### @4=3
### SET
### @1=17
### @2=5
### @3='bb'
### @4=3
# at 15476
#161019 15:13:18 server id 22100 end_log_pos 15507 CRC32 0xe02d7749 Xid = 179
COMMIT/*!*/;mysqlbinlog不显示“删除”和“插入”。
Case 3:auto_increment=18
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 17 | 5 | bb | 3 |
+----+------+------+------+
5 rows in set (0.00 sec)
root:test> replace into t3 (id,c1,c2,c3) values(17,5,'cc',4);
Query OK, 2 rows affected (0.01 sec)
root:test> select * from t3;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | 1 | a | 1 |
| 2 | 2 | a | 1 |
| 8 | NULL | NULL | 1 |
| 14 | 4 | bb | NULL |
| 17 | 5 | cc | 4 |
+----+------+------+------+
5 rows in set (0.00 sec)mysqlbinlog显示如下:
# at 15745
#161019 15:30:49 server id 22100 end_log_pos 15796 CRC32 0x258b633a Write_rows: table id 234 flags: STMT_END_F
### DELETE FROM `test`.`t3`
### WHERE
### @1=17
### @2=5
### @3='bb'
### @4=3
### INSERT INTO `test`.`t3`
### SET
### @1=17
### @2=5
### @3='cc'
### @4=4
# at 15796
#161019 15:30:49 server id 22100 end_log_pos 15827 CRC32 0xcc4e1740 Xid = 183
COMMIT/*!*/;mysqlbinlog显示删除和插入。
因此,当主键值相同时,二进制日志使用delete+insert .If主键值不一样,二进制日志使用update。
为什么?
发布于 2016-10-19 08:02:13
看起来您使用的是基于行的复制,而不是基于语句的复制。
使用基于行的复制,您只会看到更改在主服务器上执行时的效果。如果运行update t3 set c3 = 1;来更改所有5行,一条语句可能导致多行更改。
https://stackoverflow.com/questions/40125273
复制相似问题