0x01 前言

我这个博客的服务器架构有点奇怪,后端有两个处于不同地域的PHP服务器,一个在我家里、另一个在腾讯云,而数据库只有一个,在腾讯云上。

因为我家里的服务器资源比较充足,可以承载更多的负载,但有时候会出现停电的情况。为此,我特意在腾讯云上部署第二个PHP服务器,以实现高可用。

但这里会有个问题,数据库在腾讯云,如果我家里的服务端需要查询数据库,则需要较长的时间才能得到结果,这样会导致整体的响应时间被拉长。

访客在我的站点上几乎没有需要写数据库的操作,所以我决定在家里部署一个从数据库,实现读写分离,将所有读库的操作都强制连接至从数据库。

其实我也想过配置主主模式,但考虑到家里有停电的可能,我还是采用主从模式。

0x02 准备

为实现主从模式,至少需要2个mariadb服务器:

在这里,我将mariadb-t1设为master;mariadb-t2设为slave。

为了这次测试,我将我博客的数据库dump一份出来用于测试:

大小约为29M:

然后根据以下文章进行mariadb的安装与预配置:

以下是我用于测试的两台mariadb服务器:

用于主从复制的mariadb版本不一致一般不会有什么问题,但为了可靠性与稳定性,建议不要跨大版本。

完成服务器的搭建后,我需要在主服务器里新建一个数据库并将上面导出的数据库导入到这个新的数据库中:

至此,准备工作已全部完成,接下来开始配置主服务器。

0x03 主服务器

我们需要先准备以下配置信息:

以上配置中的第二和第三项的值必须唯一,监听地址可以设为特定的IP,但无论如何,都需要通过防火墙进行控制,谨防未经授权的连接。

在实际环境中,一个mariadb服务器中可能有多个数据库,那么可以选择仅复制某个库或者不复制某个库:

如果需要添加多个库,则在新的一行添加即可。

完成后即可将配置信息写入文件,在这里我遵循mariadb文档的要求,将其写入到以下文件:

最终的结果如下:

完成后重启mariadb主服务器的服务:

然后新建一个名为slave的用户,并为其分配REPLICATION SLAVE权限:

然后启用读锁:

一定要启用读锁后再检查主服务器的状态,然后把File名称和Position的值记录下来:

最后把数据库dump一份出来,但这里需要注意!!不要关闭当前的mysql会话,请重新打开一个shell会话,在这新的shell会话中执行mysqldump命令。因为一旦关闭mysql会话,读锁会自动解除。

为什么要启用读锁?

如果业务在运行,当有新数据写入库的时候,二进制日志就会更新,那么这个Position会随之增长,这时候去dump这个库的时候,与记录的Position会不一致。当配置从服务器时会出现异常,从而导致同步失败。

了解基本的知识后,就可以打开一个新的shell会话并执行以下命令以导出数据库:

然后回到mysql会话的shell窗口,执行以下命令解除读锁并退出mysql会话:

最后把上面dump出来的数据库文件传输到从服务器上:

至此,主服务器的部分已全部结束。

0x04 从服务器

首先开启一个mysql会话并新建数据库、新建用户并然后将dump出来的数据库导入到该数据库中:

同样地,从服务器也需要修改配置文件,但是配置内容比主服务器简单得多:

打开文件并将其写入到文件:

然后重启mariadb从服务器的服务:

在继续往下之前,我们先准备一下mysql语句:

从字面上的意思不难看出,主要是告诉从服务器与主服务器连接的一些关键参数。主要是主服务器的IP地址、用户名、密码、端口、二进制文件名、日志记录节点与重连次数等。

准备好这些信息后,建立一个mysql会话并执行以上mysql语句:

然后通过以下命令启动复制进程:

通过以下命令检查复制情况:

检查的时候要注意以下两项:

需要确认服务是否处于运行的状态,如果不是,则需要检查日志查找原因。

还需要确认Read_Master_Log_Pos与Exec_Master_Log_Pos的值是否一致,如果稍等片刻之后还是不一致,则主从复制可能出现了问题,也需要检查日志查找原因。

如果需要停止slave复制,只需要在mysql会话下执行以下语句即可:

0x05 结语

主从服务器意外断开后,从服务器会尝试重连,如果连上,会再次复制同步,如果重连次数超过设定的值,则不会再次尝试,此时需要手动启动slave进程。

最后,附上我博客主从复制的情况图: