环形复制
MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并 维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一 次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
环境介绍:
本测试系统平台为window7.
各个机器的mysql版本均为5.1.38,其他版本没有测试。
一般只要是5.1.x版本,且每台机器版本一致的情况下都适用。
一、主从备份
顾名思义,就是一台机器作为主服务器,另外一台或多台作为从服务器。
配置过程如下:
1. 在主服务器找到MySQL安装目录下(如:C:\Program Files\MySQL\MySQL Server 5.1)my.ini文件,在文件末尾添加如下代码:
server-id=1 |
log-bin=C:\mysqlback |
binlog-do-db=test |
#log-bin=C:\mysqlback
#这里的mysqlback是日志文件名,C:\是路径,在正常运行时,会在C盘下产生mysqlback.000001、 mysqlback.000002等日志文件。如果直接设置为log-bin=mysqlback,则会在mysql的data目录下产生这些 mysqlback.000001、mysqlback.000002等日志文件。
#binlog-do-db=test1
#test为需要同步的数据库名。如果需要同步多个数据库,多次使用这条语句即可
2. 从服务器找到my.ini文件,在文件末尾添加如下代码:
server-id=2 |
master-host=192.168.1.104 |
master-user=user1 |
master-password=user1 |
master-port=3306 |
master-connect-retry=60 |
#master-host=192.168.1.104
#主复制服务器的主机名或IP地址。如果没有给出该选项,从服务器线程不启动。
#master-port=3306
#如果mysql服务使用的默认端口3306,就可以省略此项
#master-connect-retry=60
#在主服务器宕机或连接丢失的情况下,从服务器线程重新尝试连接主服务器之前睡眠的秒数。如果未设置, 默认值为60。
#replicate-do-db=test
#告诉从服务器限制默认数据库(由USE所选择)为test的语句的复制。要指定多个数据库,应多次使用该选项,每个数据库使用一次。
#slave-skip-errors=all
#忽略错误继续同步
3. 在主服务器上为从服务器打开权限:
GRANT REPLICATION SLAVE ON *.* TO ‘user1’@‘192.168.1.11’IDENTIFIED BY ‘user1’;
4. 重启主从服务器的mysql服务
5. 使主从服务器的数据库保持一致
根据数据库使用的引擎不同有些区别:
MyISAM(本次测试采用的引擎):
1) 在锁定主服务器数据库的情况下,可以直接将data下面的数据库文件复制到从服务器data下面,并重启从服务器(如果是直接添加新的数据库不需要重启)
2) 在从服务器的mysql命令行内输入如下命令:LOAD DATA FROM MASTER
需要说明的是:你需要授予该账户其它权限:授予账户SUPER和RELOAD全局权限。为所有想要装载的表授予SELECT权限。任何该 账户不能SELECT的主服务器上的表被LOAD DATA FROM MASTER忽略掉。
InnoDb:
1) MyISAM的第二种办法可以
2) 获得全局读锁定,然后开始InnoDB表的文件系统快照。创建快照最简单的途径是使用归档程序对主服务器上的数据目录中的数据库进行二进制备份。(这部分没有具体测试,就不说了,摘自《mysql参考手册》第6章 Mysql中的负责 6.4 如何设置复制)
6. 查看结果
主服务器:
一般情况下第一次使用命令show master status查看主服务器状态File 是mysqlback.000001,position是106.
从服务器:
说明:在第一次设置完成master,slave之后,如果要修改slave的my.ini里master的设置必须先删 除data下面的master.info文件,重启服务才能生效。否则服务器会以master.info中的信息为准。或者另外一个办法就是直接在 mysql命令行中使用chang master to 命令。
二、主主同步
主主同步是指AB同时互为master和slave,其操作就是在主从同步的基础上在反过来再设置一次,将从服务器作为主服务器,主服务器作为从服务器。
添加代码如下:
A(192.168.1.104) |
server-id=1 |
log-bin=mysqlback |
binlog-do-db=test |
|
master-host=192.168.1.11 |
master-user=user1 |
master-password=user1 |
master-port=3306 |
master-connect-retry=60 |
replicate-do-db=test |
slave-skip-errors=all |
B(192.168.1.11) |
server-id=2 |
log-bin=mysqlback |
binlog-do-db=test |
master-host=192.168.1.104 |
master-user=user2 |
master-password=user2 |
master-port=3306 |
master-connect-retry=60 |
replicate-do-db=test |
slave-skip-errors=all |
注:如果有第三台mysql服务器C同步AB其中任意一台服务器(设为A),只要在AB的配置中加上log-slave-updates,一旦 A服务器宕机,B会接管A作为C的master的角色。但是在接下来要讲的环形同步中,一旦其中一台服务器D宕机,该服务器D的master并不会接管D 的slave。为什么?还没查清楚,要是有哪位大虾知道指点下哈。
三、三个或多个服务器同步
三台服务器A(192.168.1.104)、B(192.168.1.11)、C(192.168.1.117),可以设置为一个环形 A->B->C->A。即三个服务器都同时作为master和slave,A为B的master,B为C的master,C再为A的 master。
三个服务器的配置分别为:
A(192.168.1.104): |
server-id=1 |
log-bin=C:\mysqlback |
binlog-do-db=test |
master-host=192.168.1.117 |
master-user=user1 |
master-password=user1 |
master-port=3306 |
master-connect-retry=60 |
replicate-do-db=test |
log-slave-updates |
slave-skip-errors=all |
sync_binlog=1 |
B(192.168.1.11): |
server-id=2 |
log-bin=C:\mysqlback |
binlog-do-db=test |
master-host=192.168.1.104 |
master-user=user2 |
master-password=user2 |
master-port=3306 |
master-connect-retry=60 |
replicate-do-db=test |
log-slave-updates |
slave-skip-errors=all |
sync_binlog=1 |
C(192.168.1.117): |
server-id=3 |
log-bin=C:\mysqlback |
binlog-do-db=test |
master-host=192.168.1.11 |
master-user=user3 |
master-password=user3 |
master-port=5306 |
master-connect-retry=60 |
replicate-do-db=test |
log-slave-updates |
slave-skip-errors=all |
sync_binlog=1 |
其中user1,user2,user3等需要在不同的服务器上为不同的服务器打开相应的权限:
A:mysql> GRANT REPLICATION SLAVE ON *.*
TO ‘user1’@‘192.168.1. 117’IDENTIFIED BY ‘user1’;
B:mysql> GRANT REPLICATION SLAVE ON *.*
TO ‘user2’@‘192.168.1. 104’IDENTIFIED BY ‘user2’;
C:mysql> GRANT REPLICATION SLAVE ON *.*
TO ‘user3’@‘192.168.1. 11’IDENTIFIED BY ‘user3’;
#log-slave-updates
#通常情况,从服务器从主服务器接收到的更新不记入它的二进制日志。该选项告诉从服务器将其SQL线程执行的更新记入到从服务器自己的二进制日志。为了使该选项生效,还必须用--logs-bin选项启动从服务器以启用二进制日志。
#在这里此项必须设置,要不然从上一台服务器更新过来的信息不能传递到下一台服务器。
#sync_binlog=1
#如果为正,当每个sync_binlog'th写入该二进制日志后,MySQL服务器将它的二进制日志同步到硬盘上 (fdatasync())。请注意如果在autocommit模式,每执行一个语句向二进制日志写入一次,否则每个事务写入一次。 默认值是0,不与硬盘同步。值为1是最安全的选择,因为崩溃时,你最多丢掉二进制日志中的一个语句/事务;但是,这是最慢的选择(除非硬盘有电池备份缓 存,从而使同步工作较快)。
多个服务器的同步就只是在环中多添加几个节点。
在环形的同步中,有一个很大的缺陷,就是如果其中一台服务器E宕机,那么其他的服务器就只能单项同步了。我查了很久没有找到如何配置能是其他的服务器自动接管宕机的服务器的master功能。知道的大虾还请指点哈。
但是我找到了手动同步所有服务器的办法。
1) 如果能尽快的将宕机的服务器E再启动起来,不需要做任何操作,一切都会正常的运行起来。
2) 如果不能做到1),那么就在E的slave服务器上面进行如下操作:
打开mysql命令行
A.mysql> slave stop;#关闭同步操作
B.mysql> CHANGE MASTER TO
mysql> MASTER_HOST='Host-Name',
mysql> MASTER_USER='user4',
mysql> MASTER_PASSWORD='user4',
mysql> MASTER_LOG_FILE='mysqlback.000027',
mysql> MASTER_LOG_POS=2531;#修改master信息
#其中Host-Name为E的master。mysqlback.000027、2531为E宕机时其data下面master.info文件中保存的当前更新到的日志文件以及读取到日志文件中的位置。
C.slave start;#打开同步操作
其原理是:E的master一直处于运行中,其日志文件正在不停的更新,而E在宕机时已经更新到了mysqlback.000027:2531 位置,由于是环状同步,所以在整个环中也都已经更新到了这个位置,现在slave只需要接着在E的master那里从E宕机时的这个位置继续同步数据即 可。
这里没有考虑E宕机的时候本机更新了mysqlback.000027:2531而其他机器还没来的及更新的情况。一旦出现这种问题,可以去取环形中数据最完整那个服务器(即E的master)的数据来来覆盖其他服务器数据再做同步了了,不知道还有没有其他更好的办法
来源
http://blog.sina.com.cn/s/blog_8a2a32b10100x3gt.html