🔑 权限管理
MySQL 采用基于用户+主机的权限体系,遵循最小权限原则。
用户管理
-- 创建用户(仅允许本地连接)
CREATE USER 'app_user'@'127.0.0.1'
IDENTIFIED BY 'StrongP@ss2025!';
-- 授予只读权限
GRANT SELECT ON tech_blog.* TO 'app_user'@'127.0.0.1';
-- 授予指定表的读写权限
GRANT SELECT, INSERT, UPDATE ON tech_blog.articles
TO 'app_user'@'127.0.0.1';
-- 立即生效
FLUSH PRIVILEGES;
-- 查看权限
SHOW GRANTS FOR 'app_user'@'127.0.0.1';
-- 撤销权限
REVOKE INSERT, UPDATE ON tech_blog.articles
FROM 'app_user'@'127.0.0.1';
💡 最小权限原则:应用账号只给业务所需权限,禁止使用 root 账号连接生产库,不同业务使用不同账号。
💾 备份策略
备份类型对比
| 类型 | 工具 | 特点 | 适用 |
|---|---|---|---|
| 逻辑备份(全量) | mysqldump | SQL 文本,可跨版本恢复,速度慢 | 中小库、迁移 |
| 物理备份(全量) | XtraBackup | 热备、速度快、文件级备份 | 大库、生产推荐 |
| 增量备份 | XtraBackup --incremental | 只备份变化数据,节省空间 | 配合全量使用 |
| binlog 备份 | mysqlbinlog | 实时增量,可精确到秒级恢复 | 必备,与全量配合 |
mysqldump 常用命令
# 备份整个数据库
mysqldump -h 127.0.0.1 -u root -p \
--single-transaction \
--routines --triggers --events \
tech_blog > /backup/tech_blog_$(date +%Y%m%d).sql
# 备份单张表
mysqldump -u root -p tech_blog articles > /backup/articles.sql
# 压缩备份
mysqldump -u root -p tech_blog | gzip > /backup/tech_blog.sql.gz
⚠️ 备份三原则:定期备份 + 异地存储 + 定期演练恢复。备份文件没有测试过恢复的,等于没有备份!
♻️ 数据恢复
从 mysqldump 恢复
# 恢复整库
mysql -u root -p tech_blog < /backup/tech_blog_20260101.sql
# 恢复压缩备份
gunzip -c /backup/tech_blog.sql.gz | mysql -u root -p tech_blog
利用 binlog 恢复误操作数据
# 1. 找到误操作前的 binlog 位置
mysqlbinlog --start-datetime="2026-03-25 10:00:00" \
--stop-datetime="2026-03-25 14:30:00" \
/var/lib/mysql/mysql-bin.000123
# 2. 回放 binlog(跳过误操作语句)
mysqlbinlog --start-position=100 --stop-position=5000 \
mysql-bin.000123 | mysql -u root -p tech_blog
💡 生产环境建议开启 binlog_format=ROW + binlog_row_image=FULL,这样可以精确回放每行变化,便于数据恢复。
🚫 SQL 注入防护
SQL 注入是最常见的数据库安全威胁,正确使用参数化查询可完全防止。
危险示例 vs 安全写法
// ❌ 危险:字符串拼接,存在注入风险
String sql = "SELECT * FROM users WHERE name='" + name + "'";
// 攻击者输入 name = "' OR '1'='1" 可绕过认证
// ✅ 安全:使用预编译语句(PreparedStatement)
String sql = "SELECT * FROM users WHERE name = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, name); // 自动转义特殊字符
其他防护措施
| 措施 | 说明 |
|---|---|
| 使用 ORM 框架 | MyBatis、Hibernate 等自动参数化,减少手写 SQL 风险 |
| 输入验证 | 对用户输入进行类型、长度、格式校验 |
| 错误信息控制 | 生产环境不向用户返回数据库错误详情 |
| WAF 防护 | Web 应用防火墙检测并拦截注入攻击 |
| 最小权限 | 应用账号不赋予 DROP/ALTER 等高危权限 |
📋 安全审计
开启通用查询日志(审计)
-- 开启通用日志(记录所有 SQL,生产慎用,性能影响大)
SET GLOBAL general_log = ON;
SET GLOBAL general_log_file = '/var/log/mysql/general.log';
-- 查看当前状态
SHOW VARIABLES LIKE 'general%';
💡 生产环境推荐使用 MySQL Enterprise Audit 或开源的 MariaDB Audit Plugin,可按需过滤记录操作日志,性能影响小。