第6章:MySQL中的复制 / 6.4. 如何设置复制

这里简单描述了如何为你当前的MySQL服务器设置完整的复制。假设你想要复制主服务器上的所有数据库,并且还没有配置的复制。你需要关闭主服务器来完成下面所列的步骤。

下面的程序针对设置一个从服务器,你可以用来设置多个从服务器。

虽然该方法是设置从服务器的最直接的途径,它并不是唯一的一个。例如,如果你有一个主服务器的数据快照,并且主服务器已经设置了服务器ID,启用了二进制日志,不需要关闭主服务器或停止对它的更新也可以设置从服务器。详情请参见6.9节,“复制FAQ”

如果想要管理MySQL复制设置,我们建议你通读本章,并尝试13.6.1节,“用于控制主服务器的SQL语句”13.6.2节,“用于控制从服务器的SQL语句”中的所有语句。还应熟悉6.8节,“复制启动选项”中描述的复制启动选项。

注释:该程序和后面章节所示的复制SQL语句需要SUPER权限。

1.    确保在服务器和从服务器上安装的MySQL版本与6.5节,“不同MySQL版本之间的复制兼容性”所示的表兼容。理想情况,应在主服务器和从服务器上使用最近版本的MySQL

请先证实问题不是出现在最新的MySQL版本中再通报bug

