选 MySQL 还是 MariaDB
- MySQL — Oracle 维护,社区版(Community)免费
- MariaDB — MySQL 的开源分支,由 Monty(MySQL 原作者)维护
两者 API 高度兼容,绝大多数应用都能直接换。新项目两者都可以,看公司既有栈和团队习惯。本文以 MariaDB 为例(默认包更新)。
装 MariaDB
sudo apt update
sudo apt install mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo systemctl status mariadb
安全初始化(必跑)
sudo mysql_secure_installation
按提示选:
Switch to unix_socket authentication? [Y/n] Y
Change the root password? [Y/n] Y ← 设密码
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y ← 强烈推荐
Remove test database? [Y/n] Y
Reload privilege tables? [Y/n] Y
创建数据库 + 用户
sudo mysql -u root
-- 建库
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 建用户
CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'StrongPassword!';
-- 授权
GRANT ALL PRIVILEGES ON myapp.* TO 'myapp'@'localhost';
-- 应用变更
FLUSH PRIVILEGES;
-- 验证
SHOW DATABASES;
SELECT user, host FROM mysql.user;
EXIT;
测试用新用户登录:
mysql -u myapp -p myapp
远程访问(小心配)
默认 MariaDB 只监听 127.0.0.1——外网连不上。
如果要远程连(不推荐生产直接开公网):
sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf
bind-address = 0.0.0.0
sudo systemctl restart mariadb
授权远程用户(指定来源 IP,不要 % 全开):
CREATE USER 'myapp'@'192.168.1.%' IDENTIFIED BY 'StrongPassword!';
GRANT ALL ON myapp.* TO 'myapp'@'192.168.1.%';
FLUSH PRIVILEGES;
防火墙开 3306:
sudo ufw allow from 192.168.1.0/24 to any port 3306
⚠ 绝对不要 bind-address = 0.0.0.0 + 'myapp'@'%' + ufw 全开——一夜被扫库。
生产推荐:通过 SSH 隧道 / VPN / 内网 / 跳板机访问数据库,公网零暴露。
关键配置(性能)
/etc/mysql/mariadb.conf.d/50-server.cnf:
[mysqld]
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 连接数
max_connections = 200
# 内存(⚠ 按机器内存调,**别照抄**)
# 经验:调到机器可用内存的 50%–70%
# 4G 机器:1G–2G;8G:4G–6G;机器只有 1G 时设 256M 即可
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
# 日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1 # 慢于 1 秒的查询记下来
# 二进制日志(主从复制 / 时间点恢复)
log_bin = /var/log/mysql/mysql-bin
expire_logs_days = 7
改完重启:
sudo systemctl restart mariadb
备份
mysqldump(小数据库)
# 备份单库
mysqldump -u root -p myapp > myapp-$(date +%F).sql
# 备份所有
mysqldump -u root -p --all-databases > all-$(date +%F).sql
# 压缩
mysqldump -u root -p myapp | gzip > myapp-$(date +%F).sql.gz
# 只结构 / 只数据
mysqldump --no-data myapp > schema.sql
mysqldump --no-create-info myapp > data.sql
恢复
mysql -u root -p myapp < myapp-2026-05-09.sql
gunzip < myapp-2026-05-09.sql.gz | mysql -u root -p myapp
大库用 mariabackup / Percona XtraBackup
sudo apt install mariadb-backup
sudo mariabackup --backup --target-dir=/backups/db --user=root --password=...
物理备份,不锁表,适合 GB 级以上。
监控
mysql -e "SHOW STATUS LIKE 'Threads_connected'"
mysql -e "SHOW PROCESSLIST"
# 慢查询
sudo tail -f /var/log/mysql/slow.log
# 错误日志
sudo tail -f /var/log/mysql/error.log
实战:自动化每日备份脚本
#!/bin/bash
set -euo pipefail
readonly DB="myapp"
readonly BACKUP_DIR="/backups/db"
readonly DATE=$(date +%F)
readonly KEEP_DAYS=14
mkdir -p "$BACKUP_DIR"
# 备份(密码从 ~/.my.cnf 读,**不要写命令行**)
mariadb-dump --single-transaction "$DB" | gzip > "$BACKUP_DIR/$DB-$DATE.sql.gz"
# 同步到对象存储
rclone copy "$BACKUP_DIR" r2:db-backup --include "*-$DATE.*"
# 清理旧的
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
echo "✓ Backup done: $BACKUP_DIR/$DB-$DATE.sql.gz"
~/.my.cnf(权限 600):
[client]
user=root
password=YourPassword
crontab:
0 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
几条生产建议
- 数据库不要和应用同机器(如果资源允许)—— 容易互相 OOM
- 生产用主从(master + slave 复制)—— 见 ops-corp/34-db-ha
- 绝不裸密码远程—— SSH 隧道 / VPN / 私网
- 托管 RDS / Aurora / 云数据库 通常比自己运维划算(前期值,规模后看)
下一篇:自动化备份系统(不只是数据库)。