MySQL面试-日志录入格式


接上篇《两道常见的MySQL面试题》,今天小树懒来给大家讲另一道面试题,关于MySQL binlog的几种日志录入格式。

一、MySQL BinLog日志的录入格式以及区别

Statement:将修改数据的所有sql都记录在binlog中。

好处:无需记录每行的变化,减少了binlog日志数量,节省了IO,提高了性能。(相对于row可以节省多少性能和日志数量,这取决于SQL应用程序的情况,通常同一记录修改或插入row格式所产生的日志数量比Statement所产生的日志数量少,但考虑到如果有条件的update操作,以及整个表格的删除,ROW格式会产生大量的日志,所以在考虑是否使用ROW格式日志时,应该根据实际情况,它所产生的日志数量会增加多少,以及IO性能问题。)

缺点:由于只记录执行句子,为了使这些句子能够在slave上正确运行,还必须记录每个句子执行时的一些相关信息,以确保所有句子都能在slave上得到与在master端执行时相同的结果。此外,mysql的复制,如一些特定的函数功能,如果slave能够与master保持一致,将会出现许多相关问题(如sleep()函数、last_insert_id()和user-definedfunctions(udf)。

使用以下函数的句子不能复制:

LOAD_FILE()

UUID()

USER()

FOUND_ROWS()

SYSDATE()(除非启动时启用-sysdate-is-now选项),否则INSERT..SELECT会产生比RBR更多的行级锁。

Row:不记录sql句子上下文的相关信息,只保存修改过的记录。

好处:binlog中可以不记录执行的sql语句的上下文相关信息,只需记录下该记录被修改为什么。因此,rowlevel的日志内容将清楚地记录每行数据修改的细节。并且不会出现某些特定情况下的存储过程,或者function,以及trigger的调用和触发不能正确复制的问题。

缺点:当所有执行的句子都记录在日志中时,它们会被每行记录的修改记录下来,这可能会产生大量的日志内容。例如,如果一个update句子被修改为多个记录,那么binlog中的每个修改都会被记录下来,这将导致binlog日志的大量数量,尤其是当执行altertable等句子时,由于表格结构的修改,每个记录都会发生变化,所以表格中的每个记录都会被记录在日志中。

Mixedlevel:是上述两种level的混合使用,一般的语句修改使用statment格式来保存binlog,例如某些函数,statement不能完成主从复制操作,则使用row格式来保存binlog,MySQL将根据执行的每个具体的sql语句来区分处理记录的日志形式,即在Statement和Row格式之间选择一种。新版本的MySQL中队rowlevel模式也进行了优化,并非所有的修改都是用rowlevel来记录的,比如在表结构发生变化时,用statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的变更。

二、适用场景

在一条 SQL 操作了多行数据时, statement 更节省空间, row 更占用空间。但是 row模式更可靠。

总结:Statement 可能占用空间会相对小一些,传送到 slave 的时间可能也短,但是没有 row模式的可靠。 Row 模式在操作多行数据时更占用空间, 但是可靠。