资源规划。申请并启动3个节点,一主两从,统一安装好MySQL-5.7(参见 https://www.notion.so/MySQL-080ad77acae04a7fbdd1caddfc3881af)(MySQL服务很小,可以让主机开机自启动: chkconfig mysqld on
)
并作出如下规划:
主机名 IP 角色
mysql-1 192.168.1.25 主(master/source)
mysql-2 192.168.1.26 从(slave/replica)
mysql-3 192.168.1.27 从(slave/replica)
配置主从节点的binlog开启和server_id
vim /etc/my.cnf
追加:
log-bin=mysql-bin
server-id=1
重启主节点。执行 service mysqld restart
创建用来做主从同步的用户,并赋予主从同步的权限. 在主节点(source)上执行:
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'P@ssw0rd';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
注:安全起见,应该像官网那样限定一个域名,如“example.com”或者“192.168.1.%”
主节点上刷写所有表的数据并阻止所有的写操作,以保证下一步的数据准确性,但执行完了之后不要退出这个mysql提示符:
mysql> FLUSH TABLES WITH READ LOCK;
重启一个ssh连接,并也登陆到这个主节点的MySQL命令行。然后执行 SHOW MASTER STATUS
命令,获取当前主节点的状态:
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 587 | | | |
+------------------+----------+--------------+------------------+-------------------+
记录下 mysql-bin.000001 和 587 这两个值,他们分别代表log文件存放位置和当前的偏移量。
(选做,如果主库已有数据而从库是新的)退出第二个MySQL命令行,然后执行:
mysqldump --all-databases --master-data > dbdump.db
拷贝全量数据
在主节点第一个登录的mysql命令行中执行:
mysql> UNLOCK TABLES;
释放锁
在从节点上修改 /etc/my.cnf, 追加:
server-id=x
其中,x=2,3,4等唯一标识出主机就可以
重启(启动)各个从节点。执行 service mysqld restart
在各个从节点执行如下命令,从库通过执行这个命令连接主库,并提供了连接的用户的一切条件:usernbame、password、主节点IP、port、binlog文件和读取位置(这里最后两个配置项用到了第5步记录下来的数值):
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.1.25',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='P@ssw0rd',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=587;
单行版,方便修改执行:
CHANGE MASTER TO MASTER_HOST='192.168.1.25',MASTER_USER='repl',MASTER_PASSWORD='P@ssw0rd',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=587;
(选做,如果主库已有数据而从库是新的)把步骤7的文件拷贝到从节点,并执行如下命令恢复数据快照:
mysql < fulldb.dump
(选做)往已经运行的集群中添加新的从节点:https://dev.mysql.com/doc/refman/5.7/en/replication-howto-additionalslaves.html
验证。执行:
mysql> show slave status\\G;
如果输出中以下两项均为“YES”,则说明已经配置运行成功:
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
注意⚠️:如果各台机器的server UUID有重复的,则会造成Slave_IO_Running: NO. 这就要修改auto.cnf文件,使之各不相同: vim /var/lib/mysql/auto.cnf
https://blog.csdn.net/cug_jiang126com/article/details/46846031
进一步验证。在主库上面执行:
mysql> create database test;
新建一个名为“test”的数据库,然后在从库上显示所有数据库可得:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
则说明主库所做的更改已经同步到了从库。然后再去检查主库的binLog文件 ( /var/lib/mysql/mysql-bin.00000x
),则发现其中有如下乱码:
...
std^D!^@!^@^H^@^L^Atest^@test^@create database test^U=²$
...
所以从库的test数据库应该就是通过这一条binlog的复制而被创建出来的。乱码是因为默认binlog格式是mixed
再进一步验证。在主库上执行如下几条命令,建表、插入数据并查询,然后得到结果:
mysql> use test;
mysql> create table `student` (`id` int, `name` varchar(10), primary key (`id`));
mysql> insert into student (id, name) value (1, 'zhangsan');
mysql> select * from student;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
+----+----------+
然后在从库执行 mysql> select * from student;
也会得到与上面相同的结果。
注意事项
虽然主从同步已经配置好并运行起来了,但是客户端一旦往从库里面做写操作,则还是会出现人为造成的主从不一致,这个时候就要保证数据库集群所接到的写请求都要作用在主库上。例如:
直接登陆从库,执行
insert into student (id, name) value (2, 'lisi');