对于企业来说,最早的时候可能只需一台数据库服务器就能满足自身的需求,但随着企业的壮大和业务的发展,可能会对数据库的架构进行变更和升级,本篇主要模拟一下数据库主从复制和主主复制的实现,这也是很多企业使用的数据库架构。

  1. 主从复制

    MySQL或者MariaDB主从复制有着负载均衡读操作、备份、高可用和故障切换、数据分布和数据库升级等作用。其实现的整体思路是主节点服务器进行完全备份和主节点服务器通过二进制日志查看完全备份后的位置来将之后的数据进行同步到从节点服务器上,从而保证数据不会产生丢失。笔者这边准备两台虚拟机,下载同版本的MariaDB并开启服务,主节点服务器取名为master,从节点服务器取名为slave。

1.1 主节点服务器端

    主节点服务器导入hellodb数据库,模拟企业在之前的业务中生成的数据库​(如下图)​。

主从复制及主主复制的实现_数据库

1.1.1 修改配置文件

    打开/etc/my.cnf.d/mariadb-server.cnf配置文件,添加主节点服务器的server-id,建议id号为服务器ip的尾数,避免与其他节点的server-id发生冲突;同时开启二进制日志以备将来用于还原,建议与数据库文件相分离,相对更为安全,笔者这边实验就不单独去写路径并进行创建了​(如下图)​。

主从复制及主主复制的实现_数据库_02

1.1.2 完全备份

   执行 ​mysqldump -A -F --master-data=1 --single-transaction > /data/all.sql​ 命令将主节点服务器中的所有数据库数据导入到/data/all.sql目录下,生产中如果数据较大,建议进行压缩。其中,-A表示全备份;-F表示刷新日志,重新开启新的日志;--master-data设为1可直接用在从数据库中,2一般用在单机上,且为注释内容;--single-transaction表示以事物的方式开启备份功能。

主从复制及主主复制的实现_数据库_03

    此时,我们可以通过 ​less /data/all.sql ​命令查看完全复制后的位置​(如下图)​。

主从复制及主主复制的实现_服务器_04

1.1.3 创建账号并授权

    因笔者这边使用的是MariaDB数据库,创建账号和授权是可以一条命令完成的,如果是MySQL8.0版本需要分两步进行。

主从复制及主主复制的实现_数据库_05

1.1.4 复制完全备份至从节点

    根据主从复制的整体思路,我们还需将完全备份的内容发送到从节点服务器中。

主从复制及主主复制的实现_数据库_06

1.2 从节点服务器端

1.2.1 修改配置文件

    与主节点服务器相同,从节点也需要修改配置文件,添加自己的server-id,同时建议开启read-only​(如下图)​。

主从复制及主主复制的实现_数据库_07

1.2.2 修改备份文件

    完全备份文件中记录了完全备份完成后的二进制日志位置信息,但是我们还要将主节点服务器的信息添加进来,包括主节点服务器的ip、创建账号的名称及密*码和端口​(如下图)​。

主从复制及主主复制的实现_数据_08

1.2.3 关闭二进制日志

    登录数据库,查看二进制日志是都是开启的,如果已经开启,需要先进行关闭再进行备份数据还原​(如下图)​。

主从复制及主主复制的实现_数据库_09

1.2.4 还原数据

    ​执行 ​source /data/all.sql​ 命令进行备份数据还原,因为已经对完全备份文件进行了修改,所以此命令会同时完成CHANGE MASTER TO中的主节点ip和授权用户等信息。

主从复制及主主复制的实现_数据_10

1.2.5 开启复制线程

    上一步的操作完成后,从节点上查看状态,已经有了主节点的相关信息,但是IO线程和SQL线程尚未开启,因此还需执行 ​start slave; ​命令开启复制线程​(如下图)​。

主从复制及主主复制的实现_数据_11

主从复制及主主复制的实现_服务器_12

1.2.6 重新开启二进制日志

    在完成上述操作后,从节点服务器需重新开启二进制日志。此时,我们查看数据库和数据库中的信息,已经与主节点同步。

