主从复制:将主mysql上的数据复制到从mysql的过程(1主拖8从)
master为主服务器,slave为从服务器,数据属于单向流动,由主到从。
复制属于异步过程,因为在主服务器写入数据后,从服务器需要拉取主服务器的二进制日志来复制数据,中间存在拉取日志的时间间隔,所以是异步过程。
主从复制可以提高数据库的数据安全性,当主服务器宕机时,从服务器可以提供主服务器一样的数据,实现高可用。
数据库数据复制流程
- 主服务器将新增数据或者修改数据的SQL语句存放在binlog二进制日志中
- 从服务器通过I/O线程将主服务器的二进制日志复制到从服务器的中继日志中(relay-log)
- 从服务器通过sql线程执行中继日志中的SQL语句,得到和主服务器一样的数据
部署MySQL主从复制
实验环境
两台已经安装好MySQL的Linux服务器
192.168.1.4(master)
192.168.1.5(slave)
MySQL最好都是刚安装好的,安装步骤可参考部署MySQL
实验目的
当主服务器写入数据后,从服务器会自动更新主服务器的相同数据
实验步骤
192.168.1.4
修改配置文件
vim /etc/my.cnf
# 在[mysqld]模块下添加:
server-id = 1 # 集群中每台mysql的server-id不能重复,必须唯一
log-bin = master-bin # 开启二进制日志并指定以master-bin命名
log-slave-updates = true # 允许slave更新
重启mysqld服务
systemctl restart mysqld
192.168.1.5
修改配置文件
vim /etc/my.cnf
# 在[mysqld]模块下添加:
server-id = 2
# 开启中继日志,拉取到master的二进制日志内容会存放在这个文件
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index # 中继日志索引文件
重启mysqld服务
systemctl restart mysqld
192.168.1.4
登录mysql数据库
master需要为slave进行拉取二进制日志文件授权,这里给予的ip是作为slave的mysql的ip
mysql -uroot
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.1.5' IDENTIFIED BY '123.com';
继续在1.4的mysql查看master现在使用的日志以及偏移量
mysql> SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 120 | | | |
+-------------------+----------+--------------+------------------+-------------------+
以上需要的信息为File
字段和Position
字段,可以用来指定slave可以从master中的这个文件中的这个位置开始复制sql语句
192.168.1.5
登录mysql数据库
为slave指定需要它要复制的主机以及文件,并开启slave功能
mysql -uroot
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.4', /*master主机ip*/
-> MASTER_USER='slave', /*授权用户*/
-> MASTER_PASSWORD='123.com', /*用户密码*/
-> MASTER_LOG_FILE='master-bin.000001', /*在master查看到的二进制文件名*/
-> MASTER_LOG_POS=120; /*该二进制文件的偏移量位置*/
mysql> START SLAVE; /*开启从功能*/
查看slave状态,是否复制成功
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 192.168.1.4
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 120
Relay_Log_File: relay-log-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 120
Relay_Log_Space: 120
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 2003
Last_IO_Error: error connecting to master 'slave@192.168.1.4:3306' - retry-time: 60 retries: 3
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_UUID:
Master_Info_File: /usr/local/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 200320 10:13:55
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
1 row in set (0.00 sec)
ERROR:
No query specified
最主要的看两个信息,如果以下两个为Yes,则成功,可以看到IO为Connecting
,这种情况可以检查防火墙是否放行端口,或者关闭
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
现在我们将两台主机的3306端口在防火墙放行
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
将1.5的slave功能停止,重新启动,再次查看状态
mysql> STOP SLAVE;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.4
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 120
Relay_Log_File: relay-log-bin.000003
Relay_Log_Pos: 284
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 120
Relay_Log_Space: 619
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 2c90975a-69c3-11ea-99d9-000c2922e28f
Master_Info_File: /usr/local/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
已经可以看到两个Yes
验证
在master创建数据,查看slave是否可以获取到
192.168.1.4
mysql> CREATE DATABASE pjf;
在master只是创建了一个数据库,去slave查看数据库验证
192.168.1.5
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| pjf |
| test |
+--------------------+
复制成功
复制常见报错
Slave_IO_Running: No //检查/etc/my.cnf中的server-id是否是不同的id号,如果相同,则更改为不同的
Slave_SQL_Running: No
问题原因:
1、可能是主库的表,在从库中没有找到。
解决方法:
1、先停止同步:mysql>stop slave;
2、使用命令:mysql>set GLOBAL SQL_SLAVE_SKIP_COUNTER=1; # 跳过错误
3、开启同步:mysql>start slave;
4、使用命令:mysql>show slave status\G,查看Slave_SQL_Running的值,如果不为Yes,则重复上述3步,直到为Yes