这里使用两台Linux主机(一台充当MySQL主服务器,另一台充当MySQL从服务器),MySQL用yum安装,版本均为5.7,下表是它们所使用的操作系统以及IP地址。
两台Linux主机所使用的操作系统以及IP地址 |
||
主机名称 | 操作系统 | IP地址 |
MySQL主服务器 | CentOS7.5 | 192.168.5.21 |
MySQL从服务器 | CentOS7.5 | 192.168.5.23 |
一、主服务器的配置
在实际的生产环境中,可能在还没有部署数据主从复制前,数据库中就已经存在大量的数据。所以,这里事先创建一个测试用的数据库及数据表,用来演示如何对已经存在的数据进行数据同步备份。
mysql -u root -p
mysql> create database ops;
mysql> use ops;
mysql> create table employees(employee_id int not null auto_increment, name char(20) not null, e_mail varchar(50), primary key(employee_id));
mysql> insert into employees values (1, 'TOM','tom@example.com'),(2, 'Jerry','jerry@example.com');
mysql> exit
接下来需要在主服务器上开启二进制日志并设置服务器编号,服务器唯一编号必须是1至232-1之间的整数,根据自己的实际情况进行设置。编辑 MySQL配置文件 my.cnf,然后在 [mysqld] 段添加相应的配置选项。
vim /etc/my.cnf
[mysqld]
server_id = 1 # 设置服务器编号
log_bin = master-bin # 启用二进制日志,并设置二进制日志文件前缀
# 重启MySQL
systemctl restart mysqld
# 停止firewall防火墙
systemctl stop firewalld
# 临时关闭selinux,注意:系统重启后会失效
setenforce 0
# 查看selinux的状态
getenforce 0
注意:在配置文件中不可以使用skip-networking(开启该选项后就不能远程访问MySQL)参数选项,否则从服务器将无法与主服务器进行连接并复制数据。
二、从服务器的配置
如果从服务器ID编号没有设置,或服务器ID编号与主服务器有冲突,就必须重新编辑配置文件,设置唯一的服务器编号,最后重启MySQL服务。如果有多台从服务器,则所有的服务器ID编号都必须是唯一的。可以考虑将服务器ID编号与服务器IP地址关联,这样ID编号可以同时唯一标识一台服务器计算机,如采用IP地址的最后一位作为MySQL服务器ID编号。
vim /etc/my.cnf
[mysqld]
server_id = 2 # 唯一标识,主库从库不能重复
对复制而言,MySQL从服务器上二进制日志功能是不需要开启的。但是,也可以通过启用从服务器的二进制日志功能,实现数据备份与恢复。此外,在一些更复杂的拓扑环境中,MySQL从服务器也可以扮演其他从服务器的主服务器。
# 重启MySQL
systemctl restart mysqld
# 停止firewall防火墙
systemctl stop firewalld
# 临时关闭selinux,系统重启后失效
setenforce 0
# 查看selinux的状态
getenforce 0
三、创建复制账号
执行数据复制时,所有的从服务器都需要使用账户与密码连接MySQL主服务器,所以在主服务器上必须存在至少一个用户账户及相应的密码供从服务器连接。这个账户必须拥有replication slave权限,你可以为不同的从服务器创建不同的账户与密码,也可以使用统一的账户与密码。MySQL可以使用create user语句创建用户,使用gant语句为账户赋权。如果该用户仅为数据库复制所使用,则该账户仅需要replication slave权限即可。下面的例子将在MySQL主服务器上创建一个拥有复制权限的slave_cp账户,该账户可以从 192.168.5.% 网段内的任何主机连接主服务器,密码为SlaveAdmin。
mysql> create user 'slave_cp'@'192.168.5.%' identified by 'SlaveAdmin';
mysql> grant replication slave on *.* to 'slave_cp'@'192.168.5.%';
mysql> exit
四、获取主服务器二进制日志信息
在进行主从数据复制之前,需要查看一些主服务器的二进制日志文件的基本信息,这些信息在对从服务器的设置中需要用到,它包括主服务器二进制文件名称及当前日志记录位置,这样从服务器就可以知道从哪里开始进行复制操作。可以使用如下操作查看主服务器二进制日志数据信息。
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 154 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
其中,File列显示的是二进制日志文件名,Position为当前日志记录位置。
flush tables with read lock;命令的作用是对所有数据库的表执行只读锁定,只读锁定后所有数据库的写操作将被拒绝,但读操作可以继续。执行锁定可以防止在查看二进制日志信息的同时有人对数据进行修改操作,最后使用unlock tables;语句对全局锁执行结束操作。
五、对现有数据库进行快照备份
如果在使用二进制日志进行数据复制以前,MySQL数据库系统中已经存在大量的数据资源,对这些数据进行备份的一种方法是使用mysqldump工具,在主服务器上使用该工具对数据备份后,即可在从服务器上进行数据还原操作。当要备份的数据达到主从一致后,就可以使用数据复制功能进行自动同步操作。具体操作如下(实际的生成环境中需要根据自己的需要有选择地对数据库进行备份与还原)
在MySQL主服务器上执行:
# 备份所有的数据库
mysqldump -u root -p --all-databases --lock-all-tables > /tmp/dbdump.sql
# 将备份好的数据库传到MySQL从数据库
scp /tmp/dbdump.sql 192.168.5.23:/tmp/
在MySQL从服务器上执行:
mysql -u root -p < /tmp/dbdump.sql
六、配置从服务器连接主服务器进行数据复制
数据复制的关键操作是配置从服务器去连接主服务器进行数据复制,需要告知从服务器建立网络连接所有必要的信息。使用change master to语句即可完成该项工作,master_host指定主服务器主机名或IP地址,master_user为主服务器上创建的拥有复制权限的账户名称,master_password为该账户的密码,master_log_file指定主服务器二进制日志文件名称,master_log_pos为主服务器二进制日志当前记录的位置。start slave;开启从服务器功能进行主从连接,show slave statusG查看从服务器状态。
mysql> change master to
-> master_host='192.168.5.21',
-> master_user='slave_cp',
-> master_password='SlaveAdmin',
-> master_port=3306,
-> master_log_file='master-bin.000001',
-> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave statusG
执行 show slave statusG 后遇到报错,如下:
Last_IO_Error处错误提示,大概是说:从I/O线程停止,因为主和从有相同的MySQL服务器uuid;这些uuid必须不同
这是因为我是在虚拟机下操作,Linux系统都是克隆的,克隆的系统上MySQL已安装好,所以MySQL的UUID相同。
解决方法:
查看主库的UUID号:
vim /var/lib/mysql/auto.cnf
查看从库的UUID号:
vim /var/lib/mysql/auto.cnf
可以看到主从MySQL数据库的UUID号是一样的
修改从库的UUID号(随便改一个数字或字母即可)
重启从库
systemctl restart mysqld
mysql -u root -p
show slave statusG
七、数据同步验证
所有的主从服务器均设置完毕后,可以通过在主服务器上创建新的数据库,然后在从服务器上查看,所有的数据将自动同步。
在主库执行:
mysql> create database demo;
mysql> use demo;
mysql> create table t_table(name char(20),age int, note varchar(50));
mysql> insert into t_table values ('linda',23,'BeiJing'),('jerry',33,'ShangHai');
在从库执行:
mysql> select * from demo.t_table;
可以看到同步成功了!
八、主从复制原理描述(图片来自:https://www.jianshu.com/p/6ed2cc292077)
- 在从库上执行change master to 时,将主库的 ip port user password binlog position 写入到master.info进行记录
- start slave 时,从库会启动IO线程和SQL线程
- IO线程,读取master.info信息,获取主库信息连接主库
- 主库会生成一个准备binlog DUMP线程,来响应从库
- IO线程根据master.info记录的binlog文件名和position号,请求主库DUMP最新日志
- DUMP线程检查主库的binlog日志,如果有新的,TP(传送)给从库的IO线程
- IO线程将收到的日志存储到了TCP/IP 缓存,立即返回ACK给主库 ,主库工作完成
- IO线程将缓存中的数据,存储到relay-log日志文件,更新master.info文件binlog文件名和position,IO线程工作完成
- SQL线程读取relay-log.info文件,获取到上次执行到的relay-log的位置,作为起点,回放relay-log
- SQL线程回放完成之后,会更新relay-log.info文件。
- relay-log会有自动清理的功能。
细节:
- 主库一旦有新的日志生成,会发送“信号”给binlog dump,IO线程再请求
主库和从库用到的文件
主:
master-bin.000001 ===> 主库操作记录日志
从:
主机名-relay-bin.000001 ===> 中继日志
master.info ===> 主库信息记录日志
relay-log.info ===> 记录中继应用情况信息
九、线程相关查看
主库:
show full processlist;
每个从库都会有一行dump相关的信息
如果现实非以上信息,说明主从之间的关系出现了问题
从库:
mysql> show slave statusG
(1)主库相关信息监控
Master_Host: 192.168.5.21
Master_User: slave_cp
Master_Port: 3306
Master_Log_File: master-bin.000003
Read_Master_Log_Pos: 154
(2)从库中继日志的应用状态
Relay_Log_File: centos7-relay-bin.000009
Relay_Log_Pos: 369
(3)从库复制线程有关的状态
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
(4)过滤复制有关的状态
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
(5)主从延时相关状态(非人为)
Seconds_Behind_Master: 0
(6)延时从库有关的状态(人为)
SQL_Delay: 0
SQL_Remaining_Delay: NULL
(7)GTID 复制有关的状态
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
十、其他相关操作命令
(1)stop slave;
停止从库
(2)reset master;
将删除日志索引文件中记录的所有二进制文件,创建一个新的日志文件起始值从000001开始。
注意:在生产环境的主从复制,禁止在主库中使用reset master;可以选择 expire 进行定期清理主库二进制日志
(3)reset slave;
使slave 忘记主从复制关系的位置信息。该语句旨在用于全新启动, 它删除master.info文件和relay-log.info 文件以及所有的relay log 文件并重新启用一个新的relaylog文件。
使用reset slave之前必须使用stop slave 命令将复制进程停止。
(4)reset slave all;
在 5.6 版本中 reset slave 并不会清理存储于内存中的复制信息比如 master host, master port, master user, or master password,也就是说如果没有使用change master 命令做重新定向,执行start slave 还是会指向旧的master 上面。
在MySQL 5.6.3和更高版本中,可以使用reset slave all;重置这些连接参数。
本文参考自:
(1)丁明一 编著 《Linux运维之道》