LNMP架构(9)——mysql的半同步复制原理及配置

本文深入探讨MySQL半同步复制机制,解析其如何提高数据完整性,防止数据丢失。通过实例演示半同步复制的配置与测试过程,揭示其在主从同步中的作用及优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:相比异步复制提高了数据的完整性,因为增加了ack信号确认是否正常。

1.介绍mysql半同步复制的基础知识

半同步复制:一主多从模式下,有一个从节点返回成功,即成功,不必等待多个节点全部返回

MySQL半同步,该模式可以确保从服务器接收完主服务器发送的binlog日志文件并写入自己的中继日志(relay log)里,然后会给主服务器一个反馈,告诉对方已经接收到完毕,这时主库线程才返回当前session告知操作完成,当出现超时情况时,源主服务器会暂时切换到异步复制模式,直到至少有一台设置为半同步复制模式的从服务器及时收到信息为止。

主从同步可以同步多个数据库,也可以设置为一个数据库同步,如果设置一个数据库,在从服务器上其他数据可以写操作
半同步复制模式在主服务器和从服务器同时启用,否则主服务器默认使用异步复制模式

MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

异步复制可能会造成数据丢失 半同步复制就是为了解决数据丢失的问题

master做完一步等一步,需要等待至少一个slave节点完成复制之后才开始进行下一个操作
master做大事件的时候,需要进行半同步,master节点等待一个节点即可
当半同步出现问题的时候会自动切换为异步同步
银行数据库全同步,master节点等待集群中的所有全部节点
数据库要避免慢查询问题,会造成延迟,占用数据库的IO
优点:提高了数据完整性,数据至少会存在两个节点(master节点和一个slave节点)
加了消息确认ACK,不会造成数据丢失
出现问题会自动降低为异步复制

2. server2:主机的配置

mysql -p 
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  ##安装半同步模块
Query OK, 0 rows affected (0.02 sec)
 
mysql> show variables like 'rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_read_size                             | 8192       |
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
8 rows in set (0.01 sec)
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 10000;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_read_size                             | 8192       |
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)
mysql> SHOW PLUGINS;
 INNODB_SESSION_TEMP_TABLESPACES | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
mysql> create database test;
Query OK, 1 row affected (10.01 sec)
mysql> insert into test.user_tb value('user1',111);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test.user_tb value('user2',111);
Query OK, 1 row affected (0.00 sec)

slave的配置
在这里插入图片描述

