MySQL主从
一、MySQL主从介绍
注意:本文中提到的主服务器=主数据库=master;从服务器=从数据库=slave
1.MySQL主从复制是什么?
MySQL主从复制也叫MySQL主从同步:
MySQL主从复制
是一种MySQL数据库的数据同步机制,用于将一个MySQL主服务器
上的数据自动复制到一个或多个从服务器
上。主服务器
负责接收和处理写操作,而从服务器
负责接收主服务器的写操作,并将其应用到自己的数据库中,从而使得从服务器的数据与主服务器保持一致。主从复制可以提供数据冗余、负载均衡以及实时备份的能力,对于读写分离和高可用性的需求非常适用。
2.MySQL主从复制的作用
mysql主从可以使主、从数据库的数据完全同步,无论是以前产生的数据还是未来产生的数据。
MySQL主从复制是一种常见的数据库复制技术,其作用是将一个MySQL主服务器上的数据和操作同步到多个从服务器上。主从复制具有以下作用:
- 提高数据库的可用性和容错性:通过将数据复制到多个从服务器,可以实现主服务器的冗余备份。当主服务器发生故障时,可以快速切换到从服务器保障业务的持续运行。
- 分担读取负载:主服务器负责处理写操作,而从服务器可以处理读操作。通过将读请求分发到从服务器,可以减轻主服务器的负载,提高读取性能。
- 数据分布和容量扩展:通过配置多个从服务器,可以将数据分布到不同的节点上,实现数据的水平分片和分布式处理。同时,通过增加从服务器,可以扩展整个系统的容量和性能。
- 数据备份和恢复:通过主从复制,可以定期将主服务器上的数据同步到从服务器上,实现数据备份。当主服务器发生灾难性故障时,可以使用从服务器进行数据恢复。
总之,MySQL主从复制提供了高可用、容错性、读写分离以及数据备份等功能,可以提升数据库系统的性能和可靠性。
3.MySQL主从复制的几种形式
形式 | 描述 |
---|---|
一主一从 | 这是最常见和简单的复制形式。 一个MySQL主服务器(Master)负责处理写操作和记录事务日志,一个从服务器(Slave)通过复制主服务器的二进制日志来同步数据。 主服务器负责写操作,从服务器负责读操作。 当主服务器发生故障时,可以使用从服务器顶替为新的主服务器。 |
主主复制 | 主主复制是一种对等的复制形式,其中两个MySQL服务器既可以作为主服务器又可以作为从服务器。 两个服务器都可以处理写操作,并相互复制彼此的变更,以保持一致性。 主主复制通常配置在不同的物理位置,以实现高可用性和容错性。 |
一主多从 | 这种形式下,一个MySQL主服务器同时与多个从服务器建立复制关系。 主服务器负责处理写操作和记录事务日志,从服务器通过复制主服务器的二进制日志来同步数据。 多个从服务器可以处理读操作,从而分担主服务器的负载。 |
多主一从 | 这种形式下,多个MySQL主服务器同时与一个从服务器建立复制关系。 多个主服务器都可以处理写操作,并将变更复制到一个从服务器上。 从服务器负责读操作和接收多个主服务器的变更。 |
联级复制 | 在联级复制中,有多个从服务器形成复制链,从一个从服务器复制到另一个从服务器。 通常存在一个主服务器(顶级从服务器)和多个从服务器(下级从服务器)。 主服务器将变更复制到顶级从服务器,然后顶级从服务器将变更复制到下级从服务器。 联级复制可以用于构建更复杂的拓扑结构,实现数据分配和分布式处理。 |
参考图:
二、MySQL主从复制原理
主从复制步骤:
- 主库(master)将所有的写操作记录到binlog日志中并生成一个log dump线程,将binlog日志传给从库(slave)的I/O线程
- 从库(slave)生成两个线程,一个I/O线程,一个SQL线程
- I/O线程去请求主库的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中
- SQL线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,达到最终数据一致的目的
参考图:
原理:
MySQL主从复制的原理是通过复制主服务器上的二进制日志(binary log)来实现。主从复制的过程包括以下几个关键步骤:
- 主服务器记录二进制日志(Binary Log):主服务器将所有的写操作和数据变更记录在二进制日志中,包括增删改操作和事务信息。
- 从服务器连接主服务器:从服务器建立与主服务器的连接,并发送复制请求。
- 主服务器发送二进制日志:主服务器将记录的二进制日志发送给从服务器。
- 从服务器应用二进制日志:从服务器接收主服务器发送的二进制日志,并按照顺序应用这些日志来执行相应的操作,即重放主服务器上发生的写操作。
- 从服务器周期性地获取主服务器的二进制日志:从服务器会周期性地通过长连接获取主服务器的二进制日志文件的更新。
这样,从服务器就可以实时地复制主服务器上的数据和操作。
三、MySQL主从复制配置
简述配置流程
主从复制配置步骤:
- 确保从数据库与主数据库里的数据一样
- 在主数据库里创建一个同步账号授权给从数据库使用
- 配置主数据库(修改配置文件)
- 配置从数据库(修改配置文件)
注意: 如果是主数据库是已经运行过一段时间的数据库(已经存放了数据),就需要做第一步。做法是在主数据库上做一次全量备份,然后把备份文件发送到从数据库上去执行一遍。这样就保证主、从数据库的数据一样了。如果你的主数据库和从数据库都是同时安装的崭新的,就不需要这样做。
配置环境
数据库角色 | IP地址 | 系统 | 主机名 | 有无数据 | 数据库版本 |
---|---|---|---|---|---|
主数据库 | 192.168.179.5 | centos8 | master | 有数据 | MariaDB-10.3.17 |
从数据库 | 192.168.179.13 | centos8 | slave | 无数据 | MariaDB-10.3.17 |
配置过程
安装MySQL
在两台主机上安装、配置mysql。此过程省略,有疑问请参考我的MySQL基础这篇文章
配置MySQL主从
注意: 在配置之前请关闭两台主机的防火墙和selinux
//主数据库服务器
[root@master ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@master ~]# setenforce 0
//从数据库服务器
[root@slave ~]# systemctl disable --now firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@slave ~]# setenforce 0
1.先将主数据上的已经存在数据同步到从数据库
//查看主数据库上的数据
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.000 sec)
MariaDB [(none)]> show tables from test;
+----------------+
| Tables_in_test |
+----------------+
| student |
+----------------+
1 row in set (0.000 sec)
MariaDB [(none)]> select * from test.student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | lrf | 20 |
| 2 | cl | 21 |
| 3 | lxy | 22 |
+----+------+------+
3 rows in set (0.000 sec)
//在主数据库上进行全量备份
//在全备的时候要另外开启一个终端开启读锁,避免在备份数据库时有其他人还在写入数据导致数据不一致
MariaDB [(none)]> flush tables with read lock;
Query OK, 0 rows affected (0.000 sec)
//全备数据库
[root@master ~]# mysqldump -uroot -p --all-databases > all-data-newslave.sql
Enter password:
[root@master ~]# ls
all-data-newslave.sql anaconda-ks.cfg
//把备份文件发送到从数据库服务器上
[root@master ~]# scp all-data-newslave.sql [email protected]:/opt
The authenticity of host '192.168.179.13 (192.168.179.13)' can't be established.
ECDSA key fingerprint is SHA256:QIg6m6fw/NexKvp1qhh3cr17bwESuRxduIeS5LGDYVA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.179.13' (ECDSA) to the list of known hosts.
[email protected]'s password:
all-data-newslave.sql 100% 469KB 69.2MB/s 00:00
//在从数据库服务器上使用这个备份文件进行数据恢复,从而以达到主、从数据库的数据一模一样
[root@slave ~]# ls /opt/
all-data-newslave.sql
[root@slave ~]# mysql -uroot -p < /opt/all-data-newslave.sql
Enter password:
//登录到从数据库中查看数据
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.001 sec)
MariaDB [(none)]> select * from test.student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | lrf | 20 |
| 2 | cl | 21 |
| 3 | lxy | 22 |
+----+------+------+
3 rows in set (0.000 sec) //已经有了
//退出进行读锁的交互式终端,解锁
MariaDB [(none)]> quit
Bye
2.在主数据库里创建一个同步账号授权给从数据库使用
//创建用户wanf
MariaDB [(none)]> create user 'wanf'@'192.168.179.13' identified by 'wanf001';
Query OK, 0 rows affected (0.000 sec)
//授权
MariaDB [(none)]> grant replication slave on *.* to 'wanf'@'192.168.179.13';
Query OK, 0 rows affected (0.000 sec)
//刷新授权信息
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.000 sec)
3.配置主数据库
//编写配置文件,添加两行
[root@master ~]# vim /etc/my.cnf
[root@master ~]# cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=mysql-bin //添加此行,启用binlog日志
server-id=10 //添加此行。数据库服务器唯一标识符,从库的server-id值必须比主库的大。推荐主 库使用10,从库使用20。这样后面不论是添加主库还是从库都有多余的id可以用。
symbolic-links=0
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
//重启mysql服务
[root@master ~]# systemctl restart mariadb.service
//查看主数据库的状态
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000007 | 328 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)
//显示当前使用的日志文件是mysql-bin.000007,当前所在的位置是328
4.配置从数据库
//编写配置文件,添加两行
[root@slave ~]# vim /etc/my.cnf
[root@slave ~]# cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server-id=20 //添加此行。数据库服务器唯一标识符
relay-log=mysql-relay-bin //添加此行。启用中继日志relay-log
symbolic-links=0
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
//重启服务
[root@slave ~]# systemctl restart mariadb.service
//配置从数据库的主从复制
MariaDB [(none)]> change master to master_host='192.168.179.5',
-> master_user='wanf',
-> master_password='wanf001',
-> master_log_file='mysql-bin.000007',
-> master_log_pos=328;
Query OK, 0 rows affected (0.003 sec)
//启动主从复制
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.001 sec)
//查看从数据库的状态
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.179.5
Master_User: wanf
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 328
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: mysql-bin.000007
Slave_IO_Running: Yes //此处必须为yes
Slave_SQL_Running: Yes //此处必须为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: 328
Relay_Log_Space: 864
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 //数字大小表示落后主服务器多少,如果是上下波动是 正常的。如果一直增大就不正常。
(省略)
1 row in set (0.000 sec)
5.测试验证
//在主服务器中的数据库test中的student表里写入新的数据
MariaDB [test]> insert student (name,age) values ('xc',20),('wyq',21);
Query OK, 2 rows affected (0.001 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [test]> select * from student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | lrf | 20 |
| 2 | cl | 21 |
| 3 | lxy | 22 |
| 4 | xc | 20 |
| 5 | wyq | 21 |
+----+------+------+
5 rows in set (0.000 sec)
//在从数据库服务器上去查看是否同步成功
MariaDB [(none)]> select * from test.student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | lrf | 20 |
| 2 | cl | 21 |
| 3 | lxy | 22 |
| 4 | xc | 20 |
| 5 | wyq | 21 |
+----+------+------+
5 rows in set (0.001 sec)
//同步成功
GTID主从
GTID(Global Transaction Identifier)主从复制是MySQL数据库中一种用于故障恢复和数据一致性维护的技术。它通过全局事务标识符(GTID)来标记和追踪事务在主库和从库之间的同步状态
通过使用GTID主从复制,可以简化主从复制的配置和管理,并提高复制的可靠性和稳定性。它可以让管理员更容易地进行故障恢复和数据同步操作。
一、GTID主从介绍
简介:GTID主从复制是指在MySQL数据库中,通过使用GTID来确保主库和从库之间的数据一致性和复制进度的一种复制方式。它主要用于解决传统基于二进制日志文件(binlog)的复制方式可能出现的数据不一致或者复制中断的问题。
二、GTID主从概念
GTID主从复制中的核心概念是全局事务标识符(GTID)。每个事务都会被分配一个全局唯一的GTID,用于标识该事务在主库上的执行情况。主库将GTID信息写入二进制日志中,并通过从库将这些事务按照相同的顺序和方式进行执行,从而实现数据的复制。
三、GTID主从原理
GTID主从复制的原理如下:
- 主库生成全局事务标识符(GTID)并将其写入二进制日志。
- 从库读取主库的二进制日志,并解析其中的GTID信息。从库使用GTID来跟踪复制进度。
- 从库执行与主库上相同的事务,以保持数据的一致性。从库使用已经执行的GTID来过滤掉已经复制过的事务,避免数据重复复制。
- 当从库追上主库的复制进度后,可以进行切换,将从库提升为新的主库(主从切换)。
四、GTID主从复制配置
mariadb版本配置
环境:
主机名 | IP地址 | 系统版本 | 服务版本 | 角色 |
---|---|---|---|---|
master | 192.168.179.5 | Redhat8 | MariaDB 10.3 | 主数据库 |
slave | 192.168.179.13 | Redhat8 | MariaDB 10.3 | 从数据库 |
1.安装mariadb
//安装、启动、设置密码
[root@master ~]# yum -y install mariadb mariadb-server
[root@master ~]# systemctl start mariadb.service
[root@master ~]# systemctl enable mariadb
[root@master ~]# mysql -e "set password = password('12345678')"
//从服务器同上操作
...
2.修改配置文件
//修改主服务器配置文件,添加最后的5行
[root@master ~]# vim /etc/my.cnf
[root@master ~]# cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
[mysqld]
log-bin=mysql_bin
server-id=10
gtid_strict_mode=on
log-slave-updates=on
//重启服务
[root@master ~]# systemctl restart mariadb.service
--------------------------------------------------------------------------------
//修改从服务器配置文件,添加最后的8行
[root@slave ~]# vim /etc/my.cnf
[root@slave ~]# cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
[mysqld]
server-id=20
relay-log=myrelay
gtid_strict_mode=on
log-slave-updates=on
read_only=on
master-info-repository=TABLE
relay-log-info-repository=TABLE
//重启服务
[root@slave ~]# systemctl restart mariadb.service
3.主服务器授权
//在主服务器上进行授权
MariaDB [(none)]> grant replication slave on *.* to 'wanf'@'192.168.179.13' identified by '123';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.000 sec)
4.从服务器开启主从
MariaDB [(none)]> change master to master_host='192.168.179.5',
-> master_port=3306,
-> master_user='wanf',
-> master_password='123',
-> master_use_gtid=slave_pos;
Query OK, 0 rows affected (0.002 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.002 sec)
5.查看主、从服务器的信息
//主服务器
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 | 647 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)
MariaDB [(none)]>
//从服务器
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.179.5
Master_User: wanf
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql_bin.000003
Read_Master_Log_Pos: 647
Relay_Log_File: myrelay.000002
Relay_Log_Pos: 946
Relay_Master_Log_File: mysql_bin.000003
Slave_IO_Running: Yes //必须两个都是yes才是成功
Slave_SQL_Running: Yes //必须两个都是yes才是成功
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
(省略)
mysql5.6和5.7
mysql5.6和5.7除了在配置文件这边不一样之外其他的步骤都是一样
mysql5.6或5.7版本的配置文件写法
//主服务器
[mysqld]
log-bin=mysql_bin
server-id=10
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=on
//从服务器
[mysqld]
server-id=20
relay-log=myrelay
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=on
read_only=on
master-info-repository=TABLE
relay-log-info-repository=TABLE