环境准备

沿用上一篇操作系统及环境软件的安装方式,新建两个虚拟机,分别取名为Master、Slave并安装相同版本的MySQL数据库。

物理机连接MySQL

安装完成后先为物理机添加远程访问权限。首先在Master虚拟机登录MySQL,输入命令use mysql切换到mysql库。然后执行如下命令:

1
GRANT ALL PRIVILEGES ON *.* TO 'root'@'物理机IP' IDENTIFIED BY 'root账户密码' WITH GRANT OPTION;

执行如下命令使授权生效:

1
flush privileges;

操作完成后,若无法连接,再次确认防火墙是否关闭或查看my.cnf配置文件中bind-address的值是否为0.0.0.0

在Slave虚拟机执行上述步骤。

MySQL主从配置

Mastermy.cnf配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[mysqld]
设置server_id,一般设置为IP,注意要唯一
server_id = 1
复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db = mysql
开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin = edu-mysql-slave1-bin
为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size = 1M
主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format = mixed
二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days = 7
跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors = 1062
log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
防止改变数据(除了特殊的线程)
read_only=1

Slavemy.cnf配置

1
2
3
4
5
log_bin = mysql-bin
server_id = 2
relay_log = mysql-relay-bin
log_slave_updates = 1
read_only = 1

如果Slave不是作为其它从库的主库,则没必要开启二进制日志,只需开启relay_log中继日志即可。

创建复制账号

执行如下命令,在Master库中建立用于Slave连接的账户和密码并授权连接:

1
GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.* TO slave@'Slave机IP' IDENTIFIED BY '1234';

执行如下命令使授权生效:

1
flush privileges;

查询Master状态

执行如下命令:

1
show master status;

记录下返回结果的File列和Position列的值。

在从库中设置主库信息

执行如下命令设置:

1
CHANGE MASTER TO MASTER_HOST='Master机IP', MASTER_USER='slave', MASTER_PASSWORD='1234', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;

MASTER_LOG_FILEMASTER_LOG_POS的值设为主库中查询到的FilePosition的值。

开始复制

在从库中执行命令start slave;启用复制。运行show slave status\G;查看输出结果:

Slave_IO_RunningSlave_SQL_Running的值都为Yse时,说明Slave的I/O和SQL线程都开始了,当主库二进制日志文件发生改变时,从库会先把二进制日志文件拷贝到它的中继日志里,从库重做中继日志里的事件,将更新反映到它自己的数据库。

验证

在Master和Slave新建test数据库user数据表,必须保持库和表一致。

1
create database test;
1
2
3
4
5
6
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

在主库插入一条数据,在从库查看是否同步。

1
insert into users (username, password) values ('张三', '123456');

补充

在上次验证的时候,先在Master建立了数据库,以为Slave随后会同步,然而并没有。在Slaveshow slave status;查看从库状态,报错了(具体记不清楚,现在无法复现)。所以想当然的认为,在保持数据同步之前,主从数据库必须具有相同的库和表才行。今天仔细翻看了MySQL文档,了解到二进制日志复制数据共有三种方式,一是基于SQL语句,二是基于行改变,最后是前两者结合。MySQL默认使用第一种方式,既然是基于语句的方式复制数据,那么当在主库上创建了数据库,肯定会将SQL记录到二进制日志中。从库没道理不同步的。于是在Master新建库新建表,在Slave查看,果然同步了。至于那个报错,有机会出现再探究一下原因。