mysql> show variables like 'rpl%';  
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_read_size                   | 8192     |
| rpl_semi_sync_slave_enabled     | OFF      |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
4 rows in set (0.01 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;  ##开启半同步,激活插件
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'rpl%';
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_read_size                   | 8192     |
| rpl_semi_sync_slave_enabled     | ON       |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
4 rows in set (0.01 sec)

测试:slave没开启时 在master上测试

mysql> show status like 'rpl%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 4     |同步失败
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
# 结果显示有四条sql语句没有同步过去,因为在slave上没有开启io 线程。

开启之后 在主机上插入一条语句,

mysql> STOP SLAVE IO_THREAD;
 
mysql> START SLAVE IO_THREAD; ##重启IO线程
 
mysql> show status like 'rpl%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 4     |之前的同步失败
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 442   |
| Rpl_semi_sync_master_tx_wait_time          | 442   |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     | #表示同步成功
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
 

测试:
1、关闭server2上面的slave,然后在server1上面插入数据
2、sever1(master)等待10s发现server2(slave)没有发送ACK消息,自动变为异步同步,
3、然后在server2上把slave上面开启,会把之前的数据读过来
也就是说只要从库的io进程恢复工作就会立即同步没有同步的数据
半同步复制失败后会自动切换成异步复制,从库进程起来之后会检测主从库数据是否同步;若不同步,将会采用异步复制的方式同步数据

<think>嗯,用户的问题是关于在公有云上为运行LNMP+WordPress的云主机扩容存储空间。之前已经给过一些解决方案,但用户似乎希望更聚焦于云平台提供的扩容功能,特别是参考了提供的ECS文档片段。用户可能实际面临两种场景:要么是系统盘不够用导致无法更新或写入日志,要么是网站数据(尤其是媒体库)膨胀过快。从技术文档看,云平台确实提供两种扩容路径——直接扩大原有磁盘或添加新数据盘,这点和AWSEBS或阿里云云盘的操作逻辑一致。注意到用户引用的文档提到关键细节:"按量付费实例需先转包年包月才能扩容",这个限制很容易被忽略但很重要,应该在方案里突出提醒。另外文档提到"扩容后需重启ECS",这在生产环境是需要谨慎处理的点,需要给用户补充无损重启方案。考虑到用户使用WordPress,其实除了硬件扩容,还可以在应用层减压:比如用云存储分流媒体文件这个方案性价比很高。不过用户特别强调要参考云平台文档,所以重点应该放在:1控制台操作流程(扩容/挂载新盘)2文件系统层面的扩展操作(特别是resize2fs命令)3扩容后的目录迁移方案(如把/var/www迁移到新盘)用户似乎对纯命令操作有些顾虑,所以回复里加入了具体的fdisk交互步骤(分区创建)和blkid使用示例(UUID绑定)。这些在Linux运维中都是标准操作,但对新手可能容易出错,需要分步骤说明。安全方面特别提醒了快照重要性——毕竟存储操作有风险,阿里云自己的文档也强调这点。最后补充的"无需重启"方案可能更符合用户需求(毕竟网站停机代价大),通过软链接迁移WordPress上传目录到新分区是个实用技巧。</think> 根据您的LNMP+WordPress架构和云服务特性,以下是完整的存储空间不足解决方案(结合操作步骤和平台特性): --- ### 一、存储诊断与清理(优先操作) 1. **查看磁盘使用** ```bash df -hT # 查看分区使用情况 du -sh /var/* # 分析大目录 ``` *重点关注:`/var/log/`(日志)、`/var/www/`(网站)、`/var/lib/mysql/`(数据库)* 2. **清理策略** - **日志清理**: ```bash sudo journalctl --vacuum-size=100M # 限制系统日志大小 sudo rm /var/log/nginx/*.log # 删除旧Nginx日志(先停止Nginx) ``` - **WordPress缓存**: 使用`WP-Optimize`插件清理数据库冗余数据[^1] - **无用文件**: ```bash sudo apt autoremove # 删除无用软件包 sudo rm -rf /tmp/* # 清理临时文件 ``` --- ### 二、云平台扩容操作(核心方案) #### ▶ 方案1:原磁盘扩容(推荐)[^1] 1. **控制台操作** - 在云控制台找到实例 → 停止实例 → 调整系统盘/数据盘容量 - *注意:按量付费需先转包年包月,扩容后需重启实例* 2. **扩展文件系统**(以ext4为例): ```bash sudo growpart /dev/vda 1 # 扩展分区(设备名需替换) sudo resize2fs /dev/vda1 # 调整文件系统大小 ``` #### ▶ 方案2:挂载新数据盘[^1] 1. **控制台操作** 购买新云盘 → 挂载到同可用区实例 → 重启生效 2. **配置新盘**: ```bash sudo mkfs.ext4 /dev/vdb # 格式化新盘 sudo mkdir /mnt/wordpress_data # 创建挂载点 sudo mount /dev/vdb /mnt/wordpress_data # 挂载 ``` 3. **迁移数据**: ```bash sudo systemctl stop nginx php-fpm # 停止服务 sudo mv /var/www/* /mnt/wordpress_data/ # 迁移网站数据 sudo ln -s /mnt/wordpress_data /var/www/html # 创建软链接 ``` --- ### 三、应用层优化(减轻存储压力) | 优化项 | 实施方式 | |-----------------|-------------------------------------------------------------------------| | **媒体文件分流** | 使用云存储OSS/COS存放图片视频,通过`WP Offload Media`插件同步[^2] | | **日志外存** | 配置Nginx日志输出到云日志服务: ```nginx access_log /dev/stdout; error_log /dev/stderr; ``` | | **自动清理** | 设置Crontab定时清理: ```bash 0 3 * * * find /var/log/nginx -name "*.log" -mtime +7 -delete ``` | --- ### 四、安全与验证 1. **操作前必做**: - 创建磁盘快照 [^1] - 备份数据库:`mysqldump -u root -p wordpress > wp_backup.sql` 2. **验证步骤**: ```bash df -hT # 确认扩容后大小 ls -l /var/www/html # 检查软链接有效性 sudo systemctl restart nginx # 重启服务测试 ``` > ⚠️ **关键提示** > 1. 阿里云扩容后需`重启实例`生效(腾讯云支持在线扩容) > 2. 按量付费实例需转`包年包月`才能扩容[^1] > 3. 生产环境建议在业务低峰期操作 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值