EQVPS
控制台开始使用

如何在 VPS 上安装 MySQL:用户、安全的远程访问、更省内存和备份

在 Ubuntu 24.04 VPS 上安装 MySQL 8.0,创建数据库和应用用户,不开放 3306 端口就能从自己的电脑访问,把空闲内存从 383 MB 降到 165 MB,并用一个出错就明确报错的脚本每晚备份。

安装 MySQL 只要一条命令。真正的工作在后面:给应用的用户、一种不把 3306 端口暴露在互联网上就能从自己电脑访问数据库的方法、适合小服务器的内存设置,以及不用你操心就能自动运行的备份。本指南在 Ubuntu 24.04 上把这四件事都讲清楚。每一步都在我们的 Ubuntu 24.04 镜像上执行过,下面的数字都来自那台服务器。

用有 sudo 权限的用户执行命令。Ubuntu 配置指南会创建一个。

1. 安装

sudo apt update
sudo apt install -y mysql-server
mysql --version

在我们的服务器上,安装用了 51 秒,装上的是 MySQL 8.0.46。它会立即启动,每次开机自动启动,并且只在服务器本机上监听:普通连接是 127.0.0.1:3306,MySQL 较新的 X 协议是 127.0.0.1:33060。此时外部还什么都访问不到。

2. 创建数据库和用户

在 Ubuntu 上,MySQL 的 root 账户使用套接字认证,所以 sudo mysql 不用密码就能登录。为你的应用创建数据库和用户:

sudo mysql
CREATE DATABASE app CHARACTER SET utf8mb4;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'localhost';
EXIT;

按应用的连接方式测试一下:

mysql -u app -p app -e "SELECT CURRENT_USER();"

应该输出 app@localhost。密码错误会得到 ERROR 1045 (28000): Access denied for user 'app'@'localhost'。这个用户在 app 里可以做任何事,在它之外什么都不能做。

3. 从你的电脑连接:SSH 隧道

要在自己的电脑上用 DBeaver、MySQL Workbench 或 mysql 命令行这类桌面客户端,也不要开放端口。通过 SSH 转发一个:

ssh -L 3307:127.0.0.1:3306 deploy@YOUR.SERVER.IP

NAT 套餐要加上 -p 和控制面板里的专属 SSH 端口。保持这个窗口打开,把客户端指向主机 127.0.0.1、端口 3307、用户 app。本地一侧用 3307,是为了不和你电脑上可能运行的 MySQL 冲突。在我们的测试中,服务器通过隧道立刻响应,而直接连接它地址上的 3306 则被拒绝。

4. 给另一台服务器直接访问

有时应用运行在第二台服务器上,必须直接连接数据库。这时数据库需要一个带独立 IPv4 的套餐,因为 NAT 套餐只转发你的 SSH 端口。共三处修改,都只限于应用服务器的地址(这里是 203.0.113.20):

sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp
CREATE USER 'app'@'203.0.113.20' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'203.0.113.20';

如果 ufw 还没启用,先允许 SSH(sudo ufw allow OpenSSH),再运行 sudo ufw enable。详细内容见 ufw 指南。

我们分别检查了两道锁。有防火墙规则但没有对应的 MySQL 用户时,服务器以 error 1130: Host '…' is not allowed to connect to this MySQL server 拒绝。加上用户后,连接成功。去掉防火墙规则后,连接直接超时。互联网上的其他任何地址都会遇到同样的超时。

5. 更省内存

空闲且没有自己的数据时,MySQL 8.0 在我们的服务器上用了 383 MB。其中大部分是 Performance Schema,一个预先占用内存的诊断功能。在小 VPS 上把它关掉,并自己设定主缓存的大小:

sudo tee /etc/mysql/mysql.conf.d/zz-small-vps.cnf >/dev/null <<'EOF'
[mysqld]
performance_schema = OFF
innodb_buffer_pool_size = 256M
max_connections = 50
EOF
sudo systemctl restart mysql
ps -o rss= -C mysqld

重启后它只用了 165 MB。buffer pool 用来缓存数据和索引,对同时运行应用的 2 GB 服务器来说,256 MB 比较合适。如果数据库是服务器上的主要负载、而且已经比缓存还大,就把它调大。max_connections = 50 对一个使用连接池的应用来说绰绰有余。你会失去 performance_schema 的统计数据;如果哪天需要深入排查慢查询,再把它打开。