主从复制及主主复制的实现_数据_13

1.3 测试环节

    主节点服务器上删除hellodb数据库中的coc表,此时返回从节点服务器查看,数据也已经同步,hellodb数据库中少了coc表​(如下图)​。

主从复制及主主复制的实现_数据库_14

主从复制及主主复制的实现_数据库_15

1.4 从节点误操作及修复

1.4.1 误操作

    从节点虽然设置的是read-only,但是可能也会存在公司内部人员误操作的行为。例如本来要在主节点服务器hellodb数据中的teachers表里添加LeoMessi的信息,但是添加在了从节点服务器中。由于主从复制只能是主节点进行数据变更,从节点拉取主节点上的数据实现同步,此时从节点添加了信息,虽然自己能看到,但是主节点上缺看不到​(如下图)​。

主从复制及主主复制的实现_数据库_16

主从复制及主主复制的实现_数据库_17

    主节点上在teachers表中添加一条Cristiano Ronaldo的信息,自己能看到,但是从节点已经无法实现同步功能,显示的仍是之前在从节点添加的信息,查看状态也已经报错,并且SQL线程已经关闭​(如下图)​。

主从复制及主主复制的实现_服务器_18

主从复制及主主复制的实现_数据库_19

    这就相当于高速堵车了,虽然后面的车在源源不断的来,但是由于前方出现故障,无法达到目的地。如果不根据报错内容修改,后续在主节点上添加的其他信息,从节点上也无法同步​(如下图)​。

主从复制及主主复制的实现_数据_20

主从复制及主主复制的实现_数据库_21

1.4.2 修复

    如果清空从节点服务器的数据,重新进行主从复制,这个方法固然可行,但是生产中的数据较大,操作起来工作量会比较大。我们可以根据报错内容,跳过已经出现的报错点。

    首先从节点服务器停止复制线程,查看状态只显示一个报错,因此可以执行 ​set global sql_slave_skip_counter = 1;​ 命令,跳过一个错误。重新开启复制线程后,IO和SQL线程都已经显示yes,报错部分也消失了,同时查看teachers表时,主节点添加的TID为6和7的信息也同步过来了​(如下图)​。

主从复制及主主复制的实现_数据_22

主从复制及主主复制的实现_服务器_23

主从复制及主主复制的实现_服务器_24

主从复制及主主复制的实现_数据库_25

    由于以上只是跳过了错误,虽然不影响主从复制的后续使用,但为了防止以后要用到从节点服务器的数据进行还原,建议手动改正过来​(如下图)​。

主从复制及主主复制的实现_服务器_26

    除了登录后去执行此操作,也可以将错误编号添加到配置文件中,例如以上报错的编号为1062,可以在从节点服务器的配置文件中添加slave_skip_errors=1062一行,如果将1062改为ALL,即视为跳过所有的错误编号,一般生产中不推荐设为ALL。

1.5 从节点变更为主节点

    假设现在主节点服务器出现故障,要将从节点服务器变更为主节点服务器。

    由于从节点服务器设置的是read-only,即只读,无法进行写操作,因此要将变量改为0,即关闭read-only​(如下图)​。

主从复制及主主复制的实现_数据_27

    同时要删除/etc/my.cnf.d/mariadb-server.cnf配置文件中添加的read-only一行,因为已经在登录状态下修改了变量,修改配置文件后无需重启服务。

    接着登录数据库后停掉复制进程,查看状态会显示很多之前的信息,因此还需清除信息,再次查看复制线程状态已经显示空内容,即从节点服务器已变成了主节点,如果想继续使用主从复制架构,可以参照上面的方法继续配置从节点服务器​(如下图)​。

主从复制及主主复制的实现_服务器_28

