PS:这里我是按照基于二进制日志( based on binary log file position) 的方法来搭建的副本集,好像Mysql8.0还支持另外一种搭建方式(基于GTIDs),有兴趣的可以自己去官网了解一下。
实验环境:
主机(master) -------> IP: 222.192.192.65,操作系统:Ubuntu 18.04LTS,MySQL版本:8.0.13
从机(slave) ---------->IP:202.192.63.61, 操作系统:Ubuntu 18.04LTS,MySQL版本:8.0.13
这里我为了保护隐私,我把主机和从机的IP进行了改变,不过丝毫不会影响我们构造的步骤。
我们知道,MySQL服务器上的二进制日志记录了所有主机上有关数据更改的操作,所以我们可以通过二进制来重现之前的操作。所以基于二进制日志文件进行复制的基本原理就是:
从机(slave)通过读取和同步主机(master)上的二进制日志上的事件(events),在从机本地的数据库中来重现(也可理解为重做)这些操作,从而达到复制的效果。更加深入的涉及到从机需要记录主机上二进制日志文件的名称和读取文件的位置(binary log coordinates),同步异步问题(默认是异步的),延迟复制问题,可以仔细阅读官方文档来深入了解。另外需要注意到,由从机来决定是否执行主机二进制日志上所有的操作,用户可以通过配置,来让从机只执行二进制日志上特定数据库或者特定表上的更改,同时需要特别指出,不能配置主机(master)只记录特定的事件。
首先声明一点,有很多种方法来搭建主从复制,具体的方法取决于你怎样建立的复制,以及当前主数据库(master database)中是否已经存在数据,是否已经存在数据的差别主要在于主数据库的数据备份和从数据库的数据恢复上,由于我的主数据库中已经有数据,所以这里讲的是主要是第二种情况。
不管是哪一种情况,有一些通用的步骤需要去操作:
- 对于主机(master)来说,必须确保开启二进制日志的功能(默认是开启的,可以通过执行 show variables like "%log_bin%"来查看相关的系统变量),同时还要确保给主机配置一个唯一的server ID(取值范围1-232,用来标识不同的主机),每次配置完成后,需要重启服务器才能生效。
- 对于每一个想要连接主机的从机(slave)来说,也要必须配置一个唯一的serverID,同时也需要重启服务器才能生效。
- 有一个可选的操作:在读二进制日志的时候,可以在从机上创建一个单独的用户来和主机进行认证。
- 在从机开始复制之前。在主机上,应该先记录下当前二进制日志文件的位置。当配置从机的时候,我们需要这个信息来让从机知道从二进制日志文件的哪个位置来开始执行事件。
- 如果主机上有数据存在,并且想要把他同步到从机上,那么我们需要创建一个数据快照(data snapshot),从而把数据同步在主机上。根据你使用存储引擎的不同,那么创建数据快照的方式也是不同的(我这里使用的默认的InnoDB)。
- 我们需要在从机上配置,来连接主机,例如:主机上的主机名,认证信息,二进制日志文件的文件名和位置。
BTW:在搭建的过程中,有一些步骤是需要root权限的,如果没有root权限,可能一些操作进行不了。
Step1:配置主机(Setting the Replication Master Configuration)
主机上必须具有唯一的server-id,该值默认值是1,如果配置主机的server-id是0,那么它将会拒绝任何从机的连接,如果在从机上设置server-id是0,那么它将拒绝连接上主机,除此之外,你可以选取任意值和主机通信,只要它们是唯一的就可以。
这里我选取的主机server-id是456,操作步骤如下:
vim /etc/mysql/mysql.conf.d/mysqld.cnf # 编辑默认的配置文件
在文件中的mysqld的组中添加一个选项:
[mysqld]
server-id = 456 # 配置主机的server-id 为 456
在保存后,执行以下命令,重启Mysql服务
service mysql restart
重新登录MySQL客户端,执行下面的命令
show variables like '%server_id%'
Step2:从机配置(Setting the Replication Slave Configuration)
从机的配置和主机是一样的,每一个从机也需要有一个唯一的server-id,配置方法和第一步中服务器的是一样的,这里不再赘述,这里我配置的从机server-id为2。
这里需要明确一点:服务器上的二进制日志默认是开启的,从机上的二进制是可以设置为不开启的。如果从机上的二进制日志是开启的话,那么意味着从机上的二进制日志也可以作为其他机器的主机,如:
A -> B -> C # A是B的主机,B又可以作为C的主机
具体的实施情况可以参考其他教程做一下。
Step3:为复制创建用户(Creating a User for Replication)
每一个从机连接上主机都需要进行一个MySQL的用户名和密码,这里用户名和密码指的主机上的用户名。任何主机上的用户都可以作为从机登录时使用的用户名,只要它被赋予REPLICATION_SLAVE的权限。可以为每一个从机分别分配一个单独的用户,也可以让所有的从机使用同一个用户名。
这里我们选择创建一个新的用户,来专用于复制,只需要赋给它REPLICATION_SLAVE的权限就行。
登录MySQL客户端,在终端下执行
create user 'repl_slave'@'202.192.63.61' identified by 'password';
创建完用户后,给它赋予相应的权限。
grant replication slave on *.* to 'repl_slave'@'202.192.63.61'
执行完上面的命令后,就已经创建用户完成。
这里有一点需要我们注意一下,MySQL存储密码的插件是默认是caching_sha2_password,这个可以查看mysql数据库中的user表的plugin字段来进行查看,如果你创建的用户用的是这个插件,那么在最后进行在第7步的时候,会有所不同,我这里创建的用户用的是mysql_native_password,不同之处我会在第7步说到。
Step4:获取主机二进制日志位置(Obtaining the Replication Master Binary log Coordinates)
我们需要明确一点:如果想要从机能够从正确的地方开始,我们就必须让从机知道主机现在处在二进制日志的什么位置,这样从机才能正确的开始复制的流程,因此我们这一步所要做的就是获取到主机的位置。
如果你想先把主机先关机,再创建一个数据快照(data snapshot),那么几乎不需要这个流程,我们只需要将二进制日志的索引文件(binary log index file,默认的文件名为binlog.index)和数据快照备份一份。那么为什么先把主机关机后我们可以省去这个步骤呢?原因如下:
服务器在每次重启的时候,会重新创建一个新的二进制日志(可以在终端下执行 “show binary logs” 来查看系统当前的二进制日志文件),那么在主机关机的情况下,从机待读取二进制日志的位置一定是新创建的日志文件的开始位置,也就是主机上二进制日志索引文件列表中的下一个文件(文件名依次递增),这时候我们就不需要再刻意去找到二进制日志文件的位置了。
下面是具体的操作步骤
在主机上登录命令行模式下登录,在命令行中执行以下命令,对主机中的表加锁,阻止提交操作。
FLUSH TABLES WITH READ LOCK;
ATTENTION:我们需要保持执行这个命令的客户端一直处于登录状态,一旦推出客户端,这个 read lock将会失效。
在另外开启一个终端,登录客户端,在客户端吗命令行模式线下执行下面的命令。
show master status;
在上面命令的输出结果中,我们看到,File列正是当前正在使用的二进制日志文件的文件名,Positon列指出的是在这个二进制日志文件中的位置。有了这2个参数,我们就知道了从机该从主机的哪个位置开始复制了,我们需要记录下这2个值,后面在开启从机的时候要用到它们。
现在我们得到了从哪里让从机开始我们的复制,接下来的具体步骤取决于我们的主机(master)中是否有数据,由于我的主机中已经有了数据,所以我就按照主机中存在数据的步骤来走。
Step5:创建数据快照(Choosing a Method for Data Snapshots)
有不同的方法来从主机上来备份数据库,这里我们采用mysqldump工具的方法来备份所有的数据库,这也是推荐的方法,尤其当我们在使用InnoDB存储引擎来使用存储数据的时候。
我们来使用mysqldump来备份数据库。当数据库的备份创建以后,我们需要在从机开始复制前,将这份数据导入到从机中。
下面的命令,我们需要备份数据备份到一个dbdump.db的文件名中。
mysqldump --all-databases --master-data > dbdump.db
上面的命令中,我们加上了 –master-data 的选项,之所以加上这个选项是因为它会自动加上CHANGE_MASTER_TO给从机来开始复制过程。
另外需要说明一点,我上面的命令中备份了所有的数据库。如果你想备份特定的数据库或者不想备份某些表,可以在备份时使用–databases(备份特定的数据库)和–ignore-tables(排除备份特定的表) 选项,各个数据库和表名之间用空格隔开。
执行完上述的命令后,我们执行命令,我们可以发现已经备份成功:
Step6:创建复制的从机(Setting up Replication Slaves)
在开始之前,我们需要提前做一个准备工作,在第4步中,我们对主机中的表进行了加锁,在开始从机之前我们需要先释放锁。
在之前加锁的客户端下,我们执行下面的命令:
unlock tables;
通过上面的命令,我们将之前加的锁释放了。
接下来的步骤同样取决于我们是否有现有的数据需要导入到从机中,同样的,我们按照需要导入的这种方式来走(Setting Up Replication with Existing Data)。
导入数据的过程取决于你创建备份的方式,由于我们之前是采用mysqldump的方式来备份的数据库,我们就对应这种方式来在从机上恢复数据库。
首先,我们需要启动从机,并且使用 –skip-slave-start的选项来确保没有开始复制。
在终端下执行下面的命令
vim /etc/mysql/mysql.conf.d/mysqld.cnf # 默认的mysqld服务器进程的配置文件
在这个文件的mysqld组中我们需要追加下面的内容。
[mysqld]
skip-slave-start
保存退出后,我们可以执行下面的命令来重启mysql服务。
service mysql restart
执行完上面的命令后,我们的从机就已经启动了,只不过现在从机没有开始复制,这时候我们需要将主机上备份的数据库传输到从机的某个目录下(这一步可以通过scp命令进行传输,具体命令格式可以百度或谷歌),传输完成后,我们可以在从机上看到下面的情况。
我们的文档在从机上看到了之前备份的数据,文件名同主机上的备份文件名相同,这时候我们需要将改备份数据导入到从库中。执行下面的命令。
mysql < dbdump -u root -p # 我这里是使用的 root 用户来登录的,可以替换成自己的用户名
输入密码后,我们可以发现数据已经成功导入到从机中。
Step7:在从机上建立主机的配置(Setting the Master Configuration on the Slave)
为了让从机和主机建立连接,能够通信,我们需要让从机知道主机的主机名,用户名,密码,二进制日志文件的文件名和位置,所以这里我们就需要在从机上配置这些信息。
在从机上,登录MySQL的客户端,在命令行模式下,执行下面的命令。
mysql> change master to
-> master_host = '222.192.192.65', # 主机的IP地址
-> master_user = 'repl_slave', # 之前在主机上创建的用户
-> master_password = 'password', # 主机上创建的新用户的密码
-> master_log_file = 'binlog.000010'# 之前记录的二进制日志文件的名称
-> master_log_pos = 1389 # 之前记录的二进制日志文件的位置
在第3步中提到,提到如果在主机上创建的用户如果使用了默认的密码插件(caching_sha2_password),那么这一步中需要多一些操作,而使用mysql_native_password的用户则不需要,具体的需要多做的步骤可以参阅官方文档的介绍:使用默认密码插件的额外操作。
在执行完这个命令后,我们需要进行让从机的复制开始(之前在启动的时候使用了skip-slave-start选项,复制没有开始),在MySQL客户端下,执行以下的命令:
start slave; #开启从机的复制
这时候我们整个的搭建过程就结束了,大家可以在测试下,在主机上执行一些更改数据的操作。再登录一下从机,看一下过程是否主机的操作是否已经同步到从机。
最后想说一句:书上有路勤为径,学海无涯苦作舟。这几天的努力终于没有白费。希望本文对大家有一丝帮助吧。还是希望大家有时间可以阅读下官方文档,一定会有所裨益的。