当前位置: 首页 > 科技观察

如何搭建双M结构的主从备份?

时间:2023-03-16 15:56:37 科技观察

关于MySQL主从搭建,宋大哥之前写了很多文章,录了个视频。不过之前的结构是一主一从,但是小伙伴们都知道,在我们的项目中,比较常见的结构是双M结构,即两个MySQL实例,互为主备。当主节点突然断电或不可用时,从节点可以快速切换为主节点。架构图如下:在这个结构中,两个MySQL实例的地位是平等的,互为主备。我们判断谁是master谁是slave主要看readonly,谁是read-only,那么谁是slave,所以这种情况下主从切换也很方便,修改readonly属性即可。接下来我们搭建一个双M的主从备份,看看和简单的M-S结构的区别。一、准备工作以下配置基于Docker。这里,我们先准备两台机器:M1:10.3.50.27:33061M2:10.3.50.27:330621.1M1M1的配置比较简单,分三步:(1)授权M2服务器GRANTREPLICATIONSLAVEON*.*to'rep1'@'10.3.50.27'由'123'标识;冲洗特权;这里的意思是配置M2登录用户名rep1,密码123,必须从地址10.3.50.27登录,登录成功后可以操作任意库任意表。其中,如果不需要限制登录地址,可以用%代替IP地址。请注意,在MySQL8中,这方面有一些变化。在MySQL8中,用户的创建和授权需要分开,不能像上面那样一步到位。具体方法如下:CREATEUSER`rep1`@`10.3.50.27`IDENTIFIEDWITHcaching_sha2_passwordBY'javaboy.COM';GRANTReplicationSlaveON*.*TO`rep1`@`10.3.50.27`;(2)修改主库配置文件,开启binlog并设置server-id。每次修改配置文件后,都必须重启MySQL服务才能生效。开启binlog主要是修改mysql.cnf的配置文件mysqld,该文件在容器的/etc/mysql/mysql.conf.d目录下。对于这个配置文件,我们做如下修改:[mysqld]#该参数表示开启binlog功能,指定binlog存放目录log-bin=javaboy_logbin#设置binlog_format格式,注意不要使用STATEMENTbinlog_format=ROW#设置一个binlog文件的最大大小Byte#设置最大100MBmax_binlog_size=104857600#设置binlog文件的有效期(单位:天)expire_logs_days=7#binlog日志只记录指定库的更新(使用配置主从复制时)binlog-do-db=javaboy_db#binlog日志不记录指定库的更新(配置主从复制时会用到)#binlog-ignore-db=javaboy_no_db#有多少个timestowritecache,refreshthedisk一次,默认0表示这个操作由操作系统根据自身的负载决定多久写一次磁盘#1表示每次事务提交will会立即写入磁盘,n表示n次事务提交会写入磁盘sync_binlog=0#为当前服务取一个唯一的id(MySQL5.7开始要求)server-id=1每个配置的意思都有宋大哥在Gaze里已经解释过了。截图如下:如下图所示:log-bin:同步日志的路径和文件名。一定要注意这个目录如果MySQL有写权限(这里我偷懒了,直接放在下面的datadir下)。binlog-do-db:要同步的数据库名称。当slave连接master时,只会同步这里配置的数据库,其他的不会同步。server-id:MySQL在主从环境下的唯一标识,随便给一个数字,注意不要和M2重复,因为以后会用server-id来表示binlog是从哪个库生成的,所以主从数据库的server-id不能相同,否则可能导致主从数据库binlog循环复制的问题。请注意,binlog_format的值为ROW。具体原因在之前的文章中已经和大家讨论过,这里不再赘述。配置完成后,重启MySQL服务器:dockerrestartmysql33061(3)查看当前二进制日志名称和M1的偏移量。这个操作的目的是在M2启动后从这个点开始恢复数据:showmasterstatus;至此,M1配置完成。1.2M2配置M2的配置与M1完全相同。唯一不同的是M2的mysqld.cnf文件中的server-id=2是一样的,这里不再赘述。配置完成后,相当于M2现在也是一台主机了。我们也可以执行showmasterstatus;M2上的命令,结果如下:1.3主从配置接下来,将M1和M2配置为彼此的主机。M1配置我们先配置M1,执行如下命令设置主机:更改master为master_host='10.3.50.77',master_port=33062,master_user='rep1',master_password='123',master_log_file='javaboy_logbin.000001',master_log_pos=154;这里配置主机地址、端口以及从机登录主机的用户名和密码。注意最后两个参数必须和M2中的保持一致。注意由于MySQL8密码插件的问题,这个问题也会导致主从配置出现问题,所以在MySQL8主从配置中,上面的命令需要加上get_master_public_key=1,完整的命令是如下:修改master为master_host='10.3.50.77',master_port=33062,master_user='rep1',master_password='123',master_log_file='javaboy_logbin.000001',master_log_pos=154,get_master_public_key=1;(1)启动slave进程startslave;启动后查看slave状态:showslavestatus\G;(2)检查slave的状态。下面两个值必须是YES,说明配置正确:Slave_IO_Running:YesSlave_SQL_Running:Yes至此配置完成,宿主机创建数据库,添加数据,从机自动同步。如果这两个中有一个不是YES,则说明主从环境搭建失败。这时候可以通过阅读日志查看错误原因,再针对具体问题进行解决。M2配置接下来,让我们配置M2。M2和M1的配置基本相同。记得在changemaster里把地址和端口写对:把master改成master_host='10.3.50.77',master_port=33061,master_user='rep1',master_password='123',master_log_file='javaboy_logbin.000001',master_log_pos=154;配置完成后,M1和M2互为主备。1.4测试测试分为两步:在M1新建javaboy_db库,在库中创建user表,向表中插入一条记录,然后在M2中查看数据是否已经同步。在M2中的user表中增加一条记录,查看M1中是否有对应的值。经过测试,我们发现没有问题,现在双方可以同步彼此的数据了。2、谁是主人,谁是奴隶?虽然是双M结构,但是在实际应用中还是有主从之分的。那么双M应该如何分主从呢?在生产环境中,我们一般会将备份节点设置为read_only,即只读,防止误操作。当然不用担心设置成read_only后binlog的写入也会被阻塞,超级用户还是有写权限的。将整个库设置为只读也很简单。首先,我们执行如下SQL查看对应变量的值:showvariableslike'read_only';可以看到,默认情况下read_only是OFF的,也就是关闭的。我们先把它设置为ON,执行如下SQL:setglobalread_only=1;1表示ON,0表示OFF,执行结果如下:这个read_only对超级用户无效,所以设置完成后,然后我们退出这个session,然后创建一个不包含超级权限的Users,loginwith一个新用户,登录成功后,执行一条insertSQL,结果如下:可以看到报错提示说当前MySQL是只读的(只能查询),不能执行当前SQL。这样设置后,当master出现异常,需要从master切换成slave时,slave会被临时替换。为了更好的实现主从同步,binlog的类型推荐使用行模式。