第6章:MySQL中的复制 / 6.8. 复制启动选项

在主服务器和从服务器上,均必须使用server-id选项为每个服务器建立唯一的复制ID。你应为每个主服务器和从服务器从12321的范围挑一个唯一的正整数。例如:server-id=3

用于主服务器上控制二进制日志的选项的相关描述见5.11.3节,“二进制日志”

下表描述了可以用于MySQL 5.1从属复制服务器的选项。你可以在命令行中或在选项文件中指定这些选项。

某些从服务器复制选项按特殊方式处理,当从服务器启动时如果master.info文件存在并且包含选项值,它们将被忽略掉。下面的选项按这种方式处理:

·         --master-host

·         --master-user

·         --master-password

·         --master-port

·         --master-connect-retry

·         --master-ssl

·         --master-ssl-ca

·         --master-ssl-capath

·         --master-ssl-cert

·         --master-ssl-cipher

·         --master-ssl-key

5.1中的master.info文件格式包括对应SSL选项的值。并且,文件格式包括文件中的行号,如同第1行。如果你将旧的服务器升级到新的版本,新服务器启动时自动将smaster.info文件升级到新的格式。然而,如果将新服务器降级到旧的版本,首次启动旧版本的服务器之前应删除第1行。

如果从服务器启动时master.info文件不存在,选项采用选项文件或命令行中指定的值。首次将服务器作为从服务器启动时,或者已经运行RESET SLAVE然后已经关闭并重启从服务器时会发生。

如果从服务器启动时master.info文件存在,服务器忽略那些选项。使用master.info文件中发现的值。

如果你使用与master.info文件中相对应的启动选项的不同的值重启从服务器,启动选项的不同的值不会生效,因为服务器继续使用master.info文件。要想使用启动选项的不同的值,必须删除master.info文件并重启从服务器,或(最好是)在从服务器运行时使用CHANGE MASTER TO语句重新设置值。

假定在my.cnf文件中指定该选项:

[mysqld]
master-host=some_host

1次作为复制从服务器启动服务器时,从my.cnf文件读取并使用选项。服务器然后记录master.info文件中的值。下次启动服务器时,它只从服务器的master.info文件读取主服务器主机值并忽略选项文件中的值。如果你修改my.cnf文件为some_other_host指定其它主服务器主机,更改仍然不会生效。你应使用CHANGE MASTER TO

因为服务器给已有master.info文件的优先权高于刚刚描述的启动选项,可以选择不使用这些值的启动选项,而是使用CHANGE MASTER TO语句来指定。参见13.6.2.1节,“CHANGE MASTER TO语法”

下面的例子显示了如何更广泛地使用启动选项来配置从服务器:

