mysql数据库同步.
(平台: Redhat AS 4 Linux 2.6.9-5.ELsmp)
(mysql版本:Server version: 4.1.7 )
(时间:2007-03-30)
一、 mysql数据库同步介绍
MySQL 3.23.15及更高的版本支持单向同步。一个服务器作为master(主服务器),一个或者多个服务器作为slave(从服务器)。master服务器把更新的内容写到二进制日志(binary log或binlog)中,并且维护了一个索引文件来记录日志循环的情况。这些日志中的更新部分会被发送到slave服务器。一个slave连接到master之后,它通知master最后一次成功增量更新的日志位置。slave会找出所有从那个时刻开始的更新操作,然后阻塞并等待master发送新的更新操作。
注意,启用同步后,所有要同步的更新操作都必须在master上执行。否则,必须注意不要造成用户在master上的更新和在slave上的更新引起冲突
二、 mysql数据库同步的优点
1、 有了master/slave机制后,就更稳健了。当master上发生问题时,可以把slave作为备用切换过去。
2、 可以在slave和master之间分担一些查询,这就能加速响应时间。SELECT 查询就可以在slave上执行以减少master的负载。更新数据的语句则要放在mater上执行以保持master和slave的同步。当非更新操作占多数时,负载均衡就很有效了,不过这只是普通情况而言。
3、 另一个好处是可以在slave上备份数据,无需干扰master。备份数据时master照样继续运作。
三、 同步实现细节
MySQL同步机制基于master把所有对数据库的更新、删除 等)都记录在二进制日志里。因此,想要启用同步机制,在master就必须启用二进制日志
每个slave接受来自master上在二进制日志中记录的更新操作,因此在slave上执行了这个操作的一个拷贝。
应该非常重要地意识到,二进制日志只是从启用二进制日志开始的时刻才记录更新操作的。所有的slave必须在启用二进制日志时把master上已经存在的数据拷贝过来。如果运行同步时slave上的数据和master上启用二进制日志时的数据不一致的话,那么slave同步就会失败。
MySQL同步功能由3个线程(master上1个,slave上2个)来实现。执行 START SLAVE 语句后,slave就创建一个I/O线程。I/O线程连接到master上,并请求master发送二进制日志中的语句。master创建一个线程来把日志的内容发送到slave上。这个线程在master上执行 SHOW PROCESSLIST 语句后的结果中的 Binlog Dump 线程便是。slave上的I/O线程读取master的 Binlog Dump 线程发送的语句,并且把它们拷贝到其数据目录下的中继日志(relay logs)中。第三个是SQL线程,salve用它来读取中继日志,然后执行它们来更新数据。
四、 同步设置
1、 请确认master和slave上都安装了较近的MySQL版本,且这些版本之间要能兼容性;查看mysql版本可以用 mysql> status来查看;
Master | Master | Master | ||
3.23.33 and up | 4.0.3 and up or any 4.1.x | 5.0.0 | ||
Slave | 3.23.33 and up | yes | no | no |
Slave | 4.0.3 and up | yes | yes | no |
Slave | 5.0.0 | yes | yes | yes |
2、 MySQL各版本之间的兼容性如下表所示:
3、 在master上新加一个帐户,slave才能用它来连接。这个帐户必须授予 REPLICATION SLAVE 权限。如果这个帐户只用于同步(推荐这么做),那就没必要授予其他权限了。设定你的域是 mydomain.com,想要授权一个帐户 repl 使用密码 slavepass,允许它可以在域里的任何主机连接到master上。用 GRANT 语句来创建帐户:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED
BY 'smartpay';
其中: repl是用户名,而smartpay是用户密码
在MySQL 4.0.2以前,用 FILE 权限来代替 REPLICATION SLAVE,对应的语句如下:
mysql> GRANT FILE ON *.*TO 'repl'@'% IDENTIFIED BY 'smartpay';
在本例中,将所有的权限都付给了repl用户了,语句如下:
mysql> GRANT ALL ON *.* TO 'repl'@'%' IDENTIFIED BY 'smartpay';
4、 master上的数据移值到slave上去
a. 在master机器上:
mysql > mysqldump -A -u root –p --add-drop-table > mp.sql
mysql > quit;
b. 换到slave 机器上
# scp [email protected]:/root/tmp.sql ./
# mysql –u root –p
c. 在 master机器上:
# mysqladmin –u root –p shutdown # 关闭mysql数据库
d. 编辑 my.cnf(一般这个文件在/etc/my.cnf下)文件,看看这个文件里的[mysqld]区间里有没有以下内容:
[mysqld]
log-bin
server-id=1
binlog-do-db=dotproject 允许同步的数据库
binlog-ignore-db=mysql, test 禁止同步的数据库
其中server-id 的值可以取1~2的32次方减的值,但里这个值应该是所有的参与同步的mysql数据库中是唯一的,即不能重复。这里取1
e. 在slave服务器上
# mysqladmin –u root –p shutdown # 关闭mysql数据库
# vi /etc/my.cnf 加入以下内容
[mysqld]
server-id=2
这里的server-id值的要求和上述是一样的,这里取2
# /usr/bin/mysqld_safe & #启动mysql数据库
# mysql –u root –p
然后执行下列语句:
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.0.241', #master机器的IP地址或机器的名称
-> MASTER_USER='repl', #就是上面付权限的用户名
-> MASTER_PASSWORD='smartpay’, # 上面用户对应的密码
-> MASTER_LOG_FILE='’,
-> MASTER_LOG_POS=4;
然后启动 slave线程
Mysql > START SLAVE
f. 在master服务器上
/usr/bin/mysqld_safe & 启动mysql数据库
e. 分别在master和slave机器上用 mysql> SHOW PROCESSLIST \G查看一下以下
进程是否已经存在了。
在master机器上
Id: 2
User: repl
Host: smartpayapp1:38556
db: NULL
Command: Binlog Dump
Time: 9548
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
在slave机器上:
Id: 3
User: system user
Host:
db: NULL
Command: Connect
Time: 9864
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 4
User: system user
Host:
db: NULL
Command: Connect
Time: 3109
State: Has read all relay log; waiting for the slave I/O thread to update it
一旦slave开始同步了,就能在数据文件目录下找到2个文件 `master.info` 和`relay-log.info`。slave利用这2个文件来跟踪处理了多少master的二进制日志。
不要删除或者修改这2个文件,除非知道怎么改。尽管如此,我们更推荐用 CHANGE MASTER TO 语句来做。