Mysql主从复制方式以及可能出现的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql主从复制方式以及可能出现的问题相关的知识,希望对你有一定的参考价值。

参考技术A 大致流程:主库将变更写binlog日志,然后从库连接到主库之后,从库有一个IO线程,将主库的binlog日志拷贝到自己本地,写入一个中继日志 relay日志中。接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容,也就是在自己本地再次执行一遍SQL,这样就可以保证自己跟主库的数据是一样的。

如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,这时候从库成为了主库,那么有些数据可能就丢失了。

开启半同步复制 semi-sync ,用来解决主库数据丢失问题;

这个所谓半同步复制, semi-sync复制 ,指的就是主库写入binlog日志之后,就会将强制此时立即将数据同步到从库,从库将日志 写入自己本地的relay log之后 ,接着会 返回一个ack 给主库, 主库接收到至少一个从库的ack之后才会认为写操作完成了。 如果 过程出现失败 ,那么 我们的客户端就可以进行重试了 ;

主从延迟对于读写分离的涉及影响比较大
这里有一个非常重要的一点,就是 从库同步主库数据的过程是串行化的 ,也就是说 主库上并行的操作,在从库上会串行执行 。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行SQL的特点,在 高并发场景下,主库大量的写,那么从库的数据一个个的读,那么就会导致从库同步一定会比主库慢一些,是有延时的 。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。(主库并发写的量级越高,从库积压的同步数据越多,延迟越高)

我们可以用 show status 看看 Seconds_Behind_Master 参数,你可以看到从库复制主库的数据落后了几ms,但是这个也不是完全准确,可以看 Seconds_Behind_Master的

对于解决主从延迟,解决方案可以从以下方面考虑

搭建 MySQL 5.7.19 主从复制,以及复制实现细节分析

主从复制可以使MySQL数据库主服务器的主数据库,复制到一个或多个MySQL从服务器从数据库,默认情况下,复制异步; 根据配置,可以复制数据库中的所有数据库,选定的数据库或甚至选定的表。

Mysql 主从复制的优点:

  

横向扩展解决方案

在多个从库之间扩展负载以提高性能。在这种环境中,所有写入和更新在主库上进行。但是,读取可能发生在一个或多个从库上。该模型可以提高写入的性能(由于主库专用于更新),同时在多个从库上读取,可以大大提高读取速度。

数据安全性

由于主库数据被复制到从库,从库可以暂停复制过程,可以在从库上运行备份服务,而不会破坏对应的主库数据。

分析

可以在主库上创建实时数据,而信息分析可以在从库上进行,而不会影响主服务器的性能。

长距离数据分发

可以使用复制创建远程站点使用的数据的本地副本,而无需永久访问主库。

1.准备工作

Mysql版本:MySQL 5.7.19
Master-Server : 192.168.252.123
Slave-Server : 192.168.252.124

关闭防火墙 

iptables -F

2. Master-Server 配置

配置 Master 以使用基于二进制日志文件位置的复制,必须启用二进制日志记录并建立唯一的服务器ID,否则则无法进行主从复制。

停止MySQL服务。

systemctl stop mysqld

开启binlog ,每台设置不同的 server-id

cat /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1

启动MySQL服务

systemctl start mysqld

 登录MySQL

mysql -uroot -p

创建用户

每个从库使用MySQL用户名和密码连接到主库,因此主库上必须有用户帐户,从库可以连接。任何帐户都可以用于此操作,只要它已被授予 REPLICATION SLAVE权限。可以选择为每个从库创建不同的帐户,或者每个从库使用相同帐户连接到主库

虽然不必专门为复制创建帐户,但应注意,复制用到的用户名和密码会以纯文本格式存储在主信息存储库文件或表中 。因此,需要创建一个单独的帐户,该帐户只具有复制过程的权限,以尽可能减少对其他帐户的危害。

mysql> CREATE USER ‘replication‘@‘192.168.252.124‘ IDENTIFIED BY ‘mima‘;
mysql> GRANT REPLICATION SLAVE ON *.* TO ‘replication‘@‘192.168.252.124‘; 

备注:如果创建用户的时候出现密码错误的问题:

error:Your password does not satisfy the current policy requirements

查看密码策略:

show variables like ‘%password%‘;

+---------------------------------------+--------+
| Variable_name | Value |
+---------------------------------------+--------+
| default_password_lifetime | 0 |
| disconnect_on_expired_password | ON |
| log_builtin_as_identified_by_password | OFF |
| mysql_native_password_proxy_users | OFF |
| old_passwords | 0 |
| report_password | |
| sha256_password_proxy_users | OFF |
| validate_password_check_user_name | OFF |
| validate_password_dictionary_file | |
| validate_password_length | 8 |
| validate_password_mixed_case_count | 0 |
| validate_password_number_count | 1 |
| validate_password_policy | MEDIUM |
| validate_password_special_char_count | 1 |
+---------------------------------------+--------+