[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-*选项,只能在从服务器启动时进行设置。我们计划将修复该问题。

·         --logs-slave-updates

通常情况,从服务器从主服务器接收到的更新不记入它的二进制日志。该选项告诉从服务器将其SQL线程执行的更新记入到从服务器自己的二进制日志。为了使该选项生效,还必须用--logs-bin选项启动从服务器以启用二进制日志。如果想要应用链式复制服务器,应使用--logs-slave-updates。例如,可能你想要这样设置:

A -> B -> C

也就是说,A为从服务器B的主服务器,B为从服务器C的主服务器。为了能工作,B必须既为主服务器又为从服务器。你必须用--logs-bin启动AB以启用二进制日志,并且用--logs-slave-updates选项启动B

·         --logs-warnings

让从服务器向错误日志输出更详细的关于其执行操作的消息。例如,通知你网络/连接失败后已经成功重新连接,并通知你每个从服务器线程如何启动。该选项默认启用;要想禁用它,使用--skip-logs-warnings。放弃的连接不记入错误日志,除非该值大于1

请注意该选项的效果不限于复制。可以对服务器的部分动作产生警告。

·         --master-connect-retry=seconds

在主服务器宕机或连接丢失的情况下,从服务器线程重新尝试连接主服务器之前睡眠的秒数。如果主服务器.info文件中的值可以读取则优先使用。如果未设置, 默认值为60

·         --master-host=host

主复制服务器的主机名或IP地址。如果没有给出该选项,从服务器线程不启动。如果主服务器.info文件中的值可以读取则优先使用。

·         --master-info-file=file_name

从服务器用于记录主服务器的相关信息使用的文件名。默认名为数据目录中的mysql.info

·         --master-password=password

连接主服务器时从服务器线程用于鉴定的账户的密码。如果主服务器.info文件中的值可以读取则优先使用。如果未设置,假定 密码为空。

·         --master-port=port_number

主服务器正帧听的TCP/IP端口号。如果主服务器.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设置与主服务器的安全复制连接。它们的含义与5.8.7.6节,“SSL命令行选项”中描述的相应ssl--ssl-ca--ssl-capath--ssl-cert--ssl-cipher--ssl-key选项相同。如果主服务器.info文件中的值可以读取则优先使用。

·         --master-user=username

连接主服务器时从服务器线程用于鉴定的账户的用户名。该账户必须具有REPLICATION SLAVE权限。如果主服务器.info文件中的值可以读取则优先使用。如果未设置主服务器用户,假定使用用户test

·         --max-relay-logs-size=size

自动循环中继日志。参见5.3.3节,“服务器系统变量”

·         --read-only

该选项让从服务器只允许来自从服务器线程或具有SUPER权限的用户的更新。可以确保从服务器不接受来自客户的更新。

·         --relay-log=file_name

中继日志名。默认名为host_name-relay-bin.nnnnnn,其中host_name是从服务器主机的名,nnnnnn表示中继日志在编号序列中创建。如果中继日志太大(并且你不想降低max_relay_log_size),需要将它们放到数据目录之外的其它地方,或者如果想要通过硬盘之间的负载均衡提高速度,可以指定选项创建与主机名无关的中继日志名。

·         --relay-log-index=file_name

中继日志索引文件使用的位置和名称。默认名为host_name-relay-bin.index,其中host_name为从服务器名。

·         --relay-log-info-file=file_name

从服务器用于记录中继日志相关信息的文件名。默认名为数据目录中的relay-log.info

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

禁用或启用不再需要中继日志时是否自动清空它们。默认值为1(启用)。这是一个全局变量,可以用SET GLOBAL Relay_log_purge动态更改。

·         --relay-log-space-limit=size

限制所有中继日志在从服务器上所占用空间的上限(0值表示“无限制)。从服务器主机硬盘空间有限时很有用。达到限制后,I/O线程停止从主服务器读取二进制日志中的事件,直到SQL线程被闭锁并且删除了部分未使用的中继日志。请注意该限制并不是绝对的:有可能SQL线程删除中继日志前需要更多的事件。在这种情况下,I/O线程将超过限制,直到SQL线程可以删除部分中继日志。(不这样做将会造成死锁)--relay-log-space-limit的值不能小于--max-relay-logs-size(或如果--max-relay-logs-size0,选--max-binlog-size)的值的两倍。在这种情况下,有可能I/O线程等待释放空间,因为超过了--relay-log-space-limit,但SQL线程没有要清空的中继日志,不能满足I/O线程的需求。强制I/O线程临时忽视--relay-log-space-limit

·         --replicate-do-db=db_name

告诉从服务器限制默认数据库(USE所选择)db_name的语句的复制。要指定多个数据库,应多次使用该选项,每个数据库使用一次。请注意不复制跨数据库的语句,例如当已经选择了其它数据库或没有数据库时执行UPDATE some_db.some_table SET foo='bar'。如果需要跨数据库进行更新,使用--replicate-wild-do-table=db_name.%。请读取该选项列表后面的注意事项。

一个不能按照期望工作的例子:如果用--replicate-do-db=sales启动从服务器,并且在主服务器上执行下面的语句,UPDATE语句不会复制:

USE prices;
UPDATE sales.january SET amount=amount+1000;

如果需要跨数据库进行更新,应使用--replicate-wild-do-table=db_name.%

只检查默认数据库”行为的主要原因是语句自己很难知道它是否应被复制(例如,如果你正使用跨数据库的多表DELETE语句或多表UPDATE语句)。如果不需要,只检查默认数据库比检查所有数据库要快得多。

·         --replicate-do-table=db_name.tbl_name

告诉从服务器线程限制对指定表的复制。要指定多个表,应多次使用该选项,每个表使用一次。同--replicate-do-db对比,允许跨数据库更新。请读取该选项列表后面的注意事项。

·         --replicate-ignore-db=db_name

告诉从服务器不要复制默认数据库(USE所选择)db_name的语句。要想忽略多个数据库,应多次使用该选项,每个数据库使用一次。如果正进行跨数据库更新并且不想复制这些更新,不应使用该选项。请读取该选项后面的注意事项。

一个不能按照期望工作的例如:如果用--replicate-ignore-db=sales启动从服务器,并且在主服务器上执行下面的语句,UPDATE语句不会复制:

·                USE prices;
·                UPDATE sales.january SET amount=amount+1000;

如果需要跨数据库更新,应使用--replicate-wild-ignore-table=db_name.%

·         --replicate-ignore-table=db_name.tbl_name

告诉从服务器线程不要复制更新指定表的任何语句(即使该语句可能更新其它的表)。要想忽略多个表,应多次使用该选项,每个表使用一次。同--replicate-ignore-db对比,该选项可以跨数据库进行更新。请读取该选项后面的注意事项。

·         --replicate-wild-do-table=db_name.tbl_name

告诉从服务器线程限制复制更新的表匹配指定的数据库和表名模式的语句。模式可以包含‘%’和‘_’通配符,与LIKE模式匹配操作符具有相同的含义。要指定多个表,应多次使用该选项,每个表使用一次。该选项可以跨数据库进行更新。请读取该选项后面的注意事项。

例如:--replicate-wild-do-table=foo%.bar%只复制数据库名以foo开始和表名以bar开始的表的更新。

如果表名模式为%,可匹配任何表名,选项也适合数据库级语句(CREATE DATABASEDROP DATABASEALTER DATABASE)。例如,如果使用--replicate-wild-do-table=foo%.%,如果数据库名匹配模式foo%,则复制数据库级语句。

要想在数据库或表名模式中包括通配符,用反斜线对它们进行转义。例如,要复制名为my_own%db的数据库的所有表,但不复制my1ownAABCdb数据库的表,应这样转义‘_’和‘%’字符:--replicate-wild-do-table=my\_own\%db。如果在命令行中使用选项,可能需要双反斜线或将选项值引起来,取决于命令解释符。例如,用bash外壳则需要输入--replicate-wild-do-table=my\\_own\\%db

·         --replicate-wild-ignore-table=db_name.tbl_name

告诉从服务器线程不要复制表匹配给出的通配符模式的语句。要想忽略多个表,应多次使用该选项,每个表使用一次。该选项可以跨数据库进行更新。请读取该选项后面的注意事项。

例如:--replicate-wild-ignore-table=foo%.bar%不复制数据库名以foo开始和表名以bar开始的表的更新。

关于匹配如何工作的信息,参见--replicate-wild-do-table选项的描述。在选项值中包括通配符的规则与--replicate-wild-ignore-table相同。

·         --replicate-rewrite-db=from_name->to_name

告诉从服务器如果默认数据库(USE所选择)为主服务器上的from_name,则翻译为to_name。只影响含有表的语句(不是类似CREATE DATABASEDROP DATABASEALTER DATABASE的语句),并且只有from_name为主服务器上的默认数据库时。该选项不可以跨数据库进行更新。请注意在测试--replicate-*规则之前翻译数据库名。

如果在命令行中使用该选项, ‘>’字符专用于命令解释符,应将选项值引起来。例如:

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

·         --replicate-same-server-id

将用于从服务器上。通常可以默认设置为0以防止循环复制中的无限循环。如果设置为1,该从服务器不跳过有自己的服务器id的事件;通常只在有很少配置的情况下有用。如果使用--logs-slave-updates不能设置为1。请注意默认情况下如果有从服务器的id,服务器I/O线程不将二进制日志事件写入中继日志(该优化可以帮助节省硬盘的使用)。因此如果想要使用--replicate-same-server-id,让从服务器读取自己的SQL线程执行的事件前,一定要用该选项启动。

·         --report-host=slave_name

从服务器注册过程中报告给主服务器的主机名或IP地址。该值出现在主服务器上SHOW SLAVE HOSTS的输出中。如果不想让从服务器自己在主服务器上注册,则不设置该值。请注意从服务器连接后,主服务器仅仅从TCP/IP套接字读取从服务器的IP号是不够的。由于 NAT和其它路由问题,IP可能不合法,不能从主服务器或其它主机连接从服务器。

·         --report-port=slave_port

连接从服务器的TCP/IP端口号,从服务器注册过程中报告给主服务器。只有从服务器帧听非默认端口或如果有一个特殊隧道供主服务器或其它客户连接从服务器时才设置它。如果你不确定,不设置该选项。

·         --skip-slave-start

告诉从服务器当服务器启动时不启动从服务器线程。使用START SLAVE语句在以后启动线程。

·         --slave_compressed_protocol={0|1}

如果该选项设置为 1,如果从服务器和主服务器均支持,使用压缩从服务器/主服务器协议。

·         --slave-load-tmpdir=file_name

从服务器创建临时文件的目录名。该选项默认等于tmpdir系统变量的值。当从服务器SQL线程复制LOAD DATA INFILE语句时,从中继日志将待装载的文件提取到临时文件,然后将这些文件装入到表中。如果装载到主服务器上的文件很大,从服务器上的临时文件也很大。因此,建议使用该选项告诉从服务器将临时文件放到文件系统中有大量可用空间的目录下。在这种情况下,也可以使用--relay-log选项将中继日志放到该文件系统中,因为中继日志也很大。--slave-load-tmpdir应指向基于硬盘的文件系统,而非基于内存的文件系统:从服务器需要用临时文件在机器重启时用于复制LOAD DATA INFILE。系统启动过程中操作系统也不能清除该目录。

·         --slave-net-timeout=seconds

放弃读之前从主服务器等候更多数据的秒数,考虑到连接中断和尝试重新连接。超时后立即开始第1次重试。由--master-connect-retry选项控制重试之间的间隔。

·         --slave-skip-errors=[err_code1,err_code2,... | all]

通常情况,当出现错误时复制停止,这样给你一个机会手动解决数据中的不一致性问题。该选项告诉从服务器SQL线程当语句返回任何选项值中所列的错误时继续复制。

如果你不能完全理解为什么发生错误,则不要使用该选项。如果复制设置和客户程序中没有bug,并且MySQL自身也没有bug,应不会发生停止复制的错误。滥用该选项会使从服务器与主服务器不能保存同步,并且你找不到原因。

对于错误代码,你应使用从服务器错误日志中错误消息提供的编号和SHOW SLAVE STATUS的输出。服务器错误代码列于附录B:错误代码和消息

你也可以(但不应)使用不推荐的all值忽略所有错误消息,不考虑所发生的错误。无需而言,如果使用该值,我们不能保证数据的完整性。在这种情况下,如果从服务器的数据与主服务器上的不相近请不要抱怨(或编写bug报告)已经警告你了

例如:

--slave-skip-errors=1062,1053
--slave-skip-errors=all

从服务器按下面评估--replicate-*规则,确定是否执行或忽视语句:

1.    是否有--replicate-do-db--replicate-ignore-db规则?

·         :测试--binlog-do-db--binlog-ignore-db(参见5.11.3节,“二进制日志”)。测试结果是什么?

o        忽视语句:忽视并退出。

o        许可语句:不立即执行语句。推迟决策;继续下一步。

·         没有:继续下一步。

2.    我们目前正执行保存的程序或函数吗?

·         :执行查询并退出。

·         :继续下一步。

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

·         没有:执行查询并退出。

·         :继续下一步并开始按所示顺序评估表规则(首先是非通配规则,然后是通配规则)。只有待更新的表根据这些规则进行比较(INSERT INTO sales SELECT * FROM prices:只有sales根据这些规则进行比较)。如果要更新几个表(多表语句),第1个匹配的表(匹配“do”或“ignore)获赢。也就是说,根据这些规则比较第1个表。然后,如果不能进行决策,根据这些规则比较第2个表等等。

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

·         :表匹配吗?

o        :执行查询并退出。

o        :继续下一步。

·         没有:继续下一步。

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

·         :表匹配吗?

o        :忽视查询并退出。

o        :继续下一步。

·         没有:继续下一步。

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

·         :表匹配吗?

o        :执行查询并退出。

o        :继续下一步。

·         没有:继续下一步。

7.    是否有--replicate-wild-ignore-table规则?

·         :表匹配吗?

o        :忽视查询并退出。

o        :继续下一步。

·         没有:继续下一步。

8.    没有匹配的--replicate-*-table规则。要根据这些规则测试其它表吗?

·         :执行循环。

·         :我们现在已经测试了所有待更新的表,结果不能匹配任何规则。是否有--replicate-do-table--replicate-wild-do-table规则?

o        :有“do”规则但不匹配。忽视查询并退出。

o        没有:执行查询并退出。