努力
加油

如何在ECS服务器上安全地安装和配置MySQL?

在阿里云 ECS(或者任何主流云厂商的云服务器)上部署 MySQL,看似简单,实则坑不少。很多新手直接 yum install mysql 或者 apt-get install mysql-server 一通乱搞,结果就是端口没开、密码忘了、数据丢了,最后还得重装。

作为在云上摸爬滚打多年的老鸟,我把这套流程拆解为“事前准备”、“安装选型”、“安全加固”、“持久化配置”四个核心环节。这里以目前最主流的 CentOS 7/8 或 Ubuntu 20.04+ 为例,因为这是国内企业级应用的主流底座。


一、 事前准备:别急着装软件,先搞环境

很多人忽略这一步,导致后续防火墙和权限问题层出不穷。

  1. 系统更新与基础依赖
    无论 CentOS 还是 Ubuntu,第一步永远是同步源并安装基础工具。

    # CentOS/RHEL
    sudo yum update -y
    sudo yum install -y vim wget net-tools curl
    
    # Ubuntu/Debian
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y vim wget net-tools curl
  2. 安全组/防火墙策略(关键!)
    这是最容易翻车的地方。绝对不要直接在服务器内部用 iptables 或 firewalld 去开放 3306 端口给全世界访问。

    • 正确做法:登录云控制台 -> 找到你的 ECS 实例 -> 点击“安全组” -> “配置规则”。
    • 添加一条入方向规则:协议 TCP,端口范围 3306,授权对象填你的固定公网 IP 或 内网 CIDR(如果是同 VPC 内的其他服务器连接)。
    • 切记:授权对象千万别填 0.0.0.0/0,除非你打算让黑客随便连。
  3. 关闭 SELinux(针对 CentOS)
    SELinux 经常导致 MySQL 无法启动或权限拒绝。对于生产环境,要么彻底禁用,要么配置复杂的策略。为了省事且稳定,建议临时或永久禁用:

    sudo setenforce 0
    sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

二、 安装选型:原生包 vs Yum/Apt vs Docker

在云上,你有三种选择,推荐程度依次递减:

方案 A:使用官方 Yum/Apt 源(推荐用于单机小项目)

这是最传统的方式,但要注意,CentOS 7 自带的 MySQL 版本可能较老,且现在更推荐安装 MariaDB 或 MySQL Community Server。

  • CentOS 7/8 (安装 MySQL 8.0):

    # 下载 MySQL 官方 repo
    sudo wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
    sudo rpm -ivh mysql80-community-release-el7-3.noarch.rpm
    sudo yum module disable mysql
    sudo yum install mysql-community-server -y
    
    # 启动服务
    sudo systemctl start mysqld
    sudo systemctl enable mysqld
  • Ubuntu 20.04+:

    sudo apt install mysql-server -y
    sudo systemctl start mysql
    sudo systemctl enable mysql

方案 B:Docker 容器化部署(强烈推荐,便于迁移和管理)

在云上,容器化是趋势。好处是:环境隔离、一键备份镜像、方便升级。

# 假设已安装 Docker
docker run -d 
  --name mysql-prod 
  -p 3306:3306 
  -v /data/mysql:/var/lib/mysql 
  -e MYSQL_ROOT_PASSWORD='YourComplexPassword123!' 
  -e TZ=Asia/Shanghai 
  mysql:8.0 
  --character-set-server=utf8mb4 
  --collation-server=utf8mb4_unicode_ci

注意:务必挂载卷 /data/mysql,否则容器重启数据就没了。

方案 C:直接使用云数据库 RDS(终极推荐)

如果你的业务已经成型,强烈建议放弃自建 MySQL,改用阿里云 RDS。

  • 理由:自动备份、高可用主从切换、监控报警、SSL 加密传输、无需维护 OS 层补丁。
  • 场景:只要不是极特殊的定制需求或为了省钱(RDS 确实贵),生产环境首选 RDS。自建 MySQL 的运维成本往往被低估。

三、 安全加固:装完只是开始,不改配置等于裸奔

