### 第6章:MySQL中的复制
本章描述了MySQL提供的各种复制特性。引入了复制概念,显示如何设置复制服务器和服务以指导相应的复制选项。还提供了FAQ(以及答案) 列表,以及解决复制问题的排错建议。
关于复制相关的SQL语句的语法描述,参见[13.6节,“复制语句”](# "13.6. Replication Statements")。
我们建议你经常访问我们的网址[http://www.mysql.com](http://www.mysql.com),并检查对本章的修改。复制在不断地得到改进,我们用最新的信息定期更新本手册。
### 6.1. 复制介绍
MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。(这与_同步_复制可以进行对比,_同步_复制是MySQL簇的一个特征—参见[第17章:](#)[_MySQL簇_](# "Chapter 17. MySQL Cluster"))。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
如果你想要设置链式复制服务器,从服务器本身也可以充当主服务器。
请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
单向复制有利于健壮性、速度和系统管理:
· 主服务器/从服务器设置增加了健壮性。主服务器出现问题时,你可以切换到从服务器作为备份。
· 通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间。SELECT查询可以发送到从服务器以降低主服务器的查询处理负荷。但修改数据的语句仍然应发送到主服务器,以便主服务器和从服务器保持同步。如果非更新查询为主,该负载均衡策略很有效,但一般是更新查询。
· 使用复制的另一个好处是可以使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。参见[5.9.1节,“数据库备份”](# "5.9.1. Database Backups")。
### 6.2. 复制实施概述
MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。参见[5.11.3节,“二进制日志”](# "5.11.3. The Binary Log")。
每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。
认识到二进制日志只是一个从启用二进制日志的固定时间点开始的记录_非常_重要。任何设置的从服务器需要主服务器上的_在主服务器上启用二进制日志时的_数据库拷贝。如果启动从服务器时,其数据库与主服务器上的启动二进制日志时的状态不相同,从服务器很可能失败。
将主服务器的数据拷贝到从服务器的一个途径是使用LOAD DATA FROM MASTER语句。请注意LOAD DATA FROM MASTER目前只在所有表使用MyISAM存储引擎的主服务器上工作。并且,该语句将获得全局读锁定,因此当表正复制到从服务器上时,不可能在主服务器上进行更新。当我们执行表的无锁热备份时,则不再需要全局读锁定。
由于这些限制,我们建议只有主服务器上的数据集相对较小,或者主服务器上延迟读锁定已经被接受,才可以使用LOAD DATA FROM MASTER。而LOAD DATA FROM MASTER的实际速度随系统的不同而不同,对于执行时间,最好的规则是每1MB的数据用1秒钟。这是一个粗略的估计,但你会发现如果主服务器和从服务器的性能上等价于700MHz Pentium CPU,通过100Mbps的网络进行连接,则该估计相当准确。
从服务器设置为复制主服务器的数据后,它连接主服务器并等待更新过程。如果主服务器失败,或者从服务器失去与主服务器之间的连接,从服务器保持定期尝试连接,直到它能够继续帧听更新。由--master-connect-retry选项控制重试间隔。 默认为60秒。
每个从服务器跟踪复制时间。主服务器不知道有多少个从服务器或在某一时刻有哪些被更新了。
### 6.3. 复制实施细节
[ 6.3.1. 复制主线程状态](#)[ 6.3.2. 复制从I/O线程状态](#)[ 6.3.3. 复制从SQL线程状态](#)[ 6.3.4. 复制传递和状态文件](#)
MySQL使用3个线程来执行复制功能(其中1个在主服务器上,另两个在从服务器上。当发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以识别为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即_中继日志_。第3个线程是SQL线程,是从服务器创建用于读取中继日志并执行日志中包含的更新。
在前面的描述中,每个从服务器有3个线程。有多个从服务器的主服务器创建为每个当前连接的从服务器创建一个线程;每个从服务器有自己的I/O和SQL线程。
这样读取和执行语句被分成两个独立的任务。如果语句执行较慢则语句读取任务没有慢下来。例如,如果从服务器有一段时间没有运行了,当从服务器启动时,其I/O线程可以很快地从主服务器索取所有二进制日志内容,即使SQL线程远远滞后。如果从服务器在SQL线程执行完所有索取的语句前停止,I/O 线程至少已经索取了所有内容,以便语句的安全拷贝保存到本地从服务器的中继日志中,供从服务器下次启动时执行。这样允许清空主服务器上的二进制日志,因为不再需要等候从服务器来索取其内容。
SHOW PROCESSLIST语句可以提供在主服务器上和从服务器上发生的关于复制的信息。
下面的例子说明了这3个线程在SHOW PROCESSLIST中的显示。
在主服务器上,SHOW PROCESSLIST的输出看上去应为:
mysql> SHOW PROCESSLIST\G
*************************** 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是一个连接从服务器的复制线程。该信息表示所有主要更新已经被发送到从服务器,主服务器正等待更多的更新出现。
在从服务器上,SHOW PROCESSLIST的输出看上去应为:
mysql> SHOW PROCESSLIST\G
*************************** 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线程,线程11是处理保存在中继日志中的更新的SQL线程。SHOW PROCESSLIST运行时,两个线程均空闲,等待其它更新。
请注意Time列的值可以显示从服务器比主服务器滞后多长时间。参见[6.9节,“复制FAQ”](# "6.9. Replication FAQ")。
### 6.3.1. 复制主线程状态
下面列出了主服务器的Binlog Dump线程的State列的最常见的状态。如果你没有在主服务器上看见任何Binlog Dump线程,这说明复制没有在运行—即,目前没有连接任何从服务器。
· Sending binlog event to slave
二进制日志由各种事件组成,一个事件通常为一个更新加一些其它信息。线程已经从二进制日志读取了一个事件并且正将它发送到从服务器。
· Finished reading one binlog; switching to next binlog
线程已经读完二进制日志文件并且正打开下一个要发送到从服务器的日志文件。
· Has sent all binlog to slave; waiting for binlog to be updated
线程已经从二进制日志读取所有主要的更新并已经发送到了从服务器。线程现在正空闲,等待由主服务器上新的更新导致的出现在二进制日志中的新事件。
· Waiting to finalize termination
线程停止时发生的一个很简单的状态。
### 6.3.2. 复制从I/O线程状态
下面列出了从服务器的I/O线程的State列的最常见的状态。该状态也出现在Slave_IO_State列,由SHOW SLAVE STATUS显示。这说明你可以只通过该语句仔细浏览所发生的事情。
· Connecting to master
线程正试图连接主服务器。
· Checking master version
建立同主服务器之间的连接后立即临时出现的状态。
· Registering slave on master
建立同主服务器之间的连接后立即临时出现的状态。
· Requesting binlog dump
建立同主服务器之间的连接后立即临时出现的状态。线程向主服务器发送一条请求,索取从请求的二进制日志文件名和位置开始的二进制日志的内容。
· Waiting to reconnect after a failed binlog dump request
如果二进制日志转储请求失败(由于没有连接),线程进入睡眠状态,然后定期尝试重新连接。可以使用--master-connect-retry选项指定重试之间的间隔。
· Reconnecting after a failed binlog dump request
线程正尝试重新连接主服务器。
· Waiting for master to send event
线程已经连接上主服务器,正等待二进制日志事件到达。如果主服务器正空闲,会持续较长的时间。如果等待持续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
线程正尝试重新连接主服务器。当连接重新建立后,状态变为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. 复制从SQL线程状态
下面列出了从服务器的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
线程停止时发生的一个很简单的状态。
I/O线程的State列也可以显示语句的文本。这说明线程已经从中继日志读取了一个事件,从中提取了语句,并且正在执行语句。
### 6.3.4. 复制传递和状态文件
默认情况,中继日志使用_host_name-relay-bin.nnnnnn_形式的文件名,其中_host_name_是从服务器主机名,_nnnnnn_是序列号。用连续序列号来创建连续中继日志文件,从000001开始。从服务器跟踪索引文件中目前正使用的中继日志。 默认中继日志索引文件名为_host_name-relay-bin.index_。默认情况,在从服务器的数据目录中创建这些文件。可以用--relay-log和--relay-log-index服务器选项覆盖 默认文件名。参见[6.8节,“复制启动选项”](# "6.8. Replication Startup Options")。
中继日志与二进制日志的格式相同,并且可以用**mysqlbinlog**读取。SQL线程执行完中继日志中的所有事件并且不再需要之后,立即自动删除它。没有直接的删除中继日志的机制,因为SQL线程可以负责完成。然而,FLUSH LOGS可以循环中继日志,当SQL线程删除日志时会有影响。
在下面的条件下创建新的中继日志:
· 每次I/O线程启动时创建一个新的中继日志。
· 当日志被刷新时;例如,用FLUSH LOGS或**mysqladmin flush-logs**。
· 当当前的中继日志文件变得太大时。“太大”含义的确定方法:
o max_relay_log_size,如果max_relay_log_size > 0
o max_binlog_size,如果max_relay_log_size = 0
从属复制服务器在数据目录中另外创建两个小文件。这些_状态文件_默认名为主master.info和relay-log.info。它们包含SHOW SLAVE STATUS语句的输出所显示的信息(关于该语句的描述参见[13.6.2节,“用于控制从服务器的SQL语句”](# "13.6.2. SQL Statements for Controlling Slave Servers"))。状态文件保存在硬盘上,从服务器关闭时不会丢失。下次从服务器启动时,读取这些文件以确定它已经从主服务器读取了多少二进制日志,以及处理自己的中继日志的程度。
由I/O线程更新master.info文件。文件中的行和SHOW SLAVE STATUS显示的列的对应关系为:
<table border="1" cellpadding="0" id="table1"><tr><td> <p><strong><span>行</span></strong></p></td> <td> <p><strong><span>描述</span></strong></p></td> </tr><tr><td> <p><span>1</span></p></td> <td> <p>文件中的行号</p></td> </tr><tr><td> <p><span>2</span></p></td> <td> <p> <span>Master_Log_File</span></p></td> </tr><tr><td> <p><span>3</span></p></td> <td> <p> <span> Read_Master_Log_Pos</span></p></td> </tr><tr><td> <p><span>4</span></p></td> <td> <p> <span>Master_Host</span></p></td> </tr><tr><td> <p><span>5</span></p></td> <td> <p> <span>Master_User</span></p></td> </tr><tr><td> <p><span>6</span></p></td> <td> <p>密码<span>(</span>不由<span>SHOW SLAVE STATUS</span>显示<span>)</span></p></td> </tr><tr><td> <p><span>7</span></p></td> <td> <p> <span>Master_Port</span></p></td> </tr><tr><td> <p><span>8</span></p></td> <td> <p> <span>Connect_Retry</span></p></td> </tr><tr><td> <p><span>9</span></p></td> <td> <p> <span> Master_SSL_Allowed</span></p></td> </tr><tr><td> <p><span>10</span></p></td> <td> <p> <span> Master_SSL_CA_File</span></p></td> </tr><tr><td> <p><span>11</span></p></td> <td> <p> <span> Master_SSL_CA_Path</span></p></td> </tr><tr><td> <p><span>12</span></p></td> <td> <p> <span>Master_SSL_Cert</span></p></td> </tr><tr><td> <p><span>13</span></p></td> <td> <p> <span> Master_SSL_Cipher</span></p></td> </tr><tr><td> <p><span>14</span></p></td> <td> <p> <span>Master_SSL_Key</span></p></td> </tr></table>
由SQL线程更新relay-log.info文件。文件中的行和SHOW SLAVE STATUS显示的列的对应关系为:
<table border="1" cellpadding="0" id="table2"><tr><td> <p><strong><span>行</span></strong></p></td> <td> <p><strong><span>描述</span></strong></p></td> </tr><tr><td> <p><span>1</span></p></td> <td> <p> <span>Relay_Log_File</span></p></td> </tr><tr><td> <p><span>2</span></p></td> <td> <p> <span>Relay_Log_Pos</span></p></td> </tr><tr><td> <p><span>3</span></p></td> <td> <p> <span> Relay_Master_Log_File</span></p></td> </tr><tr><td> <p><span>4</span></p></td> <td> <p> <span> Exec_Master_Log_Pos</span></p></td> </tr></table>
当备份从服务器的数据时,你还应备份这两个小文件以及中继日志文件。它们用来在恢复从服务器的数据后继续进行复制。如果丢失了中继日志但仍然有relay-log.info文件,你可以通过检查该文件来确定SQL线程已经执行的主服务器中二进制日志的程度。然后可以用Master_Log_File和Master_LOG_POS选项执行CHANGE MASTER TO来告诉从服务器重新从该点读取二进制日志。当然,要求二进制日志仍然在主服务器上。
如果从服务器正复制LOAD DATA INFILE语句,你应也备份该目录内从服务器用于该目的的任何SQL_LOAD-*文件。从服务器需要这些文件继续复制任何中断的LOAD DATA INFILE操作。用--slave-load-tmpdir选项来指定目录的位置。如果未指定, 默认值为tmpdir变量的值。
### 6.4. 如何设置复制
这里简单描述了如何为你当前的MySQL服务器设置完整的复制。假设你想要复制主服务器上的所有数据库,并且还没有配置的复制。你需要关闭主服务器来完成下面所列的步骤。
下面的程序针对设置一个从服务器,你可以用来设置多个从服务器。
虽然该方法是设置从服务器的最直接的途径,它并不是唯一的一个。例如,如果你有一个主服务器的数据快照,并且主服务器已经设置了服务器ID,启用了二进制日志,不需要关闭主服务器或停止对它的更新也可以设置从服务器。详情请参见[6.9节,“复制FAQ”](# "6.9. Replication FAQ")。
如果想要管理MySQL复制设置,我们建议你通读本章,并尝试[13.6.1节,“用于控制主服务器的SQL语句”](# "13.6.1. SQL Statements for Controlling Master Servers")和[13.6.2节,“用于控制从服务器的SQL语句”](# "13.6.2. SQL Statements for Controlling Slave Servers")中的所有语句。还应熟悉[6.8节,“复制启动选项”](# "6.8. Replication Startup Options")中描述的复制启动选项。
**注释:**该程序和后面章节所示的复制SQL语句需要SUPER权限。
1. 确保在服务器和从服务器上安装的MySQL版本与[6.5节,“不同MySQL版本之间的复制兼容性”](# "6.5. Replication Compatibility Between MySQL Versions")所示的表兼容。理想情况,应在主服务器和从服务器上使用最近版本的MySQL。
请先证实问题不是出现在最新的MySQL版本中再通报bug。
2. 在主服务器上为服务器设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做),则不需要再授予任何其它权限。(关于设置用户 账户和权限的信息,参见[5.8节,“MySQL用户账户管理”](# "5.8. MySQL User Account Management"))。
假定你的域为mydomain.com,想要创建用户名为repl的一个账户,从服务器可以使用该账户从你的域内的任何主机使用密码slavepass来访问主服务器。要创建该 账户,可使用GRANT语句:
mysql> GRANT REPLICATION SLAVE ON *.*
-> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';
如果你计划从从属服务器主机使用LOAD TABLE FROM MASTER或LOAD DATA FROM MASTER语句,你需要授予该账户其它权限:
· 授予账户SUPER和RELOAD全局权限。
· 为所有想要装载的表授予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中使用**PowerArchiver、WinRAR**、**WinZip**或者类似的软件。要使用**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.info或relay-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.php](http://www.innodb.com/manual.php)的**InnoDB 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
适合MyISAM和InnoDB表的另一个方法是对主服务器上的SQL进行转储而不是对前面讨论的二进制复制进行转储。为了实现,可以在主服务器上使用**mysqldump --master-data**,以后将SQL转储文件装入从服务器。但是,这样比二进制复制要慢一些。
如果主服务器运行时没有启用--logs-bin,SHOW MASTER STATUS或**mysqldump --master-data**显示的日志名和位置值为空。在这种情况下,当以后指定从服务器的日志文件和位置时需要使用的值为空字符串('')和4.
5. 确保主服务器主机上my.cnf文件的[mysqld]部分包括一个log-bin选项。该部分还应有一个server-id=Master_id选项,其中master_id必须为1到232–1之间的一个正整数值。例如:
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值一样,必须为1到232–1之间的一个正整数值。并且,从服务器的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;
下面的表显示了字符串选项的最大长度:
<table border="1" cellpadding="0" id="table3"><tr><td> <p> <span>Master_Host</span></p></td> <td> <p><span>60</span></p></td> </tr><tr><td> <p> <span>Master_USER</span></p></td> <td> <p><span>16</span></p></td> </tr><tr><td> <p> <span>Master_PASSWORD</span></p></td> <td> <p><span>32</span></p></td> </tr><tr><td> <p> <span>Master_Log_File</span></p></td> <td> <p><span>255</span></p></td> </tr></table>
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.info和relay-log.info。从服务器使用这两个文件跟踪已经处理了多少主服务器的二进制日志。不要移除或编辑这些文件,除非你确切知你正在做什么并完全理解其意义。即使这样,最好是使用CHANGE MASTER TO语句。
**注释:**master.info**的**内容会覆盖命令行或in my.cnf中指定的部分选项。详情参见[6.8节,“复制启动选项”](# "6.8. Replication Startup Options")。
有了一个快照,你可以用它根据刚刚描述的从服务器部分来设置其它从服务器。你不需要主服务器的另一个快照;每个从服务器可以使用相同的快照。
注释:为了保证事务InnoDB复制设置的最大可能的耐受性和一致性,应在主服务器的my.cnf文件中使用innodb_flush_log_at_trx_commit=1和sync-binlog=1。
### 6.5. 不同MySQL版本之间的复制兼容性
MySQL 5.1中使用的二进制日志格式与以前的版本中所使用的大大不同,特别是在字符集处理、LOAD DATA INFILE以及时区方面。
**注释:**你不能从使用新二进制日志格式的主服务器向使用旧二进制日志格式的从服务器复制(例如,从MySQL 5.0到MySQL 4.1)。。这样操作在复制设置升级服务器时后果严重,参见[6.6节,“升级复制设置”](# "6.6. Upgrading a Replication Setup")。
我们推荐使用最近的MySQL版本,因为复制功能在不断地改进中。我们还推荐主服务器和从服务器使用相同的版本。我们建议升级主服务器和从服务器,运行alpha或beta版本到新的(产品)版本。在许多情况下,从新的主服务器向旧的从服务器复制将会失败。一般原则,运行MySQL 5.1.x的从服务器可以与旧的主服务器(可以运行MySQL 3.23、4.0或者4.1)一起使用,但不能反过来。
前面的信息适合协议级复制兼容性。然而,还会有一个约束条件,例如SQL级兼容性问题。例如, 5.1版本的主服务器不能复制到5.0版本的从服务器,如果复制语句使用5.1版本的SQL特性而不是5.0版本。这些问题和其它问题均在[6.7节,“复制特性和已知问题”](# "6.7. Replication Features and Known Problems")中讨论。
### 6.6. 升级复制设置
[ 6.6.1. 将复制升级到5.0版](#)
当在复制设置中升级服务器时,升级过程取决于当前的服务器版本和要升级的服务器版本。
### 6.6.1. 将复制升级到5.0版
该节适用于将复制从MySQL 3.23、4.0或者4.1升级到5.1。4.0服务器应为4.0.3或更新版。
当将早期MySQL版本系列主服务器升级到5.1时,应先确保该主服务器的所有从服务器使用了相同的5.1.x版本。如果不是这样,你应先升级从服务器。升级从服务器时,应先关闭从服务器,升级到相应5.1.x版本,然后重启从服务器并重新开始复制。5.1版本的从服务器能够读取升级前写入的旧的中继日志并执行日志中包含的语句。升级后从服务器创建的中继日志为5.1格式。
从服务器升级后,关闭主服务器,将它升级到与从服务器相同的5.1.x版本并重启它。5.1主服务器能够读取升级前写入的旧的二进制日志并将它们发送到5.1从服务器。从服务器可以识别旧的格式并正确处理它。升级后主服务器创建的二进制日志采用5.1格式。这样也可以由5.1从服务器识别。
换句话说,当升级到5.1时没有什么措施,只有将主服务器升级到5.1之前先将从服务器升级到5.1。请注意从5.1降级到旧版本不会如此简单:必须确保已经完全处理所有5.1版本的二进制日志或中继日志,以便在降级前可以移除它们。
### 6.7. 复制特性和已知问题
一般原则,SQL级复制兼容性要求主服务器和从服务器均支持使用的特性。例如,在MySQL 5.0.0中开始使用TIMESTAMPADD()函数。如果在主服务器上使用该函数,不能复制到MySQL 5.0.0之前的从服务器。如果你计划在5.1和以前版本的MySQL之间进行复制,你应查阅对应以前版本系列的MySQL参考手册,查询该系列复制特征相关信息。
下面列出了关于支持什么和不支持什么的详细信息。关于复制的其它InnoDB具体信息参见[15.2.6.5节,“InnoDB和MySQL复制”](# "15.2.6.5. InnoDB and MySQL Replication")。
关于保存的程序和触发器的复制问题在[20.4节,“存储子程序和触发程序的二进制日志功能”](# "20.4. Binary Logging of Stored Routines and Triggers")中讨论。
· 用AUTO_INCREMENT、LAST_INSERT_ID()和TIMESTAMP值正确实现复制。
· USER()、UUID()和LOAD_FILE()函数毫无改变地被,这样不能可靠地在从服务器上工作。
· _ 下面的限制只适合基于语句的复制,而不是基于行的复制。_处理用户级锁定的函数GET_LOCK()、RELEASE_LOCK()、IS_FREE_LOCK()、IS_USED_LOCK()复制时从服务器不知道在主服务器上同时进行的相关文本;因此如果从服务器上的内容不同,这些函数不用来插入到主服务器的表中(例如不执行INSERT INTO mytable VALUES(GET_LOCK(...)))。
· 在MySQL 5.1中FOREIGN_KEY_CHECKS、SQL_MODE、UNIQUE_CHECKS和SQL_AUTO_IS_NULL变量均复制。但TABLE_TYPE,即STORAGE_ENGINE变量 不复制,有利于在不同的存储引擎之间进行复制。
· 即使主服务器和从服务器有不同的全局字符集变量,以及即使有不同的全局时区变量仍可以复制。
· 下面适合使用不同字符集的MySQL服务器之间的复制:
1. 必须在主服务器和从服务器上**总是**使用相同的**全局**字符集和校对规则(--default-character-set、--default-collation)。否则,会在从服务器上遇到复制键值错误,因为在主服务器的字符集中被认为是唯一的键值在从服务器的字符集中可能不是唯一的。
2. 如果主服务器早于MySQL 4.1.3,则会话中的字符集不应与其全局值不同(换句话说,不要使用SET NAMES、SET CHARACTER SET等等),因为从服务器不知道该字符集的更改。如果主服务器和从服务器均为4.1.3或更新版,可以随便将会话的字符集变量设置为本地值(例如NAMES、CHARACTER SET、COLLATION_CLIENT和COLLATION_SERVER),因为这些设定值被写入二进制日志,因此从服务器知道。然而,禁止更改会话中这些变量的**全局**值;如前面所述,主服务器和从服务器必须具有唯一的全局字符集值。
3. 如果在主服务器上的数据库的字符集与全局collation_server值不同,则应设计CREATE TABLE语句,以便它们不隐含依赖数据库的默认字符集([Bug #2326](http://bugs.mysql.com/2326));一个好的解决办法是在CREATE TABLE中明显说明字符集和校对规则。
· 应在主服务器和从服务器上设置相同的系统时区。否则一些语句,例如使用NOW()或FROM_UNIXTIME()函数的语句,将不会正确复制。可以使用脚本mysqld_safe的--timezone=_timezone_name_选项或通过设置TZ环境变量设置MySQL服务器运行的系统的时区。主服务器和从服务器还应有相同的默认连接时区设置;即主服务器和从服务器应有相同的--default-time-zone参数值。
· CONVERT_TZ(...,...,@global.time_zone)不能正确复制。只有主服务器和从服务器均为5.0.4或更新版才能正确复制CONVERT_TZ(...,...,@session.time_zone)。
· 会话变量只有在更新表的语句中使用时才能正确复制;例如:SET MAX_JOIN_SIZE=1000;INSERT INTO mytable VALUES(@MAX_JOIN_SIZE)不能将相同的数据插入到主服务器上和从服务器上。不适用于通用的SET TIME_ZONE=...;INSERT INTO mytable VALUES(CONVERT_TZ(...,...,@time_zone))。
· 可以将从服务器上的非事务表复为主服务器上的事务表。例如,可以将主服务器上的InnoDB表复制为从服务器上的MyISAM表。然而,复制过程中,如果从服务器在BEGIN/COMMIT块过程中停止则会产生问题,因为从服务器在BEGIN块开始时会重启。该问题出现在TODO中,不久将会得到修复。
· 在MySQL 5.1中可以正确复制引用用户变量(即@_var_name_形式的变量)的更新语句;但在4.1以前的版本中却不可能。请注意从MySQL 5.1开始对用户变量名的大小写不再敏感;当在5.1和旧版本之间设置复制时应考虑该问题。
· 从服务器可以使用SSL连接到主服务器。
· 有一个全局系统变量slave_transaction_retries:如果因为某个InnoDB死锁或超过 InnoDB的innodb_lock_wait_timeout或NDB簇的TransactionDeadlockDetectionTimeout或TransactionInactiveTimeout,REPLICATION SLAVESQL线程未能执行某个事务,在给出错误停止前自动重试slave_transaction_retries次。 默认值是10。从MySQL 5.0.4开始,可以从SHOW STATUS的输出中看到重试总次数;参见[5.3.4节,“服务器状态变量”](# "5.3.4. Server Status Variables")。
· 如果在主服务器上的CREATE TABLE语句中使用了DATA DIRECTORY或INDEX DIRECTORY子句,子句也可以在从服务器上使用。如果在从服务器主机文件系统中不存在一致的目录或虽然存在但不能被从服务器访问,则会带来问题。MySQL 5.1支持一个称为NO_DIR_IN_CREATE的sql_mode选项。如果从服务器运行时将SQL模式设置为包括该选项,复制CREATE TABLE语句时将忽略这些子句。结果是在表的数据库目录中创建了MyISAM数据和索引文件。
· _下面的限制只适合__基于__语句的复制,而不是基于行的复制_:如果在查询中数据修改不确定,主服务器和从服务器上的数据可以不同;也就是由查询优化器确定。(这是常用的但不是很好的习惯,即使不是在复制中也不好)。关于该问题的详细解释,参见[A.8.1节,“MySQL中的打开事宜”](# "A.8.1. Open Issues in MySQL")。
· 带READ LOCK的FLUSH LOGS、FLUSH MASTER、FLUSH SLAVE和FLUSH TABLES不记入日志,因为如果复制到从服务器会造成问题。关于语法示例,参见[13.5.5.2节,“FLUSH语法”](# "13.5.5.2. FLUSH Syntax")。FLUSH TABLES、ANALYZE TABLE、OPTIMIZE TABLE和REPAIR TABLE语句被写入二进制日志并会复制到从服务器。一般情况不会造成问题,因为这些语句不修改表的数据。但是在某些情况下会带来问题。如果你复制mysql数据库中的授权表并且不使用GRANT直接更新那些表,必须在从服务器上执行FLUSH PRIVILEGES使新的权限生效。并且,如果使用FLUSH TABLES重新命名MERGE表的MyISAM表,必须手动在从服务器上执行FLUSH TABLES。如果不指定NO_WRITE_TO_BINLOG或其别名LOCAL,则这些语句被写入二进制日志。
· MySQL只支持一个主服务器和多个从服务器。我们计划将来添加一个投票算法,当前的主服务器出现问题时自动切换。我们还计划引入代理过程通过向不同的从服务器发送SELECT查询以帮助进行负载均衡。
· 当服务器关闭、重启时,其MEMORY表将变为空。主服务器按下述方法复制该结果:启动后第1次主服务器使用每个MEMORY表,它通知从服务器需要向表写入DELETE FROM语句来清空二进制日志的表。详细信息参见[15.4节,“MEMORY (HEAP)存储引擎”](# "15.4. The MEMORY (HEAP) Storage Engine")。
· 除了关闭从服务器(而不仅仅是从服务器线程) 临时表都被复制,并且还没有在从服务器上执行的更新所使用的临时表也已经复制。如果关闭从服务器,从服务器重启后更新需要的那些临时表不可再用。为了避免该问题,临时表打开时不要关闭从服务器。而应遵照下面的程序:
1. 执行STOP SLAVE语句。
2. 使用SHOW STATUS检查slave_open_temp_tables变量的值。
3. 如果值为0,使用**mysqladmin shutdown**命令关闭从服务器。
4. 如果值不为0,用START SLAVE重启从服务器线程。
5. 后面再重复该程序看下次的运气是否好一些。
我们计划在不久的将来修复该问题。
· 可以很安全地连接用--logs-slave-updates选项指定的循环主服务器/从服务器关系中的服务器。但请注意许多语句在这种设置中不能正确工作,除非你的客户代码关注了潜在的在不同的服务器不同顺序的更新中可能发生的这类问题。
这说明你可以象这样创建设置:
A -> B -> C -> A
服务器ID被编码在二进制日志事件中,因此服务器A知道何时自己首次创建它读取的事件并且不执行事件(除非用--replicate-same-server-id选项启动了服务器A,只在很少情况下有意义)。这样,没有无限循环。只有对表执行没有冲突的更新时该类循环设置才能工作。换句话说,如果在A和C中插入数据,绝对不应在A中插入键值可能与插入到C中的行相冲突的一行。如果更新的顺序很重要,还不应更新两个服务器上相同的行。
· 如果从服务器上的某个语句产生错误,则从服务器上的SQL线程终止,并且从服务器向错误日志写入一条消息。此时应手动连接从服务器,修复该问题(例如,一个不存在的表),然后运行START SLAVE。
· 可以很安全地关闭主服务器并在以后重启。如果某个从服务器丢失与主服务器的连接,从服务器尝试立即重新连接。如果失败,从服务器定期重试。(默认设置是每60秒重试一次。可以通过--master-connect-retry选项更改)。从服务器也能够处理网络连接中断。但是,只有从服务器超过slave_net_timeout秒没有从主服务器收到数据才通知网络中断。如果中断时间短,可以降低slave_net_timeout。参见[5.3.3节,“服务器系统变量”](# "5.3.3. Server System Variables")。
· 关闭从服务器(净关闭)也很安全,因为它可以跟踪它离开的地点。不纯净的关闭操作会产生问题,特别是系统关闭前硬盘缓存未刷新到硬盘上时。如果有不间断电源,可以大大提高系统容错能力。不纯净的关闭主服务器会造成主服务器上的表和二进制日志内容之间的不一致性;在主服务器上使用InnoDB表和--innodb-safe-binlog选项可以避免该问题。参见[5.11.3节,“二进制日志”](# "5.11.3. The Binary Log")。(**注释:**MySQL 5.1中不需要--innodb-safe-binlog,由于引入了XA事务支持已经作废了)。
· 由于MyISAM表的非事务属性,可以有一个语句只是更新一个表并返回错误代码。例如,多行插入时有一个行超过键值约束,或者如果长的更新语句更新部分行后被杀掉了。如果发生在主服务器上,除非错误代码合法并且语句执行产生相同的错误代码,从服务器线程将退出并等待数据库管理员决定如何做。如果该错误代码验证行为不理想,可以用--slave-skip-errors选项掩盖(忽视)部分或全部错误。
· 如果从BEGIN/COMMIT系列的非事务表更新事务表,如果提交事务前更新非事务表,对二进制日志的更新可能会不同步。这是因为事务提交后才被写入二进制日志。
· 事务混合更新事务表和非事务表时,二进制日志中语句的顺序是正确的,即使在ROLLBACK时,所有需要的语句也会写入二进制日志。但是如果在第1个连接的事务完成前,第2个连接更新非事务表,语句记入日志时会出现顺序错误,因为第2个连接的更新执行完后立即写入日志,而不管第1个连接执行的事务的状态如何。
### 6.8. 复制启动选项
在主服务器和从服务器上,均必须使用server-id选项为每个服务器建立唯一的复制ID。你应为每个主服务器和从服务器从1到232–1的范围挑一个唯一的正整数。例如:server-id=3
用于主服务器上控制二进制日志的选项的相关描述见[5.11.3节,“二进制日志”](# "5.11.3. The Binary Log")。
下表描述了可以用于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语法”](# "13.6.2.1. CHANGE MASTER TO Syntax")。
下面的例子显示了如何更广泛地使用启动选项来配置从服务器:
[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启动A和B以启用二进制日志,并且用--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命令行选项”](# "5.8.7.6. SSL Command-Line Options")中描述的相应—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节,“服务器系统变量”](# "5.3.3. Server System Variables")。
· --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-size为0,选--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 DATABASE、DROP DATABASE和ALTER 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 DATABASE、DROP DATABASE和ALTER 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:](#)[_错误代码和消息_](# "Appendix B. Error Codes and Messages")。
你也可以(但不应)使用不推荐的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节,“二进制日志”](# "5.11.3. The Binary Log"))。测试结果是什么?
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规则?
·
- 前言
- 1. 一般信息
- 2. 安装MySQL
- 3. 教程
- 4. MySQL程序概述
- 5. 数据库管理
- 6. MySQL中的复制
- 7. 优化
- 8. 客户端和实用工具程序
- 9. 语言结构
- 10. 字符集支持
- 11. 列类型
- 12. 函数和操作符
- 13. SQL语句语法
- 14. 插件式存储引擎体系结构
- 15. 存储引擎和表类型
- 16. 编写自定义存储引擎
- 17. MySQL簇
- 18. 分区
- 19. MySQL中的空间扩展
- 20. 存储程序和函数
- 21. 触发程序
- 22. 视图
- 23. INFORMATION_SCHEMA信息数据库
- 24. 精度数学
- 25. API和库
- 26. 连接器
- 27. 扩展MySQL
- A. 问题和常见错误
- B. 错误代码和消息
- C. 感谢
- D. MySQL变更史
- E. 移植到其他系统
- F. 环境变量
- G. MySQL正则表达式
- H. MySQL中的限制
- I. 特性限制
- J. GNU通用公共许可
- K. MySQL FLOSS许可例外
- 索引