6. 每晚备份

mysqldump --single-transaction 能在不锁住应用的情况下,得到 InnoDB 表的一致性副本。把它放进一个小脚本:

sudo tee /usr/local/bin/mysql-backup >/dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077
mkdir -p /var/backups/mysql
mysqldump --single-transaction --routines --triggers app | gzip > /var/backups/mysql/app-$(date +%F).sql.gz
find /var/backups/mysql -name 'app-*.sql.gz' -mtime +14 -delete
EOF
sudo chmod 755 /usr/local/bin/mysql-backup
echo '0 3 * * * root /usr/local/bin/mysql-backup' | sudo tee /etc/cron.d/mysql-backup
sudo /usr/local/bin/mysql-backup && sudo ls -l /var/backups/mysql

每一行都有它的道理:

  • umask 077 让转储文件只有 root 能读(-rw-------),因为里面是你的全部数据。
  • pipefail 让 mysqldump 失败时整个脚本也失败。没有它,gzip 会写出一个空空的小压缩包并报告成功。我们故意弄坏了命令,脚本果然以代码 2 退出。
  • find … -mtime +14 -delete 保留两周的副本。
  • 脚本以 root 运行,所以 mysqldump 通过套接字登录,不需要把密码写进任何文件。

从没恢复过的备份还不算数。把它恢复到一个临时数据库里看看数据:

sudo mysql -e "CREATE DATABASE app_restore"
gunzip -c /var/backups/mysql/app-2026-10-25.sql.gz | sudo mysql app_restore
sudo mysql -e "SHOW TABLES FROM app_restore"
sudo mysql -e "DROP DATABASE app_restore"

在我们的测试中,恢复出来的表和原表的行完全一样。同一块磁盘上的副本在你失去服务器时帮不上忙,所以时不时用 scp 或 restic 把它们拉到另一台机器上。Managed Backups 还会额外提供整台服务器的每日恢复点。

选哪个套餐

Micro(2 vCPU、2 GB、25 GB,$5/月)可以承载按上面调好的 MySQL 加一个网页应用。如果数据库本身超过几个 GB,Small(4 GB、35 GB,$8/月)能让你给 buffer pool 1 GB 或更多。两者都是 NAT 套餐,第 3 步的 SSH 隧道照样可用。第 4 步需要独立 IPv4:Micro-IP 为 $10/月。

更喜欢 PostgreSQL?PostgreSQL 指南按同样的思路编写。所有套餐都在 VPS 里,支付方式为 Base、Ethereum 或 Polygon 网络上的 USDT、USDC 或 ETH。

常见问题

用 MySQL 还是 MariaDB?

两者都在 Ubuntu 24.04 自带的软件仓库里:mysql-server 安装 MySQL 8.0,mariadb-server 安装 MariaDB 10.11。大多数要求“MySQL”的应用两者都能用。按应用文档的要求选;如果无所谓,就用 MySQL 8.0。本指南使用 MySQL。

MySQL 的 root 密码是什么?

没有。在 Ubuntu 上,MySQL 的 root 账户使用套接字认证:sudo mysql 就能以 root 登录,而任何人都无法通过网络以 root 登录。保持这样,并为各个应用单独创建用户。

要把 3306 端口开放到互联网吗?

不要。开放的数据库端口一直被扫描、被尝试猜密码。从你自己的电脑通过 SSH 隧道连接。如果另一台服务器必须直接连接,只允许它的 IP,MySQL 和防火墙两边都要设置。

MySQL 需要多少内存?

刚装好时,MySQL 8.0 在我们的测试服务器上、没有自己的数据库,就用了 383 MB。关闭 Performance Schema 并设置一个适中的 buffer pool 后,降到 165 MB。2 GB 的 Micro 套餐跑 MySQL 加一个应用很轻松;经过这样调整,小网站用 1 GB 也够。

需要运行 mysql_secure_installation 吗?

在 Ubuntu 24.04 上,它要做的事大多已经做好了。我们的新安装里没有匿名用户,也没有测试数据库,root 只能通过本地套接字登录。如果你想要它提供的密码强度检查组件就运行,否则可以跳过。

评论

暂无评论。来做第一个吧。

发表评论

评论在显示前会经过审核。