努力
加油

基于CentOS或Ubuntu搭建MySQL服务器的最佳实践有哪些?

在 Linux 环境下部署 MySQL,虽然核心配置逻辑相通,但 CentOS(及其继任者 Rocky/AlmaLinux)和 Ubuntu 在包管理、默认配置路径以及安全策略上存在显著差异。作为长期在一线运维和架构设计的从业者,我总结了一套兼顾稳定性、安全性和性能的最佳实践。

以下内容基于当前主流版本(CentOS Stream/Rocky Linux 9+ 和 Ubuntu 22.04 LTS/24.04 LTS)及 MySQL 8.0+ 系列编写。

一、 系统层面的基础准备

无论选择哪个发行版,以下三个步骤是地基,不能跳过。

1. 关闭 Swap 并优化内核参数

MySQL 对内存敏感,Swap 会导致严重的性能抖动甚至死锁。

# 临时禁用
sudo swapoff -a

# 永久禁用(修改 /etc/fstab,注释掉 swap 行)
sudo sed -i '/swap/s/^/#/' /etc/fstab

内核参数优化 (/etc/sysctl.conf):

# 增加文件描述符限制
fs.file-max = 655350

# 调整 TCP 连接队列,防止高并发下的 SYN Flood 或连接积压
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

# 允许重用 TIME_WAIT 状态的 socket
net.ipv4.tcp_tw_reuse = 1

# 禁用 ICMP 重定向(提升安全性)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0

应用配置:sudo sysctl -p

2. 文件系统挂载建议

  • 数据盘:务必使用 ext4 或 xfs。如果使用 SSD/NVMe,确保挂载选项中包含 noatime 以减少磁盘 I/O。
  • 独立分区:如果条件允许,将 /var/lib/mysql 单独挂载在一个高性能数据盘上,避免与系统日志混用。

3. 用户与权限隔离

绝对不要使用 root 运行 MySQL 服务。
安装完成后,确保 MySQL 以专用用户(通常是 mysql)运行,并设置严格的目录权限。


二、 安装与初始化策略

CentOS/RHEL 系

推荐使用官方 YUM 仓库或 RPM 包,而非仅依赖 EPEL。

# 添加 MySQL YUM Repository
sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el9.noarch.rpm
sudo dnf module disable mysql
sudo dnf install mysql-server

# 启动并设置开机自启
sudo systemctl enable mysqld --now

Ubuntu 系

Ubuntu 通常通过 APT 直接安装,体验更流畅。

sudo apt update
sudo apt install mysql-server

# Ubuntu 默认可能已自动启动,检查状态
sudo systemctl status mysql

关键差异点:

  • CentOS: 初始密码通常在 /var/log/mysqld.log 中生成,需先提取临时密码修改。
  • Ubuntu: 默认启用 auth_socket 插件,本地 root 用户无需密码即可通过 Unix Socket 登录,安全性较高但远程连接需额外配置。

三、 核心配置文件优化 (my.cnf / mysqld.cnf)

不要盲目套用网上的“调优脚本”,必须根据实际业务负载调整。以下是通用的高可用基线配置。

位置:

  • CentOS: /etc/my.cnf 或 /etc/my.cnf.d/mysql-server.cnf
  • Ubuntu: /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 1. 字符集:统一使用 utf8mb4,支持 Emoji 和多语言
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# 2. 时区:明确指定,避免应用层混淆
default-time-zone = '+08:00'

# 3. 连接数:根据服务器 CPU 核数和内存调整
# max_connections = 1000 (保守值)
# wait_timeout 和 interactive_timeout 设为合理值,防止空闲连接占用资源
wait_timeout = 600
interactive_timeout = 600

# 4. 缓冲池:InnoDB 核心性能指标
# InnoDB Buffer Pool 大小建议设置为物理内存的 50%-70%
innodb_buffer_pool_size = 4G  # 示例:假设服务器有 8G 内存
innodb_buffer_pool_instances = 4 # 多实例化,减少锁竞争

# 5. 日志与审计
general_log = 0
slow_query_log = 1
long_query_time = 2
log_queries_not_using_indexes = 1
# 生产环境建议开启 binlog,格式为 ROW
binlog_format = ROW
expire_logs_days = 7

