SlideShare uma empresa Scribd logo
1 de 69
MySQL 同步

6 MySQL 同步


同步功能在 MySQL 3.23.15 就开始引进了,它可以把一个 MySQL 服务器上的数据复制到另一个服务器上去。本章

描述了 MySQL 的各种复制特性。介绍了同步的概念,如何设置同步服务器,以及可用服务器的参照。还提供了一系

列的常见问题及其答案,疑难解答。



"14.6 Replication Statements"中介绍了同步相关的 SQL 语句语法。



我们建议经常访问"http://www.mysql.com"经常阅读本章的最新内容。同步功能一直在改进,我们经常把这部分

的手册更新到当前的最新内容。




6.1 同步介绍

MySQL 3.23.15 及更高的版本支持单向同步。一个服务器作为 master(主服务器),一个或者多个服务器作为

slave(从服务器)。master 服务器把更新的内容写到二进制日志(binary log 或 binlog)中,并且维护了一个索引文

件来记录日志循环的情况。这些日志中的更新部分会被发送到 slave 服务器。一个 slave 连接到 master 之后,它通

知 master 最后一次成功增量更新的日志位置。slave 会找出所有从那个时刻开始的更新操作,然后阻塞并等待

master 发送新的更新操作。




如果想要做一个同步服务器链的话,slave 同时也可以作为 master。



注意,启用同步后,所有要同步的更新操作都必须在 master 上执行。否则,必须注意不要造成用户在 master 上的

更新和在 slave 上的更新引起冲突。




单向同步的好处是稳健,高速,系统易管理:
•   有了 master/slave 机制后,就更稳健了。当 master 上发生问题时,可以把 slave 作为备用切换过去。


•   可以在 slave 和 master 之间分担一些查询,这就能加速响应时间。SELECT 查询就可以在 slave 上执行以减少 master

    的负载。更新数据的语句则要放在 mater 上执行以保持 master 和 slave 的同步。当非更新操作占多数时,负载均衡就很

    有效了,不过这只是普通情况而言。



•   另一个好处是可以在 slave 上备份数据,无需干扰 master。备份数据时 master 照样继续运作。详情请看"5.7.1

    Database Backups"。



       6.2 同步机制实现概述

       MySQL 同步机制基于 master 把所有对数据库的更新、删除 等)都记录在二进制日志里。因此,想要启用同步机制,

       在 master 就必须启用二进制日志。详情请看"5.9.4 The Binary Log"。




       每个 slave 接受来自 master 上在二进制日志中记录的更新操作,因此在 slave 上执行了这个操作的一个拷贝。



       应该非常重要地意识到,二进制日志只是从启用二进制日志开始的时刻才记录更新操作的。所有的 slave 必须在启

       用二进制日志时把 master 上已经存在的数据拷贝过来。如果运行同步时 slave 上的数据和 master 上启用二进制

       日志时的数据不一致的话,那么 slave 同步就会失败。



       把 master 上的数据拷贝过来的方法之一实在 slave 上执行    LOAD DATA FROM MASTER   语句。不过要注意,

       LOAD DATA FROM MASTER   是从 MySQL 4.0.0 之后才开始可以用的,而且只支持 master 上的    MyISAM

       类型表。同样地,这个操作需要一个全局的读锁,这样的话传送日志到 slave 的时候在 master 上就不会有更新操作

       了。当实现了自由锁表热备份时(在 MySQL 5.0 中),全局读锁就没必要了。



       由于有这些限制,因此我们建议只在 master 上相关数据比较小的时候才执行            LOAD DATA FROM MASTER

       语句,或者在 master 上允许一个长时间的读锁。由于每个系统之间          LOAD DATA FROM MASTER   的速度各

       不一样,一个比较好的衡量规则是每秒能拷贝 1MB 数据。这只是的粗略的估计,不过 master 和 slave 都是奔腾

       700MHz 的机器且用 100MBit/s 网络连接时就能达到这个速度了。
slave 上已经完整拷贝 master 数据后,就可以连接到 master 上然后等待处理更新了。如果 master 当机或者

slave 连接断开,slave 会定期尝试连接到 master 上直到能重连并且等待更新。重试的时间间隔由                 --master-

connect-retry    选项来控制,它的默认值是 60 秒。




每个 slave 都记录了它关闭时的日志位置。msater 是不知道有多少个 slave 连接上来或者哪个 slave 从什么时候开

始更新。




6.3 同步实现细节

MySQL 同步功能由 3 个线程(master 上 1 个,slave 上 2 个)来实现。执行      START SLAVE   语句后,slave 就创

建一个 I/O 线程。 线程连接到 master 上,并请求 master 发送二进制日志中的语句。
           I/O                                    master 创建一个线程来把

日志的内容发送到 slave 上。这个线程在 master 上执行         SHOW PROCESSLIST   语句后的结果中的     Binlog

Dump   线程便是。slave 上的 I/O 线程读取 master 的   Binlog Dump   线程发送的语句,并且把它们拷贝到其数

据目录下的中继日志(relay logs)中。第三个是 SQL 线程,salve 用它来读取中继日志,然后执行它们来更新数据。




如上所述,每个 mster/slave 上都有 3 个线程。每个 master 上有多个线程,它为每个 slave 连接都创建一个线程,

每个 slave 只有 I/O 和 SQL 线程。




在 MySQL 4.0.2 以前,同步只需 2 个线程(master 和 slave 各一个)。slave 上的 I/O 和 SQL 线程合并成一个了,

它不使用中继日志。




slave 上使用 2 个线程的优点是,把读日志和执行分开成 2 个独立的任务。执行任务如果慢的话,读日志任务不会跟

着慢下来。例如,如果 slave 停止了一段时间,那么 I/O 线程可以在 slave 启动后很快地从 master 上读取全部日志,

尽管 SQL 线程可能落后 I/O 线程好几的小时。如果 slave 在 SQL 线程没全部执行完就停止了,但 I/O 线程却已经把

所有的更新日志都读取并且保存在本地的中继日志中了,因此在 slave 再次启动后就会继续执行它们了。这就允许在

master 上清除二进制日志,因为 slave 已经无需去 master 读取更新日志了。




执行   SHOW PROCESSLIST   语句就会告诉我们所关心的 master 和 slave 上发生的情况。
下例说明了   SHOW PROCESSLIST     结果中的 3 个线程是什么样的。这是在 MySQL 4.0.15 及更新上执行

SHOW PROCESSLIST    的结果,State 字段的内容已经比旧版本显示的更有意义了。




在 master 上,SHOW   PROCESSLIST   的结果如下:




 mysql> SHOW PROCESSLISTG

 *************************** 1. row ***************************

      Id: 2

    User: root

    Host: localhost:32931

      db: NULL

 Command: Binlog Dump

    Time: 94

   State: Has sent all binlog to slave; waiting for binlog to

          be updated

    Info: NULL


在这里,线程 2 是为一个 slave 连接创建的。结果表明所有未完成的更新日志已经都发送到 slave 了,master 正等

待新的更新日志发生。




在 slave 上,SHOW   PROCESSLIST   的结果如下:




 mysql> SHOW PROCESSLISTG

 *************************** 1. row ***************************

      Id: 10
User: system user

    Host:

      db: NULL

 Command: Connect

    Time: 11

   State: Waiting for master to send event

    Info: NULL

 *************************** 2. row ***************************

      Id: 11

    User: system user

    Host:

      db: NULL

 Command: Connect

    Time: 11

   State: Has read all relay log; waiting for the slave I/O

            thread to update it

    Info: NULL


这表明线程 10 是 I/O 线程,它正连接到 master 上;线程 11 是 SQL 线程,它执行中继日志中的更新操作。现在,

这 2 个线程都处于空闲状态,正等待新的更新日志。




注意,Time 字段的值告诉我们 slave 上的日志比 master 晚了多久。详情请看"6.9 Replication FAQ"。




6.3.1 Master 同步线程状态
以下列出了 master 的   Binlog Dump    线程   State   字段中最常见的几种状态。如果在 master 上没有

 Binlog Dump   线程,那么同步就没有在运行。也就是说,没有 slave 连接上来。




Sending binlog event to slave

  事件是由二进制日志构成,一个事件通常由更新语句加上其他信息。线程读取到一个事件并正发送到 slave 上。


  Finished reading one binlog; switching to next binlog

  读取完了一个二进制日志,正切换到下一个。


     Has sent all binlog to slave; waiting for binlog to be updated

  已经读取完全部未完成更新日志,并且全部都发送到 slave 了。它处于空闲状态,正等待在 master 上执行新的更

  新操作以在二进制日志中产生新的事件,然后读取它们。


          Waiting to finalize termination

  当前线程停止了,这个时间很短。



 6.3.2 Slave 的 I/O 线程状态



 以下列出了 slave 的 I/O 线程   State   字段中最常见的几种状态。从 MySQL 4.1.1 开始,这个状态在执行       SHOW

 SLAVE STATUS   语句结果的    Slave_IO_State       字段也会出现。这意味着可以只执行   SHOW SLAVE

 STATUS   语句就能了解到更多的信息。




Connecting to master

  该线程证尝试连接到 master 上。


  Checking master version

  确定连接到 master 后出现的一个短暂的状态。


     Registering slave on master

  确定连接到 master 后出现的一个短暂的状态。
Requesting binlog dump

确定连接到 master 后出现的一个短暂的状态。该线程向 master 发送一个请求,告诉它要请求的二进制文件以及

开始位置。


        Waiting to reconnect after a failed binlog dump request

如果二进制日志转储(binary log dump)请求失败了(由于连接断开),该线程在休眠时进入这个状态,并定期重

连。重连的时间间隔由     --master-connect-retry   选项来指定。


           Reconnecting after a failed binlog dump request

该线程正尝试重连到 master。


              Waiting for master to send event

已经连接到 master,正等待它发送二进制日志。如果 master 闲置时,这个状态可能会持续较长时间,如果它等

待超过   slave_read_timeout   秒,就会发生超时。这时,它就会考虑断开连接,然后尝试重连。


                Queueing master event to the relay log

已经读取到一个事件,正把它拷贝到中继日志中以备 SQL 线程处理。


                   Waiting to reconnect after a failed master event

                   read

读日志时发生错误(由于连接断开)。该线程在重连之前休眠            master-connect-retry   秒。




                     Reconnecting after a failed master event read

正尝试重连到 master。当连接确定后,状态就变成         Waiting for master to send event 。


                           Waiting for the slave SQL thread to free

                           enough relay log space

relay_log_space_limit   的值非零,中继日志的大小总和超过这个值了。I/O 线程等待 SQL 线程先处理

中继日志然后删除它们以释放足够的空间。
Waiting for slave mutex on exit

  当前线程停止了,这个时间很短。



 6.3.3 Slave 的 SQL 线程状态



 以下列出了 slave 的 SQL 线程   State   字段中最常见的几种状态:




Reading event from the relay log

  从中继日志里读到一个事件以备执行。


  Has read all relay log; waiting for the slave I/O thread to update

  it

  已经处理完中继日志中的全部事件了,正等待 I/O 线程写入更新的日志。


       Waiting for slave mutex on exit

  当前线程停止了,这个时间很短。



 SQL 线程的   State   字段有时候也可能是一个 SQL 语句。这意味着它从中继日志中读取到一个事件了,从中提取出

 SQL 语句,并执行它。




 6.3.4 中继日志及状态文件



 默认地,中继日志的名字格式为          `host_name-relay-bin.nnn`,host_name 是服务器的主机名,nnn 是序

 号。中继日志是根据顺序的序号来创建的,从             000001   (MySQL 4.0 及更旧是   001 )开始。slave 上用一个索引文

 件来跟踪当前正在使用的中继日志。默认的中继日志索引文件名是                   `host_name-relay-bin.index`。默认地,

 这个文件位于 slave 的数据文件目录下。默认文件名可以根据的系统选项                 --relay-log   和   --relay-

 log-index   来替换。详情请看"6.8 Replication Startup Options"。
中继日志和二进制日志的格式一样,因此也可以用               mysqlbinlog   来读取。当 SQL 线程读取完中继日志中的全

          部事件后就不再需要它了,会自动删除它。中继日志没有显式的删除机制,因为 SQL 线程会自动关注这个。不过,从

          MySQL 4.0.14 开始,执行   FLUSH LOGS   的话就会轮转(rotate)中继日志,会让 SQL 线程删除它们。




          在下列条件中会创建一个新的中继日志:


•       slave 启动后,I/O 线程第一次启动(在 MySQL 5.0 中,每次 I/O 线程启动后都会新建一个中继日志,而不只是第一次

        启动时)。


•       刷新日志时;例如,执行       FLUSH LOGS   语句或运行   mysqladmin flush-logs   命令(从 MySQL 4.0.14 开

        始才会创建新中继日志)。


•       当前的中继日志大小太大了;"太大了"是这么判断的:




    o   max_relay_log_size , 如果 max_relay_log_size     > 0 的话



    o   max_binlog_size , 如果 max_relay_log_size     = 0 或 MySQL 低于 4.0.14




          slave 会在数据文件目录下创建两个额外的文件。它们是状态文件,名字默认为                  `master.info` and `relay-

          log.info`。它们的内容跟执行 SHOW SLAVE STATUS        语句的结果类似。详情请看"14.6.2 SQL

          Statements for Controlling Slave Servers"。由于是磁盘上的文件,它们在 slave 关闭后还会留着。下一次

          slave 启动时,就会读取这两个文件来判断从 master 读取到二进制日志的什么位置了,处理中继日志到什么位置了。



          `master.info`   文件由来 I/O 线程更新。在 MySQL 4.1 以前,文件的内容和执行        SHOW SLAVE STATUS

          语句结果中相对应的字段值一样,如下:
Line                                 Description



  1                               Master_Log_File


  2                            Read_Master_Log_Pos


  3                                  Master_Host


  4                                  Master_User


  5                  Password (not shown by   SHOW SLAVE STATUS )


  6                                  Master_Port


  7                                Connect_Retry


从 MySQL 4.1 开始,文件内容还包括了 SSL 选项:




 Line                                 Description



  1                             Number of lines in the file



  2                               Master_Log_File


  3                            Read_Master_Log_Pos


  4                                  Master_Host
5                                   Master_User


   6                    Password (not shown by   SHOW SLAVE STATUS )


   7                                   Master_Port


   8                                  Connect_Retry


   9                               Master_SSL_Allowed


  10                               Master_SSL_CA_File


  11                               Master_SSL_CA_Path


  12                                 Master_SSL_Cert


  13                               Master_SSL_Cipher


  14                                 Master_SSL_Key



`relay-log.info`   文件由 SQL 线程来更新。文件的内容和执行           SHOW SLAVE STATUS   语句结果中相对

应的字段值一样:




       Line                                 Description



        1                                Relay_Log_File
2                                Relay_Log_Pos


      3                            Relay_Master_Log_File


      4                             Exec_Master_Log_Pos



备份 slave 数据时,要把这两个文件也备份起来,和中继日志一道。想要恢复 slave 时就用得到它们了。如果丢失了

中继日志,但是    `relay-log.info` 文件还存在,那么就可以判断出 SQL 线程执行了多少 master 二进制日志。

然后执行   CHANGE MASTER TO   语句,带上    MASTER_LOG_FILE   和   MASTER_LOG_POS   选项告诉

slave 要从 master 的二进制日志哪个位置重新读取。当然了,这要求 master 上相关的二进制日志都还留着。



如果 slav 打算同步   LOAD DATA INFILE   语句,那么也要备份对应目录下的任何          `SQL_LOAD-*` 文件。这

可以在   LOAD DATA INFILE   被中断后继续保持同步。这个目录由         --slave-load-tmpdir     选项来指

定。默认地,如果没有指定的话,它的值就是变量             tmpdir   的值。




6.4 设置同步

以下描述了如何快速设置 MySQL 同步服务器。假设你打算同步全部的数据库,并且之前没有设置过。需要关闭

master 服务器以完成全部的步骤。




本章描述的过程可以用于一个 slave 的情况,也可以用于多个 slave 的情况。




这只是一个最直接设置 slave 的办法,并不是只有一个。例如,已经有了 master 的数据快照(snapshot),master

已经设置了服务器编号 ID(server_id)并且启用了二进制日志,这就无需关闭 master 或者阻止在 master 上更新

数据了。详情请看"6.9 Replication FAQ"。
想要完全掌握 MySQL 同步设置,最好把本章全部读完,并且测试在"14.6.1 SQL Statements for Controlling

 Master Servers"和"14.6.2 SQL Statements for Controlling Slave Servers"中提到的全部语句。而且要熟悉

 各种同步设置选项,详情请看"6.8 Replication Startup Options"。



 注意,这个过程以及后面一些同步 SQL 语句需要有                  SUPER   权限。MySQL 4.0.2 以前,则是   PROCESS   权限。




1. 请确认 master 和 slave 上都安装了较近的 MySQL 版本,且这些版本之间要能兼容,在"6.5 Replication

      Compatibility Between MySQL Versions"中列出来了。请确认在最新版本中还有存在问题,否则不要报告该

      bug。

2. 在 master 上新加一个帐户,slave 才能用它来连接。这个帐户必须授予 REPLICATION SLAVE 权限。如果

      这个帐户只用于同步(推荐这么做),那就没必要授予其他权限了。设定你的域是                       mydomain.com ,想要授权一

      个帐户    repl   使用密码   slavepass ,允许它可以在域里的任何主机连接到 master 上。用 GRANT              语句来

      创建帐户:


 3. mysql> GRANT REPLICATION SLAVE ON *.*

 4.          -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';


      在 MySQL 4.0.2 以前,用    FILE   权限来代替   REPLICATION SLAVE :


       mysql> GRANT FILE ON *.*

             -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';




      如果打算在 slave 上执行      LOAD TABLE FROM MASTER     或   LOAD DATA FROM MASTER   语句,那

      么必须给该帐户授予附加权限:
o   授予全局   SUPER   和   RELOAD   权限。



o   授予对想要加载的所有表上的          SELECT     权限。在 master 上任何没有   SELECT   权限的表都会被   LOAD

    DATA FROM MASTER     略过。




5. 如果只用到 MyISAM 表,执行 FLUSH TABLES WITH READ LOCK 语句刷新所有表并且阻止其他写

    入:


 6. mysql> FLUSH TABLES WITH READ LOCK;


    不要退出执行   FLUSH TABLES       语句的客户端,以保持读锁有效(如果退出了,读锁就释放了)。然后从

    master 上取得数据快照。比较简单的办法就是把数据目录打包压缩。例如,Unix 上的                    tar ,

    PowerArchiver , WinRAR , WinZip ,或 Windows 上的类似程序。想要用 tar        来创建一个压缩包,包

    括所有的数据库,只需执行以下命令(把目录改成你的真实路径):



     shell> tar -cvf /tmp/mysql-snapshot.tar .


    如果只想打包一个数据库         this_db ,只需执行命令:


     shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db


    然后把这个文件拷贝到 slave 的      `/tmp` 目录下。 slave 上,执行以下命令解开压缩包(把目录改成你的真实路
                                       在

    径):




     shell> tar -xvf /tmp/mysql-snapshot.tar
可能不需要同步      mysql   数据库,因为在 slave 上的权限表和 master 不一样。这时,解开压缩包的时候要排除

