半同步-延迟备份-主从切换
半同步-延迟备份-主从切换
思考一个问题
在已经有一台在运行的db服务器,要加一台从服务器,业务不允许停,要怎么做?
难点是找到二进制日志的位置号。业务在运行的时候,位置一直在变。
-
可以加个锁,然后从锁那里再开始做
-
xtrabackup
解决了备份的时候自动记录二进制日志文件和位置号
主从切换
failover
主从切换就是 用户只能往主里边写数据,一旦主服务器down掉了,就把提升另一台从服务器为主。更改dns域名解析到刚提拔的那台主服务器的ip地址,使得成功的进行主从复制。
正常情况:
主down掉的情况:
异步复制
异步复制是一种数据库、文件系统或其他数据存储系统中的数据复制方法。在这种模式下,数据的复制(即从一个位置到另一个位置的复制)不会实时进行。当主系统上发生数据变更后,这些变更将被记录下来,然后在之后的某个时间点(而不是立即)复制到备份系统或副本上。
优点:
- 性能提升: 由于不需要等待数据在系统间同步,所以可以提高主系统的性能。
- 减少延迟: 对主系统的操作不会因等待数据复制而延迟,特别适合延迟敏感的应用。
- 灵活性和可扩展性: 可以更容易地处理大量数据和跨越远程地理位置的复制需求。
缺点:
- 数据丢失风险: 如果在数据同步之前主系统发生故障,最近的数据变更可能会丢失。
- 数据一致性问题: 备份系统上的数据可能与主系统有短暂的不一致。
- 复杂的故障恢复: 在恢复过程中,可能需要更多的步骤来确保数据的完整性和一致性。
半同步(semi-sync)
形象的解释:
想象一下,你是一家餐厅的厨师,你的任务是制作食物(这里代表数据变更)。在半同步复制的情况下,这就像是你在做完一道菜后,需要确保至少一个服务员(代表备份系统或副本)已经拿到这道菜并准备送到顾客那里,然后你才能开始做下一道菜。
在这个过程中:
- 半同步的含义是,你不需要等到服务员真的把菜送到顾客手上(这就是全同步复制),但你至少要确保服务员已经 把菜拿在手上准备送出去。
- 这种方法的好处是,它提供了一种平衡:你不用等太久才能开始做下一道菜,但同时又确保了你的努力(即你做的菜)不会因为忘记交给服务员而浪费。
- 相比之下,异步复制就像是你做完菜后直接开始下一道,不管服务员是否已经取走菜品。
总的来说,半同步复制是一种在数据变更和数据复制之间找到平衡点的方法。它确保了数据在被复制到至少一个其他地方之前,主系统不会继续进行下一步操作,从而减少了数据丢失的风险,同时又避免了等待所有副本都接收数据所造成的延迟。
用户进行commit操作的时候,就是数据落盘,落盘得先写二进制日志。二进制日志发生变化之后,dump线程通知slave的IO线程来拿二进制日志。然后同步到磁盘里边,这个时候同时发送数据给slave,并且要求slave给他ack确认。我收到slave的ack就会开始落盘,然后通知用户落盘成功。
半同步和异步的区别
半同步要求:slave给主一个ack确认,不给就不进行操作
半同步不是完全的同步,还是会有时间差
10s不给确认 就执行异步操作
配一下半同步
官方文档: https://dev.mysql.com/doc/refman/5.7/en/replication-semisync-installation.html
在master上配置
先配置一个安装半同步的插件
root@(none) 16:26 mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
root@(none) 16:28 mysql>
临时开启一下超时时间并且开启
在master上:
root@(none) 16:28 mysql>SET GLOBAL rpl_semi_sync_master_timeout = 1;
Query OK, 0 rows affected (0.00 sec)
root@(none) 16:31 mysql>
root@(none) 16:33 mysql>SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)
root@(none) 16:34 mysql>
永久修改,就是修改配置文件
在 /etc/my.conf中加入下边两行
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1 second
刷新mysql服务
[root@sc-master ~] service mysqld restart
Shutting down MySQL............. SUCCESS!
Starting MySQL.. SUCCESS!
[root@sc-master ~]#
同样的在slave上边也配置安装半同步的插件
root@(none) 16:27 mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)
root@(none) 16:40 mysql>
root@(none) 16:40 mysql>SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)
root@(none) 16:41 mysql>
永久修改:
在 /etc/my.conf中加入下边这行
rpl_semi_sync_slave_enabled=1
刷新服务:
[root@sc-slave ~] service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@sc-slave ~]#
检验是否配成功了
得去从上重启一下io线程
因为io是拿二进制日志的,要给ack确认的
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
在master上执行sql查看是否激活半同步:
root@(none) 16:46 mysql>SELECT PLUGIN_NAME, PLUGIN_STATUS
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
+----------------------+---------------+
1 row in set (0.00 sec)
root@(none) 16:46 mysql>
验证的过程
master:
root@(none) 16:46 mysql>create database hepang123;
Query OK, 1 row affected (0.01 sec)
root@(none) 16:50 mysql>use hepang123;
Database changed
root@hepang123 16:51 mysql>create table t1(id int);
Query OK, 0 rows affected (0.00 sec)
root@hepang123 16:51 mysql>
slave:
root@(none) 16:50 mysql>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| TENNIS |
| gaohui |
| gh |
| hepang123 |
| jiaojiao |
| mysql |
| performance_schema |
| sc |
| shiyuqian |
| sys |
| wangshuai |
| yuanrd |
+--------------------+
13 rows in set (0.00 sec)
root@(none) 16:50 mysql>use hepang123;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
root@hepang123 16:51 mysql>show tables;
+---------------------+
| Tables_in_hepang123 |
+---------------------+
| t1 |
+---------------------+
1 row in set (0.00 sec)
root@hepang123 16:51 mysql>
开启log_slave_updates=ON功能
在MySQL中,
log_slave_updates
参数设置为ON
的作用是使得从服务器(Slave)接收到的复制事件不仅应用到自己的数据上,还会被记录到从服务器的二进制日志(binlog)中。这个设置通常在链式复制或多级复制架构中很有用,即当一个从服务器同时也是其他服务器的主服务器时。
当
log_slave_updates
设置为ON
,从服务器会将接收到的复制事件写入自己的二进制日志。这意味着这些变更可以被进一步复制到连接到这个从服务器的其他从服务器中去,实现了级联复制。
在/etc/my.conf中加入
log_slave_updates=ON
延迟备份
延迟备份,或者更常见的称呼“延迟复制”(Delayed Replication),是数据库复制的一种特殊形式,通常用于MySQL等数据库管理系统中。在这种模式下,从服务器(备份服务器)故意延迟应用主服务器上的变更一段指定的时间。
可以这样形象地比喻:
想象一下,你是一位摄影师,正在拍摄一个实时活动并且将照片实时传送给编辑团队。在没有延迟备份的情况下,编辑团队会立即收到照片并立即发布。这就像是标准的数据库复制,从服务器会尽快复制主服务器上的数据更改。
但如果活动中可能会出现一些错误,你可能希望给编辑一个缓冲期来撤销或修改这些照片,这时候你就可以选择发送照片到编辑团队但告诉他们延迟一段时间发布,比如延迟一小时。这样,如果发生错误,你有足够的时间发送一个撤销的信号,或者发送一个修正后的照片来替换原始的照片。在数据库的延迟复制中,这个“延迟”给了你一个时间窗口来处理主服务器上的意外情况,比如误删除数据或者错误的数据更新,在数据被应用到从服务器之前有机会去修正它们。
延迟备份的一个典型应用场景是灾难恢复。如果主服务器上执行了一个破坏性操作,比如不小心删除了一个重要的数据表,延迟备份允许从服务器在这个操作被应用之前有时间去采取措施,比如暂停复制并创建一个数据的快照。这样,即使主服务器的数据丢失了,你还能从从服务器中恢复数据。
这张图片通过一个生动的场景来说明我刚刚描述的延迟复制概念。在这个场景中,摄影师在现场活动中拍照,并带有一条注释发送给编辑团队,注释上写着“将这些照片延迟1小时发布”。编辑团队面前有一堆标有未来时间戳的照片。与此同时,摄影师手中准备着“取消”或“更正”印章,在延迟期结束之前随时准备修改任何照片。图中强调了时间缓冲的概念,象征着在问题变得公开之前修正错误的机会,这与数据库复制中的延迟备份相类似。
操作
在从服务器上:
root@(none) 17:19 mysql>stop slave;
Query OK, 0 rows affected (0.00 sec)
root@(none) 17:19 mysql>CHANGE MASTER TO MASTER_DELAY = 10; '延迟10s'
Query OK, 0 rows affected (0.01 sec)
root@(none) 17:19 mysql>start slave;
Query OK, 0 rows affected (0.00 sec)
root@(none) 17:19 mysql>show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
SQL_Delay: 10
root@(none) 17:19 mysql>
进行主从切换(failover)
完全手工去操作
步骤:
-
stop slave;
- 停止从服务器的复制进程。 -
reset master;
- 重置主服务器的二进制日志。 -
开启二进制日志 - 确保主服务器的二进制日志功能被启用。
-
切记这里要关闭半同步的设置,在/etc/my.cof 加个#
-
-
建立授权复制的用户 - 在新的主服务器上创建具有复制权限的用户。
-
再启动一台机器做从,配置master信息去拉取二进制日志 - 在新的从服务器上配置与新主服务器的连接,并开始复制过程。
CHANGE MASTER TO MASTER_HOST='192.168.153.132',
MASTER_USER='renxj',
MASTER_PASSWORD='Sanchuang123#',
MASTER_PORT=3306,
MASTER_LOG_FILE='sc-slave-bin.000001',
MASTER_LOG_POS=154;
整个过程就是把主和从的配置进行调换,更改半同步的时候记得安装插件
如何将网站的写流量切到新的master上?
- 直接修改web里的代码里的IP,换成新的master的IP。
- 修改域名对应的IP为新的master的IP。
- 如果使用中间件,需要在中间件里调整。
是否可以自动实现主从切换?
答案: 可以
使用脚本实现
:
-
监控master:
- 在另外一台机器扫描端口:
nc -zv master_ip 3306
- 直接访问:
mysql -h master_ip -uroot -p'password' -e 'show databases;'
- 每秒钟监控一次。
- 在另外一台机器扫描端口:
-
马上执行手工操作的步骤,脚本自动执行:
- 编写脚本将上述手工操作步骤自动化,一旦监控到主服务器不可用,立即执行切换。