# 6. 安全加固
# 禁用本地文件加载,防止 SQL 注入读取敏感文件
local_infile = 0
# 禁用旧式密码验证
old_passwords = 0

重启生效:

sudo systemctl restart mysqld  # CentOS
sudo systemctl restart mysql   # Ubuntu

四、 安全加固最佳实践

这是很多开发者最容易忽视的部分。

  1. 执行安全脚本
    安装后务必运行安全配置向导:

    sudo mysql_secure_installation

    它会引导你设置 root 密码、移除匿名用户、禁止远程 root 登录、删除测试数据库。

  2. 最小权限原则

    • 创建业务用户时,只授予必要库表的权限。
      CREATE USER 'app_user'@'%' IDENTIFIED BY 'StrongPassword123!';
      GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'%';
      FLUSH PRIVILEGES;
    • 严禁给应用账号赋予 GRANT OPTION 或 FILE 权限。
  3. 网络访问控制

    • 如果是云服务器(阿里云、腾讯云、AWS 等),不要在 MySQL 配置文件中绑定 0.0.0.0 来开放公网。
    • 正确做法:在云控制台的安全组/防火墙规则中,仅允许特定 IP(如应用服务器内网 IP)访问 MySQL 端口(默认 3306)。
    • 监听地址配置:bind-address = 127.0.0.1(仅限本地连接)或绑定到内网网卡 IP。
  4. SSL/TLS 加密
    MySQL 8.0 默认启用 SSL。确保客户端连接时使用 SSL,防止中间人攻击窃取数据。


五、 备份与恢复策略

没有备份的系统等于裸奔。

  1. 逻辑备份(推荐用于中小规模)
    使用 mysqldump 或 mydumper。

    # 每日凌晨全量备份 + 增量 Binlog
    crontab -e
    0 2 * * * /usr/bin/mysqldump --all-databases --single-transaction --routines --triggers | gzip > /backup/mysql/full_$(date +%F).sql.gz
  2. 物理备份(大规模数据推荐)
    使用 Percona XtraBackup,可实现热备,不影响在线业务。

  3. Binlog 保留策略
    定期清理过期的 Binlog,既节省空间又提高主从同步效率。可通过定时任务调用 PURGE BINARY LOGS BEFORE ...。


六、 监控与维护

  1. 启用慢查询日志分析
    定期使用 pt-query-digest 工具分析 slow.log,找出性能瓶颈 SQL。

  2. 系统级监控
    结合 Prometheus + Grafana 或 Zabbix,监控以下关键指标:

    • QPS/TPS
    • InnoDB Buffer Pool 命中率(应 > 99%)
    • 活跃连接数 vs Max Connections
    • 磁盘 I/O 等待时间
  3. 补丁更新

    • CentOS: sudo dnf update mysql*
    • Ubuntu: sudo apt upgrade mysql-server
    • 关注 Oracle 官方安全公告,及时修补 CVE 漏洞。

七、 常见坑与避坑指南

  1. 大事务问题:避免在代码中执行耗时过长的事务,容易导致锁表、主从延迟。
  2. 隐式类型转换:确保查询字段类型与索引列类型一致,否则会导致索引失效。
  3. UUID 做主键:尽量避免使用 UUID 作为聚簇索引主键,会导致页分裂和碎片化。建议使用自增 ID 或雪花算法生成的有序 ID。
  4. Ubuntu 的 AppArmor:Ubuntu 默认启用 AppArmor,可能会拦截 MySQL 访问某些非标准路径的数据文件。如需自定义数据目录,需修改 AppArmor 配置文件,或在初期直接使用默认路径。

总结

搭建 MySQL 服务器不仅仅是“安装软件”,而是一个系统工程。CentOS 更注重稳定性和企业级规范,Ubuntu 更注重易用性和快速迭代。 在生产环境中,无论选择哪款 OS,核心原则不变:最小权限、资源隔离、数据备份、持续监控。

如果你是在国内公有云上部署,强烈建议直接使用厂商提供的 RDS 服务(如阿里云 RDS、腾讯云 CDB),除非你有极强的 DBA 团队需要深度定制内核参数或存储引擎。自建 MySQL 适合有特殊合规要求、极致成本控制或复杂混合架构的场景。