它。同时在压缩包中也不要包含任何日志文件,或者                `master.info~ 或 `relay-log.info` 文件。当在

master 上的   FLUSH TABLES WITH READ LOCK    语句还生效时,在 master 上读取当前二进制文件的

文件名及偏移位置:



 mysql > SHOW MASTER STATUS;

 +---------------+----------+--------------+------------------+

 | File            | Position | Binlog_Do_DB | Binlog_Ignore_DB |

 +---------------+----------+--------------+------------------+

 | mysql-bin.003 | 73         | test        | manual,mysql      |

 +---------------+----------+--------------+------------------+


File   字段显示了二进制日志文件名,Position 字段显示了日志偏移位置。在这个例子中,日志文件是

mysql-bin.003 ,偏移位置是 73 。记下这些值,在后面设置 slave 的时候就需要用到它们了。它们表示了

slave 要从 master 的哪个偏移位置开始处理更新操作。取得快照和记录下日志名及偏移位置后,就可以让

master 释放读锁了:



 mysql> UNLOCK TABLES;


如果用到     InnoDB   表,那么最好使用   InnoDB Hot Backup    工具。它无需在 master 上请求任何锁就能

做到快照的一致性,并且在后面中在 slave 上要用到的快照中已经记录了日志文件名以及偏移位置。InnoDB

Hot Backup    是费免费(商业的)的附加工具,它没有包含在 MySQL 发布包中。访问              InnoDB Hot

Backup    的主页 http://www.innodb.com/manual.php 查看更多详细信息。除去    InnoDB Hot

Backup    的另一个最快的办法就是关闭 master 服务器,拷贝         InnoDB   数据文件,日志文件,以及表结构定

义文件(`.frm` 文件)。想要记录当前日志文件及偏移位置,需要在 master 关闭前执行如下可语句:




 mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;




  尽快记下     SHOW MASTER STATUS     显示结果中的日志文件及偏移位置。然后,在不解锁的情况下关闭

  master,确保 master 上的快照和记录的结果一致:




    shell> mysqladmin -u root shutdown


  还有一个方法可以同时用于           MyISAM   和   InnoDB   表,这就是在 master 上作 SQL 转储而无需如上所述备份

  二进制日志。 master 上运行
        在                  mysqldump --master-data      命令,然后把结果文件转储到 slave 上。不

  过,这比拷贝二进制日志慢点。如果 master 在以前没有启用                  --log-bin   选项,那么执行   SHOW MASTER

  STATUS   语句的结果中的文件名及偏移位置值为空了,那么后面在 slave 上指定的参数值就是空字符串('' ) 和

  4 了。



7. 确认 master 上的 `my.cnf` 文件 [mysqld] 区间有 log-bin 选项。这个区间还必须有 server-

  id=master_id    选项,的值必须是 1 到 2^32-1 之间的正整数。例如:


 8. [mysqld]

 9. log-bin

 10.server-id=1


  如果这些配置选项不存在,那么就加上并且重启 master。



11. 关闭要做 slave 的服务器,在 `my.cnf` 文件中增加如下选项:



 12.[mysqld]

 13.server-id=slave_id
slave_id    的值和   master_id   类似,是 1 到 2^32-1 之间的正整数。另外,这个 ID 必须不能和 master

  的 ID 一样。例如:




   [mysqld]

   server-id=2




  如果有多个 slave,那么每个 slave 都必须要有一个唯一的           server-id ,它的值不能和 master 以及其其他

  slave 的值一样。可以把     server-id   想象成为 IP 地址:这些 ID 标识了整个同步组合中的每个服务器。如果没

  有指定   server-id    的值,如果也没定义      master-host ,那么它的值就为 1,否则为 2。注意,如果没有

  设定   server-id ,那么 master 就会拒绝所有的 slave 连接,同时 slave 也会拒绝连接到 master 上。因此,

  省略配置   server-id    只对备份二进制日志有利。




14. 如果已经备份了 master 上的数据(直接打包压缩的方式),那么在 slave 启动之前把它们拷贝过去。要确保文件的

  权限属主等设置没问题。MySQL 运行的用户必须对这些文件有读写权限,就跟在 master 上一样。如果是用

  mysqldump   备份的,那么可以直接启动 salve(直接跳到下一步)。



15. 启动 slave,如果它之前已经运行同步了,那么在启动 slave 的时候使用 --skip-slave-start 选项使

  之不会立刻去连接 master。最好也使用          --log-warnings   选项(从 MySQL 4.0.19 和 4.1.2 开始就是默

  认启用了)来启动 slave,以知道发生问题时的更详细的信息(例如,网络或者连接问题)。从开始 MySQL 4.0.21

  和 4.1.3,异常中止的连接不再记录到错误日志中,除非                --log-warnings   选项的值大于 1。


16. 如果在 master 上用 mysqldump 备份数据的话,把文件导入 slave 中:



 17.shell> mysql -u root -p < dump_file.sql


18. 在 slave 上执行如下语句,把各个选项的值替换成真实值:
19.mysql> CHANGE MASTER TO

 20.      ->      MASTER_HOST='master_host_name',

 21.      ->      MASTER_USER='replication_user_name',

 22.      ->      MASTER_PASSWORD='replication_password',

 23.      ->      MASTER_LOG_FILE='recorded_log_file_name',

 24.      ->      MASTER_LOG_POS=recorded_log_position;


   下表列出了各个选项字符串的最大长度:




                                  MASTER_HOST                                  60




                                  MASTER_USER                                  16




                               MASTER_PASSWORD                                 32




                               MASTER_LOG_FILE                                 255




25. 启动 slave 线程:




       mysql> START SLAVE;


 做完上述过程后,slave 应该会连接到 master 上并且捕获所有从取得快照后的更新操作。

 如果忘了设置 master 的      server-id   值,那么 slave 就不能连接到 master 上。

 如果忘了设置 master 的      server-id   值,那么在错误日志中就会记录如下内容:




   Warning: You should set server-id to a non-0 value if master_host is set;
we force server id to 2, but this MySQL server will not act as a slave.


如果因为其他原因不能同步的话,错误信息也会记录在 slave 的日志上。



一旦 slave 开始同步了,就能在数据文件目录下找到 2 个文件          `master.info` 和`relay-log.info`。slave

利用这 2 个文件来跟踪处理了多少 master 的二进制日志。




不要删除或者修改这 2 个文件,除非知道怎么改。尽管如此,我们更推荐用                 CHANGE MASTER TO    语句来做。




注意:`master.info` 中的内容覆盖了部分命令行中指定的或           `my.cnf` 的选项。详情请看"6.8 Replication

Startup Options"。




只要有了 master 的数据快照,就可以按照上述几个步骤配置其它 slave 了。无需再次取得 master 的数据快照,每

个 slave 都可以用这一份快照来做。



6.5 不同 MySQL 版本之间的同步兼容性

最早的二进制格式是在 MySQL 3.23 中开发出来的。在 MySQL 4.0 中改进了,MySQL 5.0 又改进了。在配置同步

时需要升级服务器的话,它们之间的因果关系在"6.6 Upgrading a Replication Setup"中描述了。




如果只关心同步,任何 MySQL 4.1.x 版本和 MySQL 4.0.x 是一样的,因为它们都使用相同格式的二进制日志。所

以,这些版本是互相兼容的,它们之间可以无缝地运行同步。一个例外的情况是,MySQL 4.0.0 到 4.0.2 由于开发

的较早,无法和后来的版本互相兼容,所以不要使用它们(它们是 4.0 版本的 alpha 系列。它们之间的兼容性在发布

包的手册中均有相关文档)。
下表展示了不同版本的 MySQL 之间的 master/slave 同步兼容性。




                                Master                Master             Master



                            3.23.33 and up   4.0.3 and up or any 4.1.x    5.0.0



Slave    3.23.33 and up           yes                   no                 no



Slave     4.0.3 and up            yes                  yes                 no



Slave         5.0.0               yes                  yes                 yes




一个通常的规则是,我们建议使用最近的 MySQL 版本,因为同步兼容性一直在改善。我们也建议 master 和 slave

都使用同一个版本。




6.6 升级同步

如果升级服务器时涉及到配置同步,升级设置的步骤跟当前版本以及升级后的版本不同而异。




6.6.1 升级同步到 4.0 或 4.1



本节适用于从 MySQL 3.23 升级到 4.0 或者 4.1 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5 Replication

Compatibility Between MySQL Versions"中提到了。




把 master 从 MySQL 3.23 升级到 4.0 或 4.1 时,首先要确认这个 master 的所有 slave 都已经是 4.0 或 4.1 了,

否则的话,要先升级 slave:挨个关闭,升级,重启,重启同步等。
通过以下步骤可以实现安全地升级,假定 master 要升级到 3.23,而 slave 已经是 4.0 或 4.1 了。注意,master 升

 级后,不要重启使用任何旧的二进制日志的同步,因为它会干扰到 4.0 或 4.1 slave 的同步。




1. 在 master 上执行 FLUSH TABLES WITH READ LOCK 语句,阻止所有的更新。

2. 等到所有的 slave 都跟上了 master 的数据更新。在 master 上执行 SHOW MASTER STATUS 语句取得二进

  制日志以及偏移位置。然后,再 slave 用这些值执行              SELECT MASTER_POS_WAIT()          语句,它会阻止

  slave 上的同步且返回它已经同步的偏移位置。然后在 slave 上执行                   STOP SLAVE   语句。



3. 关闭 master,将它升级到 MySQL 4.0 或 4.1。


4. 重启 master,记下它的新的二进制文件名。可以在 master 上执行 SHOW MASTER STATUS 语句来取得这

  些信息。然后在每个 slave 上都执行如下语句:


 5. mysql> CHANGE MASTER TO MASTER_LOG_FILE='binary_log_name',


 6.      ->      MASTER_LOG_POS=4;


      mysql> START SLAVE;



 6.6.2 升级同步到 5.0


 本节适用于从 MySQL 3.23,4.0 或 4.1 升级到 5.0 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5

 Replication Compatibility Between MySQL Versions"中提到了。




 首先,注意到 MySQL 5.0 还是 alpha 发布系列。它在各方面都比旧版本好(更容易升级一些同步中重要的会话变量,

 例如   sql_mode ;详情请看"C.1.3 Changes in release 5.0.0 (22 Dec 2003: Alpha")。不过,它还没经过广

 泛测试。由于是 alpha 版本,我们不建议用于任何生产环境(现在已经可以用于生产了,译者注)。
把 master 从 MySQL 3.23,4.0 或 4.1 升级到 5.0.0 时,首先要确认这个 master 的所有 slave 都已经是 5.0.0

       了,否则的话,要先升级 slave:挨个关闭,升级,重启,重启同步等。5.0.0 的 slave 可以读取升级前写入的执行

       语句的中继日志。升级完后的 slave 创建的中继日志就是 5.0 格式了。




       当所有的 slave 都升级完了,关闭 master,升级到 5.0.0,然后重启。5.0.0 的 master 也可以读取旧格式的二进

       制日志。slave 能识别旧的格式并且合理处理它们。master 上新建的二进制日志都是 5.0.0 格式的。slave 也能识别

       这格式。




       换言之,在升级到 5.0.0 时无需特殊的规定,除非在升级 master 到 5.0.0 之前 slave 必须使用旧版本的。注意,把

       5.0.0 降级到旧版本中不能自动地做了:必须确保所有的 5.0.0 格式二进制日志和中继日志都已经处理完了,然后

       才能把它们删除完成降级。




       6.7 同步特性及已知问题

       以下列出了同步支持什么,不支持什么。附加的                  InnoDB   特殊相关的信息以及同步请看"16.7.5   InnoDB   and

       MySQL Replication"。




•   AUTO_INCREMENT , LAST_INSERT_ID() , 和 TIMESTAMP        的值都能被正常同步。


•   USER() , UUID() , 和 LOAD_FILE()   函数都完完全全地同步到 slave,因此可能不大可靠。MySQL 4.1.1 以前

    的版本中的   CONNECTION_ID()      函数也是如此。 MySQL 4.1.1 及更高以后,新的
                                        从                            PASSWORD()   函数可以正

    常同步,当然了,slave 必须是 4.1.1 或更高或者不同步它。如果有旧版本的 slave 必须要同步               PASSWORD()     函数,

    那么 master 启动时必须增加        --old-password   选项,这样在 master 上就用旧的方法来实现     PASSWORD()

    了(注意,MySQL 4.1.0 的   PASSWORD()   函数实现跟其他的版本都不同,最好不要同步 4.1.0)。
•   从 MySQL 4.0.14 开始同步   FOREIGN_KEY_CHECKS     变量。从 5.0.0 开始同步   sql_mode ,

    UNIQUE_CHECKS ,和 SQL_AUTO_IS_NULL      变量。    SQL_SELECT_LIMIT   和   table_type   变量目前

    还不能被同步。



•   现在讨论使用不同字符集的 MySQL 服务器间同步的问题。


       1. 首先,在 master 和 slave 上必须总是使用同样的全局字符集以及校验字符集(--default-

             character-set , --default-collation    都是相关的全局变量)。否则,slave 上可能会出现键重

             复(duplicate-key)的错误,因为用 master 的字符集认为该键可能是唯一的,但是用 slave 的字符集则未必

             然。


       2. 第二,如果 master 必须低于 MySQL 4.1.3,则会话(session)的字符集必须和全局值一样(也就是说,不能

             执行   SET NAMES , SET CHARACTER SET   等语句),因为这些对字符集的修改在 slave 不能识别。如

             果 master 是 4.1.3 或者更高,slave 也是这样的话,那么会话字符集就可以随便修改了(执行               NAMES ,

             CHARACTER SET , COLLATION_CLIENT , COLLATION_SERVER     等),并且这些修改都会被记录

             到二进制日志中,然后同步到 slave 上,它就知道怎么做了。该会话还会阻止试图修改这些全局变量的操作;

             就如前面所说,master 和 slave 必须使用同样的全局字符集。



       3. 如果在 master 上有和全局变量 collation_server 不一样字符集的数据库,那么就要设计 CREATE

             TABLE   语句使得数据表不隐式地使用该数据库的默认字符集,因为这目前还是一个 bug(Bug #2326);一

             个变通的办法是在     CREATE TABLE   语句中显式地声明数据表的字符集以及校验字符集。



•   有时可能会把 master 上的事务表同步到 slave 后变成非事务表。例如,可以在 slave 上把 master 的               InnoDB   表当成

    MyISAM   表。不过,slave 在一个    BEGIN/COMMIT   区块中停止的话就有问题了,因为 slave 会从          BEGIN    重新开

    始。这个问题已经放到 TODO 中,很快会被修复。



•   更新语句中如果用到了用户自定义变量(例如变量               @ var_name )的情况下,在 MySQL 3.23 和 4.0 不能被正确同步。

    在 4.1 这已经修复了。注意,从 MySQL 5.0 开始,用户变量就不区分大小写了。在做 MySQL 5.0 和旧版本间的同步需

    要考虑到这个问题。



•   从 4.1.1 以及更高版本中,slave 可以用 SSL 方式连接到 master。
•   在 master 上执行的     CREATE TABLE   语句如果包括了       DATA DIRECTORY 或 INDEX DIRECTORY         子句,

    那么它也会应用于 slave 上。如果 slave 上不存在对应的目录或者没有权限时便出现问题。 MySQL 4.0.15 开始,有个
                                                    从

    sql_mode    选项叫   NO_DIR_IN_CREATE 。如果 slave 的 SQL 模式包含这个选项,那么它在同步 CREATE

    TABLE   语句前会忽略前面提到的 2 个子句。结果就是               MyISAM   的数据和索引文件都只能放在该表的数据库目录下。


•   尽管没听说过发生过类似的情况,不过理论上确实存在这种可能性:如果一个查询被设计为非确定方式的修改数据,那

    么可能导致 master 和 slave 的数据不一致。那么,就把决定的权力交给查询优化器吧。(通常这不是一个好的做法,甚至

    超出了同步的范围,详情请看"1.8.7.3 Open Bugs and Design Deficiencies in MySQL")



•   在 MySQL 4.1.1 之前,FLUSH ,    ANALYZE TABLE , OPTIMIZE TABLE ,和 REPAIR TABLE        语句没有写入

    到二进制日志中,因此也不会同步到 slave 上。这通常不会引发问题,因为它们并没有修改数据。不过在特定情况下可能

    导致问题。如果同步         mysql   数据库下的权限表,在更新时不是用            GRANT   语句,那么必须在 slave 上执行那么必须在

    slave 上执行   FLUSH PRIVILEGES     语句才能使之生效。同样地,如果还有一个              MyISAM   表是   MERGE   表的一部

    分,那么必须在 slave 上手工执行          FLUSH TABLES    语句。从 MySQL 4.1.1 开始,这些语句都写入二进制日志了(除

    非指定选项    NO_WRITE_TO_BINLOG         或它的同名选项    LOCAL )。一些例外的情况是 FLUSH LOGS , FLUSH

    SLAVE , 和 FLUSH TABLES WITH READ LOCK          (它们中的任何一个同步到 slave 的话都可能导致问题)。例子

    可见"14.5.4.2   FLUSH   Syntax"。


•   MySQL 只支持一个 master 多个 slave 的机制。以后我们会增加一个表决算法,如果当前 master 出现问题时能自动切

    换。同时也会引进一个"代理"进程来帮助将                SELECT   查询发送到不同的 slave 上达到负载均衡。


•   当服务器关闭,重启后,所有的             MEMORY (HEAP ) 表都清空了。从 MySQL 4.0.18 开始,master 用以下方式同步它

    们:一旦 master 开始使用一个         MEMORY   表,它会在用完这些表之后在二进制日志中写入一个                DELETE FROM    语

    句告诉 slave 把它们删除。详情请看"15.3 The         MEMORY (HEAP ) Storage Engine"。


•   除非关闭 slave(只是关闭 slave 线程),临时表也会同步;并且在 slave 上已经记录了一些还未被执行的需要用到临时表

    的更新语句。关闭 slave 再重启后更新所需的临时表就不复存在了。为了避免这个问题,在有临时表时就不要关闭 slave。

    或者,使用以下步骤:




        1. 提交一个 STOP SLAVE 语句。
2. 使用 SHOW STATUS 语句检查变量 Slave_open_temp_tables 的值。

            3. 如果它的值是 0,运行 mysqladmin shutdown 命令关闭 slave。

            4. 如果它的值不是 0,用 START SLAVE 语句重启 slave 线程。

            5. 如果还有这样的好运气就再次执行同样的步骤吧。^_^




        我们会尽快解决这个问题。


•       如果在一个循环 master/slave 同步关系中指定     --log-slave-updates   选项,那么就可以安全地连接到各个服

        务器上。注意,很多语句可能在这种设置环境下不能正常工作,除非程序中已经特别注意避免这种更新时潜在的问题了,

        因为可能在不同服务器上不同的顺序上发生更新问题。这意味着可以设定像下面的循环:



    •    A -> B -> C -> A


        服务器 ID 都已经编码到二进制日志中了,因此服务器 A 知道那些自己创建的日志,从而不会去执行它们(除非在服务器

        A 上启动时增加      --replicate-same-server-id   选项,这个选项只在极少数情况下设置有意义)。因此,这就

        不会存在无限循环了。不过这个循环只有在更新表时没有发生冲突才不会发生问题。换言之,如果在 A 和 C 中同时插入一

        条记录,那么可能在 A 中不可能插入数据,因为它的键可能跟 C 的键冲突了。同样地,也不能在两个服务器上更新同一条

        记录,除非 2 次更新操作间有足够的时间间隔。




•       如果在 slave 上执行一个 SQL 语句后产生错误,那么 slave 的 SQL 线程就终止,然后它在错误日志中写入一条信息。可

        以连接到 slave 上,解决问题(例如,不存在表)后,运行        START SLAVE   语句重启它。


•       可以放心地关闭 master(干净地)之后再重启它。如果 slave 到 master 的连接断开了,它会立刻重连。如果失败了,

        slave 会定期重试(默认是每 60 秒重试一次,可通过      --master-connect-retry    选项来修改)。slave 也会处理

        网络断开的情况。不过,slave 会在      slave_net_timeout   秒之后如果还没收到来自 master 的数据才会当作网络

        断开的情况来处理。如果断开时间不长,可以减少            slave_net_timeout   的值。详情请看"5.2.3 Server System

        Variables"。
•   也可以放心地关闭 slave(干净地),它会记录停止的地方。不干净地关闭 slave 可能产生问题,特别是系统关闭了但缓存

    还没刷新到磁盘时。可以提供不间断电源来提高系统容错性。master 的不干净关闭可能导致表和二进制内容的不一致;如

    果是   InnoDB    表,使用   --innodb-safe-binlog     选项在 master 上就能避免这个问题。详情请看"5.9.4 The

    Binary Log"。


•   由于   MyISAM    表的非事务本质,就可能发生一个语句只更新了部分表就返回错误代码的情况。例如,一个多重插入语句

    中,有一条记录违反了约束键规则,一个更新语句在更新了一些记录后辈杀掉了。如果在 master 上发生这种情况了,那

    么 slave 线程会推出,等待数据库管理员决定要怎么做,除非这个错误代码是合法的并且这个语句的执行结果也是一样

    的错误代码。并没有关于错误代码是否合法的详细描述,一些错误代码可以用                         --slave-skip-errors      选项屏蔽

    掉。这个选项从 MySQL 3.23.47 开始就可以用了。


•   如果把非事务表同步到事务表时在一个              BEGIN/COMMIT   段内更新数据表了,如果在非事务表提交之前有其他线程更

    新它了,那么这个更新操作就不会正确地同步到二进制日志中。这是因为只有整个事务成功提交了才会写到二进制日志中。




•   在 4.0.15 之前,任何在非事务表的更新操作会在它执行的时候立刻写入到二进制日志中,然而事务表的更新只有在

    COMMIT   后才写入,ROLLBACK 的话就不写入了。因此在一些事务中更新事务表或非事务表时就需要考虑这个情况了

    (不只是同步时会碰到这个问题,想要把二进制日志作为备份时也一样)。 MySQL 4.0.15 中,我们已经修改了更新事务
                                     在

    和非事务表混合的情况下的日志记录行为,它解决了这个问题(对于二进制日志来说顺序地记录语句是比较不错的做法,

    所有必须的语句都会写进去,ROLLBACK 也一样)。当第二个连接更新非事务表而第一个连接的事务还没结束时,就会

    有同样的问题了;仍会发记录语句顺序发生错误的问题,因为第二个连接会在更新完成后立刻写入到日志中。



•   当 4.x 的 slave 从 3.23 的 master 上同步   LOAD DATA INFILE   时,SHOW   SLAVE STATUS   中的

    Exec_Master_Log_Pos      和   Relay_Log_Space   字段的值就不正确了。Exec_Master_Log_Pos 值

    不正确的话在重启 slave 之后会导致问题;因此最好在重启前修改一下这个值,只需在 master 上运行                      FLUSH

    LOGS 。这个 bug 在 MySQL 5.0.0 的 slave 中已经解决了。


         下表列出了 MySQL 3.23 同步时会发生的问题,它们在 MySQL 4.0 已经解决了:



•   LOAD DATA INFILE      能正确处理,只要那个数据文件在更新开始时仍然存在于 master 上。
•   LOAD DATA LOCAL INFILE   不再像以前 3.23 那样被略过了。


•   在 3.23 中,RAND() 更新同步不正常。因此在使用           RAND()   更新时采用   RAND(some_non_rand_expr)

    格式。例如,可以用       UNIX_TIMESTAMP()   作为   RAND()   的参数。




       6.8 同步启动选项

       不管是 master 还是 slave,都要设定   server-id    选项来确定使它们都有各自唯一的同步 ID。必须选择 1 到

       2^32-1 之间的正整数。例如:      server-id=3 。




       关于 master 服务器上可用于控制二进制日志记录的选项详细描述请看"5.9.4 The Binary Log"。




       下表描述了 slave 同步可用的选项,可以在命令行或者配置文件中设定它们。




       一些 slave 同步选项以特定的方式来处理,在 slave 启动时,如果存在              `master.info` 文件并且包含这些选项,

       那么 slave 将略过它们。这些选项如下:




•   --master-host

•   --master-user

•   --master-password

•   --master-port

•   --master-connect-retry
从 MySQL 4.1.1 开始,一下选项也按照上述方式特殊处理:



•   --master-ssl

•   --master-ssl-ca

•   --master-ssl-capath

•   --master-ssl-cert

•   --master-ssl-cipher

•   --master-ssl-key


       在 MySQL 4.1.1 中,   `master.info` 文件的格式改变了以包含相应的 SSL 选项。另外,MySQL 4.1.1 文件格

       式还包括了在第一行中的文件总行数。如果从旧版本升级到 4.1.1,那么服务器启动时会自动升级

       `master.info` 为新的格式。不过,如果是从 4.1.1 降级到旧版本,就需要在系统第一次启动时手工删除文件的

       第一行。注意,这种情况下,被降级的服务器就不能再使用 SSL 选项连接到 master 了。




       slave 启动时如果不存在      `master.info` 文件,它就使用在命令行或者配置文件中指定的参数值来启动。这在每

       次第一次启动 slave 服务器时都是这样,或者执行         RESET SLAVE   语句关闭且重启 slave 之后。




       slave 启动时如果存在      `master.info` 文件,那么它就略过这些选项,而是直接读取 `master.info` 文件

       中的值。




       如果重启 salve 时使用的选项值和      `master.info` 中的不一样,那么这个新的值不会生效,因为 slave 服务器

       还是照样只读取     `master.info` 文件。想要使用不同的选项值,可以在删除 `master.info` 后重启 slave 或

       者使用   CHANGE MASTER TO    语句(推荐)重置选项值。
假定在   `my.cnf` 设定了以下选项值:


 [mysqld]

 master-host=some_host


第一次启动 slave 的时候,它从       `my.cnf` 中读取选项值,然后再把它们保存在 `master.info` 中。下次重启

slave 时,它就只读取   `master.info` 的内容而略过 `my.cnf` 中的选项值了。企图修改 `my.cnf` 来改变

同步选项是不可行的,不过可以通过执行            CHANGE MASTER TO   语句来实现:




由于服务器认为     `master.info` 的优先级比配置文件高,因此建议根本不要在启动时附加同步选项,而只用

CHANGE MASTER TO    语句。详情请看"14.6.2.1   CHANGE MASTER TO   Syntax"。




下例显示了一些配置 slave 的扩展选项:




 [mysqld]

 server-id=2

 master-host=db-master.mycompany.com

 master-port=3306

 master-user=pertinax

 master-password=freitag

 master-connect-retry=60

 report-host=db-slave.mycompany.com
下列所述启动选项都是用来控制同步的:它们中的大部分都可以在运行时用                  CHANGE MASTER TO   语句来改变。

 其他的,例如   --replicate-* ,只能在 salve 启动时指定。我们打算在将来解决这个问题。




--log-slave-updates



  通常,slave 从 master 接收更新操作后并没有再把它们记录在二进制日志中。这个选项告诉 slave 的 SQL 线程要

  把这些更新操作记录在二进制日志中。想要这个选项起作用,需要同时启用                  --log-bin   选项才能启用二进制

  日志。在使用同步链机制时,就需要使用          --log-slave-updates   选项。例如,可能需要设置如下同步关

  系:




   A -> B -> C


  在这里,A 当作 B 的 master,B 当作 C 的 master。B 同时是 slave 又是 master,在 A 和 B 上都需要启用

  --log-bin   选项,并且在 B 上还需要启用    --log-slave-updates   选项。




  --log-warnings

  让 slave 在执行同步时记录更多的错误日志。例如,它会通知你在网络/连接失败后重连成功,并且通知了每个

  slave 线程如何启动的。这个选项在 MySQL 4.0.19 和 4.1.12 之后默认启用了;用      --skip-log-

  warnings   就可以禁用它。从 MySQL 4.0.21 和 MySQL 4.1.3 开始,除非这个选项的值大于 1,否则放弃的

  连接不再记录在错误日志中。这个选项不只是用于限制同步,它产生的警告跨越了大部分操作。



     --master-connect-retry= seconds

  在 master 当机或者网络连接中断后,slave 在重新连接到 master 之前休眠的秒数。如果在           `master.info`

  文件中存在,就优先使用它。如果没有设置,默认是 60。


       --master-host= host
master 服务器的主机名或者 ip 地址。如果没有设置它,slave 线程无法启动。如果存在的话,`master.info`

文件中选项值优先被读取。


          --master-info-file= file_name

slave 记录 master 信息的文件名。默认名字是          `master.info`,放在数据文件目录下。


                --master-password= password

用于被授权连接到 master 上运行同步的帐户密码。如果存在的话,`master.info` 文件中选项值优先被读取。

如果没有设置,就当作是空密码。


                  --master-port= port_number

master 上监听的 TCP/IP 端口号。如果存在的话,`master.info` 文件中选项值优先被读取。如果没有设置,

就当作预编译的设置。如果没有修改               configure   选项参数,那么就是 3306。


                        --master-ssl,--master-ssl-ca= file_name, --master-ssl-

                        capath= directory_name,

                        --master-ssl-cert= file_name, --master-ssl-

                        cipher= cipher_list, --master-ssl-key= file_name

用于设定用 SSL 安全连接到 master 的选项。它们的意义对应于"5.6.7.5 SSL Command-Line Options"中提到

的   --ssl , --ssl-ca , --ssl-capath , --ssl-cert , --ssl-cipher , --ssl-key   选项。

如果存在的话,`master.info` 文件中选项值优先被读取。这些选项是从 MySQL 4.1.1 之后开始可以用的。



                          --master-user= username

用于被授权连接到 master 上运行同步的帐户。这个帐户必须有                  REPLICATION SLAVE   权限(在 MySQL

4.0.2 以前,则是      FILE   权限)。如果存在的话,`master.info` 文件中选项值优先被读取。如果没有设置,就

当作是    test 。


                             --max-relay-log-size= #
中继日志自动轮转(rotate)的大小。详情请看"5.2.3 Server System Variables"。这个选项是从 MySQL 4.0.14

之后才可以用的。


                          --read-only

这个选项令 slave 除了 slave 线程或者拥有   SUPER   权限用户之外的都不能更新数据。这能确保 slave 不会接受

来自其他客户端的更新。这个选项是从 MySQL 4.0.14 开始有的。


                              --relay-log= file_name

中继日志的名字。默认名字是        host_name -relay-bin. nnn ,host_name 是 slave 服务器的主机名,

nnn 是指中继日志的顺序号。可以用这个选项创建不依赖主机名的中继日志,或者在中继日志越来越大(不想降低

max_relay_log_size   的值)且需要将它们放在非数据文件目录下,或者想使用磁盘间的负载均衡来提高

速度等情况。



                                --relay-log-index= file_name

中继日志索引文件的位置及文件名。它的默认值是             host_name -relay-bin.index ,host_name 是

slave 服务器主机名。


                                   --relay-log-info-file= file_name

slave 上记录中继日志信息的文件名。默认是数据文件目录下的`relay-log.info`。




                                       --relay-log-purge={0|1}

在不需要中继日志时禁用或启用自动清除。默认值是 1(启用)。这是一个全局变量,可以用                   SET GLOBAL

relay_log_purge   来动态更改。这个选项从 MySQL 4.1.1 开始可以用。


                                         --relay-log-space-limit= #

用于加大 slave 上中继日志的总大小(如果值为 0 表示"无限")。这在 slave 主机只有有限的空间时很有用。当达到

这个限制后,I/O 线程直到 SQL 线程删除一些无用的中继日志后才会继续从 master 读取二进制日志事件。注意,

这个限制不是绝对的:在删除中继日志之前,SQL 线程可能还需要更多的二进制日志事件。这种情况下,I/O 线程

会超越这个限制,直到 SQL 线程删除一些中继日志,因为如果不这么做的话就会导致死锁(在 MySQL 4.0.13 之
前就是这样)。不要设置     --relay-log-space-limit     的值小于 2 倍     --max-relay-log-size

(如果   --max-relay-log-size   的值为 0,则是   --max-binlog-size    ) 的值。在这种情况下,由

于已经超过    --relay-log-space-limit    了,I/O 线程需要等待更多的剩余空间,但是 SQL 线程没有

可以删除的中继日志来满足 I/O 线程的需求。这就会强制 I/O 线程暂时忽略             --relay-log-space-

limit   限制。


                                            --replicate-do-db= db_name

告诉 slave 只同步那些缺省数据库是 db_name (也就是用       USE    选中的)的语句。想要指定更多的数据库,只需

多次使用该选项,每次指定一个数据库。注意,类似              UPDATE some_db.some_table SET

foo='bar'   这样的跨库操作语句以及没有选中数据库的操作都不会被同步。如果必须使用跨库操作,要确保使

用 MySQL 3.23.28 或更高,并且使用     --replicate-wild-do-table= db_name .%   选项。请仔细

阅读最后面的注意事项。


下面是一个不能按照预期工作的例子:如果启动 slave 时使用            --replicate-do-db=sales    选项,并且

在 master 上执行下列语句,那么这个      UPDATE   语句不会被同步:




 USE prices;

 UPDATE sales.january SET amount=amount+1000;




如果需要同步跨库操作,只需使用         --replicate-wild-do-table= db_name .%     选项。这个"只检查

缺省数据库"特性的主要原因是因为想要单从一个语句中判断是否要被同步比较困难(例如,使用多表                         DELETE

或者    UPDATE ,这就跨库了)。不过想要检查是否是缺省数据库却很快。



                                                     --replicate-do-

                                                     table= db_name.tbl_nam

                                                     e
告诉 slave 只同步那些指定的数据表。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据表。这个

选项支持跨库更新,和      --replicate-do-db   选项相反。请仔细阅读最后面的注意事项。


                                                       --replicate-

                                                       ignore-db= db_name

告诉 slave 不要同步那些缺省数据库是 db_name (也就是用       USE   选中的)的语句。想要指定更多的数据库,只

需多次使用该选项,每次指定一个数据库。如果有跨库操作且希望这些操作要被同步就不要使用该选项。请仔细阅

读最后面的注意事项。



下面是一个不能按照预期工作的例子:如果启动 slave 时使用            --replicate-ignore-db=sales   选项,

并且在 master 上执行下列语句,那么这个       UPDATE   语句不会被同步:




 USE prices;

 UPDATE sales.january SET amount=amount+1000;




想要让跨库操作能正常同步,只需使用          --replicate-wild-ignore-table= db_name .%    选项。




                                                               --

                                                               replicate-

                                                               ignore-

                                                               table= db_n

                                                               ame.tbl_na

                                                               me


告诉 slave 不要同步指定数据表的任何更新语句(甚至用同一个语句更新的其他表)。想要指定更多的数据表,只需

多次使用该选项,每次指定一个数据表。这个选项支持跨库更新,和                  --replicate-ignore-db   选项相

反。请仔细阅读最后面的注意事项。
--

                                                                    replicat

                                                                    e-wild-

                                                                    do-

                                                                    table= db

                                                                    _name.tb

                                                                    l_name

限制 slave 只同步那些匹配指定模式的数据表。模式中可以包含通配符 `%` 和 `_`,它们的含义和                     LIKE   模

式一样。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据表。请仔细阅读最后面的注意事项。


例如:   --replicate-wild-do-table=foo%.bar%     会同步所有以   foo   开头的数据库下的以

bar   开头的数据表上的更新操作。


如果匹配模式是    % ,则匹配所有的表名,且应用到数据库级语句(CREATE DATABASE , DROP

DATABASE ,和 ALTER DATABASE )。例如,使用 --replicate-wild-do-table=foo%.%             选

项的话,所有匹配    foo%   模式的数据库级操作都会被同步。



如果想要在数据库/表模式中包含原义通配符,需要用反斜杠来转义它们。例如,想要同步                      my_own%db    数据库

下的所有表,但是不想同步       my1ownAABCdb   数据库下的表,就需要转义字符 `_`:        --replicate-

wild-do-table=my_own%db 。如果是在命令行中使用这个选项,就可能需要两个反斜杠来转义,这

依赖于命令行解释器。例如,在       bash   shell 下,就需要输入:   --replicate-wild-do-

table=my_own%db 。

                                                                                    --

                                                                                    re

                                                                                    pl

                                                                                    ic

                                                                                    at

                                                                                    e-
wi

                                                                         ld

                                                                         -

                                                                         ig

                                                                         no

                                                                         re

                                                                         -

                                                                         ta

                                                                         bl

                                                                         e=

                                                                         db

                                                                         _n

                                                                         am

                                                                         e.

                                                                         tb

                                                                         l_

                                                                         na

                                                                         me

限制 slave 不同步那些匹配指定模式的数据表。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据

表。请仔细阅读最后面的注意事项。


例如,--replicate-wild-ignore-table=foo%.bar% 就不会同步所有以       foo   开头的数据库

下的以   bar   开头的数据表上的更新操作。


想要了解匹配模式如何工作的,请查看        --replicate-wild-ignore-table   选项的具体描述。模式中

包含原义通配符的规则和      --replicate-wild-ignore-table   选项一样。


                                                                         --

                                                                         replicate
-rewrite-

                                                                           db= from_n

                                                                           ame -

                                                                           > to_name

告诉 slave 把在 master 上的缺省数据库 from_name (只有用   USE   选中的)转换成 to_name 。只有涉及到数

据表的语句(不包括类似      CREATE DATABASE , DROP DATABASE ,和 ALTER DATABASE )才会被同

步,并且只针对 master 上缺省数据库为 from_name 的情况。这个选项不支持跨库操作。注意,数据库名字转换

先于   --replicate-*   规则之前测试。如果是在命令行中使用这个选项,需要把 `>' 字符用引号引用起来。

