分类: Mysql/postgreSQL
2008-04-25 22:12:40
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://yahoon.blog.51cto.com/13184/33085 | ||||||||||||||||||||||||||||||||||||||||
最近要做MySQL的复制工作,所以好好看了看MySQL的文档.第六章REPLICATION.5.1版的文档有中文版,但是无疑现在大多部署的MySQL大多还是5.0.x系列,我们公司就是,可惜的是5.0系列没有中文版的文档.还好5.1和5.0文档的内容基本一致.所以我就对照着5.1的中文文档来看5.0的文档,对其中不同的部分做了些翻译.需要说明的是里面有很多的我觉得不重要的地方做了省略.例如”报告BUG”那一章.毕竟着重实际用的技术,还有少部分我不太了解或者不好翻译的就直接用了原文.
特别说明,因为文中很多地方出现MASTERà主服务器,我一般很多时候都简写为主,相应的SLAVEà从服务器简写为了从.
原文地址
第6章:MySQL中的复制6.1. 复制介绍
MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。(这与同步复制可以进行对比,同步复制是MySQL簇的一个特征—参见第15章:MySQL簇)。在单个主服务器复制时,这个主将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志记录要发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
如果你想要设置链式复制服务器,从服务器本身也可以充当主服务器。
多个主复制时可能的,但是会出现在单个主复制中不会发生的问题.查看6.13, “Auto-Increment in Multiple-Master Replication”.
请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
6.2. 复制实施概述
MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。参见5.11.3节,“二进制日志”。
每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。
认识到二进制日志只是一个从启用二进制日志的固定时间点开始的记录非常重要。任何设置的从服务器需要主服务器上的在主服务器上启用二进制日志时的数据库拷贝。如果启动从服务器时,其数据库与主服务器上的启动二进制日志时的状态不相同,从服务器很可能失败。
从服务器设置为复制主服务器的数据后,它连接主服务器并等待更新过程。如果主服务器失败,或者从服务器失去与主服务器之间的连接,从服务器保持定期尝试连接,直到它能够继续帧听更新。由--master-connect-retry选项控制重试间隔。 默认为60秒。
每个从服务器跟踪上一次他从主服务器的复制时间和更新的地方。主服务器不知道有多少个从服务器或在某一时刻有哪些被更新了。
6.3. 复制实施细节
MySQL使用3个线程来执行复制功能(其中1个在主服务器上,另两个在从服务器上。当(从服务器)发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以识别为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志relay logs。第3个线程是SQL线程,是从服务器创建用于读取中继日志并执行日志中包含的更新。
在前面的描述中,每个主/从的连接有3个线程。有多个从服务器的主服务器创建为每个当前连接的从服务器创建一个线程;每个从服务器有自己的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.10节,“复制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_net_timeout (注:5.1里面写的是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开始。从服务器运用一个索引文件来跟踪当前正在用的中继日志文件(relay log files).默认的这个中继日志索引文件名称为host_name-relay-bin.index.默认情况,在从服务器的数据目录中创建这些relay log文件。可以用--relay-log和--relay-log-index服务器选项覆盖默认文件名(也就是重新指认文件名)。参见6.8节,“复制启动选项”。
中继日志与二进制日志的格式相同,并且可以用mysqlbinlog读取。SQL线程执行完中继日志中的所有事件并且不再需要之后,立即自动删除它。没有直接的删除中继日志的机制,因为SQL线程可以负责完成。然而,FLUSH LOGS可以循环(rotate)中继日志,当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。他们的名字可以被改变,通过用--master-info-file 和 --relay-log-info-file 选项. 查阅 Section 6.8, “Replication Startup Options”. 因为这些状态文件保存在硬盘上,所以从服务器关闭时不会丢失。下次从服务器启动时,读取这些文件以确定它已经从主服务器读取了多少二进制日志,以及处理自己的中继日志的程度。
由I/O线程更新master.info文件。文件中的行和SHOW SLAVE STATUS显示的列的对应关系为:
由SQL线程更新relay-log.info文件。文件中的行和SHOW SLAVE STATUS显示的列的对应关系为:
The contents of the relay-log.info file and the states shown by the SHOW SLAVE STATES command may not match if the relay-log.info file has not been flushed to disk. Ideally, you should only view relay-log.info on a slave that is offline (i.e. mysqld is not running). For a running system, SHOW SLAVE STATUS should be used.
当备份从服务器的数据时,你还应备份这两个小文件以及中继日志文件。它们用来在恢复从服务器的数据后继续进行复制。如果丢失了中继日志但仍然有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变量的值。
|