安装完成后,你必须做以下操作,否则第二天就会被扫库。

  1. 获取初始密码并修改 Root 密码

    • CentOS (MySQL 8.0): 安装时会生成一个临时密码在 /var/log/mysqld.log 中。
      grep 'temporary password' /var/log/mysqld.log
    • Ubuntu: 通常没有初始密码,首次登录可能需要 sudo。

    登录后立即修改密码强度(MySQL 8.0 默认要求高复杂度):

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword!2024';
    FLUSH PRIVILEGES;
  2. 运行安全脚本(mysql_secure_installation)
    这是必做项,它会引导你完成:

    • 移除匿名用户(Anonymous Users)。
    • 禁止 root 远程登录(Remote root login)。
    • 移除测试数据库(test database)。
    • 刷新权限表。
      sudo mysql_secure_installation

      提示:如果是在 Docker 里,这个脚本可能不适用,需要手动处理。

  3. 创建专用用户,严禁使用 Root 连接应用
    你的 Java/Python/PHP 代码里,绝对不要用 root/root 连接数据库。

    -- 创建一个普通用户,只允许特定 IP 访问特定库
    CREATE USER 'app_user'@'%' IDENTIFIED BY 'AppUserStr0ngP@ss!';
    GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.* TO 'app_user'@'%';
    FLUSH PRIVILEGES;

    注:% 代表任意 IP,生产环境中最好指定具体的 ECS 内网 IP,如 'app_user'@'192.168.1.100'。

  4. 配置字符集为 utf8mb4
    防止 emoji 表情报错(😂 这种字符在 utf8 下会存不进去)。
    编辑配置文件 /etc/my.cnf (CentOS) 或 /etc/mysql/mysql.conf.d/mysqld.cnf (Ubuntu)。
    在 [mysqld] 段落下添加:

    [mysqld]
    character-set-server = utf8mb4
    collation-server = utf8mb4_unicode_ci
    init_connect='SET NAMES utf8mb4'

    重启 MySQL 生效。

  5. 绑定地址限制
    默认情况下,MySQL 监听 0.0.0.0。如果你不需要远程连接(比如应用就在同一台机器上),修改 bind-address 为 127.0.0.1。

    bind-address = 127.0.0.1

    这样即使有人破解了密码,也无法从网络连接。


四、 持久化与备份:数据无价

在云上,磁盘损坏的概率虽然低,但不是零。

  1. 开启 Binlog(二进制日志)
    用于主从复制和数据恢复。
    在 my.cnf 中添加:

    server-id = 1
    log_bin = mysql-bin
    binlog_format = ROW
    expire_logs_days = 7
    max_binlog_size = 100M
  2. 自动化备份脚本
    不要依赖云厂商的快照来做数据库备份,那是整机级别的。你需要逻辑备份。
    写一个简单的 Shell 脚本,利用 crontab 每天凌晨执行:

    #!/bin/bash
    DATE=$(date +%Y%m%d_%H%M%S)
    BACKUP_DIR="/backup/mysql"
    DB_USER="app_user"
    DB_PASS="AppUserStr0ngP@ss!"
    DB_NAME="my_database"
    
    mkdir -p $BACKUP_DIR
    mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
    
    # 删除 7 天前的备份
    find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

    将备份文件定期上传到 OSS(对象存储),实现异地容灾。

  3. ECS 系统盘快照
    除了数据备份,每周对 ECS 系统盘做一次快照,以防误删配置文件或系统崩溃。


总结与建议

  1. 小规模/测试环境:用 Docker 跑 MySQL 8.0,挂载数据卷,配置好 utf8mb4,搞定。
  2. 中型/正式环境:考虑购买阿里云 RDS MySQL,把精力放在业务代码上,而不是调优 MySQL 参数。
  3. 大型/高并发环境:自建 MySQL 集群(MHA/Orchestrator)+ 读写分离 + 缓存层(Redis)。这时候你需要深入理解 InnoDB 引擎、缓冲池大小、IO 性能等,但这超出了“安装配置”的范畴。

最后提醒:所有涉及密码的操作,严禁写在公开的博客或代码仓库里。使用环境变量或密钥管理服务(如阿里云 KMS、HashiCorp Vault)来管理敏感信息。