在阿里云 1 核 1G(1 vCPU, 1 GiB RAM)的实例上运行 MySQL,资源非常紧张。MySQL 默认配置通常是为更高配置设计的,直接运行极易出现内存溢出(OOM)、CPU 飙升或查询卡顿。
优化核心思路是:极致压缩内存占用、限制并发连接、简化查询逻辑以及利用云盘特性。以下是针对该场景的具体优化方案:
1. 关键参数调整 (my.cnf)
这是最重要的一步。你需要修改 /etc/my.cnf (CentOS/RedHat) 或 /etc/mysql/my.cnf (Ubuntu/Debian),将主要配置项调至最低安全值。
[mysqld]
# --- 内存控制 (核心) ---
# 总可用内存约 900MB-950MB (留 50-100MB 给 OS)
key_buffer_size = 16M # 索引缓存,1G 机器不宜过大
max_allowed_packet = 4M # 单个包大小,防止大文本写入撑爆内存
net_buffer_length = 8K # 网络缓冲区
sort_buffer_size = 256K # 排序缓冲,必须小
read_buffer_size = 256K # 读缓冲
read_rnd_buffer_size = 256K # 随机读缓冲
join_buffer_size = 256K # 关联查询缓冲
thread_stack = 128K # 线程栈
# --- 连接与进程控制 ---
max_connections = 30 # 默认 151 太高,建议设为 20-50,防止连接数过多耗尽内存
max_connect_errors = 100
wait_timeout = 60 # 缩短空闲连接超时时间
interactive_timeout = 60
# --- 日志与调试 (减少 I/O 和内存开销) ---
log_error = /var/log/mysqld.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log
long_query_time = 2 # 记录超过 2 秒的慢查询,避免记录过多
# --- 其他优化 ---
innodb_buffer_pool_size = 128M # 最关键参数!设置为物理内存的 10%-15%
innodb_log_file_size = 32M # 重做日志大小
innodb_flush_log_at_trx_commit = 2 # 【高风险高收益】设为 2 可大幅提升写入性能,但宕机可能丢失 1 秒数据;若追求稳定可设 1
innodb_flush_method = O_DIRECT # 绕过操作系统页缓存,减少双重拷贝,降低 CPU 和内存压力
tmp_table_size = 32M # 临时表最大内存大小
max_heap_table_size = 32M
# --- 引擎设置 ---
default-storage-engine = InnoDB
skip-name-resolve # 禁用 DNS 反向解析,加快连接速度并减少网络开销
注意:修改后需重启 MySQL (systemctl restart mysqld) 生效。
2. 文件系统与存储优化
1G 实例通常挂载的是高效云盘或 SSD,I/O 是关键瓶颈。
- 使用 XFS 文件系统:如果可能,将数据目录挂载在 XFS 格式化的分区上,相比 ext4 在高并发下表现更好。
- 开启
noatime选项:在/etc/fstab中为数据盘添加noatime选项,禁止更新文件访问时间,减少不必要的写 I/O。/dev/vdb1 /data xfs defaults,noatime,nodiratime 0 0 - 关闭 Swap(慎用):1G 内存非常宝贵,Swap 交换会导致磁盘 I/O 剧增,引发系统假死。如果业务允许,建议完全关闭 Swap (
swapoff -a)。如果必须保留,请确保 Swap 空间极小(如 256M),或者将vm.swappiness设为 1。
3. 应用层与 SQL 优化
由于硬件无法升级,代码层面的优化至关重要。
- 避免全表扫描:1 核 CPU 处理复杂查询能力弱。确保所有查询都走索引。
- 检查
EXPLAIN输出,确保type不是ALL。 - 避免
SELECT *,只查需要的字段。 - 避免在
WHERE子句中对字段进行函数运算或类型转换(这会导致索引失效)。
- 检查
- 限制批量操作:不要一次性插入或删除大量数据(如
DELETE FROM table WHERE id > 10000),应分批执行。 - 引入 Redis 缓存:对于读多写少的热点数据,务必在应用层接入 Redis,大幅减少 MySQL 的读取压力。
- 读写分离(单机版):如果架构允许,尽量将报表类、统计类查询隔离到从库或专门的低优先级时段执行。
4. 阿里云特有优化手段
- 云监控告警:安装阿里云云助手 Agent,配置“内存使用率 > 85%"或"CPU 使用率 > 80%"的自动告警,以便及时干预。
- RDS vs ECS:
- 如果你使用的是 ECS + 自建 MySQL:上述所有优化都需要手动维护,且需要自己处理备份。
- 如果你使用的是 阿里云 RDS MySQL:即使是 1 核 1G 规格,RDS 底层也做了很多内核级的优化(如参数模板预置)。如果是自建,建议考虑升级到 RDS 入门版,虽然贵一点,但稳定性远高于自建在极限资源下的表现。
- 快照备份策略:由于资源紧张,数据库崩溃风险高。建议配置每日自动快照,并在业务低峰期(如凌晨)进行手动备份,避免备份过程占用过多 I/O。
5. 运维与监控建议
- 关闭不必要的服务:停止该实例上非必要的服务(如 Nginx/Apache 如果不需要,或 Docker 容器等),将资源留给 MySQL。
- 定期清理:
- 清理 MySQL 的慢查询日志(
mysqladmin flush-logs需谨慎,最好由脚本定时切割)。 - 定期执行
OPTIMIZE TABLE或ALTER TABLE ... ENGINE=InnoDB来整理碎片(建议在业务低峰期)。
- 清理 MySQL 的慢查询日志(
- 观察指标:重点关注
Threads_connected(当前连接数)和Innodb_buffer_pool_reads(缓冲池未命中次数)。如果缓冲池命中率低于 90%,说明innodb_buffer_pool_size可能需要微调,但在 1G 环境下很难再提高。
总结
在 1 核 1G 上运行 MySQL,生存是第一要务,性能是第二位的。
- 强制限制
innodb_buffer_pool_size为 128M。 - 限制
max_connections为 30 以内。 - 应用层必须加 Redis 缓存。
- SQL 必须严格走索引。
如果业务量稍有增长导致负载过高,最经济的方案通常是升级实例规格(如升至 2 核 4G),因为在这个配置级别下,软件优化的边际效应已经极低,硬件成本增加带来的体验提升是巨大的。
CLOUD技术笔记