例如:




 shell> mysqld --replicate-rewrite-db="olddb->newdb"


                                                                           --replica

                                                                           same-serv

                                                                           id


该选项用于 slave 之上。通常使用它的默认值 0,用于避免无限同步循环。如果设置为 1,那么 slave 就不会忽略那

些跟它有同样服务器编号的更新日志了;通常它只用于比较罕见的配置中。如果启用                     --log-slave-

updates   选项,则不能设置为 1。注意,从 MySQL 4.1 开始,slave 的 I/O 线程默认不把包含 slave 的服务器

编号的二进制日志写到中继日志中(相对 4.0 这能节省磁盘使用)。因此想要在 4.1 中使用              --replicate-

same-server-id   选项,在 slave 读取自己的更新事件让 SQL 线程来执行之前要确保启动 slave 时使用该

选项。



                                                                           --report-

                                                                           host= host

在 salve 注册时要报告的 master 主机名或 IP 地址。在 master 上执行    SHOW SLAVE HOSTS   语句时就会显

示出来了。如果不想 slave 注册到 master 就无需设置这个选项。注意,这在 slave 连接到 master 之后,只根据这
个配置 master 还不能直接从 TCP/IP 套接字中读取 slave 的 IP 地址。因为存在   NAT   或者其他路由机制,这个

IP 信息还不足以在 master 或者其他主机上连接到 slave 上。这个选项是从 MySQL 4.0.0 开始可以用的。


                                                                              --report-

                                                                              port= port

连接到 slave 的 TCP/IP 端口,在 slave 注册到 master 时用的到。除非 slave 在非默认端口上监听或者从

master 或其他客户端上到连接到 slave 使用的是特定的隧道,否则无需设置这个值。如果不确定,就不要设置它。

这个选项是从 MySQL 4.0.0 开始可以用的。



                                                                              --skip-sl

告诉 slave 服务器在启动时不要运行 slave 线程。只需使用    START SLAVE   语句来启动 slave 线程。




                                                                              --

                                                                              slave_com

                                                                              col={0|1}


如果它设置为 1,并且 maste/slave 都支持的话,就采用压缩协议传输数据。


                                                                              --slave-l

                                                                              tmpdir= fi

slave 创建临时文件的目录。这个选项值默认地和系统变量         tmpdir   的值一样。slave 的 SQL 线程同步   LOAD

DATA INFILE   语句时,它从中继日志中提取出要被加载的文件放到临时文件中,然后把它们加载到 slave 中。

如果在 master 上加载的文件很大,那么 slave 上的临时文件也会很大。因此建议在 slave 上指定这个选项时把它

放在剩余空间比较多的文件系统上。这是,最好也指定            --relay-log   到那个文件系统中,因为中继日志可能

也会很大。--slave-load-tmpdir 必须指向基于磁盘的文件系统,而不能是基于内存的文件系统:slave

可能会在机器重启后同步      LOAD DATA INFILE   语句时需要用到这个临时文件。这个目录同样不能在会被操

作系统的启动进程清除的目录下。



                                                                              --slave-n
salve 放弃读之后等待多少秒再次从 master 读取更多的数据,考虑到了连接断开,尝试重连的情况。第一次重试

  会在超时后立刻执行。重试的时间间隔由选项             --master-connect-retry   控制。


                                                                       --slave-s

                                                                       [ err_code

                                                                       all]


  通常,发生错误时同步就会停止,以提供手工解决数据不一致的情况。这个选项告诉 slave 的 SQL 线程当执行语

  句时返回的错误代码在该列表中时继续运行。


  除非真正的理解了为什么会产生相应的错误后,否则不要设置这个选项。如果同步设置以及客户端程序都没有

  bug,并且也不是 MySQL 自身的 bug 的话,那么就不会出现让同步停止的错误了。不加区分地使用这个选项,会

  导致 slave 无可救药地背离 master 的同步,并且你也不知道这是为什么。



  可以在从 slave 的错误日志并且在 slave 上执行     SHOW SLAVE STATUS   语句的结果中就能看到错误代码了。

  服务器错误代码详情请看"22 Error Handling in MySQL"。


  你也可以(最好不要)使用非常不推荐使用的值            all ,它能忽略所有的错误信息,不管什么情况都继续保持同步。

  不消说,如果使用这个选项值,就不可能期待有数据的完整性了。这种情况下,就不能抱怨 slave 的数据无论在哪

  个地方都和 master 不接近了。已经警告过你了。例如:



   --slave-skip-errors=1062,1053

   --slave-skip-errors=all


 --replicate-*   模式根据以下规则来决定一个语句是要执行还是被忽略:




1. 是否有 --replicate-do-db 或 --replicate-ignore-db 规则?
o    是:测试   --binlog-do-db   和   --binlog-ignore-db   选项(详情请看"5.9.4 The Binary


     Log")。测试结果?


    忽略:忽略并且退出。


    执行:不立刻执行,推迟判断,到下一步。




o    否:到下一步。




2. 是否有 --replicate-*-table 规则?




o    否:执行并且退出。


o    是:走到下一步。只有要被更新的表才和这个规则作比较(INSERT                 INTO sales SELECT * FROM

     prices :中只有 sales   和规则比较)。如果有好几个表一起被更新(多表语句),第一个匹配的表(匹配 `do`

     或 `ignore`)胜出。也就是说,只有第一个表和规则作比较。然后,如果还没有产生任何决定,就比较第二个表,

     以此类推。




3. 是否有 --replicate-do-table 规则?



o    是:这个表是否匹配这些规则?


    是:执行并且退出。


    否:走到下一步。
o    否:走到下一步。




4. 是否有 --replicate-ignore-table 规则?



o    是:这个表是否匹配这些规则?




    是:忽略并且退出。


    否:走到下一步。




o    否:走到下一步。




5. 是否有 --replicate-wild-do-table 规则?



o    是:这个表是否匹配这些规则?




    是:执行并且退出。


    否:走到下一步。




o    否:走到下一步。
6. 是否有 --replicate-wild-ignore-table 规则?



o    是:这个表是否匹配这些规则?




    是:忽略并且退出。


    否:走到下一步。




o    否:走到下一步。




7. 没有匹配 --replicate-*-table 规则。是否有其他表匹配这些规则?




o    是:循环查找匹配。


o    否:已经测试所有要被更新的表且找不到任何匹配规则。是否有          --replicate-do-table   或


     --replicate-wild-do-table   规则?




    是:忽略并且退出。


    否:执行并且退出。



 6.9 同步 FAQ

 问: master 还在运行中,如何在不停止它的情况下配置 slave?
答: 需要设计几个选项参数。如果已经有了 master 的备份并且记录了数据快照二进制日志文件名以及偏移位置(运

 行    SHOW MASTER STATUS   查看结果),执行以下步骤:




1. 确定 slave 指定了一个唯一的服务器编号。


2. 在 slave 上执行如下语句,把一些选项值改成实际值:


 3. mysql> CHANGE MASTER TO

 4.      ->     MASTER_HOST='master_host_name',

 5.      ->     MASTER_USER='master_user_name',

 6.      ->     MASTER_PASSWORD='master_pass',

 7.      ->     MASTER_LOG_FILE='recorded_log_file_name',


         ->     MASTER_LOG_POS=recorded_log_position;


8. 在 slave 上执行 START SLAVE 语句。



 如果事先没有备份 master 的数据,可以用以下方法快速创建一个备份。以下所有的操作都是在 master 上。




1. 提交语句:


 2. mysql> FLUSH TABLES WITH READ LOCK;


3. 确保这个锁一直存在,执行以下命令(或者其他类似的):
4. shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql


5. 执行以下语句,记录下输出的结果,后面要用到:


 6. mysql> SHOW MASTER STATUS;


7. 释放锁:




   mysql> UNLOCK TABLES;


 上述步骤的另一个办法是创建 master 的 SQL 转储文件。只需在 master 上执行        mysqldump --master-

 data   命令,然后将导出来的 SQL 转储文件载入 slave。不过,这么做会制作二进制数据快照的方式慢一点。




 无论使用上述两种方法的哪种,最后都能创建 master 的数据快照然后记录二进制日志文件名以及偏移位置。可以在

 好几的其他的 slave 上使用同一个备份的二进制数据快照。得到 master 的快照后,只要 master 的二进制日志完好

 无损,接着就能开始设置 slave 了。两个决定是否需要等待较长时间的限制是:在 master 上磁盘空间保存二进制日

 志,以及 slave 从 master 抓取更新事件。




 也可以使用    LOAD DATA FROM MASTER 。这个语句可以很方便地在 slave 上取得数据快照并且能立刻调整二

 进制日志文件名以及偏移位置。在将来,我们推荐用             LOAD DATA FROM MASTER   来设置 slave。警告,它只

 能用于    MyISAM   表,并且可能会保持一个较长时间的读锁。由于它还没达到所期望的高效率,因此如果数据表很

 大,最好还是在执行完        FLUSH TABLES WITH READ LOCK   后直接制作二进制数据快照。




 问:是否 slave 总是需要连接到 master?
答:不,非必需。slave 可以好几小时甚至几天关闭或者不连接 master,然后重连再取得更新操作日志。例如,可以

在拨号链接上设置一个 mater/slave 关系,拨号可能只是零星的不定期的连接。这种做法隐含的是,在任何指定的

时间里,除非使用特殊的度量标准,否则 slave 不能保证总是能和 master 保持同步。在未来,有个选项可以阻止

master,除非至少有一个 slave 在同步中。




问:怎么知道比 master 晚了多少?也就是说,怎么知道 slave 最后同步的时间?




答:如果 slave 是 4.1.1 或者更高,只需查看     SHOW SLAVE STATUS   结果中的

Seconds_Behind_Master   字段。对于老版本,可以用以下办法。如果在 slave 上执行            SHOW

PROCESSLIST   语句结果显示 SQL 线程(对 MySQL 3.23 则是 slave 线程)正在运行,这就意味着该线程至少从

master 读取一个更新操作事件。详情请看"6.3 Replication Implementation Details"。




当 SQL 线程执行一个 master 上读取的更新操作事件时,它把自己的时间改成事件的时间(这也就是

TIMESTAMP   也要同步的原因)。在

SHOW PROCESSLIST   结果中的   Time   字段中,slave 的 SQL 线程显示的秒数就是最后一次同步的时间戳和

slave 本机的实际时间相差秒数。可以根据这个值来判断最后同步的时间。注意,如果 slave 已经从 master 断开好几

个小时了,然后重新连接,就能看到 slave 的

SHOW PROCESSLIST   结果中的 SQL 线程的 Time 字段的值类似 3600。这是因为 slave 正在执行一个小时前

的语句。




问:如何强制 master 在 slave 赶上全部更新之前阻止更新操作?




答:执行以下步骤:
1. 在 master 上,执行以下语句:


 2. mysql> FLUSH TABLES WITH READ LOCK;


   mysql> SHOW MASTER STATUS;


  记录下结果中的日志文件名以及偏移位置,它们是同步的坐标值。



3. 在 slave 上,提交以下语句,MASTER_POS_WAIT() 函数的参数的值就是前面取得的同步坐标值:



 4. mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);


  SELECT   语句会阻止更新,直到 slave 同步到了上述日志文件及位置。在这个时候,slave 就和 master 保持同

  步了,并且这个语句就会返回。




5. 在 master 上,执行以下语句允许 master 重新处理更新操作:




   mysql> UNLOCK TABLES;


 问:设置一个双向复制时要注意什么问题?




 答:MySQL 同步目前还不支持任何在 master 和 slave 上的分布式(跨服务器)更新锁协议以保证操作的原子性。也

 就是说,存在这样的可能性:客户端 A 在并存的 master 1 上做了一个更新,同时,在它同步到并存 master 2 上

 之前,客户端 B 在 master 2 上可能也做了一个和客户端 A 在 master 1 上不同的更新操作。因此,当客户端 A 所做

 的更新同步到 master 2 时,它将产生和 master 1 上不同的数据表,尽管 master 2 上的更新操作也全都同步到
master 1 上去。这意味着除非能确保所有的更新都能以任何顺序安全地执行,否则不要使用双向同步,或者除非注

意在客户端程序中的不知原因的无序更新操作。




同时也要意识到在所关心的更新问题上,双向同步实际上并不能很大地改善性能(甚至没有)。两个服务器都需要执行

同样数量的更新操作,在一台服务器上也是。唯一区别的是,可能这样做会减少一些锁争夺,因为来自其他服务器的

更新操作都会被串行地放到 slave 线程中。甚至这种好处还可以作为网络延迟的补偿。




问:我如何利用同步来提高系统性能?




答:需要安装一个服务器作为 master 并且把所有的写操作直接放在这上面。然后配置多个廉价的使用机架磁盘的

slave,把读操作分配给 master 和 slave。还可以在启动 slave 时使用         --skip-innodb , --skip-bdb ,

--low-priority-updates ,和 --delay-key-write=ALL          选项来提高 slave 端的性能。这种情况

下,slave 会使用非事务的   MyISAM   表来代替   InnoDB   和   BDB   表,已取得更快速度。




问:如何准备客户端应用程序的代码来适应同步应用?




答:如果代码中负责存取数据库的部分已经被合理地抽象化/模块化了,将它们转化成适用运行于同步环境中将会很