修改MySQL密码策略

set global validate_password_mixed_case_count=0;

3.Slave-Server 配置

修改my.cnf

cat /etc/my.cnf
[mysqld]
server-id=2

如果要设置多个从库,则每个从库的server-id与主库和其他从库设置不同的唯一值。

启动MySQL服务,登录MySQL

systemctl start mysqld
mysql -uroot -p

配置主库通信

查看 Master-Server , binlog File 文件名称和 Position值位置 并且记下来

mysql>  show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      629 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

要设置从库与主库进行通信,进行复制,使用必要的连接信息配置从库在从库上执行以下语句
将选项值替换为与系统相关的实际值

CHANGE MASTER TO MASTER_HOST=‘192.168.252.123‘, MASTER_USER=‘replication‘, MASTER_PASSWORD=‘mima‘, MASTER_LOG_FILE=‘mysql-bin.000001‘, MASTER_LOG_POS=629;

启动从服务器复制线程

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.252.123
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 629
               Relay_Log_File: master2-relay-bin.000003
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
......

 

检查主从复制通信状态

Slave_IO_State #从站的当前状态
Slave_IO_Running: Yes #读取主程序二进制日志的I/O线程是否正在运行
Slave_SQL_Running: Yes #执行读取主服务器中二进制日志事件的SQL线程是否正在运行。与I/O线程一样
Seconds_Behind_Master #是否为0,0就是已经同步了

必须都是 Yes

如果不是原因主要有以下 4 个方面:

1、网络不通
2、密码不对
3、MASTER_LOG_POS 不对 ps
4、mysql 的 auto.cnf server-uuid 一样(可能你是复制的mysql)

$ cat /var/lib/mysql/auto.cnf
[auto]
server-uuid=6b831bf3-8ae7-11e7-a178-000c29cb5cbc # 按照这个16进制格式,修改server-uuid,重启mysql即可

4.测试主从复制

启动MySQL服务

 登录MySQL

在 Master-Server 创建测试库

在 Slave-Server 查看是否同步过来

 

一些命令

查看主服务器的运行状态

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     1190 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

查看从服务器主机列表

mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3306 |         1 | 6b831bf2-8ae7-11e7-a178-000c29cb5cbc |
+-----------+------+------+-----------+--------------------------------------+

获取binlog文件列表

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |      1190 |
+------------------+-----------+

只查看第一个binlog文件的内容

mysql> mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                                                                                                                                                                  |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.19-log, Binlog ver: 4                                                                                                                                                                 |
| mysql-bin.000001 | 123 | Previous_gtids |         1 |         154 |                                                                                                                                                                                                       |
| mysql-bin.000001 | 420 | Anonymous_Gtid |         1 |         485 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 485 | Query          |         1 |         629 | GRANT REPLICATION SLAVE ON *.* TO ‘replication‘@‘192.168.252.124‘                                                                                                                                     |
| mysql-bin.000001 | 629 | Anonymous_Gtid |         1 |         694 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 694 | Query          |         1 |         847 | CREATE DATABASE `replication_wwww.ymq.io`                                                                                                                                                             |
| mysql-bin.000001 | 847 | Anonymous_Gtid |         1 |         912 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 912 | Query          |         1 |        1190 | use `replication_wwww.ymq.io`; CREATE TABLE `sync_test` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

查看指定binlog文件的内容

mysql> mysql> show binlog events in ‘mysql-bin.000001‘;
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                                                                                                                                                                  |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.19-log, Binlog ver: 4                                                                                                                                                                 |
| mysql-bin.000001 | 123 | Previous_gtids |         1 |         154 |                                                                                                                                                                                                       |
| mysql-bin.000001 | 420 | Anonymous_Gtid |         1 |         485 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 485 | Query          |         1 |         629 | GRANT REPLICATION SLAVE ON *.* TO ‘replication‘@‘192.168.252.124‘                                                                                                                                     |
| mysql-bin.000001 | 629 | Anonymous_Gtid |         1 |         694 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 694 | Query          |         1 |         847 | CREATE DATABASE `replication_wwww.ymq.io`                                                                                                                                                             |
| mysql-bin.000001 | 847 | Anonymous_Gtid |         1 |         912 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘                                                                                                                                                                  |
| mysql-bin.000001 | 912 | Query          |         1 |        1190 | use `replication_wwww.ymq.io`; CREATE TABLE `sync_test` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

启动从库复制线程

mysql> START SLAVE;
Query OK, 0 rows affected, 1 warning (0.00 sec)

停止从库复制线程

mysql> STOP SLAVE;
Query OK, 0 rows affected (0.00 sec)

 

以上是关于Mysql主从复制方式以及可能出现的问题的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 主从复制

MySQL主从复制

开启GTID主从同步出现1236错误问题

docker 配置mysql8主从复制出现的问题

搭建 MySQL 5.7.19 主从复制,以及复制实现细节分析

mysql主从同步中出现的问题梳理