2.    在主服务器上为服务器设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做),则不需要再授予任何其它权限。(关于设置用户 账户和权限的信息,参见5.8节,“MySQL用户账户管理”

假定你的域为mydomain.com,想要创建用户名为repl的一个账户,从服务器可以使用该账户从你的域内的任何主机使用密码slavepass来访问主服务器。要创建该 账户,可使用GRANT语句:

mysql> GRANT REPLICATION SLAVE ON *.*
    -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';

如果你计划从从属服务器主机使用LOAD TABLE FROM MASTERLOAD DATA FROM MASTER语句,你需要授予该账户其它权限:

·         授予账户SUPERRELOAD全局权限。

·         为所有想要装载的表授予SELECT权限。任何该 账户不能SELECT的主服务器上的表被LOAD DATA FROM MASTER忽略掉。

3.    执行FLUSH TABLES WITH READ LOCK语句清空所有表和块写入语句:

4.            mysql> FLUSH TABLES WITH READ LOCK

对于InnoDB表,请注意:FLUSH TABLES WITH READ LOCK还锁定COMMIT操作。当获得全局读锁定后,可以开始InnoDB表的文件系统快照。快照不能保证内部(InnoDB存储引擎内部)一致性(因为InnoDB缓存没有刷新),但并不需要关心该问题,因为InnoDB可以在启动时解决该问题并给出一致的结果。这说明InnoDB在启动快照时可以进行崩溃恢复,而不会破坏。然而,当保证一致的InnoDB表快照时,还没有途径来停止MySQL服务器。

让客户程序保持运行,发出FLUSH TABLES语句让读锁定保持有效。(如果退出客户程序,锁被释放)然后对主服务器上的数据进行快照。

创建快照最简单的途径是使用归档程序对主服务器上的数据目录中的数据库进行二进制备份。例如,在Unix中使用tar,或者在Windows中使用PowerArchiverWinRARWinZip或者类似的软件。要使用tar来创建包括所有数据库的归档文件,进入主服务器的数据目录,然后执行命令:

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

如果你想让归档只包括this_db数据库,应使用命令:

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

然后将归档文件复制到从服务器主机的/tmp目录。在该机器上,进入从服务器的数据目录,并使用下述命令解压缩归档文件:

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

如果从服务器的用户账户与主服务器的不同,你可能不想复制mysql数据库。在这种情况下,应从归档中排除该数据库。你也不需要在归档中包括任何日志文件或者master.inforelay-log.info文件。

FLUSH TABLES WITH READ LOCK所置读锁定有效时,读取主服务器上当前的二进制日志名和偏移量值:

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。记录该值。以后设置从服务器时需要使用这些值。它们表示复制坐标,从服务器应从该点开始从主服务器上进行新的更新。

取得快照并记录日志名和偏移量后,可以在主服务器上重新启用写活动:

mysql> UNLOCK TABLES

如果你正使用InnoDB表,理想情况应使用InnoDB Hot Backup工具,使用该工具可以获得一致的快照而不需要在主服务器上进行锁定,并且可以对应从服务器上使用的快照来记录日志名和偏移量。Hot Backup是一个附加的非免费(商业)工具,没有包含在标准 MySQL分发中。详细信息参见http://www.innodb.com/manual.phpInnoDB Hot Backup主页。

不使用Hot Backup工具,最快捷的途径是使用InnoDB表的二进制快照来关闭主服务器并复制InnoDB数据文件、日志文件和表定义文件(.frm文件)。要记录当前的日志文件名和偏移量,关闭服务器之前应发出下面的语句:

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

然后记录前面所示的SHOW MASTER STATUS的输出中显示的日志名和偏移量。记录日志名和偏移量后,解锁表关闭服务器以确保  服务器关闭时的快照与当前的日志文件和偏移量相对应:

shell> mysqladmin -u root shutdown

适合MyISAMInnoDB表的另一个方法是对主服务器上的SQL进行转储而不是对前面讨论的二进制复制进行转储。为了实现,可以在主服务器上使用mysqldump --master-data,以后将SQL转储文件装入从服务器。但是,这样比二进制复制要慢一些。

如果主服务器运行时没有启用--logs-binSHOW MASTER STATUSmysqldump --master-data显示的日志名和位置值为空。在这种情况下,当以后指定从服务器的日志文件和位置时需要使用的值为空字符串('')4.

5.    确保主服务器主机上my.cnf文件的[mysqld]部分包括一个log-bin选项。该部分还应有一个server-id=Master_id选项,其中master_id必须为12321之间的一个正整数值。例如:

6.            [mysqld]
7.            log-bin=mysql-bin
8.            server-id=1

如果没有提供那些选项,应添加它们并重启服务器。

9.    停止用于从服务器的服务器并在其my.cnf文件中添加下面的行:

10.        [mysqld]
11.        server-id=slave_id

slave_id值同Master_id值一样,必须为12321之间的一个正整数值。并且,从服务器的ID必须与主服务器的ID不相同。例如:

[mysqld]
server-id=2

如果设置多个从服务器,每个从服务器必须有一个唯一的server-id值,必须与主服务器的以及其它从服务器的不相同。可以认为server-id值类似于IP地址:这些ID值能唯一识别复制服务器群集中的每个服务器实例。

如果不指定一个server-id值,如果没有定义master-host,则将它设置为1;否则设置为2。请注意如果server-id太长,主服务器 拒绝所有来自从服务器的连接,并且从服务器拒绝连接到主服务器。这样,省略server-id只适合用二进制日志备份。

12.如果对主服务器的数据进行二进制备份,启动从服务器之前将它复制到从服务器的数据目录中。确保对这些文件和目录的权限正确。服务器 MySQL运行的用户必须能够读写文件,如同在主服务器上一样。

如果使用mysqldum备份,先启动从服务器(看下一步)

13.启动从服务器。如果前面已经复制了,用--skip-slave-start选项启动从服务器,以便它不立即尝试连接主服务器。你也可能想要用--logs-warnings选项启动从服务器(默认设置启用),以便在错误日志中显示更多的问题相关的信息(例如,网络或连接问题)。放弃的连接将记入错误日志,除非其值大于1

14.如果使用mysqldump备份主服务器的数据,将转储文件装载到从服务器:

15.        shell> mysql -u root -p < dump_file.sql
16.        在从服务器上执行下面的语句,用你的系统的实际值替换选项值:
17.        mysql> CHANGE MASTER TO
18.            ->     MASTER_HOST='master_host_name',
19.            ->     MASTER_USER='replication_user_name',
20.            ->     MASTER_PASSWORD='replication_password',
21.            ->     MASTER_LOG_FILE='recorded_log_file_name',
22.            ->     MASTER_LOG_POS=recorded_log_position;

下面的表显示了字符串选项的最大长度:

Master_Host

60

Master_USER

16

Master_PASSWORD

32

Master_Log_File

255

23.启动从服务器线程:

24.        mysql> START SLAVE

执行这些程序后,从服务器应连接主服务器,并补充自从快照以来发生的任何更新。

如果你忘记设置主服务器的server-id值,从服务器不能连接主服务器。

如果你忘记设置从服务器的server-id值,在从服务器的错误日志中会出现下面的错误:

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

如果由于其它原因不能复制,从服务器的错误日志中也会出现错误消息。

从服务器复制时,会在其数据目录中发现文件dmaster.inforelay-log.info。从服务器使用这两个文件跟踪已经处理了多少主服务器的二进制日志。不要移除或编辑这些文件,除非你确切知你正在做什么并完全理解其意义。即使这样,最好是使用CHANGE MASTER TO语句。

注释:master.info内容会覆盖命令行或in my.cnf中指定的部分选项。详情参见6.8节,“复制启动选项”

有了一个快照,你可以用它根据刚刚描述的从服务器部分来设置其它从服务器。你不需要主服务器的另一个快照;每个从服务器可以使用相同的快照。

注释:为了保证事务InnoDB复制设置的最大可能的耐受性和一致性,应在主服务器的my.cnf文件中使用innodb_flush_log_at_trx_commit=1sync-binlog=1