1.主(master)服务器把数据更改的记录或者事件记录到二进制日志里。
2.从(slave)服务器把主服务器的二进制日志复制到自己的中继日志里。
3.从(slave)服务器根据中继日志的内容应用到自己的数据上。
假设我们的主从复制结构是由3台服务器构成,1台master,2台slave。
文章中的命令行提示符的含义:
1
2
3
|
[root@m /s/s ~] # 表示要在master slave slave三台服务器里都要执行的命令
[root@master ~] # 表示只在master服务器里执行的命令
[root@s /s ~] # 表示要在2台slave服务器里都要执行的命令
|
第一步,分别在3台机器上安装MySql,并使用MySql自带的my-medium.cnf作为初始配置文件,在3台服务器里分别执行如下命令。
1
2
|
[root@m /s/s ~] # yum -y install mysql mysql-server
[root@m /s/s ~] # \cp -f /usr/share/doc/mysql-server-*/my-medium.cnf /etc/my.cnf
|
第二步,创建用于复制的账户,我们不管主从,在3台MySql创建相同用户名密码的用户。
1.首先启动MySql,并设置root密码,我这里是测试,所以你千万别把密码设置的这么简单。
1
2
|
[root@m /s/s ~] # /etc/init.d/mysqld start
[root@m /s/s ~] # /usr/bin/mysqladmin -u root password 'masterpass'
|
2.创建并授权用于从服务器复制的复制账户。
1
2
3
4
5
|
[root@m /s/s ~] # mysql -uroot -p
Enter password:
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser' @'192.168.
0.% ' IDENTIFIED BY ' replpass';
Query OK, 0 rows affected (0.00 sec)
|
★:如果你了解MySql,可能你会说只需要在主服务器上添加一个从服务器用于复制的账户即可,也不需要REPLICATION SLAVE权限,但是我这样做的好处有2个方面,1是监视和管理复制,2是方便将来主从交换角色。
第三步,配置主(Master)服务器配置文件,此步在主(Master)里操作。
在/etc/my.cnf的[mysqld]域后追加
1
2
3
4
5
|
server_id = 100
log_bin = mysql-bin
log_bin_index = mysql-bin.index
sync_binlog = 1
max_binlog_size = 200M
|
1
2
3
4
5
|
server_id 服务器ID,不要和别的服务器冲突了,在同一个局域网里,我习惯使用ip的最后一位
log_bin 显式的指定二进制日志的文件名
log_bin_index 注意这里指定的文件名不是记录的表的索引,而是记录了二进制日志的文件名
sync_binlog 设为1就是把MySql每次发生的修改和事件的日志即时同步到硬盘上
max_binlog_size 指定二进制日志的大小
|
添加完设置后,重启MySql,并确认主服务器状态。
1
2
3
4
5
6
7
8
9
10
|
[root@master ~] # /etc/init.d/mysqld restart
[root@master ~] # mysql -uroot -p
Enter password:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 | 98 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
|
可见,二进制日志已经开启并生效了,接下来该配置从(Slave)服务器了。
第三步,配置2台从(Slave)服务器配置文件,此步分别在2台从(Slave)里操作。
1.在192.168.0.101的/etc/my.cnf的[mysqld]域后追加
1
2
3
4
5
6
7
8
9
10
|
server_id = 101
log_bin = mysql-bin
log_bin_index = mysql-bin.index
log_slave_updates = 1
relay_log = mysql-relay-bin
relay_log_index = mysql-relay-bin.index
max_binlog_size = 200M
read_only = 1
slave-skip-errors = 1062,1053
skip_slave_start = 1
|
2.在192.168.0.102的/etc/my.cnf的[mysqld]域后追加
1
2
3
4
5
6
7
8
9
10
|
server_id = 102
log_bin = mysql-bin
log_bin_index = mysql-bin.index
log_slave_updates = 1
relay_log = mysql-relay-bin
relay_log_index = mysql-relay-bin.index
max_binlog_size = 200M
read_only = 1
slave-skip-errors = 1062,1053
skip_slave_start = 1
|
前面解释的参数,这里就不解释了。
1
2
3
4
5
|
log_slave_updates 让从服务器把自身复制的事件和记录都写到自己的二进制日志里
relay_log 中继日志
read_only 让从服务器只读,可以防止有人误从服务器插入数据,导致主从数据不一致。
slave-skip-errors 在复制过程中忽略一些错误,让复制继续进行,在这里我忽略了1062和1053号错误,如果要忽略所有错误就设成all
skip_slave_start 防止从服务器在崩溃后自动开启,以给你足够的时间修复。
|
另外,你可能发现我把主(Master)服务器里的一些配置,比如二进制日志的设置也拿过来了,同样是方便将来不停服务实现主从交换角色。
★:有人肯定要疑问了,为什么在从(Slave)服务器的配置里没有从主服务器复制的账户等相关信息?
回答:直接把这些的信息写到配置文件是没有好处的,根据一些高手的经验,还可以能出不可以预知的错误,因此我们将在下一步启动复制的时候,
在MySql命令行里执行命令来指定这些信息,这样做还有一个很大的好处,在我们要变换主服务器的时候不需要重启MySql。
★:关于过滤复制对象的问题,但是如果不是特殊需要,不要使用复制过滤,因为同样有几率在一些事件触发的时候导致一些错误。介绍几种过滤参数。
binlog_do_db 只复制指定的数据库(主服务器配置文件里设置)
binlog_ignore_db 不复制指定的数据库(主服务器配置文件里设置)
replicate_ignore_table 不复制指定的表(从服务器配置文件里设置)
replicate_wild_ignore_table 使用wild匹配来不复制的指定表(从服务器配置文件里设置),比如参数设为abc.%,表示不复制abc的所有表。
3.在2台从(Slave)服务器里重启MySql服务器
1
|
[root@s /s ~] # /etc/init.d/mysqld restart
|
★:因为我们是新装的MySql服务器,所以接下来我们就可以开启复制了,如果你是给已经有大量数据的MySql服务器添加从(Slave)服务器,那么先从主(Master)服务器把数据导入到从(Slave)服务器里,让2者的数据一致,然后再开启复制。最简单的方法就是关闭主服务器MySql的写入,用mysqldump工具导出所有主(Master)服务器数据并上传到从(Slave)服务器:
1
2
3
4
|
[root@master ~] # mysqldump -u root -p --all-databases > /tmp/dbbackup.sql
[root@master ~] # scp /tmp/dbbackup.sql [email protected]:/tmp/dbbackup.sql
[root@master ~] # scp /tmp/dbbackup.sql [email protected]:/tmp/dbbackup.sql
[root@master ~] # rm -f /tmp/dbbackup.sql
|
然后把备份导入到从(Slave)服务器里:
1
2
|
[root@s /s ~] # mysql -u root -p < /tmp/dbbackup.sql
[root@s /s ~] # rm -f /tmp/dbbackup.sql
|
如果你要在主服务器MySql正常运行的状态下进行热拷贝等方法,我建议你不要用mysqldump这个命令,如果是MyISAM存储引擎,用mysqlhotcopy进行热备份会更好,如果是InnoDB存储引擎,使用ibbacup这样的工具更好。
第四步,在从(Slave)服务器里开启复制,次步的操作在2台从(Slave)服务器里执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[root@s /s ~] # mysql -uroot -p
Enter password:
mysql> CHANGE MASTER TO MASTER_HOST= '192.168.0.100' ,
-> MASTER_PORT=3306,
-> MASTER_USER= 'repluser' ,
-> MASTER_PASSWORD= 'replpass' ,
-> MASTER_LOG_FILE= 'mysql-bin.000001' ,
-> MASTER_LOG_POS=0;
Query OK, 0 rows affected (0.20 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.100
Master_User: repluser
Master_Port: 3306
............
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
............
1 row in set (0.00 sec)
|
最后我用了SHOW SLAVE STATUS来查看复制情况,从第一行可以看出从服务器已经在等待主服务器的event了,也可以看到Slave_IO,Slave_SQL线程都正常开启,最好同时查看从(Slave)服务器的日志/var/log/mysqld.log,确认没有错误信息,接下来你就可以去主服务器进行一些操作看看同步是否正常。
另外,在上面的操作中MASTER_LOG_POS=0,这里0的意思是从日志开头开始复制的意思,并不是实际的日志里的位置,实际的日志里的开始位置默认应该是4。
★:有人觉得,数据分别保存在2个机器里,就认为备份不需要了,千万别这么想,只能说有助于备份,绝对不能替代备份。
到此为止,简单的主从配置就完了,但是真正要使用和管理好主从MySql服务器,不是靠这点知识就可以的。