平滑和简单。只需要修改数据库存取实现部分,把所有的写操作放到 master 上,把所有的读操作放到 master 或者

slave 上。如果你的代码还没达到这个层次的抽象化,那么这将成为整理代码的机会和动机。可以使用类似以下函数

创建封装类库或者模块:
•   safe_writer_connect()


•   safe_reader_connect()


•   safe_reader_statement()


•   safe_writer_statement()


       每个函数名的   safe_   表示它们会处理所有的错误情况。可以使用其他函数名。重要的是,要为读连接、写连接、读、

       写定义好统一的接口。




       然后将客户端代码转换成使用封装的类库。已开始可能是很痛苦且麻烦的,不过在将来长期运行中就能得到回报了。

       所有使用上述方法的应用程序都会在 master/slave 配置中有优势,即使包含多个 slave。这些代码将很容易维护,

       一些额外的麻烦也会很少。自豪需要修改一个或者两个函数;例如,想要记录每个语句执行了多长时间,或者在上千

       个语句中哪个出现错误了。




       如果已经写了很多代码,你可能想要自动转换它们,那么可以使用 MySQL 发布的    replace   工具,或者自己写

       转换脚本。理想地,你的代码已经使用了统一的编程风格。如果不是,最好重写它们,或者可以遍历检查一下,手工

       规范化一下代码风格。




       问:MySQL 同步何时且有多少能提高系统性能?
答:MySQL 同步对于频繁读但不频繁写的系统很有好处。理论上来讲,使用单一 master/多 slave 的配置,就可以

通过这个方法来衡量系统:增加更多的 slave 直到用完所有的网络带宽或者 master 的更新操作增长到了不能再处

理的点了。




想要知道增加多少个 slave 之后得到的性能才能平稳,以及能提高多少性能,就需要知道查询模式,并且根据经验

对典型的 master 和 slave 做读(每秒读或   max_reads )和写(max_write )基准测试得到它们之间的关系。下

例展示了一个理想系统取得的性能的简单计算方法。




设定系统负载由 10%写和 90%读组成,我们已经通过基准测试确定           max_reads   是 1200 - 2 *

max_writes 。换句话说,系统可以达到每秒做没有写的 1200 次读操作,写操作平均是读操作的 2 倍慢,它们

之间的关系是线性的。让我们假设 master 和每个 slave 都有同样的容量,有一个 master 和 N 个 slave。每个服务器

(master 或 slave):




reads = 1200 - 2 * writes




reads = 9 * writes / (N + 1)     (读是分开的,但是所有写是在所有的服务器上的)




9 * writes / (N + 1) + 2 * writes = 1200
writes = 1200 / (2 + 9/(N+1))




      最后的等式说明了 N 个 slave 的最大写数量,给它每分钟的最高读频率 1200 和 1 次写 9 次读的机率。




      分析结论比率如下:




•   如果 N = 0(意味着没有同步),系统大致可以处理每秒 1200/11 = 109 次写。


•   如果 N = 1,增加到每秒 184 次写。


•   如果 N = 8,增加到每秒 400 次写。


•   如果 N = 17,增加到每秒 480 次写。


•   最终,随着 N 接近无穷大(我们的预算为负无穷大),则可以达到几乎每秒 600 次写,大约提高系统吞吐量 5.5 倍。尽管

    如此,当有 8 台服务器时,已经提高了 4 倍了。


      注意,上面的计算是假设了网络带宽无穷大,并且忽略了一些系统中比较大的因素。在很多情况下,当系统增加 N

      个同步 slave 之后,是无法精确计算出上述预计结果的。不过,先看看下列问题将有助于你知道是否有和有多少系统

      性能上的改善:




•   系统读/写得比率是多少?


•   减少读操作后一个服务器能增加处理多少写操作?


•   你的网络带宽足够给多少 slave 使用?
问:如何利用同步提供冗余/高可用性?




             答:使用当前已经可用的特性,可以配置一个 master 和一个(或多个)slave,并且写一个脚本监控 master 是否运

             行着。然后通知应用程序和 slave 在发现错误时修改 master。一些建议如下:




•       使用   CHANGE MASTER TO      语句告诉 slave 修改 master。


•       一个让应用程序定位 master 所在主机的办法就是给 master 使用动态 DNS。例如 bind 就可以用             `nsupdate` 来动态

        更新 DNS。


•       使用   --log-bin        选项,不使用

        --log-slave-updates       选项来启动 slave。这样就能让 slave 运行   STOP SLAVE ; RESET MASTER   语句

        后随时准备变成 master,并且在其他 slave 上运行

        CHANGE MASTER TO 。例如,有以下配置方案:



    •              WC

    •               

    •                v

    •     WC----> M

    •              / | 

    •           /    |    

    •          v     v     v

    •         S1     S2    S3
M 表示 masetr,S 表示 slave,WC 表示提交读写操作的客户端;只提交读操作的客户端没有表示出来,因为它们无需

切换。S1,S2,S3 都是使用

--log-bin      选项,不用   --log-slave-updates        选项运行的 slave。由于除非指定     --log-slave-

updates     参数,否则从 master 读到的更新操作都不会记录到二进制日志中,因此每个 slave 上的二进制日志都是空

的。如果因为某些原因 M 不能用了,可以指定一个 slave 作为 master。例如,如果指定 S1,则所有的 WC 都要重定向

到 S1 上,S2 和 S3 都需要从 S1 上同步。



确定所有的 slave 都已经处理完各自的中继日志了。在每个 slave 上,提交                  STOP SLAVE IO_THREAD    语句,然

后检查    SHOW PROCESSLIST        的结果直到看到     Has read all relay log     了。当所有的 slave 都这样子

之后,就可以按照新的方案设置了。在 slave S1 上提交



STOP SLAVE     和   RESET MASTER      语句将其提升为 master。



在其他 slave S2 和 S3 上,提交        STOP SLAVE   和   CHANGE MASTER

TO MASTER_HOST='S1'       (   'S1'   代表 S1 的真实主机名) 语句修改 master。把 S2,S3 如何连接到 S1 的参数

(用户,密码,端口等)都附加到           CHANGE MASTER        后面。在

CHANGE MASTER      中无需指定 S1 的二进制日志文件名和偏移位置:因为                  CHANGE MASTER   默认就是第一个二

进制日志和偏移位置 4。最后,在 S2 和 S3 上提交               START SLAVE   语句。




然后让所有的 WC 都把他们的语句重定向到 S1 上。从这个时候开始,从所有的 WC 发送到 S1 上的更新语句都会写到 S1

的二进制日志中,它们包含了从 M 死掉之后发送到 S1 的全部更新语句。




配置结果如下:




          WC

        /

        |

  WC    |    M(unavailable)
|

            |

          v v

            S1<--S2   S3

             ^        |

             +-------+




    当 M 又起来了之后,只需在 M 上提交和在 S2 和 S3 上的一样的                CHANGE MASTER   语句,将它变成一个 slave 并且

    读取自从它死掉之后的全部 WC 提交的更新操作。想要把 M 重新变成 master(例如因为它的性能更好),就执行类似上面

    的操作,把 S1 当作失效了,把 M 提升为新的 master。在这个步骤中,别忘了在把 S2 和 S3 修改成为 M 的 slave 之前在

    M 上运行   RESET MASTER      语句。否则的话,它们会从 M 开始失效的那个时刻开始读取 WC 提交的更新操作日志。



      现在我们就运行着一个完整的自动选择 master 的 MySQL 同步系统,不过在它准备好之前,需要创建自己的监控

      工具。




      6.10 同步疑难解答

      如果按照上述步骤设定好同步之后,它不能正常工作的话,首先检查以下内容:




•   查看一下错入日志信息。不少用户都在这方面做得不够好以至于浪费时间。


•   master 是否在记录二进制日志?用          SHOW MASTER STATUS      检查一下状态。如果是,Position 的值不为零;

    否则,确定 master 上使用了        log-bin   和   server-id   选项。


•   slave 是否运行着?运行         SHOW SLAVE STATUS    语句检查
Slave_IO_Running   和   Slave_SQL_Running   的值是否都是。如果不是,确定是否用同步参数启动 slave

    服务器了。




•   如果 slave 正在运行,它是否建立了到 master 的连接?运行

    SHOW PROCESSLIST   语句检查 I/O 和 SQL 线程的   State   字段值。详情请看"6.3 Replication Implementation

    Details"。如果 I/O 线程状态为   Connecting to master ,就检查一下 master 上同步用户的权限是否正确,

    master 的主机名,DNS 设置,master 是否确实正在运行着,以及 slave 是否可连接到 master,等等。


•   如果 slave 以前运行着,但是现在停止了,原因通常是一些语句在 master 上能成功但在 slave 上却失败了。如果 salve

    已经取得了 master 的全部快照,并且除了 slave 线程之外不会修改他的数据,那么应该不会发生这样的情形。如果确实

    发生了,那么可能是一个 bug 或者你碰到了"6.7 Replication Features and Known Problems"中提到的同步限制之

    一。如果是一个 bug,那么请按照"6.11 Reporting Replication Bugs"的说明报告它。


•   如果一个语句在 master 上成功了,但是在 slave 上却失败了,并且这时不能做一次完整的数据库再同步(也就是删除

    slave 上的数据,重新拷贝 master 的快照),那么试一下:


       1. 判断 slave 的数据表是否和 master 的不一样。试着找到怎么会发生这种情况,然后将 slave 的表同步成和

          master 一样之后运行     START SLAVE 。

       2. 如果上述步骤不生效或者没有执行,试着这个语句是否能被手工安全地运行(如果有必要),然后忽略 master

          的下一个语句。


       3. 如果决定要忽略 master 的下一个语句,只需在 slave 上提交以下语句:


         4. mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;


            mysql> START SLAVE;


          如果下一个语句没有使用         AUTO_INCREMENT   或   LAST_INSERT_ID() ,那么 n    的值应为为    1 。否

          则,它的值为    2 。设定为 2   是因为   AUTO_INCREMENT    或   LAST_INSERT_ID()   在 master 的二进

          制日志中占用了 2 条日志。
5. 如果确定 slave 精确地同步 master 了,并且没有除了 slave 线程之外的对数据表的更新操作,则推断这是因

     为 bug 产生的差异。如果是使用最近的版本,请报告这个问题,如果使用的是旧版本,试着升级一下。




 6.11 报告同步 Bugs

 当确定没有包含用户的错误,并且同步还是不能正常工作或者不稳定,就可以报告 bug 了。我们需要你尽量多的跟

 踪 bug 的信息。请花点时间和努力准备一个好的 bug 报告。




 如果有一个演示 bug 的可重现测试案例的话,请进入我们的 bug 数据库 http://bugs.mysql.com/。如果碰到一个

 幽灵般的问题(不可重现),请按照如下步骤:




1. 确定没有包含用户错误。例如,在 slave 线程以外更新 slave 的数据,那么数据就会不能保持同步,也可能会导致

    违反更新时的唯一键问题。这是外部干涉导致同步失败的问题。


2. 使用 --log-slave-updates 和 --log-bin 选项启动 slave。这会导致 slave 将从 master 读取的更

    新操作写到自己的二进制日志中。


3. 在重设同步状态之前保存所有的证据。如果我们没有任何信息或者只有粗略的信息,这将很难或者不可能追查到这

    个问题。需要收集以下证据:




o   master 上的所有二进制日志


o   slave 上的所有二进制日志
o    发现问题时,在 master 上执行          SHOW MASTER STATUS   的结果



       o    发现问题时,在 master 上执行          SHOW SLAVE STATUS   的结果


       o    记录 master 和 slave 的错误日志




      4. 用 mysqlbinlog 来检查二进制日志。例如,用以下方法有助于找到有问题的查询:



       5. shell> mysqlbinlog -j pos_from_slave_status 

       6.                /path/to/log_from_slave_status | head


       一旦收集好了问题的证据,首先将它隔离到一个独立的测试系统上。然后在我们的 bug 数据库

       http://bugs.mysql.com/上进可能详细地报告问题。




       ‹ MySQL 同步(四)up


•   MySQL 文档翻译


•   Add new comment



Comments

       Thu, 2007/07/05 - 11:10 — junphine (not verified)



       我想问一下,数据库
我想问一下,数据库同步需要库中的表结构相同,那么我能不能在 Master 上的表中的某个字段不设索引,而在

            slave 上建索引?

            还有同步会不会将 Slave 中已经存在的数据删除掉(这些数据的 key 和 Master 不同)?



•   reply


            Thu, 2007/07/05 - 18:56 — yejr



            1. 可以 2.


            1. 可以

            2. 如果 master 上有删除数据的操作,那么 slave 也会跟着做的




            MySQL 方案、培训、支持



            给你的祝福,要让你招架不住!



    •   reply


            Fri, 2007/01/26 - 11:56 — 游客 (not verified)



            你好。我想咨询一下


            你好。

            我想咨询一下,在同步的时候,电脑断电了,重新启动电脑后不能再同步,要重新设置 MASTER_LOG_FILE 和

            MASTER_LOG_POS 值才可以继续同步。

            请问有什么设置或者方法可以使同步在电脑突然断电重启后还能正常进行?



•   reply


            Fri, 2007/01/26 - 14:24 — yejr
老规矩,先贴上报错


     老规矩,先贴上报错信息,mysql 版本,配置等资料。



     MySQL 中文网: http://imysql.cn

     Google MySQL 中文用户群:http://groups.google.com/group/imysql




     给你的祝福,要让你招架不住!



•   reply


     Sat, 2007/01/27 - 11:11 — 游客 (not verified)



     感谢你抽空解答我的


     感谢你抽空解答我的问题。下面这些就是版本,错误信息及设置。我刚接触 mysql,请多多指教。

     版本:mysql 5.0.20-nt




     *.err 的错误信息:

     070127 10:25:11 InnoDB: Database was not shut down normally!

     InnoDB: Starting crash recovery.

     InnoDB: Reading tablespace information from the .ibd files...

     InnoDB: Restoring possible half-written data pages from the doublewrite

     InnoDB: buffer...

     070127 10:26:22 InnoDB: Starting log scan based on checkpoint at

     InnoDB: log sequence number 8 3059764932.

     InnoDB: Doing recovery: scanned up to log sequence number 8 3065007616

     InnoDB: Doing recovery: scanned up to log sequence number 8 3070250496

     InnoDB: Doing recovery: scanned up to log sequence number 8 3075493376
InnoDB: Doing recovery: scanned up to log sequence number 8 3077233098

070127 10:26:24 InnoDB: Starting an apply batch of log records to the database...

InnoDB: Progress in percents: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

98 99

InnoDB: Apply batch completed

InnoDB: In a MySQL replication slave the last master binlog file

InnoDB: position 0 47510, file name My binLog.000051

InnoDB: Last MySQL binlog file position 0 319593, file name .My binLog.000001

070127 10:26:29 InnoDB: Started; log sequence number 8 3077233098

070127 10:26:30 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may

break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-

log=tests8000-02-relay-bin' to avoid this problem.

070127 10:26:30 [Note] D:GreenampMySQLbinmysqld-nt: ready for connections.

Version: '5.0.20-nt' socket: '' port: 3308 MySQL Community Edition (GPL)

070127 10:26:30 [Note] Slave SQL thread initialized, starting replication in log 'My binLog.000051'

at position 31899609, relay log '.tests8000-02-relay-bin.000029' position: 31890015

070127 10:26:30 [ERROR] Error in Log_event::read_log_event(): 'Event too small', data_len: 0,

event_type: 0

070127 10:26:30 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O

error

070127 10:26:30 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are:

the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log),

the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a

network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's

binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE
STATUS' on this slave. Error_code: 0

070127 10:26:30 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and

restart the slave SQL thread with "SLAVE START". We stopped at log 'My binLog.000051' position

31899609

070127 10:26:31 [ERROR] Slave I/O thread: error connecting to master 'Ad@localhost:3306':

Error: 'Can't connect to MySQL server on 'localhost' (10061)' errno: 2003 retry-time: 60 retries:

86400

070127 10:27:31 [Note] Slave I/O thread: connected to master 'Ad@localhost:3306', replication

started in log 'My binLog.000051' at position 31899609




但在 slave 端用 show slave status,则显示如下内容:

mysql> show slave statusG

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: localhost

Master_User: Ad

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: My binLog.000052

Read_Master_Log_Pos: 260

Relay_Log_File: tests8000-02-relay-bin.000029

Relay_Log_Pos: 31890015

Relay_Master_Log_File: My binLog.000051

Slave_IO_Running: Yes

Slave_SQL_Running: No

Replicate_Do_DB:

Replicate_Ignore_DB:
My sql 同步
My sql 同步
My sql 同步
My sql 同步
My sql 同步
My sql 同步
My sql 同步
My sql 同步
My sql 同步

Mais conteúdo relacionado

Mais procurados

为10g rac cluster添加节点
为10g rac cluster添加节点为10g rac cluster添加节点
为10g rac cluster添加节点maclean liu
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理Lixun Peng
 
MySQL Replication新功能介绍
MySQL Replication新功能介绍 MySQL Replication新功能介绍
MySQL Replication新功能介绍 orczhou
 
Mysql proxy cluster
Mysql proxy clusterMysql proxy cluster
Mysql proxy clusterYiwei Ma
 
Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作maclean liu
 
Database.Cache&Buffer&Lock
Database.Cache&Buffer&LockDatabase.Cache&Buffer&Lock
Database.Cache&Buffer&LockLixun Peng
 
使用Rpm&yum进行基础软件管理
使用Rpm&yum进行基础软件管理使用Rpm&yum进行基础软件管理
使用Rpm&yum进行基础软件管理haiyuan ning
 
五款常用mysql slow log分析工具的比较
五款常用mysql slow log分析工具的比较 五款常用mysql slow log分析工具的比较
五款常用mysql slow log分析工具的比较 colderboy17
 
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11gOracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11gChien Chung Shen
 
Google mysql-tools overview
Google mysql-tools overviewGoogle mysql-tools overview
Google mysql-tools overviewPickup Li
 
第一讲 My sql初步
第一讲 My sql初步第一讲 My sql初步
第一讲 My sql初步hjl888666
 
Cent os 安装 subversion
Cent os 安装 subversionCent os 安装 subversion
Cent os 安装 subversionYUCHENG HU
 
Cassandra运维之道(office2003)
Cassandra运维之道(office2003)Cassandra运维之道(office2003)
Cassandra运维之道(office2003)haiyuan ning
 
MySQL基础技能与原理——高级应用
MySQL基础技能与原理——高级应用MySQL基础技能与原理——高级应用
MySQL基础技能与原理——高级应用Michael Zhang
 
MySQL新技术探索与实践
MySQL新技术探索与实践MySQL新技术探索与实践
MySQL新技术探索与实践Lixun Peng
 

Mais procurados (19)

为10g rac cluster添加节点
为10g rac cluster添加节点为10g rac cluster添加节点
为10g rac cluster添加节点
 
Sae
SaeSae
Sae
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理
 
MySQL Replication新功能介绍
MySQL Replication新功能介绍 MySQL Replication新功能介绍
MySQL Replication新功能介绍
 
Mysql proxy cluster
Mysql proxy clusterMysql proxy cluster
Mysql proxy cluster
 
Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作
 
Database.Cache&Buffer&Lock
Database.Cache&Buffer&LockDatabase.Cache&Buffer&Lock
Database.Cache&Buffer&Lock
 
使用Rpm&yum进行基础软件管理
使用Rpm&yum进行基础软件管理使用Rpm&yum进行基础软件管理
使用Rpm&yum进行基础软件管理
 
五款常用mysql slow log分析工具的比较
五款常用mysql slow log分析工具的比较 五款常用mysql slow log分析工具的比较
五款常用mysql slow log分析工具的比较
 
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11gOracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
 
Google mysql-tools overview
Google mysql-tools overviewGoogle mysql-tools overview
Google mysql-tools overview
 
第一讲 My sql初步
第一讲 My sql初步第一讲 My sql初步
第一讲 My sql初步
 
Mysql集群
Mysql集群Mysql集群
Mysql集群
 
Aswan&hump
Aswan&humpAswan&hump
Aswan&hump
 
Cent os 安装 subversion
Cent os 安装 subversionCent os 安装 subversion
Cent os 安装 subversion
 
Cvs
CvsCvs
Cvs
 
Cassandra运维之道(office2003)
Cassandra运维之道(office2003)Cassandra运维之道(office2003)
Cassandra运维之道(office2003)
 
MySQL基础技能与原理——高级应用
MySQL基础技能与原理——高级应用MySQL基础技能与原理——高级应用
MySQL基础技能与原理——高级应用
 
MySQL新技术探索与实践
MySQL新技术探索与实践MySQL新技术探索与实践
MySQL新技术探索与实践
 

Destaque

Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"
Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"
Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"St. Petersburg Foundation for SME Development
 
Организационно правовые формы предприятий, налогообложение, управление финанс...
Организационно правовые формы предприятий, налогообложение, управление финанс...Организационно правовые формы предприятий, налогообложение, управление финанс...
Организационно правовые формы предприятий, налогообложение, управление финанс...St. Petersburg Foundation for SME Development
 
Alibaba server-zhangxuseng-qcon
Alibaba server-zhangxuseng-qconAlibaba server-zhangxuseng-qcon
Alibaba server-zhangxuseng-qconYiwei Ma
 
Claiming your Facebook Place
Claiming your Facebook PlaceClaiming your Facebook Place
Claiming your Facebook Placelinkup marketing
 
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...St. Petersburg Foundation for SME Development
 
Aristotle, the Rhetoric, Book II - Audience
Aristotle, the Rhetoric, Book II  - AudienceAristotle, the Rhetoric, Book II  - Audience
Aristotle, the Rhetoric, Book II - AudiencewritRHET -
 

Destaque (10)

Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"
Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"
Виртуальная ИТ-инфраструктура предприятия на базе свободного ПО "под ключ"
 
экспорт на рынок ес знак се
экспорт на рынок ес   знак сеэкспорт на рынок ес   знак се
экспорт на рынок ес знак се
 
Организационно правовые формы предприятий, налогообложение, управление финанс...
Организационно правовые формы предприятий, налогообложение, управление финанс...Организационно правовые формы предприятий, налогообложение, управление финанс...
Организационно правовые формы предприятий, налогообложение, управление финанс...
 
Alibaba server-zhangxuseng-qcon
Alibaba server-zhangxuseng-qconAlibaba server-zhangxuseng-qcon
Alibaba server-zhangxuseng-qcon
 
Doing.business.in.st.petersburg.2012
Doing.business.in.st.petersburg.2012Doing.business.in.st.petersburg.2012
Doing.business.in.st.petersburg.2012
 
Claiming your Facebook Place
Claiming your Facebook PlaceClaiming your Facebook Place
Claiming your Facebook Place
 
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...
Деловые возможности региона Тампере - Кари Канкаала, Директор экономического ...
 
Rubicon Forum 2014 Sponsorship package (English language)
Rubicon Forum 2014 Sponsorship package (English language)Rubicon Forum 2014 Sponsorship package (English language)
Rubicon Forum 2014 Sponsorship package (English language)
 
Рубикон Форму 2014 - Спонсорский пакет
Рубикон Форму 2014 - Спонсорский пакетРубикон Форму 2014 - Спонсорский пакет
Рубикон Форму 2014 - Спонсорский пакет
 
Aristotle, the Rhetoric, Book II - Audience
Aristotle, the Rhetoric, Book II  - AudienceAristotle, the Rhetoric, Book II  - Audience
Aristotle, the Rhetoric, Book II - Audience
 