主从复制及主主复制的实现_服务器_29


  1. 主主复制

    主主复制即两个节点服务器之间互为主从,都能够进行数据的更新。但此种架构也有弊端,即两个节点服务器如果同时进行某项操作,比如同时执行了某一个相同的写操作时,会导致两个节点出现类似于主从复制中的线程堵塞现象,因此,虽然有些企业使用主主复制架构,但真正使用时,只在某一个节点上进行数据更新。当在使用的主节点服务器出现故障时,另一个节点服务器会自动的替补上来,因此短时间内可以不用停掉服务去重新设置主节点。

    笔者这边准备了两台虚拟机,下载同版本的MySQL数据库,同时分别取名为master1和master2。

2.1 修改配置文件

    两个节点都是master属性,因此server-id需进行修改,与主从复制建议相同,将server-id改为自己的ip尾数。因为用的是MySQL8.0版本,二进制日志会默认开启,笔者这边设置一下二进制日志的存放路径,放在/data/mysql目录下,设置二进制日志文件的开头为mysql-bin;同时要根据配置文件中设置的二进制日志存放路径来创建目录,并进行权限的修改​(如下图)​。

主从复制及主主复制的实现_服务器_30

主从复制及主主复制的实现_数据库_31

2.2 创建账号并授权

    在master1中先查看当前的位置,同时创建账号并进行授权,假设现在要创建的账号名为johnny,因为是MySQL8.0版本,创建账号和授权要分两步进行​(如下图)​。

主从复制及主主复制的实现_数据库_32

2.3 开启复制线程

2.3.1 master2开启复制线程

    根据master1创建的账号以及查看二进制日志文件时的位置,在master2中添加相关信息,查看线程状态无报错,但IO线程和SQL线程尚未开启,因此还需执行 ​start slave; ​命令来开启复制线程​(如下图)​。

主从复制及主主复制的实现_数据_33

主从复制及主主复制的实现_数据库_34

2.3.2 master1开启复制线程

    master2上查看当前二进制日志的位置,因为是主主复制架构,所以无需在master2数据库上创建账号,就用之前在master1上创建的johnny账号即可。master1数据库参照master2的操作进行信息的修改后,开启复制线程​(如下图)​。

主从复制及主主复制的实现_服务器_35

主从复制及主主复制的实现_数据_36

2.4 测试环节

    在完成上诉操作后,两个节点的数据库已经互为主从,实现了主主复制架构。此时在master1上创建db1数据库,在master2上是可以查看的;同理,在master2上创建db2数据库,在master1上也可以查看​(如下图)​。

主从复制及主主复制的实现_服务器_37

主从复制及主主复制的实现_服务器_38

2.5 报错及修复

2.5.1 报错

    假设现在有两个用户刚好都在db1数据库中,在同一时刻创建了test1表,表面上来看都是创建成功的,但是查看复制线程状态时会显示错误,两边的SQL线程均已关闭​(如下图)​。

主从复制及主主复制的实现_数据库_39

    如果不根据报错内容进行修改,后续更新将无法进行同步,例如在master1上创建test2表,在master2上已无法查看到​(如下图)​。

主从复制及主主复制的实现_服务器_40

主从复制及主主复制的实现_数据_41

2.5.2 修复

    该部分与主从复制的报错及修改类似,也可以直接在登录数据库的情况下通过变量来跳过报错点,这里换个方法,即在配置文件中进行修改。因为报错编号为1050,两个节点均在/etc/my.cnf文件中添加一行slave_skip_errors=1050,同时重启MySQL服务​(如下图)​。

主从复制及主主复制的实现_服务器_42

主从复制及主主复制的实现_数据库_43

    此时登录数据库查看线程状态,均已正常,master2在使用sb1数据库时,也能查看master1在报错期间创建的test2表,同时自己创建一个test3表,返回master1服务器也能查看到​(如下图)​。

主从复制及主主复制的实现_数据_44

主从复制及主主复制的实现_数据_45

主从复制及主主复制的实现_服务器_46

主从复制及主主复制的实现_服务器_47

    ​提示:如果在配置文件中添加了跳过报错点的信息后立即登录数据库,查看线程状态时可能会有最长等待60秒的提示,可以等,也可以先先执行 sttop slave; 命令停掉线程,再执行 start slave; 命令重新开启线程,这样就不用去等待系统自己去完成线程的修复。