技术开发 频道

MySQL Replication的实现原理

  二、Replication 实现级别

  由于MySQL Replication 是基于 Binary Log 实现的,所以Replication 的实现级别实际上是由Binary Log 的存储格式所决定。Binary Log 中记录 Eent 的方式可以是基于一条语句(Statement Level),也可以是基于一条记录(Row level),这可以在 MySQL 的配置参数(—binlog-format)中设定这个格式。

  1. Row Level:Binary Log 中会记录成每一行数据被修改的形式,然后在 Slave 端再对相同的数据进行修改。

  优点:在 Row Level 模式下,Binary Log 中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成什么样了。所以 Row Level 的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题。

  缺点:Row Level下,所有的执行的语句当记录到 Binary Log 中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如有这样一条update语句:UPDATE group_message SET group_id = 1 where group_id = 2,执行之后,日志中记录的不是这条update语句所对应的事件(MySQL以事件的形式来记录 Binary Log 日志),而是这条语句所更新的每一条记录的变化情况,这样就记录成很多条记录被更新的很多个事件。自然,Binary Log 日志的量就会很大。尤其是当执行ALTER TABLE 之类的语句的时候,产生的日志量是惊人的。因为MySQL对于 ALTER TABLE 之类的 DDL 变更语句的处理方式是重建整个表的所有数据,也就是说表中的每一条记录都需要变动,那么该表的每一条记录都会被记录到日志中。

  2. Statement Level:每一条会修改数据的 Query 都会记录到 Master的 Binary Log 中。Slave在复制的时候 SQL 线程会解析成和原来 Master 端执行过的相同的 Query 来再次执行。

  优点:Statement Level下的优点首先就是解决了Row Level下的缺点,不需要记录每一行数据的变化,减少 Binary Log 日志量,节约了 IO 成本,提高了性能。因为他只需要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。

  缺点:由于他是记录的执行语句,所以,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端杯执行的时候能够得到和在master端执行时候相同的结果。另外就是,由于Mysql现在发展比较快,很多的新功能不断的加入,使mysql得复制遇到了不小的挑战,自然复制的时候涉及到越复杂的内容,bug也就越容易出现。在statement level下,目前已经发现的就有不少情况会造成mysql的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现,比如:sleep()函数在有些版本中就不能真确复制,在存储过程中使用了last_insert_id()函数,可能会使slave和master上得到不一致的id等等。由于row level是基于每一行来记录的变化,所以不会出现类似的问题。

  3. Mixed Level: 从 5.1.8 版本开始,MySQL 提供了除Statement Level和Row Level之外的第三种 Mixed Level,实际上就是前两种模式的结合。在Mixed模式下,MySQL会根据执行的每一条具体的 Query 语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。除了MySQL认为通过STATEMENT方式可能造成复制过程中Master与Slave之间产生不一致数据(如特殊Procedure和Function的使用,UUID()函数的使用等特殊情况)的时候MySQL会选择ROW的模式来记录变更之外,都会使用STATEMENT模式来记录变更。当然,这里需要排除的特殊情况并不仅仅只有上面所描述的这几种,具体请参考 MySQL 官方的详细手册。

  老版本的 MySQL 一直都只有基于 Statement 的复制模式,直到5.1.5版本的 MySQL 才开始支持Row Level的复制。从5.0开始,MySQL 的复制已经解决了大量老版本中出现的无法正确复制的问题。但是由于存储过程的出现,给 MySQL 的复制又带来了更大的新挑战。另外,看到官方文档说,从5.1.8版本开始,MySQL 开始提供 Mixed Level,新版本中的Statment level还是和以前一样,仅仅记录执行的语句。而新版本的Mysql中队Row Level模式也被做了优化,并不是所有的修改都会以Row Level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果 Query 语句确实就是 UPDATE 或者 DELETE 等修改数据的语句,那么还是会记录所有行的变更。

0
相关文章