Semelhante a My sql 同步

备库预热工具relayfetch介绍及性能测试
备库预热工具relayfetch介绍及性能测试备库预热工具relayfetch介绍及性能测试
备库预热工具relayfetch介绍及性能测试zhaiwx1987
 
test
testtest
testxieyq
 
3, OCP - instance management
3, OCP - instance management3, OCP - instance management
3, OCP - instance managementted-xu
 
深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)wang hongjiang
 
数据库性能诊断的七种武器
数据库性能诊断的七种武器数据库性能诊断的七种武器
数据库性能诊断的七种武器Leyi (Kamus) Zhang
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江thinkinlamp
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysqlpwesh
 
7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recoveryted-xu
 
1, OCP - architecture intro
1, OCP - architecture intro1, OCP - architecture intro
1, OCP - architecture introted-xu
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开longxibendi
 
A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题WASecurity
 
11g r2新特性之standby max_data_delay
11g r2新特性之standby max_data_delay11g r2新特性之standby max_data_delay
11g r2新特性之standby max_data_delaymaclean liu
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记yiditushe
 
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用hugo
 
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletServlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletJustin Lin
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料yiditushe
 
Struts快速学习指南
Struts快速学习指南Struts快速学习指南
Struts快速学习指南yiditushe
 
百度分布式数据实践与进展
百度分布式数据实践与进展百度分布式数据实践与进展
百度分布式数据实践与进展yp_fangdong
 
11g新特性streams同步捕获
11g新特性streams同步捕获11g新特性streams同步捕获
11g新特性streams同步捕获maclean liu
 

Semelhante a My sql 同步 (20)

备库预热工具relayfetch介绍及性能测试
备库预热工具relayfetch介绍及性能测试备库预热工具relayfetch介绍及性能测试
备库预热工具relayfetch介绍及性能测试
 
test
testtest
test
 
3, OCP - instance management
3, OCP - instance management3, OCP - instance management
3, OCP - instance management
 
深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)
 
数据库性能诊断的七种武器
数据库性能诊断的七种武器数据库性能诊断的七种武器
数据库性能诊断的七种武器
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysql
 
7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery
 
1, OCP - architecture intro
1, OCP - architecture intro1, OCP - architecture intro
1, OCP - architecture intro
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开
 
A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题
 
11g r2新特性之standby max_data_delay
11g r2新特性之standby max_data_delay11g r2新特性之standby max_data_delay
11g r2新特性之standby max_data_delay
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记
 
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用
 
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 ServletServlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料
 
Jsp
JspJsp
Jsp
 
Struts快速学习指南
Struts快速学习指南Struts快速学习指南
Struts快速学习指南
 
百度分布式数据实践与进展
百度分布式数据实践与进展百度分布式数据实践与进展
百度分布式数据实践与进展
 
11g新特性streams同步捕获
11g新特性streams同步捕获11g新特性streams同步捕获
11g新特性streams同步捕获
 

Mais de Yiwei Ma

Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconYiwei Ma
 
Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconYiwei Ma
 
Taobao casestudy-yufeng-qcon
Taobao casestudy-yufeng-qconTaobao casestudy-yufeng-qcon
Taobao casestudy-yufeng-qconYiwei Ma
 
Zhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconZhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconYiwei Ma
 
Taobao practice-liyu-qcon
Taobao practice-liyu-qconTaobao practice-liyu-qcon
Taobao practice-liyu-qconYiwei Ma
 
Thoughtworks practice-hukai-qcon
Thoughtworks practice-hukai-qconThoughtworks practice-hukai-qcon
Thoughtworks practice-hukai-qconYiwei Ma
 
Ufida design-chijianqiang-qcon
Ufida design-chijianqiang-qconUfida design-chijianqiang-qcon
Ufida design-chijianqiang-qconYiwei Ma
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qconYiwei Ma
 
Netflix web-adrian-qcon
Netflix web-adrian-qconNetflix web-adrian-qcon
Netflix web-adrian-qconYiwei Ma
 
Google arch-fangkun-qcon
Google arch-fangkun-qconGoogle arch-fangkun-qcon
Google arch-fangkun-qconYiwei Ma
 
Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconYiwei Ma
 
Alibaba arch-jiangtao-qcon
Alibaba arch-jiangtao-qconAlibaba arch-jiangtao-qcon
Alibaba arch-jiangtao-qconYiwei Ma
 
Twitter keynote-evan-qcon
Twitter keynote-evan-qconTwitter keynote-evan-qcon
Twitter keynote-evan-qconYiwei Ma
 
Netflix keynote-adrian-qcon
Netflix keynote-adrian-qconNetflix keynote-adrian-qcon
Netflix keynote-adrian-qconYiwei Ma
 
Facebook keynote-nicolas-qcon
Facebook keynote-nicolas-qconFacebook keynote-nicolas-qcon
Facebook keynote-nicolas-qconYiwei Ma
 
Domainlang keynote-eric-qcon
Domainlang keynote-eric-qconDomainlang keynote-eric-qcon
Domainlang keynote-eric-qconYiwei Ma
 
Devjam keynote-david-qcon
Devjam keynote-david-qconDevjam keynote-david-qcon
Devjam keynote-david-qconYiwei Ma
 
Baidu keynote-wubo-qcon
Baidu keynote-wubo-qconBaidu keynote-wubo-qcon
Baidu keynote-wubo-qconYiwei Ma
 
淘宝线上线下性能跟踪体系和容量规划-Qcon2011
淘宝线上线下性能跟踪体系和容量规划-Qcon2011淘宝线上线下性能跟踪体系和容量规划-Qcon2011
淘宝线上线下性能跟踪体系和容量规划-Qcon2011Yiwei Ma
 
网游服务器性能优化-Qcon2011
网游服务器性能优化-Qcon2011网游服务器性能优化-Qcon2011
网游服务器性能优化-Qcon2011Yiwei Ma
 

Mais de Yiwei Ma (20)

Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qcon
 
Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qcon
 
Taobao casestudy-yufeng-qcon
Taobao casestudy-yufeng-qconTaobao casestudy-yufeng-qcon
Taobao casestudy-yufeng-qcon
 
Zhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconZhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qcon
 
Taobao practice-liyu-qcon
Taobao practice-liyu-qconTaobao practice-liyu-qcon
Taobao practice-liyu-qcon
 
Thoughtworks practice-hukai-qcon
Thoughtworks practice-hukai-qconThoughtworks practice-hukai-qcon
Thoughtworks practice-hukai-qcon
 
Ufida design-chijianqiang-qcon
Ufida design-chijianqiang-qconUfida design-chijianqiang-qcon
Ufida design-chijianqiang-qcon
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qcon
 
Netflix web-adrian-qcon
Netflix web-adrian-qconNetflix web-adrian-qcon
Netflix web-adrian-qcon
 
Google arch-fangkun-qcon
Google arch-fangkun-qconGoogle arch-fangkun-qcon
Google arch-fangkun-qcon
 
Cibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qconCibank arch-zhouweiran-qcon
Cibank arch-zhouweiran-qcon
 
Alibaba arch-jiangtao-qcon
Alibaba arch-jiangtao-qconAlibaba arch-jiangtao-qcon
Alibaba arch-jiangtao-qcon
 
Twitter keynote-evan-qcon
Twitter keynote-evan-qconTwitter keynote-evan-qcon
Twitter keynote-evan-qcon
 
Netflix keynote-adrian-qcon
Netflix keynote-adrian-qconNetflix keynote-adrian-qcon
Netflix keynote-adrian-qcon
 
Facebook keynote-nicolas-qcon
Facebook keynote-nicolas-qconFacebook keynote-nicolas-qcon
Facebook keynote-nicolas-qcon
 
Domainlang keynote-eric-qcon
Domainlang keynote-eric-qconDomainlang keynote-eric-qcon
Domainlang keynote-eric-qcon
 
Devjam keynote-david-qcon
Devjam keynote-david-qconDevjam keynote-david-qcon
Devjam keynote-david-qcon
 
Baidu keynote-wubo-qcon
Baidu keynote-wubo-qconBaidu keynote-wubo-qcon
Baidu keynote-wubo-qcon
 
淘宝线上线下性能跟踪体系和容量规划-Qcon2011
淘宝线上线下性能跟踪体系和容量规划-Qcon2011淘宝线上线下性能跟踪体系和容量规划-Qcon2011
淘宝线上线下性能跟踪体系和容量规划-Qcon2011
 
网游服务器性能优化-Qcon2011
网游服务器性能优化-Qcon2011网游服务器性能优化-Qcon2011
网游服务器性能优化-Qcon2011
 

Último

函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptxNCU MCL
 
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】黑客 接单【TG/微信qoqoqdqd】
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptxNCU MCL
 
20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLPJamie (Taka) Wang
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptxNCU MCL
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxNCU MCL
 
20161220 - domain-driven design
20161220 - domain-driven design20161220 - domain-driven design
20161220 - domain-driven designJamie (Taka) Wang
 
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxNCU MCL
 
20170104 - transaction_pattern
20170104 - transaction_pattern20170104 - transaction_pattern
20170104 - transaction_patternJamie (Taka) Wang
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptxNCU MCL
 

Último (15)

20161027 - edge part2
20161027 - edge part220161027 - edge part2
20161027 - edge part2
 
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
 
20200323 - AI Intro
20200323 - AI Intro20200323 - AI Intro
20200323 - AI Intro
 
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
 
20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP
 
20151111 - IoT Sync Up
20151111 - IoT Sync Up20151111 - IoT Sync Up
20151111 - IoT Sync Up
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
 
20200226 - AI Overview
20200226 - AI Overview20200226 - AI Overview
20200226 - AI Overview
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
 
20161220 - domain-driven design
20161220 - domain-driven design20161220 - domain-driven design
20161220 - domain-driven design
 
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
 
Entities in DCPS (DDS)
Entities in DCPS (DDS)Entities in DCPS (DDS)
Entities in DCPS (DDS)
 
20170104 - transaction_pattern
20170104 - transaction_pattern20170104 - transaction_pattern
20170104 - transaction_pattern
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
 

