mysql 在row模式下truncate 与 delete 二进制日志记录的差异

二进行日志的格式为row

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

在testdb库下执行

mysql> select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | NULL |
|  2 | chen |
|  3 | li   |
+----+------+
3 rows in set (0.00 sec)


mysql> select * from t2;
+------+--------+
| id   | course |
+------+--------+
|    1 | NULL   |
|    2 | chen   |
|    3 | math   |
+------+--------+
3 rows in set (0.00 sec)


mysql> truncate table t1;


mysql> delete from t2;

执行命令:mysqlbinlog --no-defaults -vv good.000001:主要看红色加粗字体部分:

# at 2162
#160303 11:02:51 server id 4  end_log_pos 2248 CRC32 0x3544cc1f     Query    thread_id=2755623    exec_time=0    error_code=0
SET TIMESTAMP=1456974171/*!*/;
truncate table t1
/*!*/;
# at 2248
#160303 11:05:40 server id 4  end_log_pos 2322 CRC32 0xf5126972     Query    thread_id=2756326    exec_time=0    error_code=0
SET TIMESTAMP=1456974340/*!*/;
BEGIN
/*!*/;
# at 2322
#160303 11:05:40 server id 4  end_log_pos 2372 CRC32 0xba9c0edd     Table_map: `testdb`.`t2` mapped to number 12204
# at 2372
#160303 11:05:40 server id 4  end_log_pos 2432 CRC32 0xd1433d85     Delete_rows: table id 12204 flags: STMT_END_F

BINLOG '
BKrXVhMEAAAAMgAAAEQJAAAAAKwvAAAAAAEABnRlc3RkYgACdDIAAgMPAhQAA90OnLo=
BKrXViAEAAAAPAAAAIAJAAAAAKwvAAAAAAEAAgAC//4BAAAA/AIAAAAEY2hlbvwDAAAABG1hdGiF
PUPR
'/*!*/;
### DELETE FROM `testdb`.`t2`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2=NULL /* INT meta=20 nullable=1 is_null=1 */
### DELETE FROM `testdb`.`t2`
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='chen' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### DELETE FROM `testdb`.`t2`
### WHERE
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
###   @2='math' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
# at 2432
#160303 11:05:40 server id 4  end_log_pos 2463 CRC32 0x225aa989     Xid = 8390829
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
可以看到二者的不同,truncate直接是以一条语句复杂过来,而delete命令是直接把每条删除的语句一条条记录下来,所以假如要删除全表的数据,用truncate命令会比用delete命令少记录很多内容,日志内容会大减少,肯效率会更高

另外:delete与truncate还有以下的不同:
1. truncatedelete只删除数据不删除表的结构(定义)

2.delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发.
truncateddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger.

3.delete语句不影响表所占用的extent, 高水线(high watermark)保持原位置不动
显然drop语句将表所占用的空间全部释放
truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage; truncate 会将高水线复位(回到最开始).

4.速度,一般来说: truncate > delete

5.安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及.

使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大.
想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete.
如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据/
原文地址:https://www.cnblogs.com/zejin2008/p/5237902.html