My sql 同步

  • 1. MySQL 同步 6 MySQL 同步 同步功能在 MySQL 3.23.15 就开始引进了,它可以把一个 MySQL 服务器上的数据复制到另一个服务器上去。本章 描述了 MySQL 的各种复制特性。介绍了同步的概念,如何设置同步服务器,以及可用服务器的参照。还提供了一系 列的常见问题及其答案,疑难解答。 "14.6 Replication Statements"中介绍了同步相关的 SQL 语句语法。 我们建议经常访问"http://www.mysql.com"经常阅读本章的最新内容。同步功能一直在改进,我们经常把这部分 的手册更新到当前的最新内容。 6.1 同步介绍 MySQL 3.23.15 及更高的版本支持单向同步。一个服务器作为 master(主服务器),一个或者多个服务器作为 slave(从服务器)。master 服务器把更新的内容写到二进制日志(binary log 或 binlog)中,并且维护了一个索引文 件来记录日志循环的情况。这些日志中的更新部分会被发送到 slave 服务器。一个 slave 连接到 master 之后,它通 知 master 最后一次成功增量更新的日志位置。slave 会找出所有从那个时刻开始的更新操作,然后阻塞并等待 master 发送新的更新操作。 如果想要做一个同步服务器链的话,slave 同时也可以作为 master。 注意,启用同步后,所有要同步的更新操作都必须在 master 上执行。否则,必须注意不要造成用户在 master 上的 更新和在 slave 上的更新引起冲突。 单向同步的好处是稳健,高速,系统易管理:
  • 2. 有了 master/slave 机制后,就更稳健了。当 master 上发生问题时,可以把 slave 作为备用切换过去。 • 可以在 slave 和 master 之间分担一些查询,这就能加速响应时间。SELECT 查询就可以在 slave 上执行以减少 master 的负载。更新数据的语句则要放在 mater 上执行以保持 master 和 slave 的同步。当非更新操作占多数时,负载均衡就很 有效了,不过这只是普通情况而言。 • 另一个好处是可以在 slave 上备份数据,无需干扰 master。备份数据时 master 照样继续运作。详情请看"5.7.1 Database Backups"。 6.2 同步机制实现概述 MySQL 同步机制基于 master 把所有对数据库的更新、删除 等)都记录在二进制日志里。因此,想要启用同步机制, 在 master 就必须启用二进制日志。详情请看"5.9.4 The Binary Log"。 每个 slave 接受来自 master 上在二进制日志中记录的更新操作,因此在 slave 上执行了这个操作的一个拷贝。 应该非常重要地意识到,二进制日志只是从启用二进制日志开始的时刻才记录更新操作的。所有的 slave 必须在启 用二进制日志时把 master 上已经存在的数据拷贝过来。如果运行同步时 slave 上的数据和 master 上启用二进制 日志时的数据不一致的话,那么 slave 同步就会失败。 把 master 上的数据拷贝过来的方法之一实在 slave 上执行 LOAD DATA FROM MASTER 语句。不过要注意, LOAD DATA FROM MASTER 是从 MySQL 4.0.0 之后才开始可以用的,而且只支持 master 上的 MyISAM 类型表。同样地,这个操作需要一个全局的读锁,这样的话传送日志到 slave 的时候在 master 上就不会有更新操作 了。当实现了自由锁表热备份时(在 MySQL 5.0 中),全局读锁就没必要了。 由于有这些限制,因此我们建议只在 master 上相关数据比较小的时候才执行 LOAD DATA FROM MASTER 语句,或者在 master 上允许一个长时间的读锁。由于每个系统之间 LOAD DATA FROM MASTER 的速度各 不一样,一个比较好的衡量规则是每秒能拷贝 1MB 数据。这只是的粗略的估计,不过 master 和 slave 都是奔腾 700MHz 的机器且用 100MBit/s 网络连接时就能达到这个速度了。
  • 3. slave 上已经完整拷贝 master 数据后,就可以连接到 master 上然后等待处理更新了。如果 master 当机或者 slave 连接断开,slave 会定期尝试连接到 master 上直到能重连并且等待更新。重试的时间间隔由 --master- connect-retry 选项来控制,它的默认值是 60 秒。 每个 slave 都记录了它关闭时的日志位置。msater 是不知道有多少个 slave 连接上来或者哪个 slave 从什么时候开 始更新。 6.3 同步实现细节 MySQL 同步功能由 3 个线程(master 上 1 个,slave 上 2 个)来实现。执行 START SLAVE 语句后,slave 就创 建一个 I/O 线程。 线程连接到 master 上,并请求 master 发送二进制日志中的语句。 I/O master 创建一个线程来把 日志的内容发送到 slave 上。这个线程在 master 上执行 SHOW PROCESSLIST 语句后的结果中的 Binlog Dump 线程便是。slave 上的 I/O 线程读取 master 的 Binlog Dump 线程发送的语句,并且把它们拷贝到其数 据目录下的中继日志(relay logs)中。第三个是 SQL 线程,salve 用它来读取中继日志,然后执行它们来更新数据。 如上所述,每个 mster/slave 上都有 3 个线程。每个 master 上有多个线程,它为每个 slave 连接都创建一个线程, 每个 slave 只有 I/O 和 SQL 线程。 在 MySQL 4.0.2 以前,同步只需 2 个线程(master 和 slave 各一个)。slave 上的 I/O 和 SQL 线程合并成一个了, 它不使用中继日志。 slave 上使用 2 个线程的优点是,把读日志和执行分开成 2 个独立的任务。执行任务如果慢的话,读日志任务不会跟 着慢下来。例如,如果 slave 停止了一段时间,那么 I/O 线程可以在 slave 启动后很快地从 master 上读取全部日志, 尽管 SQL 线程可能落后 I/O 线程好几的小时。如果 slave 在 SQL 线程没全部执行完就停止了,但 I/O 线程却已经把 所有的更新日志都读取并且保存在本地的中继日志中了,因此在 slave 再次启动后就会继续执行它们了。这就允许在 master 上清除二进制日志,因为 slave 已经无需去 master 读取更新日志了。 执行 SHOW PROCESSLIST 语句就会告诉我们所关心的 master 和 slave 上发生的情况。
  • 4. 下例说明了 SHOW PROCESSLIST 结果中的 3 个线程是什么样的。这是在 MySQL 4.0.15 及更新上执行 SHOW PROCESSLIST 的结果,State 字段的内容已经比旧版本显示的更有意义了。 在 master 上,SHOW PROCESSLIST 的结果如下: mysql> SHOW PROCESSLISTG *************************** 1. row *************************** Id: 2 User: root Host: localhost:32931 db: NULL Command: Binlog Dump Time: 94 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL 在这里,线程 2 是为一个 slave 连接创建的。结果表明所有未完成的更新日志已经都发送到 slave 了,master 正等 待新的更新日志发生。 在 slave 上,SHOW PROCESSLIST 的结果如下: mysql> SHOW PROCESSLISTG *************************** 1. row *************************** Id: 10
  • 5. User: system user Host: db: NULL Command: Connect Time: 11 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 11 User: system user Host: db: NULL Command: Connect Time: 11 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL 这表明线程 10 是 I/O 线程,它正连接到 master 上;线程 11 是 SQL 线程,它执行中继日志中的更新操作。现在, 这 2 个线程都处于空闲状态,正等待新的更新日志。 注意,Time 字段的值告诉我们 slave 上的日志比 master 晚了多久。详情请看"6.9 Replication FAQ"。 6.3.1 Master 同步线程状态
  • 6. 以下列出了 master 的 Binlog Dump 线程 State 字段中最常见的几种状态。如果在 master 上没有 Binlog Dump 线程,那么同步就没有在运行。也就是说,没有 slave 连接上来。 Sending binlog event to slave 事件是由二进制日志构成,一个事件通常由更新语句加上其他信息。线程读取到一个事件并正发送到 slave 上。 Finished reading one binlog; switching to next binlog 读取完了一个二进制日志,正切换到下一个。 Has sent all binlog to slave; waiting for binlog to be updated 已经读取完全部未完成更新日志,并且全部都发送到 slave 了。它处于空闲状态,正等待在 master 上执行新的更 新操作以在二进制日志中产生新的事件,然后读取它们。 Waiting to finalize termination 当前线程停止了,这个时间很短。 6.3.2 Slave 的 I/O 线程状态 以下列出了 slave 的 I/O 线程 State 字段中最常见的几种状态。从 MySQL 4.1.1 开始,这个状态在执行 SHOW SLAVE STATUS 语句结果的 Slave_IO_State 字段也会出现。这意味着可以只执行 SHOW SLAVE STATUS 语句就能了解到更多的信息。 Connecting to master 该线程证尝试连接到 master 上。 Checking master version 确定连接到 master 后出现的一个短暂的状态。 Registering slave on master 确定连接到 master 后出现的一个短暂的状态。
  • 7. Requesting binlog dump 确定连接到 master 后出现的一个短暂的状态。该线程向 master 发送一个请求,告诉它要请求的二进制文件以及 开始位置。 Waiting to reconnect after a failed binlog dump request 如果二进制日志转储(binary log dump)请求失败了(由于连接断开),该线程在休眠时进入这个状态,并定期重 连。重连的时间间隔由 --master-connect-retry 选项来指定。 Reconnecting after a failed binlog dump request 该线程正尝试重连到 master。 Waiting for master to send event 已经连接到 master,正等待它发送二进制日志。如果 master 闲置时,这个状态可能会持续较长时间,如果它等 待超过 slave_read_timeout 秒,就会发生超时。这时,它就会考虑断开连接,然后尝试重连。 Queueing master event to the relay log 已经读取到一个事件,正把它拷贝到中继日志中以备 SQL 线程处理。 Waiting to reconnect after a failed master event read 读日志时发生错误(由于连接断开)。该线程在重连之前休眠 master-connect-retry 秒。 Reconnecting after a failed master event read 正尝试重连到 master。当连接确定后,状态就变成 Waiting for master to send event 。 Waiting for the slave SQL thread to free enough relay log space relay_log_space_limit 的值非零,中继日志的大小总和超过这个值了。I/O 线程等待 SQL 线程先处理 中继日志然后删除它们以释放足够的空间。
  • 8. Waiting for slave mutex on exit 当前线程停止了,这个时间很短。 6.3.3 Slave 的 SQL 线程状态 以下列出了 slave 的 SQL 线程 State 字段中最常见的几种状态: Reading event from the relay log 从中继日志里读到一个事件以备执行。 Has read all relay log; waiting for the slave I/O thread to update it 已经处理完中继日志中的全部事件了,正等待 I/O 线程写入更新的日志。 Waiting for slave mutex on exit 当前线程停止了,这个时间很短。 SQL 线程的 State 字段有时候也可能是一个 SQL 语句。这意味着它从中继日志中读取到一个事件了,从中提取出 SQL 语句,并执行它。 6.3.4 中继日志及状态文件 默认地,中继日志的名字格式为 `host_name-relay-bin.nnn`,host_name 是服务器的主机名,nnn 是序 号。中继日志是根据顺序的序号来创建的,从 000001 (MySQL 4.0 及更旧是 001 )开始。slave 上用一个索引文 件来跟踪当前正在使用的中继日志。默认的中继日志索引文件名是 `host_name-relay-bin.index`。默认地, 这个文件位于 slave 的数据文件目录下。默认文件名可以根据的系统选项 --relay-log 和 --relay- log-index 来替换。详情请看"6.8 Replication Startup Options"。
  • 9. 中继日志和二进制日志的格式一样,因此也可以用 mysqlbinlog 来读取。当 SQL 线程读取完中继日志中的全 部事件后就不再需要它了,会自动删除它。中继日志没有显式的删除机制,因为 SQL 线程会自动关注这个。不过,从 MySQL 4.0.14 开始,执行 FLUSH LOGS 的话就会轮转(rotate)中继日志,会让 SQL 线程删除它们。 在下列条件中会创建一个新的中继日志: • slave 启动后,I/O 线程第一次启动(在 MySQL 5.0 中,每次 I/O 线程启动后都会新建一个中继日志,而不只是第一次 启动时)。 • 刷新日志时;例如,执行 FLUSH LOGS 语句或运行 mysqladmin flush-logs 命令(从 MySQL 4.0.14 开 始才会创建新中继日志)。 • 当前的中继日志大小太大了;"太大了"是这么判断的: o max_relay_log_size , 如果 max_relay_log_size > 0 的话 o max_binlog_size , 如果 max_relay_log_size = 0 或 MySQL 低于 4.0.14 slave 会在数据文件目录下创建两个额外的文件。它们是状态文件,名字默认为 `master.info` and `relay- log.info`。它们的内容跟执行 SHOW SLAVE STATUS 语句的结果类似。详情请看"14.6.2 SQL Statements for Controlling Slave Servers"。由于是磁盘上的文件,它们在 slave 关闭后还会留着。下一次 slave 启动时,就会读取这两个文件来判断从 master 读取到二进制日志的什么位置了,处理中继日志到什么位置了。 `master.info` 文件由来 I/O 线程更新。在 MySQL 4.1 以前,文件的内容和执行 SHOW SLAVE STATUS 语句结果中相对应的字段值一样,如下:
  • 10. Line Description 1 Master_Log_File 2 Read_Master_Log_Pos 3 Master_Host 4 Master_User 5 Password (not shown by SHOW SLAVE STATUS ) 6 Master_Port 7 Connect_Retry 从 MySQL 4.1 开始,文件内容还包括了 SSL 选项: Line Description 1 Number of lines in the file 2 Master_Log_File 3 Read_Master_Log_Pos 4 Master_Host
  • 11. 5 Master_User 6 Password (not shown by SHOW SLAVE STATUS ) 7 Master_Port 8 Connect_Retry 9 Master_SSL_Allowed 10 Master_SSL_CA_File 11 Master_SSL_CA_Path 12 Master_SSL_Cert 13 Master_SSL_Cipher 14 Master_SSL_Key `relay-log.info` 文件由 SQL 线程来更新。文件的内容和执行 SHOW SLAVE STATUS 语句结果中相对 应的字段值一样: Line Description 1 Relay_Log_File
  • 12. 2 Relay_Log_Pos 3 Relay_Master_Log_File 4 Exec_Master_Log_Pos 备份 slave 数据时,要把这两个文件也备份起来,和中继日志一道。想要恢复 slave 时就用得到它们了。如果丢失了 中继日志,但是 `relay-log.info` 文件还存在,那么就可以判断出 SQL 线程执行了多少 master 二进制日志。 然后执行 CHANGE MASTER TO 语句,带上 MASTER_LOG_FILE 和 MASTER_LOG_POS 选项告诉 slave 要从 master 的二进制日志哪个位置重新读取。当然了,这要求 master 上相关的二进制日志都还留着。 如果 slav 打算同步 LOAD DATA INFILE 语句,那么也要备份对应目录下的任何 `SQL_LOAD-*` 文件。这 可以在 LOAD DATA INFILE 被中断后继续保持同步。这个目录由 --slave-load-tmpdir 选项来指 定。默认地,如果没有指定的话,它的值就是变量 tmpdir 的值。 6.4 设置同步 以下描述了如何快速设置 MySQL 同步服务器。假设你打算同步全部的数据库,并且之前没有设置过。需要关闭 master 服务器以完成全部的步骤。 本章描述的过程可以用于一个 slave 的情况,也可以用于多个 slave 的情况。 这只是一个最直接设置 slave 的办法,并不是只有一个。例如,已经有了 master 的数据快照(snapshot),master 已经设置了服务器编号 ID(server_id)并且启用了二进制日志,这就无需关闭 master 或者阻止在 master 上更新 数据了。详情请看"6.9 Replication FAQ"。
  • 13. 想要完全掌握 MySQL 同步设置,最好把本章全部读完,并且测试在"14.6.1 SQL Statements for Controlling Master Servers"和"14.6.2 SQL Statements for Controlling Slave Servers"中提到的全部语句。而且要熟悉 各种同步设置选项,详情请看"6.8 Replication Startup Options"。 注意,这个过程以及后面一些同步 SQL 语句需要有 SUPER 权限。MySQL 4.0.2 以前,则是 PROCESS 权限。 1. 请确认 master 和 slave 上都安装了较近的 MySQL 版本,且这些版本之间要能兼容,在"6.5 Replication Compatibility Between MySQL Versions"中列出来了。请确认在最新版本中还有存在问题,否则不要报告该 bug。 2. 在 master 上新加一个帐户,slave 才能用它来连接。这个帐户必须授予 REPLICATION SLAVE 权限。如果 这个帐户只用于同步(推荐这么做),那就没必要授予其他权限了。设定你的域是 mydomain.com ,想要授权一 个帐户 repl 使用密码 slavepass ,允许它可以在域里的任何主机连接到 master 上。用 GRANT 语句来 创建帐户: 3. mysql> GRANT REPLICATION SLAVE ON *.* 4. -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass'; 在 MySQL 4.0.2 以前,用 FILE 权限来代替 REPLICATION SLAVE : mysql> GRANT FILE ON *.* -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass'; 如果打算在 slave 上执行 LOAD TABLE FROM MASTER 或 LOAD DATA FROM MASTER 语句,那 么必须给该帐户授予附加权限:
  • 14. o 授予全局 SUPER 和 RELOAD 权限。 o 授予对想要加载的所有表上的 SELECT 权限。在 master 上任何没有 SELECT 权限的表都会被 LOAD DATA FROM MASTER 略过。 5. 如果只用到 MyISAM 表,执行 FLUSH TABLES WITH READ LOCK 语句刷新所有表并且阻止其他写 入: 6. mysql> FLUSH TABLES WITH READ LOCK; 不要退出执行 FLUSH TABLES 语句的客户端,以保持读锁有效(如果退出了,读锁就释放了)。然后从 master 上取得数据快照。比较简单的办法就是把数据目录打包压缩。例如,Unix 上的 tar , PowerArchiver , WinRAR , WinZip ,或 Windows 上的类似程序。想要用 tar 来创建一个压缩包,包 括所有的数据库,只需执行以下命令(把目录改成你的真实路径): shell> tar -cvf /tmp/mysql-snapshot.tar . 如果只想打包一个数据库 this_db ,只需执行命令: shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db 然后把这个文件拷贝到 slave 的 `/tmp` 目录下。 slave 上,执行以下命令解开压缩包(把目录改成你的真实路 在 径): shell> tar -xvf /tmp/mysql-snapshot.tar
  • 15. 可能不需要同步 mysql 数据库,因为在 slave 上的权限表和 master 不一样。这时,解开压缩包的时候要排除 它。同时在压缩包中也不要包含任何日志文件,或者 `master.info~ 或 `relay-log.info` 文件。当在 master 上的 FLUSH TABLES WITH READ LOCK 语句还生效时,在 master 上读取当前二进制文件的 文件名及偏移位置: mysql > SHOW MASTER STATUS; +---------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +---------------+----------+--------------+------------------+ | mysql-bin.003 | 73 | test | manual,mysql | +---------------+----------+--------------+------------------+ File 字段显示了二进制日志文件名,Position 字段显示了日志偏移位置。在这个例子中,日志文件是 mysql-bin.003 ,偏移位置是 73 。记下这些值,在后面设置 slave 的时候就需要用到它们了。它们表示了 slave 要从 master 的哪个偏移位置开始处理更新操作。取得快照和记录下日志名及偏移位置后,就可以让 master 释放读锁了: mysql> UNLOCK TABLES; 如果用到 InnoDB 表,那么最好使用 InnoDB Hot Backup 工具。它无需在 master 上请求任何锁就能 做到快照的一致性,并且在后面中在 slave 上要用到的快照中已经记录了日志文件名以及偏移位置。InnoDB Hot Backup 是费免费(商业的)的附加工具,它没有包含在 MySQL 发布包中。访问 InnoDB Hot Backup 的主页 http://www.innodb.com/manual.php 查看更多详细信息。除去 InnoDB Hot Backup 的另一个最快的办法就是关闭 master 服务器,拷贝 InnoDB 数据文件,日志文件,以及表结构定 义文件(`.frm` 文件)。想要记录当前日志文件及偏移位置,需要在 master 关闭前执行如下可语句: mysql> FLUSH TABLES WITH READ LOCK;
  • 16. mysql> SHOW MASTER STATUS; 尽快记下 SHOW MASTER STATUS 显示结果中的日志文件及偏移位置。然后,在不解锁的情况下关闭 master,确保 master 上的快照和记录的结果一致: shell> mysqladmin -u root shutdown 还有一个方法可以同时用于 MyISAM 和 InnoDB 表,这就是在 master 上作 SQL 转储而无需如上所述备份 二进制日志。 master 上运行 在 mysqldump --master-data 命令,然后把结果文件转储到 slave 上。不 过,这比拷贝二进制日志慢点。如果 master 在以前没有启用 --log-bin 选项,那么执行 SHOW MASTER STATUS 语句的结果中的文件名及偏移位置值为空了,那么后面在 slave 上指定的参数值就是空字符串('' ) 和 4 了。 7. 确认 master 上的 `my.cnf` 文件 [mysqld] 区间有 log-bin 选项。这个区间还必须有 server- id=master_id 选项,的值必须是 1 到 2^32-1 之间的正整数。例如: 8. [mysqld] 9. log-bin 10.server-id=1 如果这些配置选项不存在,那么就加上并且重启 master。 11. 关闭要做 slave 的服务器,在 `my.cnf` 文件中增加如下选项: 12.[mysqld] 13.server-id=slave_id
  • 17. slave_id 的值和 master_id 类似,是 1 到 2^32-1 之间的正整数。另外,这个 ID 必须不能和 master 的 ID 一样。例如: [mysqld] server-id=2 如果有多个 slave,那么每个 slave 都必须要有一个唯一的 server-id ,它的值不能和 master 以及其其他 slave 的值一样。可以把 server-id 想象成为 IP 地址:这些 ID 标识了整个同步组合中的每个服务器。如果没 有指定 server-id 的值,如果也没定义 master-host ,那么它的值就为 1,否则为 2。注意,如果没有 设定 server-id ,那么 master 就会拒绝所有的 slave 连接,同时 slave 也会拒绝连接到 master 上。因此, 省略配置 server-id 只对备份二进制日志有利。 14. 如果已经备份了 master 上的数据(直接打包压缩的方式),那么在 slave 启动之前把它们拷贝过去。要确保文件的 权限属主等设置没问题。MySQL 运行的用户必须对这些文件有读写权限,就跟在 master 上一样。如果是用 mysqldump 备份的,那么可以直接启动 salve(直接跳到下一步)。 15. 启动 slave,如果它之前已经运行同步了,那么在启动 slave 的时候使用 --skip-slave-start 选项使 之不会立刻去连接 master。最好也使用 --log-warnings 选项(从 MySQL 4.0.19 和 4.1.2 开始就是默 认启用了)来启动 slave,以知道发生问题时的更详细的信息(例如,网络或者连接问题)。从开始 MySQL 4.0.21 和 4.1.3,异常中止的连接不再记录到错误日志中,除非 --log-warnings 选项的值大于 1。 16. 如果在 master 上用 mysqldump 备份数据的话,把文件导入 slave 中: 17.shell> mysql -u root -p < dump_file.sql 18. 在 slave 上执行如下语句,把各个选项的值替换成真实值:
  • 18. 19.mysql> CHANGE MASTER TO 20. -> MASTER_HOST='master_host_name', 21. -> MASTER_USER='replication_user_name', 22. -> MASTER_PASSWORD='replication_password', 23. -> MASTER_LOG_FILE='recorded_log_file_name', 24. -> MASTER_LOG_POS=recorded_log_position; 下表列出了各个选项字符串的最大长度: MASTER_HOST 60 MASTER_USER 16 MASTER_PASSWORD 32 MASTER_LOG_FILE 255 25. 启动 slave 线程: mysql> START SLAVE; 做完上述过程后,slave 应该会连接到 master 上并且捕获所有从取得快照后的更新操作。 如果忘了设置 master 的 server-id 值,那么 slave 就不能连接到 master 上。 如果忘了设置 master 的 server-id 值,那么在错误日志中就会记录如下内容: Warning: You should set server-id to a non-0 value if master_host is set;
  • 19. we force server id to 2, but this MySQL server will not act as a slave. 如果因为其他原因不能同步的话,错误信息也会记录在 slave 的日志上。 一旦 slave 开始同步了,就能在数据文件目录下找到 2 个文件 `master.info` 和`relay-log.info`。slave 利用这 2 个文件来跟踪处理了多少 master 的二进制日志。 不要删除或者修改这 2 个文件,除非知道怎么改。尽管如此,我们更推荐用 CHANGE MASTER TO 语句来做。 注意:`master.info` 中的内容覆盖了部分命令行中指定的或 `my.cnf` 的选项。详情请看"6.8 Replication Startup Options"。 只要有了 master 的数据快照,就可以按照上述几个步骤配置其它 slave 了。无需再次取得 master 的数据快照,每 个 slave 都可以用这一份快照来做。 6.5 不同 MySQL 版本之间的同步兼容性 最早的二进制格式是在 MySQL 3.23 中开发出来的。在 MySQL 4.0 中改进了,MySQL 5.0 又改进了。在配置同步 时需要升级服务器的话,它们之间的因果关系在"6.6 Upgrading a Replication Setup"中描述了。 如果只关心同步,任何 MySQL 4.1.x 版本和 MySQL 4.0.x 是一样的,因为它们都使用相同格式的二进制日志。所 以,这些版本是互相兼容的,它们之间可以无缝地运行同步。一个例外的情况是,MySQL 4.0.0 到 4.0.2 由于开发 的较早,无法和后来的版本互相兼容,所以不要使用它们(它们是 4.0 版本的 alpha 系列。它们之间的兼容性在发布 包的手册中均有相关文档)。
  • 20. 下表展示了不同版本的 MySQL 之间的 master/slave 同步兼容性。 Master Master Master 3.23.33 and up 4.0.3 and up or any 4.1.x 5.0.0 Slave 3.23.33 and up yes no no Slave 4.0.3 and up yes yes no Slave 5.0.0 yes yes yes 一个通常的规则是,我们建议使用最近的 MySQL 版本,因为同步兼容性一直在改善。我们也建议 master 和 slave 都使用同一个版本。 6.6 升级同步 如果升级服务器时涉及到配置同步,升级设置的步骤跟当前版本以及升级后的版本不同而异。 6.6.1 升级同步到 4.0 或 4.1 本节适用于从 MySQL 3.23 升级到 4.0 或者 4.1 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5 Replication Compatibility Between MySQL Versions"中提到了。 把 master 从 MySQL 3.23 升级到 4.0 或 4.1 时,首先要确认这个 master 的所有 slave 都已经是 4.0 或 4.1 了, 否则的话,要先升级 slave:挨个关闭,升级,重启,重启同步等。
  • 21. 通过以下步骤可以实现安全地升级,假定 master 要升级到 3.23,而 slave 已经是 4.0 或 4.1 了。注意,master 升 级后,不要重启使用任何旧的二进制日志的同步,因为它会干扰到 4.0 或 4.1 slave 的同步。 1. 在 master 上执行 FLUSH TABLES WITH READ LOCK 语句,阻止所有的更新。 2. 等到所有的 slave 都跟上了 master 的数据更新。在 master 上执行 SHOW MASTER STATUS 语句取得二进 制日志以及偏移位置。然后,再 slave 用这些值执行 SELECT MASTER_POS_WAIT() 语句,它会阻止 slave 上的同步且返回它已经同步的偏移位置。然后在 slave 上执行 STOP SLAVE 语句。 3. 关闭 master,将它升级到 MySQL 4.0 或 4.1。 4. 重启 master,记下它的新的二进制文件名。可以在 master 上执行 SHOW MASTER STATUS 语句来取得这 些信息。然后在每个 slave 上都执行如下语句: 5. mysql> CHANGE MASTER TO MASTER_LOG_FILE='binary_log_name', 6. -> MASTER_LOG_POS=4; mysql> START SLAVE; 6.6.2 升级同步到 5.0 本节适用于从 MySQL 3.23,4.0 或 4.1 升级到 5.0 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5 Replication Compatibility Between MySQL Versions"中提到了。 首先,注意到 MySQL 5.0 还是 alpha 发布系列。它在各方面都比旧版本好(更容易升级一些同步中重要的会话变量, 例如 sql_mode ;详情请看"C.1.3 Changes in release 5.0.0 (22 Dec 2003: Alpha")。不过,它还没经过广 泛测试。由于是 alpha 版本,我们不建议用于任何生产环境(现在已经可以用于生产了,译者注)。
  • 22. 把 master 从 MySQL 3.23,4.0 或 4.1 升级到 5.0.0 时,首先要确认这个 master 的所有 slave 都已经是 5.0.0 了,否则的话,要先升级 slave:挨个关闭,升级,重启,重启同步等。5.0.0 的 slave 可以读取升级前写入的执行 语句的中继日志。升级完后的 slave 创建的中继日志就是 5.0 格式了。 当所有的 slave 都升级完了,关闭 master,升级到 5.0.0,然后重启。5.0.0 的 master 也可以读取旧格式的二进 制日志。slave 能识别旧的格式并且合理处理它们。master 上新建的二进制日志都是 5.0.0 格式的。slave 也能识别 这格式。 换言之,在升级到 5.0.0 时无需特殊的规定,除非在升级 master 到 5.0.0 之前 slave 必须使用旧版本的。注意,把 5.0.0 降级到旧版本中不能自动地做了:必须确保所有的 5.0.0 格式二进制日志和中继日志都已经处理完了,然后 才能把它们删除完成降级。 6.7 同步特性及已知问题 以下列出了同步支持什么,不支持什么。附加的 InnoDB 特殊相关的信息以及同步请看"16.7.5 InnoDB and MySQL Replication"。 • AUTO_INCREMENT , LAST_INSERT_ID() , 和 TIMESTAMP 的值都能被正常同步。 • USER() , UUID() , 和 LOAD_FILE() 函数都完完全全地同步到 slave,因此可能不大可靠。MySQL 4.1.1 以前 的版本中的 CONNECTION_ID() 函数也是如此。 MySQL 4.1.1 及更高以后,新的 从 PASSWORD() 函数可以正 常同步,当然了,slave 必须是 4.1.1 或更高或者不同步它。如果有旧版本的 slave 必须要同步 PASSWORD() 函数, 那么 master 启动时必须增加 --old-password 选项,这样在 master 上就用旧的方法来实现 PASSWORD() 了(注意,MySQL 4.1.0 的 PASSWORD() 函数实现跟其他的版本都不同,最好不要同步 4.1.0)。
  • 23. 从 MySQL 4.0.14 开始同步 FOREIGN_KEY_CHECKS 变量。从 5.0.0 开始同步 sql_mode , UNIQUE_CHECKS ,和 SQL_AUTO_IS_NULL 变量。 SQL_SELECT_LIMIT 和 table_type 变量目前 还不能被同步。 • 现在讨论使用不同字符集的 MySQL 服务器间同步的问题。 1. 首先,在 master 和 slave 上必须总是使用同样的全局字符集以及校验字符集(--default- character-set , --default-collation 都是相关的全局变量)。否则,slave 上可能会出现键重 复(duplicate-key)的错误,因为用 master 的字符集认为该键可能是唯一的,但是用 slave 的字符集则未必 然。 2. 第二,如果 master 必须低于 MySQL 4.1.3,则会话(session)的字符集必须和全局值一样(也就是说,不能 执行 SET NAMES , SET CHARACTER SET 等语句),因为这些对字符集的修改在 slave 不能识别。如 果 master 是 4.1.3 或者更高,slave 也是这样的话,那么会话字符集就可以随便修改了(执行 NAMES , CHARACTER SET , COLLATION_CLIENT , COLLATION_SERVER 等),并且这些修改都会被记录 到二进制日志中,然后同步到 slave 上,它就知道怎么做了。该会话还会阻止试图修改这些全局变量的操作; 就如前面所说,master 和 slave 必须使用同样的全局字符集。 3. 如果在 master 上有和全局变量 collation_server 不一样字符集的数据库,那么就要设计 CREATE TABLE 语句使得数据表不隐式地使用该数据库的默认字符集,因为这目前还是一个 bug(Bug #2326);一 个变通的办法是在 CREATE TABLE 语句中显式地声明数据表的字符集以及校验字符集。 • 有时可能会把 master 上的事务表同步到 slave 后变成非事务表。例如,可以在 slave 上把 master 的 InnoDB 表当成 MyISAM 表。不过,slave 在一个 BEGIN/COMMIT 区块中停止的话就有问题了,因为 slave 会从 BEGIN 重新开 始。这个问题已经放到 TODO 中,很快会被修复。 • 更新语句中如果用到了用户自定义变量(例如变量 @ var_name )的情况下,在 MySQL 3.23 和 4.0 不能被正确同步。 在 4.1 这已经修复了。注意,从 MySQL 5.0 开始,用户变量就不区分大小写了。在做 MySQL 5.0 和旧版本间的同步需 要考虑到这个问题。 • 从 4.1.1 以及更高版本中,slave 可以用 SSL 方式连接到 master。
  • 24. 在 master 上执行的 CREATE TABLE 语句如果包括了 DATA DIRECTORY 或 INDEX DIRECTORY 子句, 那么它也会应用于 slave 上。如果 slave 上不存在对应的目录或者没有权限时便出现问题。 MySQL 4.0.15 开始,有个 从 sql_mode 选项叫 NO_DIR_IN_CREATE 。如果 slave 的 SQL 模式包含这个选项,那么它在同步 CREATE TABLE 语句前会忽略前面提到的 2 个子句。结果就是 MyISAM 的数据和索引文件都只能放在该表的数据库目录下。 • 尽管没听说过发生过类似的情况,不过理论上确实存在这种可能性:如果一个查询被设计为非确定方式的修改数据,那 么可能导致 master 和 slave 的数据不一致。那么,就把决定的权力交给查询优化器吧。(通常这不是一个好的做法,甚至 超出了同步的范围,详情请看"1.8.7.3 Open Bugs and Design Deficiencies in MySQL") • 在 MySQL 4.1.1 之前,FLUSH , ANALYZE TABLE , OPTIMIZE TABLE ,和 REPAIR TABLE 语句没有写入 到二进制日志中,因此也不会同步到 slave 上。这通常不会引发问题,因为它们并没有修改数据。不过在特定情况下可能 导致问题。如果同步 mysql 数据库下的权限表,在更新时不是用 GRANT 语句,那么必须在 slave 上执行那么必须在 slave 上执行 FLUSH PRIVILEGES 语句才能使之生效。同样地,如果还有一个 MyISAM 表是 MERGE 表的一部 分,那么必须在 slave 上手工执行 FLUSH TABLES 语句。从 MySQL 4.1.1 开始,这些语句都写入二进制日志了(除 非指定选项 NO_WRITE_TO_BINLOG 或它的同名选项 LOCAL )。一些例外的情况是 FLUSH LOGS , FLUSH SLAVE , 和 FLUSH TABLES WITH READ LOCK (它们中的任何一个同步到 slave 的话都可能导致问题)。例子 可见"14.5.4.2 FLUSH Syntax"。 • MySQL 只支持一个 master 多个 slave 的机制。以后我们会增加一个表决算法,如果当前 master 出现问题时能自动切 换。同时也会引进一个"代理"进程来帮助将 SELECT 查询发送到不同的 slave 上达到负载均衡。 • 当服务器关闭,重启后,所有的 MEMORY (HEAP ) 表都清空了。从 MySQL 4.0.18 开始,master 用以下方式同步它 们:一旦 master 开始使用一个 MEMORY 表,它会在用完这些表之后在二进制日志中写入一个 DELETE FROM 语 句告诉 slave 把它们删除。详情请看"15.3 The MEMORY (HEAP ) Storage Engine"。 • 除非关闭 slave(只是关闭 slave 线程),临时表也会同步;并且在 slave 上已经记录了一些还未被执行的需要用到临时表 的更新语句。关闭 slave 再重启后更新所需的临时表就不复存在了。为了避免这个问题,在有临时表时就不要关闭 slave。 或者,使用以下步骤: 1. 提交一个 STOP SLAVE 语句。
  • 25. 2. 使用 SHOW STATUS 语句检查变量 Slave_open_temp_tables 的值。 3. 如果它的值是 0,运行 mysqladmin shutdown 命令关闭 slave。 4. 如果它的值不是 0,用 START SLAVE 语句重启 slave 线程。 5. 如果还有这样的好运气就再次执行同样的步骤吧。^_^ 我们会尽快解决这个问题。 • 如果在一个循环 master/slave 同步关系中指定 --log-slave-updates 选项,那么就可以安全地连接到各个服 务器上。注意,很多语句可能在这种设置环境下不能正常工作,除非程序中已经特别注意避免这种更新时潜在的问题了, 因为可能在不同服务器上不同的顺序上发生更新问题。这意味着可以设定像下面的循环: • A -> B -> C -> A 服务器 ID 都已经编码到二进制日志中了,因此服务器 A 知道那些自己创建的日志,从而不会去执行它们(除非在服务器 A 上启动时增加 --replicate-same-server-id 选项,这个选项只在极少数情况下设置有意义)。因此,这就 不会存在无限循环了。不过这个循环只有在更新表时没有发生冲突才不会发生问题。换言之,如果在 A 和 C 中同时插入一 条记录,那么可能在 A 中不可能插入数据,因为它的键可能跟 C 的键冲突了。同样地,也不能在两个服务器上更新同一条 记录,除非 2 次更新操作间有足够的时间间隔。 • 如果在 slave 上执行一个 SQL 语句后产生错误,那么 slave 的 SQL 线程就终止,然后它在错误日志中写入一条信息。可 以连接到 slave 上,解决问题(例如,不存在表)后,运行 START SLAVE 语句重启它。 • 可以放心地关闭 master(干净地)之后再重启它。如果 slave 到 master 的连接断开了,它会立刻重连。如果失败了, slave 会定期重试(默认是每 60 秒重试一次,可通过 --master-connect-retry 选项来修改)。slave 也会处理 网络断开的情况。不过,slave 会在 slave_net_timeout 秒之后如果还没收到来自 master 的数据才会当作网络 断开的情况来处理。如果断开时间不长,可以减少 slave_net_timeout 的值。详情请看"5.2.3 Server System Variables"。
  • 26. 也可以放心地关闭 slave(干净地),它会记录停止的地方。不干净地关闭 slave 可能产生问题,特别是系统关闭了但缓存 还没刷新到磁盘时。可以提供不间断电源来提高系统容错性。master 的不干净关闭可能导致表和二进制内容的不一致;如 果是 InnoDB 表,使用 --innodb-safe-binlog 选项在 master 上就能避免这个问题。详情请看"5.9.4 The Binary Log"。 • 由于 MyISAM 表的非事务本质,就可能发生一个语句只更新了部分表就返回错误代码的情况。例如,一个多重插入语句 中,有一条记录违反了约束键规则,一个更新语句在更新了一些记录后辈杀掉了。如果在 master 上发生这种情况了,那 么 slave 线程会推出,等待数据库管理员决定要怎么做,除非这个错误代码是合法的并且这个语句的执行结果也是一样 的错误代码。并没有关于错误代码是否合法的详细描述,一些错误代码可以用 --slave-skip-errors 选项屏蔽 掉。这个选项从 MySQL 3.23.47 开始就可以用了。 • 如果把非事务表同步到事务表时在一个 BEGIN/COMMIT 段内更新数据表了,如果在非事务表提交之前有其他线程更 新它了,那么这个更新操作就不会正确地同步到二进制日志中。这是因为只有整个事务成功提交了才会写到二进制日志中。 • 在 4.0.15 之前,任何在非事务表的更新操作会在它执行的时候立刻写入到二进制日志中,然而事务表的更新只有在 COMMIT 后才写入,ROLLBACK 的话就不写入了。因此在一些事务中更新事务表或非事务表时就需要考虑这个情况了 (不只是同步时会碰到这个问题,想要把二进制日志作为备份时也一样)。 MySQL 4.0.15 中,我们已经修改了更新事务 在 和非事务表混合的情况下的日志记录行为,它解决了这个问题(对于二进制日志来说顺序地记录语句是比较不错的做法, 所有必须的语句都会写进去,ROLLBACK 也一样)。当第二个连接更新非事务表而第一个连接的事务还没结束时,就会 有同样的问题了;仍会发记录语句顺序发生错误的问题,因为第二个连接会在更新完成后立刻写入到日志中。 • 当 4.x 的 slave 从 3.23 的 master 上同步 LOAD DATA INFILE 时,SHOW SLAVE STATUS 中的 Exec_Master_Log_Pos 和 Relay_Log_Space 字段的值就不正确了。Exec_Master_Log_Pos 值 不正确的话在重启 slave 之后会导致问题;因此最好在重启前修改一下这个值,只需在 master 上运行 FLUSH LOGS 。这个 bug 在 MySQL 5.0.0 的 slave 中已经解决了。 下表列出了 MySQL 3.23 同步时会发生的问题,它们在 MySQL 4.0 已经解决了: • LOAD DATA INFILE 能正确处理,只要那个数据文件在更新开始时仍然存在于 master 上。
  • 27. LOAD DATA LOCAL INFILE 不再像以前 3.23 那样被略过了。 • 在 3.23 中,RAND() 更新同步不正常。因此在使用 RAND() 更新时采用 RAND(some_non_rand_expr) 格式。例如,可以用 UNIX_TIMESTAMP() 作为 RAND() 的参数。 6.8 同步启动选项 不管是 master 还是 slave,都要设定 server-id 选项来确定使它们都有各自唯一的同步 ID。必须选择 1 到 2^32-1 之间的正整数。例如: server-id=3 。 关于 master 服务器上可用于控制二进制日志记录的选项详细描述请看"5.9.4 The Binary Log"。 下表描述了 slave 同步可用的选项,可以在命令行或者配置文件中设定它们。 一些 slave 同步选项以特定的方式来处理,在 slave 启动时,如果存在 `master.info` 文件并且包含这些选项, 那么 slave 将略过它们。这些选项如下: • --master-host • --master-user • --master-password • --master-port • --master-connect-retry
  • 28. 从 MySQL 4.1.1 开始,一下选项也按照上述方式特殊处理: • --master-ssl • --master-ssl-ca • --master-ssl-capath • --master-ssl-cert • --master-ssl-cipher • --master-ssl-key 在 MySQL 4.1.1 中, `master.info` 文件的格式改变了以包含相应的 SSL 选项。另外,MySQL 4.1.1 文件格 式还包括了在第一行中的文件总行数。如果从旧版本升级到 4.1.1,那么服务器启动时会自动升级 `master.info` 为新的格式。不过,如果是从 4.1.1 降级到旧版本,就需要在系统第一次启动时手工删除文件的 第一行。注意,这种情况下,被降级的服务器就不能再使用 SSL 选项连接到 master 了。 slave 启动时如果不存在 `master.info` 文件,它就使用在命令行或者配置文件中指定的参数值来启动。这在每 次第一次启动 slave 服务器时都是这样,或者执行 RESET SLAVE 语句关闭且重启 slave 之后。 slave 启动时如果存在 `master.info` 文件,那么它就略过这些选项,而是直接读取 `master.info` 文件 中的值。 如果重启 salve 时使用的选项值和 `master.info` 中的不一样,那么这个新的值不会生效,因为 slave 服务器 还是照样只读取 `master.info` 文件。想要使用不同的选项值,可以在删除 `master.info` 后重启 slave 或 者使用 CHANGE MASTER TO 语句(推荐)重置选项值。
  • 29. 假定在 `my.cnf` 设定了以下选项值: [mysqld] master-host=some_host 第一次启动 slave 的时候,它从 `my.cnf` 中读取选项值,然后再把它们保存在 `master.info` 中。下次重启 slave 时,它就只读取 `master.info` 的内容而略过 `my.cnf` 中的选项值了。企图修改 `my.cnf` 来改变 同步选项是不可行的,不过可以通过执行 CHANGE MASTER TO 语句来实现: 由于服务器认为 `master.info` 的优先级比配置文件高,因此建议根本不要在启动时附加同步选项,而只用 CHANGE MASTER TO 语句。详情请看"14.6.2.1 CHANGE MASTER TO Syntax"。 下例显示了一些配置 slave 的扩展选项: [mysqld] server-id=2 master-host=db-master.mycompany.com master-port=3306 master-user=pertinax master-password=freitag master-connect-retry=60 report-host=db-slave.mycompany.com
  • 30. 下列所述启动选项都是用来控制同步的:它们中的大部分都可以在运行时用 CHANGE MASTER TO 语句来改变。 其他的,例如 --replicate-* ,只能在 salve 启动时指定。我们打算在将来解决这个问题。 --log-slave-updates 通常,slave 从 master 接收更新操作后并没有再把它们记录在二进制日志中。这个选项告诉 slave 的 SQL 线程要 把这些更新操作记录在二进制日志中。想要这个选项起作用,需要同时启用 --log-bin 选项才能启用二进制 日志。在使用同步链机制时,就需要使用 --log-slave-updates 选项。例如,可能需要设置如下同步关 系: A -> B -> C 在这里,A 当作 B 的 master,B 当作 C 的 master。B 同时是 slave 又是 master,在 A 和 B 上都需要启用 --log-bin 选项,并且在 B 上还需要启用 --log-slave-updates 选项。 --log-warnings 让 slave 在执行同步时记录更多的错误日志。例如,它会通知你在网络/连接失败后重连成功,并且通知了每个 slave 线程如何启动的。这个选项在 MySQL 4.0.19 和 4.1.12 之后默认启用了;用 --skip-log- warnings 就可以禁用它。从 MySQL 4.0.21 和 MySQL 4.1.3 开始,除非这个选项的值大于 1,否则放弃的 连接不再记录在错误日志中。这个选项不只是用于限制同步,它产生的警告跨越了大部分操作。 --master-connect-retry= seconds 在 master 当机或者网络连接中断后,slave 在重新连接到 master 之前休眠的秒数。如果在 `master.info` 文件中存在,就优先使用它。如果没有设置,默认是 60。 --master-host= host
  • 31. master 服务器的主机名或者 ip 地址。如果没有设置它,slave 线程无法启动。如果存在的话,`master.info` 文件中选项值优先被读取。 --master-info-file= file_name slave 记录 master 信息的文件名。默认名字是 `master.info`,放在数据文件目录下。 --master-password= password 用于被授权连接到 master 上运行同步的帐户密码。如果存在的话,`master.info` 文件中选项值优先被读取。 如果没有设置,就当作是空密码。 --master-port= port_number master 上监听的 TCP/IP 端口号。如果存在的话,`master.info` 文件中选项值优先被读取。如果没有设置, 就当作预编译的设置。如果没有修改 configure 选项参数,那么就是 3306。 --master-ssl,--master-ssl-ca= file_name, --master-ssl- capath= directory_name, --master-ssl-cert= file_name, --master-ssl- cipher= cipher_list, --master-ssl-key= file_name 用于设定用 SSL 安全连接到 master 的选项。它们的意义对应于"5.6.7.5 SSL Command-Line Options"中提到 的 --ssl , --ssl-ca , --ssl-capath , --ssl-cert , --ssl-cipher , --ssl-key 选项。 如果存在的话,`master.info` 文件中选项值优先被读取。这些选项是从 MySQL 4.1.1 之后开始可以用的。 --master-user= username 用于被授权连接到 master 上运行同步的帐户。这个帐户必须有 REPLICATION SLAVE 权限(在 MySQL 4.0.2 以前,则是 FILE 权限)。如果存在的话,`master.info` 文件中选项值优先被读取。如果没有设置,就 当作是 test 。 --max-relay-log-size= #
  • 32. 中继日志自动轮转(rotate)的大小。详情请看"5.2.3 Server System Variables"。这个选项是从 MySQL 4.0.14 之后才可以用的。 --read-only 这个选项令 slave 除了 slave 线程或者拥有 SUPER 权限用户之外的都不能更新数据。这能确保 slave 不会接受 来自其他客户端的更新。这个选项是从 MySQL 4.0.14 开始有的。 --relay-log= file_name 中继日志的名字。默认名字是 host_name -relay-bin. nnn ,host_name 是 slave 服务器的主机名, nnn 是指中继日志的顺序号。可以用这个选项创建不依赖主机名的中继日志,或者在中继日志越来越大(不想降低 max_relay_log_size 的值)且需要将它们放在非数据文件目录下,或者想使用磁盘间的负载均衡来提高 速度等情况。 --relay-log-index= file_name 中继日志索引文件的位置及文件名。它的默认值是 host_name -relay-bin.index ,host_name 是 slave 服务器主机名。 --relay-log-info-file= file_name slave 上记录中继日志信息的文件名。默认是数据文件目录下的`relay-log.info`。 --relay-log-purge={0|1} 在不需要中继日志时禁用或启用自动清除。默认值是 1(启用)。这是一个全局变量,可以用 SET GLOBAL relay_log_purge 来动态更改。这个选项从 MySQL 4.1.1 开始可以用。 --relay-log-space-limit= # 用于加大 slave 上中继日志的总大小(如果值为 0 表示"无限")。这在 slave 主机只有有限的空间时很有用。当达到 这个限制后,I/O 线程直到 SQL 线程删除一些无用的中继日志后才会继续从 master 读取二进制日志事件。注意, 这个限制不是绝对的:在删除中继日志之前,SQL 线程可能还需要更多的二进制日志事件。这种情况下,I/O 线程 会超越这个限制,直到 SQL 线程删除一些中继日志,因为如果不这么做的话就会导致死锁(在 MySQL 4.0.13 之
  • 33. 前就是这样)。不要设置 --relay-log-space-limit 的值小于 2 倍 --max-relay-log-size (如果 --max-relay-log-size 的值为 0,则是 --max-binlog-size ) 的值。在这种情况下,由 于已经超过 --relay-log-space-limit 了,I/O 线程需要等待更多的剩余空间,但是 SQL 线程没有 可以删除的中继日志来满足 I/O 线程的需求。这就会强制 I/O 线程暂时忽略 --relay-log-space- limit 限制。 --replicate-do-db= db_name 告诉 slave 只同步那些缺省数据库是 db_name (也就是用 USE 选中的)的语句。想要指定更多的数据库,只需 多次使用该选项,每次指定一个数据库。注意,类似 UPDATE some_db.some_table SET foo='bar' 这样的跨库操作语句以及没有选中数据库的操作都不会被同步。如果必须使用跨库操作,要确保使 用 MySQL 3.23.28 或更高,并且使用 --replicate-wild-do-table= db_name .% 选项。请仔细 阅读最后面的注意事项。 下面是一个不能按照预期工作的例子:如果启动 slave 时使用 --replicate-do-db=sales 选项,并且 在 master 上执行下列语句,那么这个 UPDATE 语句不会被同步: USE prices; UPDATE sales.january SET amount=amount+1000; 如果需要同步跨库操作,只需使用 --replicate-wild-do-table= db_name .% 选项。这个"只检查 缺省数据库"特性的主要原因是因为想要单从一个语句中判断是否要被同步比较困难(例如,使用多表 DELETE 或者 UPDATE ,这就跨库了)。不过想要检查是否是缺省数据库却很快。 --replicate-do- table= db_name.tbl_nam e
  • 34. 告诉 slave 只同步那些指定的数据表。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据表。这个 选项支持跨库更新,和 --replicate-do-db 选项相反。请仔细阅读最后面的注意事项。 --replicate- ignore-db= db_name 告诉 slave 不要同步那些缺省数据库是 db_name (也就是用 USE 选中的)的语句。想要指定更多的数据库,只 需多次使用该选项,每次指定一个数据库。如果有跨库操作且希望这些操作要被同步就不要使用该选项。请仔细阅 读最后面的注意事项。 下面是一个不能按照预期工作的例子:如果启动 slave 时使用 --replicate-ignore-db=sales 选项, 并且在 master 上执行下列语句,那么这个 UPDATE 语句不会被同步: USE prices; UPDATE sales.january SET amount=amount+1000; 想要让跨库操作能正常同步,只需使用 --replicate-wild-ignore-table= db_name .% 选项。 -- replicate- ignore- table= db_n ame.tbl_na me 告诉 slave 不要同步指定数据表的任何更新语句(甚至用同一个语句更新的其他表)。想要指定更多的数据表,只需 多次使用该选项,每次指定一个数据表。这个选项支持跨库更新,和 --replicate-ignore-db 选项相 反。请仔细阅读最后面的注意事项。
  • 35. -- replicat e-wild- do- table= db _name.tb l_name 限制 slave 只同步那些匹配指定模式的数据表。模式中可以包含通配符 `%` 和 `_`,它们的含义和 LIKE 模 式一样。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据表。请仔细阅读最后面的注意事项。 例如: --replicate-wild-do-table=foo%.bar% 会同步所有以 foo 开头的数据库下的以 bar 开头的数据表上的更新操作。 如果匹配模式是 % ,则匹配所有的表名,且应用到数据库级语句(CREATE DATABASE , DROP DATABASE ,和 ALTER DATABASE )。例如,使用 --replicate-wild-do-table=foo%.% 选 项的话,所有匹配 foo% 模式的数据库级操作都会被同步。 如果想要在数据库/表模式中包含原义通配符,需要用反斜杠来转义它们。例如,想要同步 my_own%db 数据库 下的所有表,但是不想同步 my1ownAABCdb 数据库下的表,就需要转义字符 `_`: --replicate- wild-do-table=my_own%db 。如果是在命令行中使用这个选项,就可能需要两个反斜杠来转义,这 依赖于命令行解释器。例如,在 bash shell 下,就需要输入: --replicate-wild-do- table=my_own%db 。 -- re pl ic at e-
  • 36. wi ld - ig no re - ta bl e= db _n am e. tb l_ na me 限制 slave 不同步那些匹配指定模式的数据表。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据 表。请仔细阅读最后面的注意事项。 例如,--replicate-wild-ignore-table=foo%.bar% 就不会同步所有以 foo 开头的数据库 下的以 bar 开头的数据表上的更新操作。 想要了解匹配模式如何工作的,请查看 --replicate-wild-ignore-table 选项的具体描述。模式中 包含原义通配符的规则和 --replicate-wild-ignore-table 选项一样。 -- replicate
  • 37. -rewrite- db= from_n ame - > to_name 告诉 slave 把在 master 上的缺省数据库 from_name (只有用 USE 选中的)转换成 to_name 。只有涉及到数 据表的语句(不包括类似 CREATE DATABASE , DROP DATABASE ,和 ALTER DATABASE )才会被同 步,并且只针对 master 上缺省数据库为 from_name 的情况。这个选项不支持跨库操作。注意,数据库名字转换 先于 --replicate-* 规则之前测试。如果是在命令行中使用这个选项,需要把 `>' 字符用引号引用起来。 例如: shell> mysqld --replicate-rewrite-db="olddb->newdb" --replica same-serv id 该选项用于 slave 之上。通常使用它的默认值 0,用于避免无限同步循环。如果设置为 1,那么 slave 就不会忽略那 些跟它有同样服务器编号的更新日志了;通常它只用于比较罕见的配置中。如果启用 --log-slave- updates 选项,则不能设置为 1。注意,从 MySQL 4.1 开始,slave 的 I/O 线程默认不把包含 slave 的服务器 编号的二进制日志写到中继日志中(相对 4.0 这能节省磁盘使用)。因此想要在 4.1 中使用 --replicate- same-server-id 选项,在 slave 读取自己的更新事件让 SQL 线程来执行之前要确保启动 slave 时使用该 选项。 --report- host= host 在 salve 注册时要报告的 master 主机名或 IP 地址。在 master 上执行 SHOW SLAVE HOSTS 语句时就会显 示出来了。如果不想 slave 注册到 master 就无需设置这个选项。注意,这在 slave 连接到 master 之后,只根据这
  • 38. 个配置 master 还不能直接从 TCP/IP 套接字中读取 slave 的 IP 地址。因为存在 NAT 或者其他路由机制,这个 IP 信息还不足以在 master 或者其他主机上连接到 slave 上。这个选项是从 MySQL 4.0.0 开始可以用的。 --report- port= port 连接到 slave 的 TCP/IP 端口,在 slave 注册到 master 时用的到。除非 slave 在非默认端口上监听或者从 master 或其他客户端上到连接到 slave 使用的是特定的隧道,否则无需设置这个值。如果不确定,就不要设置它。 这个选项是从 MySQL 4.0.0 开始可以用的。 --skip-sl 告诉 slave 服务器在启动时不要运行 slave 线程。只需使用 START SLAVE 语句来启动 slave 线程。 -- slave_com col={0|1} 如果它设置为 1,并且 maste/slave 都支持的话,就采用压缩协议传输数据。 --slave-l tmpdir= fi slave 创建临时文件的目录。这个选项值默认地和系统变量 tmpdir 的值一样。slave 的 SQL 线程同步 LOAD DATA INFILE 语句时,它从中继日志中提取出要被加载的文件放到临时文件中,然后把它们加载到 slave 中。 如果在 master 上加载的文件很大,那么 slave 上的临时文件也会很大。因此建议在 slave 上指定这个选项时把它 放在剩余空间比较多的文件系统上。这是,最好也指定 --relay-log 到那个文件系统中,因为中继日志可能 也会很大。--slave-load-tmpdir 必须指向基于磁盘的文件系统,而不能是基于内存的文件系统:slave 可能会在机器重启后同步 LOAD DATA INFILE 语句时需要用到这个临时文件。这个目录同样不能在会被操 作系统的启动进程清除的目录下。 --slave-n
  • 39. salve 放弃读之后等待多少秒再次从 master 读取更多的数据,考虑到了连接断开,尝试重连的情况。第一次重试 会在超时后立刻执行。重试的时间间隔由选项 --master-connect-retry 控制。 --slave-s [ err_code all] 通常,发生错误时同步就会停止,以提供手工解决数据不一致的情况。这个选项告诉 slave 的 SQL 线程当执行语 句时返回的错误代码在该列表中时继续运行。 除非真正的理解了为什么会产生相应的错误后,否则不要设置这个选项。如果同步设置以及客户端程序都没有 bug,并且也不是 MySQL 自身的 bug 的话,那么就不会出现让同步停止的错误了。不加区分地使用这个选项,会 导致 slave 无可救药地背离 master 的同步,并且你也不知道这是为什么。 可以在从 slave 的错误日志并且在 slave 上执行 SHOW SLAVE STATUS 语句的结果中就能看到错误代码了。 服务器错误代码详情请看"22 Error Handling in MySQL"。 你也可以(最好不要)使用非常不推荐使用的值 all ,它能忽略所有的错误信息,不管什么情况都继续保持同步。 不消说,如果使用这个选项值,就不可能期待有数据的完整性了。这种情况下,就不能抱怨 slave 的数据无论在哪 个地方都和 master 不接近了。已经警告过你了。例如: --slave-skip-errors=1062,1053 --slave-skip-errors=all --replicate-* 模式根据以下规则来决定一个语句是要执行还是被忽略: 1. 是否有 --replicate-do-db 或 --replicate-ignore-db 规则?
  • 40. o 是:测试 --binlog-do-db 和 --binlog-ignore-db 选项(详情请看"5.9.4 The Binary Log")。测试结果?  忽略:忽略并且退出。  执行:不立刻执行,推迟判断,到下一步。 o 否:到下一步。 2. 是否有 --replicate-*-table 规则? o 否:执行并且退出。 o 是:走到下一步。只有要被更新的表才和这个规则作比较(INSERT INTO sales SELECT * FROM prices :中只有 sales 和规则比较)。如果有好几个表一起被更新(多表语句),第一个匹配的表(匹配 `do` 或 `ignore`)胜出。也就是说,只有第一个表和规则作比较。然后,如果还没有产生任何决定,就比较第二个表, 以此类推。 3. 是否有 --replicate-do-table 规则? o 是:这个表是否匹配这些规则?  是:执行并且退出。  否:走到下一步。
  • 41. o 否:走到下一步。 4. 是否有 --replicate-ignore-table 规则? o 是:这个表是否匹配这些规则?  是:忽略并且退出。  否:走到下一步。 o 否:走到下一步。 5. 是否有 --replicate-wild-do-table 规则? o 是:这个表是否匹配这些规则?  是:执行并且退出。  否:走到下一步。 o 否:走到下一步。
  • 42. 6. 是否有 --replicate-wild-ignore-table 规则? o 是:这个表是否匹配这些规则?  是:忽略并且退出。  否:走到下一步。 o 否:走到下一步。 7. 没有匹配 --replicate-*-table 规则。是否有其他表匹配这些规则? o 是:循环查找匹配。 o 否:已经测试所有要被更新的表且找不到任何匹配规则。是否有 --replicate-do-table 或 --replicate-wild-do-table 规则?  是:忽略并且退出。  否:执行并且退出。 6.9 同步 FAQ 问: master 还在运行中,如何在不停止它的情况下配置 slave?
  • 43. 答: 需要设计几个选项参数。如果已经有了 master 的备份并且记录了数据快照二进制日志文件名以及偏移位置(运 行 SHOW MASTER STATUS 查看结果),执行以下步骤: 1. 确定 slave 指定了一个唯一的服务器编号。 2. 在 slave 上执行如下语句,把一些选项值改成实际值: 3. mysql> CHANGE MASTER TO 4. -> MASTER_HOST='master_host_name', 5. -> MASTER_USER='master_user_name', 6. -> MASTER_PASSWORD='master_pass', 7. -> MASTER_LOG_FILE='recorded_log_file_name', -> MASTER_LOG_POS=recorded_log_position; 8. 在 slave 上执行 START SLAVE 语句。 如果事先没有备份 master 的数据,可以用以下方法快速创建一个备份。以下所有的操作都是在 master 上。 1. 提交语句: 2. mysql> FLUSH TABLES WITH READ LOCK; 3. 确保这个锁一直存在,执行以下命令(或者其他类似的):
  • 44. 4. shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql 5. 执行以下语句,记录下输出的结果,后面要用到: 6. mysql> SHOW MASTER STATUS; 7. 释放锁: mysql> UNLOCK TABLES; 上述步骤的另一个办法是创建 master 的 SQL 转储文件。只需在 master 上执行 mysqldump --master- data 命令,然后将导出来的 SQL 转储文件载入 slave。不过,这么做会制作二进制数据快照的方式慢一点。 无论使用上述两种方法的哪种,最后都能创建 master 的数据快照然后记录二进制日志文件名以及偏移位置。可以在 好几的其他的 slave 上使用同一个备份的二进制数据快照。得到 master 的快照后,只要 master 的二进制日志完好 无损,接着就能开始设置 slave 了。两个决定是否需要等待较长时间的限制是:在 master 上磁盘空间保存二进制日 志,以及 slave 从 master 抓取更新事件。 也可以使用 LOAD DATA FROM MASTER 。这个语句可以很方便地在 slave 上取得数据快照并且能立刻调整二 进制日志文件名以及偏移位置。在将来,我们推荐用 LOAD DATA FROM MASTER 来设置 slave。警告,它只 能用于 MyISAM 表,并且可能会保持一个较长时间的读锁。由于它还没达到所期望的高效率,因此如果数据表很 大,最好还是在执行完 FLUSH TABLES WITH READ LOCK 后直接制作二进制数据快照。 问:是否 slave 总是需要连接到 master?
  • 45. 答:不,非必需。slave 可以好几小时甚至几天关闭或者不连接 master,然后重连再取得更新操作日志。例如,可以 在拨号链接上设置一个 mater/slave 关系,拨号可能只是零星的不定期的连接。这种做法隐含的是,在任何指定的 时间里,除非使用特殊的度量标准,否则 slave 不能保证总是能和 master 保持同步。在未来,有个选项可以阻止 master,除非至少有一个 slave 在同步中。 问:怎么知道比 master 晚了多少?也就是说,怎么知道 slave 最后同步的时间? 答:如果 slave 是 4.1.1 或者更高,只需查看 SHOW SLAVE STATUS 结果中的 Seconds_Behind_Master 字段。对于老版本,可以用以下办法。如果在 slave 上执行 SHOW PROCESSLIST 语句结果显示 SQL 线程(对 MySQL 3.23 则是 slave 线程)正在运行,这就意味着该线程至少从 master 读取一个更新操作事件。详情请看"6.3 Replication Implementation Details"。 当 SQL 线程执行一个 master 上读取的更新操作事件时,它把自己的时间改成事件的时间(这也就是 TIMESTAMP 也要同步的原因)。在 SHOW PROCESSLIST 结果中的 Time 字段中,slave 的 SQL 线程显示的秒数就是最后一次同步的时间戳和 slave 本机的实际时间相差秒数。可以根据这个值来判断最后同步的时间。注意,如果 slave 已经从 master 断开好几 个小时了,然后重新连接,就能看到 slave 的 SHOW PROCESSLIST 结果中的 SQL 线程的 Time 字段的值类似 3600。这是因为 slave 正在执行一个小时前 的语句。 问:如何强制 master 在 slave 赶上全部更新之前阻止更新操作? 答:执行以下步骤:
  • 46. 1. 在 master 上,执行以下语句: 2. mysql> FLUSH TABLES WITH READ LOCK; mysql> SHOW MASTER STATUS; 记录下结果中的日志文件名以及偏移位置,它们是同步的坐标值。 3. 在 slave 上,提交以下语句,MASTER_POS_WAIT() 函数的参数的值就是前面取得的同步坐标值: 4. mysql> SELECT MASTER_POS_WAIT('log_name', log_offset); SELECT 语句会阻止更新,直到 slave 同步到了上述日志文件及位置。在这个时候,slave 就和 master 保持同 步了,并且这个语句就会返回。 5. 在 master 上,执行以下语句允许 master 重新处理更新操作: mysql> UNLOCK TABLES; 问:设置一个双向复制时要注意什么问题? 答:MySQL 同步目前还不支持任何在 master 和 slave 上的分布式(跨服务器)更新锁协议以保证操作的原子性。也 就是说,存在这样的可能性:客户端 A 在并存的 master 1 上做了一个更新,同时,在它同步到并存 master 2 上 之前,客户端 B 在 master 2 上可能也做了一个和客户端 A 在 master 1 上不同的更新操作。因此,当客户端 A 所做 的更新同步到 master 2 时,它将产生和 master 1 上不同的数据表,尽管 master 2 上的更新操作也全都同步到
  • 47. master 1 上去。这意味着除非能确保所有的更新都能以任何顺序安全地执行,否则不要使用双向同步,或者除非注 意在客户端程序中的不知原因的无序更新操作。 同时也要意识到在所关心的更新问题上,双向同步实际上并不能很大地改善性能(甚至没有)。两个服务器都需要执行 同样数量的更新操作,在一台服务器上也是。唯一区别的是,可能这样做会减少一些锁争夺,因为来自其他服务器的 更新操作都会被串行地放到 slave 线程中。甚至这种好处还可以作为网络延迟的补偿。 问:我如何利用同步来提高系统性能? 答:需要安装一个服务器作为 master 并且把所有的写操作直接放在这上面。然后配置多个廉价的使用机架磁盘的 slave,把读操作分配给 master 和 slave。还可以在启动 slave 时使用 --skip-innodb , --skip-bdb , --low-priority-updates ,和 --delay-key-write=ALL 选项来提高 slave 端的性能。这种情况 下,slave 会使用非事务的 MyISAM 表来代替 InnoDB 和 BDB 表,已取得更快速度。 问:如何准备客户端应用程序的代码来适应同步应用? 答:如果代码中负责存取数据库的部分已经被合理地抽象化/模块化了,将它们转化成适用运行于同步环境中将会很 平滑和简单。只需要修改数据库存取实现部分,把所有的写操作放到 master 上,把所有的读操作放到 master 或者 slave 上。如果你的代码还没达到这个层次的抽象化,那么这将成为整理代码的机会和动机。可以使用类似以下函数 创建封装类库或者模块:
  • 48. safe_writer_connect() • safe_reader_connect() • safe_reader_statement() • safe_writer_statement() 每个函数名的 safe_ 表示它们会处理所有的错误情况。可以使用其他函数名。重要的是,要为读连接、写连接、读、 写定义好统一的接口。 然后将客户端代码转换成使用封装的类库。已开始可能是很痛苦且麻烦的,不过在将来长期运行中就能得到回报了。 所有使用上述方法的应用程序都会在 master/slave 配置中有优势,即使包含多个 slave。这些代码将很容易维护, 一些额外的麻烦也会很少。自豪需要修改一个或者两个函数;例如,想要记录每个语句执行了多长时间,或者在上千 个语句中哪个出现错误了。 如果已经写了很多代码,你可能想要自动转换它们,那么可以使用 MySQL 发布的 replace 工具,或者自己写 转换脚本。理想地,你的代码已经使用了统一的编程风格。如果不是,最好重写它们,或者可以遍历检查一下,手工 规范化一下代码风格。 问:MySQL 同步何时且有多少能提高系统性能?
  • 49. 答:MySQL 同步对于频繁读但不频繁写的系统很有好处。理论上来讲,使用单一 master/多 slave 的配置,就可以 通过这个方法来衡量系统:增加更多的 slave 直到用完所有的网络带宽或者 master 的更新操作增长到了不能再处 理的点了。 想要知道增加多少个 slave 之后得到的性能才能平稳,以及能提高多少性能,就需要知道查询模式,并且根据经验 对典型的 master 和 slave 做读(每秒读或 max_reads )和写(max_write )基准测试得到它们之间的关系。下 例展示了一个理想系统取得的性能的简单计算方法。 设定系统负载由 10%写和 90%读组成,我们已经通过基准测试确定 max_reads 是 1200 - 2 * max_writes 。换句话说,系统可以达到每秒做没有写的 1200 次读操作,写操作平均是读操作的 2 倍慢,它们 之间的关系是线性的。让我们假设 master 和每个 slave 都有同样的容量,有一个 master 和 N 个 slave。每个服务器 (master 或 slave): reads = 1200 - 2 * writes reads = 9 * writes / (N + 1) (读是分开的,但是所有写是在所有的服务器上的) 9 * writes / (N + 1) + 2 * writes = 1200
  • 50. writes = 1200 / (2 + 9/(N+1)) 最后的等式说明了 N 个 slave 的最大写数量,给它每分钟的最高读频率 1200 和 1 次写 9 次读的机率。 分析结论比率如下: • 如果 N = 0(意味着没有同步),系统大致可以处理每秒 1200/11 = 109 次写。 • 如果 N = 1,增加到每秒 184 次写。 • 如果 N = 8,增加到每秒 400 次写。 • 如果 N = 17,增加到每秒 480 次写。 • 最终,随着 N 接近无穷大(我们的预算为负无穷大),则可以达到几乎每秒 600 次写,大约提高系统吞吐量 5.5 倍。尽管 如此,当有 8 台服务器时,已经提高了 4 倍了。 注意,上面的计算是假设了网络带宽无穷大,并且忽略了一些系统中比较大的因素。在很多情况下,当系统增加 N 个同步 slave 之后,是无法精确计算出上述预计结果的。不过,先看看下列问题将有助于你知道是否有和有多少系统 性能上的改善: • 系统读/写得比率是多少? • 减少读操作后一个服务器能增加处理多少写操作? • 你的网络带宽足够给多少 slave 使用?
  • 51. 问:如何利用同步提供冗余/高可用性? 答:使用当前已经可用的特性,可以配置一个 master 和一个(或多个)slave,并且写一个脚本监控 master 是否运 行着。然后通知应用程序和 slave 在发现错误时修改 master。一些建议如下: • 使用 CHANGE MASTER TO 语句告诉 slave 修改 master。 • 一个让应用程序定位 master 所在主机的办法就是给 master 使用动态 DNS。例如 bind 就可以用 `nsupdate` 来动态 更新 DNS。 • 使用 --log-bin 选项,不使用 --log-slave-updates 选项来启动 slave。这样就能让 slave 运行 STOP SLAVE ; RESET MASTER 语句 后随时准备变成 master,并且在其他 slave 上运行 CHANGE MASTER TO 。例如,有以下配置方案: • WC • • v • WC----> M • / | • / | • v v v • S1 S2 S3
  • 52. M 表示 masetr,S 表示 slave,WC 表示提交读写操作的客户端;只提交读操作的客户端没有表示出来,因为它们无需 切换。S1,S2,S3 都是使用 --log-bin 选项,不用 --log-slave-updates 选项运行的 slave。由于除非指定 --log-slave- updates 参数,否则从 master 读到的更新操作都不会记录到二进制日志中,因此每个 slave 上的二进制日志都是空 的。如果因为某些原因 M 不能用了,可以指定一个 slave 作为 master。例如,如果指定 S1,则所有的 WC 都要重定向 到 S1 上,S2 和 S3 都需要从 S1 上同步。 确定所有的 slave 都已经处理完各自的中继日志了。在每个 slave 上,提交 STOP SLAVE IO_THREAD 语句,然 后检查 SHOW PROCESSLIST 的结果直到看到 Has read all relay log 了。当所有的 slave 都这样子 之后,就可以按照新的方案设置了。在 slave S1 上提交 STOP SLAVE 和 RESET MASTER 语句将其提升为 master。 在其他 slave S2 和 S3 上,提交 STOP SLAVE 和 CHANGE MASTER TO MASTER_HOST='S1' ( 'S1' 代表 S1 的真实主机名) 语句修改 master。把 S2,S3 如何连接到 S1 的参数 (用户,密码,端口等)都附加到 CHANGE MASTER 后面。在 CHANGE MASTER 中无需指定 S1 的二进制日志文件名和偏移位置:因为 CHANGE MASTER 默认就是第一个二 进制日志和偏移位置 4。最后,在 S2 和 S3 上提交 START SLAVE 语句。 然后让所有的 WC 都把他们的语句重定向到 S1 上。从这个时候开始,从所有的 WC 发送到 S1 上的更新语句都会写到 S1 的二进制日志中,它们包含了从 M 死掉之后发送到 S1 的全部更新语句。 配置结果如下: WC / | WC | M(unavailable)
  • 53. | | v v S1<--S2 S3 ^ | +-------+ 当 M 又起来了之后,只需在 M 上提交和在 S2 和 S3 上的一样的 CHANGE MASTER 语句,将它变成一个 slave 并且 读取自从它死掉之后的全部 WC 提交的更新操作。想要把 M 重新变成 master(例如因为它的性能更好),就执行类似上面 的操作,把 S1 当作失效了,把 M 提升为新的 master。在这个步骤中,别忘了在把 S2 和 S3 修改成为 M 的 slave 之前在 M 上运行 RESET MASTER 语句。否则的话,它们会从 M 开始失效的那个时刻开始读取 WC 提交的更新操作日志。 现在我们就运行着一个完整的自动选择 master 的 MySQL 同步系统,不过在它准备好之前,需要创建自己的监控 工具。 6.10 同步疑难解答 如果按照上述步骤设定好同步之后,它不能正常工作的话,首先检查以下内容: • 查看一下错入日志信息。不少用户都在这方面做得不够好以至于浪费时间。 • master 是否在记录二进制日志?用 SHOW MASTER STATUS 检查一下状态。如果是,Position 的值不为零; 否则,确定 master 上使用了 log-bin 和 server-id 选项。 • slave 是否运行着?运行 SHOW SLAVE STATUS 语句检查
  • 54. Slave_IO_Running 和 Slave_SQL_Running 的值是否都是。如果不是,确定是否用同步参数启动 slave 服务器了。 • 如果 slave 正在运行,它是否建立了到 master 的连接?运行 SHOW PROCESSLIST 语句检查 I/O 和 SQL 线程的 State 字段值。详情请看"6.3 Replication Implementation Details"。如果 I/O 线程状态为 Connecting to master ,就检查一下 master 上同步用户的权限是否正确, master 的主机名,DNS 设置,master 是否确实正在运行着,以及 slave 是否可连接到 master,等等。 • 如果 slave 以前运行着,但是现在停止了,原因通常是一些语句在 master 上能成功但在 slave 上却失败了。如果 salve 已经取得了 master 的全部快照,并且除了 slave 线程之外不会修改他的数据,那么应该不会发生这样的情形。如果确实 发生了,那么可能是一个 bug 或者你碰到了"6.7 Replication Features and Known Problems"中提到的同步限制之 一。如果是一个 bug,那么请按照"6.11 Reporting Replication Bugs"的说明报告它。 • 如果一个语句在 master 上成功了,但是在 slave 上却失败了,并且这时不能做一次完整的数据库再同步(也就是删除 slave 上的数据,重新拷贝 master 的快照),那么试一下: 1. 判断 slave 的数据表是否和 master 的不一样。试着找到怎么会发生这种情况,然后将 slave 的表同步成和 master 一样之后运行 START SLAVE 。 2. 如果上述步骤不生效或者没有执行,试着这个语句是否能被手工安全地运行(如果有必要),然后忽略 master 的下一个语句。 3. 如果决定要忽略 master 的下一个语句,只需在 slave 上提交以下语句: 4. mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n; mysql> START SLAVE; 如果下一个语句没有使用 AUTO_INCREMENT 或 LAST_INSERT_ID() ,那么 n 的值应为为 1 。否 则,它的值为 2 。设定为 2 是因为 AUTO_INCREMENT 或 LAST_INSERT_ID() 在 master 的二进 制日志中占用了 2 条日志。
  • 55. 5. 如果确定 slave 精确地同步 master 了,并且没有除了 slave 线程之外的对数据表的更新操作,则推断这是因 为 bug 产生的差异。如果是使用最近的版本,请报告这个问题,如果使用的是旧版本,试着升级一下。 6.11 报告同步 Bugs 当确定没有包含用户的错误,并且同步还是不能正常工作或者不稳定,就可以报告 bug 了。我们需要你尽量多的跟 踪 bug 的信息。请花点时间和努力准备一个好的 bug 报告。 如果有一个演示 bug 的可重现测试案例的话,请进入我们的 bug 数据库 http://bugs.mysql.com/。如果碰到一个 幽灵般的问题(不可重现),请按照如下步骤: 1. 确定没有包含用户错误。例如,在 slave 线程以外更新 slave 的数据,那么数据就会不能保持同步,也可能会导致 违反更新时的唯一键问题。这是外部干涉导致同步失败的问题。 2. 使用 --log-slave-updates 和 --log-bin 选项启动 slave。这会导致 slave 将从 master 读取的更 新操作写到自己的二进制日志中。 3. 在重设同步状态之前保存所有的证据。如果我们没有任何信息或者只有粗略的信息,这将很难或者不可能追查到这 个问题。需要收集以下证据: o master 上的所有二进制日志 o slave 上的所有二进制日志
  • 56. o 发现问题时,在 master 上执行 SHOW MASTER STATUS 的结果 o 发现问题时,在 master 上执行 SHOW SLAVE STATUS 的结果 o 记录 master 和 slave 的错误日志 4. 用 mysqlbinlog 来检查二进制日志。例如,用以下方法有助于找到有问题的查询: 5. shell> mysqlbinlog -j pos_from_slave_status 6. /path/to/log_from_slave_status | head 一旦收集好了问题的证据,首先将它隔离到一个独立的测试系统上。然后在我们的 bug 数据库 http://bugs.mysql.com/上进可能详细地报告问题。 ‹ MySQL 同步(四)up • MySQL 文档翻译 • Add new comment Comments Thu, 2007/07/05 - 11:10 — junphine (not verified) 我想问一下,数据库
  • 57. 我想问一下,数据库同步需要库中的表结构相同,那么我能不能在 Master 上的表中的某个字段不设索引,而在 slave 上建索引? 还有同步会不会将 Slave 中已经存在的数据删除掉(这些数据的 key 和 Master 不同)? • reply Thu, 2007/07/05 - 18:56 — yejr 1. 可以 2. 1. 可以 2. 如果 master 上有删除数据的操作,那么 slave 也会跟着做的 MySQL 方案、培训、支持 给你的祝福,要让你招架不住! • reply Fri, 2007/01/26 - 11:56 — 游客 (not verified) 你好。我想咨询一下 你好。 我想咨询一下,在同步的时候,电脑断电了,重新启动电脑后不能再同步,要重新设置 MASTER_LOG_FILE 和 MASTER_LOG_POS 值才可以继续同步。 请问有什么设置或者方法可以使同步在电脑突然断电重启后还能正常进行? • reply Fri, 2007/01/26 - 14:24 — yejr
  • 58. 老规矩,先贴上报错 老规矩,先贴上报错信息,mysql 版本,配置等资料。 MySQL 中文网: http://imysql.cn Google MySQL 中文用户群:http://groups.google.com/group/imysql 给你的祝福,要让你招架不住! • reply Sat, 2007/01/27 - 11:11 — 游客 (not verified) 感谢你抽空解答我的 感谢你抽空解答我的问题。下面这些就是版本,错误信息及设置。我刚接触 mysql,请多多指教。 版本:mysql 5.0.20-nt *.err 的错误信息: 070127 10:25:11 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Restoring possible half-written data pages from the doublewrite InnoDB: buffer... 070127 10:26:22 InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 8 3059764932. InnoDB: Doing recovery: scanned up to log sequence number 8 3065007616 InnoDB: Doing recovery: scanned up to log sequence number 8 3070250496 InnoDB: Doing recovery: scanned up to log sequence number 8 3075493376
  • 59. InnoDB: Doing recovery: scanned up to log sequence number 8 3077233098 070127 10:26:24 InnoDB: Starting an apply batch of log records to the database... InnoDB: Progress in percents: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 InnoDB: Apply batch completed InnoDB: In a MySQL replication slave the last master binlog file InnoDB: position 0 47510, file name My binLog.000051 InnoDB: Last MySQL binlog file position 0 319593, file name .My binLog.000001 070127 10:26:29 InnoDB: Started; log sequence number 8 3077233098 070127 10:26:30 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay- log=tests8000-02-relay-bin' to avoid this problem. 070127 10:26:30 [Note] D:GreenampMySQLbinmysqld-nt: ready for connections. Version: '5.0.20-nt' socket: '' port: 3308 MySQL Community Edition (GPL) 070127 10:26:30 [Note] Slave SQL thread initialized, starting replication in log 'My binLog.000051' at position 31899609, relay log '.tests8000-02-relay-bin.000029' position: 31890015 070127 10:26:30 [ERROR] Error in Log_event::read_log_event(): 'Event too small', data_len: 0, event_type: 0 070127 10:26:30 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O error 070127 10:26:30 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE
  • 60. STATUS' on this slave. Error_code: 0 070127 10:26:30 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'My binLog.000051' position 31899609 070127 10:26:31 [ERROR] Slave I/O thread: error connecting to master 'Ad@localhost:3306': Error: 'Can't connect to MySQL server on 'localhost' (10061)' errno: 2003 retry-time: 60 retries: 86400 070127 10:27:31 [Note] Slave I/O thread: connected to master 'Ad@localhost:3306', replication started in log 'My binLog.000051' at position 31899609 但在 slave 端用 show slave status,则显示如下内容: mysql> show slave statusG *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: Ad Master_Port: 3306 Connect_Retry: 60 Master_Log_File: My binLog.000052 Read_Master_Log_Pos: 260 Relay_Log_File: tests8000-02-relay-bin.000029 Relay_Log_Pos: 31890015 Relay_Master_Log_File: My binLog.000051 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: