本文要点
- Ubuntu 24.04 官方源里
apt install mysql-server一条命令装好 MySQL 8,systemd 以mysql.service管理,装完即自动启动 - Ubuntu 打包版 root 默认走
auth_socket插件:系统 root 用户在命令行直接mysql就能进,不需要密码;默认只监听127.0.0.1,不对外网开放 - 建库建表一套
mysql -e就能跑:CREATE DATABASE+CREATE TABLE+SHOW TABLES,MySQL 8 默认字符集就是utf8mb4,中文直接存 - 权限最小化:
CREATE USER+GRANT SELECT,INSERT,UPDATE,DELETE ON 库.*只给业务所需权限,用SHOW GRANTS随时核对 - 备份恢复实测一条链走通:
mysqldump --databases导出 → 删库模拟灾难 →mysql < 备份文件还原 → COUNT 校验数据行数。⚠️--databases必须带:它让备份文件自带建库语句,否则恢复会报ERROR 1046 No database selected(首轮实测就栽在这) - 演示产生的库、用户、备份文件在文章写完前已全部清理,不污染服务器
- 全部命令在 Ubuntu 24.04.4(MySQL 8.0.46)上真实执行,截图即真实输出
MySQL 8 数据库运维:从安装启动到用户授权与备份恢复
网站、监控、日志系统……后台几乎都挂着一个数据库。Linux 服务器上最常见的选择就是 MySQL——开源、成熟、生态庞大,Ubuntu 官方源里就有现成的 MySQL 8。这一篇从零走一遍数据库日常运维的主线:安装启动 → 建库建表 → 写入查询 → 用户授权 → 备份恢复,全部命令在一台 Ubuntu 24.04.4 服务器上真实执行,装的是源内的 MySQL 8.0.46。文中演示用的库、用户和备份文件,在演示结束后已全部清理。
安装与启动
Ubuntu 的 mysql-server 包把 MySQL 8 的安装简化到了极致:软件源里就有,依赖自动处理,装完服务自动启动。以下命令需要 root 权限(本文演示环境直接以 root 操作,普通用户请自行加 sudo):
apt install -y mysql-server安装完成后 MySQL 由 systemd 管理,服务名是 mysql。把它设为开机自启并立即启动:
systemctl enable --now mysql
mysqladmin pingmysqladmin ping 会向服务器发一个轻量探测,返回 mysqld is alive 就说明服务在正常工作;systemctl is-active mysql 也会输出 active。
确认版本和数据目录默认监听:
mysql --versionmysql Ver 8.0.46-0ubuntu0.24.04.4 for Linux on x86_64 ((Ubuntu))两个 Ubuntu 打包版特有的安全默认值,值得先知道:
- root 免密但只在本地:root 账号默认用
auth_socket插件认证——只要你是系统 root 用户,从本机命令行直接敲mysql就能以数据库 root 身份进入,不需要密码;但同时它也拒绝了所有密码登录和远程登录。日常管理很方便,生产环境建议另外创建专用管理账号并禁用 socket 之外的 root 访问。 - 默认只监听本机:实测配置文件里
bind-address = 127.0.0.1、mysqlx-bind-address = 127.0.0.1——MySQL 服务端只对 127.0.0.1 开放 3306 端口。要让外部访问,需要改监听地址为0.0.0.0(同时务必配好防火墙/云安全组),MySQL 默认绝不暴露公网。
建库建表:第一个业务库
安装完成先建库。mysql -e "SQL 语句" 可以在命令行直接执行 SQL 而不进入交互界面,适合脚本和教程演示。下面一条命令完成"建库 → 进入库 → 建表 → 确认":
mysql -e "CREATE DATABASE IF NOT EXISTS blog_demo; USE blog_demo; CREATE TABLE IF NOT EXISTS articles (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(100), views INT); SHOW TABLES;"
输出里的 Tables_in_blog_demo 是 SHOW TABLES 的结果列名,下面列出了刚建好的 articles 表。拆开看这几条语句各做了什么:
| 语句 | 作用 |
|---|---|
CREATE DATABASE IF NOT EXISTS blog_demo | 建库,IF NOT EXISTS 让重复执行不报错 |
USE blog_demo | 把后续操作切到该库(同一批语句里直接用) |
CREATE TABLE articles (...) | 建表:id 自增主键、title 变长字符串、views 整数 |
SHOW TABLES | 列出当前库的所有表,验证建表成功 |
MySQL 8 的两个默认值省了不少事:默认存储引擎是 InnoDB(支持事务与行级锁),默认字符集是 utf8mb4(完整 Unicode,存中文、emoji 都没问题),所以建表语句里不需要再写 ENGINE=InnoDB 和 DEFAULT CHARSET。
写入数据与查询
表建好了,写入三条演示数据再查出来:
mysql -e "USE blog_demo; INSERT INTO articles (title, views) VALUES ('MySQL 入门', 120), ('索引优化', 340), ('备份实践', 560); SELECT id, title, views FROM articles;"
INSERT ... VALUES 用括号括起一行数据、逗号分隔多行,一次插入三条;随后的 SELECT 把整张表读了出来。中文标题写入和显示都正常——这正是 utf8mb4 的功劳,老项目常见的中文乱码问题多数出在库/表还是 latin1 字符集。
日常查询当然不限于全表 SELECT:加条件用 WHERE(如 SELECT * FROM articles WHERE views > 200),改数据用 UPDATE ... SET ... WHERE,删数据用 DELETE FROM ... WHERE。所有写操作前养成先 SELECT 看一眼条件的习惯,能避免误伤整张表——尤其 DELETE 不带 WHERE 会清空全表。
用户与权限:最小授权原则
运维铁律:业务代码不要用 root 连数据库。root 权限过大,一旦代码被注入,攻击者等于拿到了整台数据库服务器。正确的做法是给每个应用建专属账号,只授它需要的权限。
MySQL 8 的账号创建和授权是分开的两步——CREATE USER 先建账号(含密码),GRANT 再给权限:
mysql -e "CREATE USER IF NOT EXISTS 'bloguser'@'localhost' IDENTIFIED BY 'BlogPass-2026'; GRANT SELECT,INSERT,UPDATE,DELETE ON blog_demo.* TO 'bloguser'@'localhost'; SHOW GRANTS FOR 'bloguser'@'localhost';"Grants for bloguser@localhost
GRANT USAGE ON *.* TO `bloguser`@`localhost`
GRANT SELECT, INSERT, UPDATE, DELETE ON `blog_demo`.* TO `bloguser`@`localhost`SHOW GRANTS 是核对权限的官方途径,输出里两行都值得读懂:
GRANT USAGE ON *.*——USAGE 表示"只有连接权限",是每个新建账号的默认行,没有实际能力,不用慌;- 第二行才是真授权:只对
blog_demo这一个库、只给增删改查四种语句权限。
'bloguser'@'localhost' 的 localhost 部分限定"从哪来",这里只允许本机连接。业务与数据库同机部署时这是最安全的形态;若真要跨机访问,需要改成 'bloguser'@'%' 或具体 IP 段,并同步放开服务端 bind-address——两处缺一不可,这也是 MySQL 默认不对外监听的原因。
验证一下新账号真的能登录干活:
MYSQL_PWD=BlogPass-2026 mysql -ubloguser -e 'SELECT CURRENT_USER() AS login_as;'login_as
bloguser@localhostCURRENT_USER() 返回 bloguser@localhost,说明账号、密码、授权全部生效。这里用环境变量 MYSQL_PWD 传密码而不是 -p 明文跟参,能少一条泄露路径——但环境变量对同机其他用户仍可见,生产环境更推荐把账号密码写进 ~/.my.cnf(权限 600)或使用 MySQL 8 的 caching_sha2 凭据。权限要调整时,回收用 REVOKE SELECT ON blog_demo.* FROM 'bloguser'@'localhost';,删账号用 DROP USER。
备份与恢复:删库后能否跑路
备份有没有用,要看恢复能不能走通。下面这条命令串起完整演练:先 mysqldump 导出整个库,然后直接 DROP DATABASE 模拟一次灾难,再拿备份文件还原,最后用 COUNT 校验数据是否完整:
mysqldump --databases blog_demo > blog_demo.sql && mysql -e "DROP DATABASE blog_demo" && mysql < blog_demo.sql && mysql -e "SELECT COUNT(*) AS restored_rows FROM blog_demo.articles"
最终输出 restored_rows = 3,与删库前的三行数据完全一致,恢复成功。拆开解读每一步:
mysqldump --databases blog_demo > blog_demo.sql——把整个库导出成 SQL 文本文件。--databases是恢复成败的关键:加上它,备份文件开头会自带CREATE DATABASE和USE blog_demo语句,还原时库会被自动重建。不带的话备份文件里只有表语句,恢复前必须手动先建库——否则mysql < 备份文件会直接报ERROR 1046 (3D000): No database selected(这个错我在初版演练里真实踩过,加--databases即解);mysql -e "DROP DATABASE blog_demo"——模拟数据被误删/被攻击清库的灾难现场;mysql < blog_demo.sql——把备份文件的 SQL 逐条重放,建库、建表、导数据一步完成;mysql -e "SELECT COUNT(*) ..."——恢复后数行数,与灾前对比,确认一条不少。
生产环境的备份建议在此基础上加三件事:加 --single-transaction 让导出基于 InnoDB 一致性快照(备份过程中业务继续写入也不影响备份数据一致性);压缩存储(| gzip > blog_demo-$(date +%F).sql.gz 这种命名天然带日期);定时执行——配合 Linux crontab 定时任务 每天凌晨跑一次,再定期(建议每月)实际演练一次恢复,确保备份真的可用。
演示环境的清理
教程演示难免在服务器上留下痕迹,收尾把它们清干净——这也是日常运维习惯的体现:
mysql -e "DROP DATABASE IF EXISTS blog_demo; DROP USER IF EXISTS 'bloguser'@'localhost';"
rm -f blog_demo.sql删库、删用户、删备份文件一次到位。至此本文安装的 MySQL 服务本身保留(mysql-server 是干净的系统组件),但所有演示数据都已不复存在。
总结
把这一篇的主线浓缩成速查表:
| 场景 | 命令 |
|---|---|
| 安装 | apt install -y mysql-server |
| 启动/自启 | systemctl enable --now mysql |
| 连通性探测 | mysqladmin ping |
| 建库建表 | mysql -e "CREATE DATABASE ...; CREATE TABLE ...;" |
| 授权 | CREATE USER ...; GRANT 权限 ON 库.* TO '用户'@'主机'; |
| 核对权限 | SHOW GRANTS FOR '用户'@'主机'; |
| 备份 | mysqldump --databases 库名 > 备份.sql |
| 恢复 | mysql < 备份.sql(备份需带 --databases) |
| 清理演示对象 | DROP DATABASE / DROP USER |
数据库运维没有银弹,但有几条贯穿始终的原则:root 只留本地、应用账号最小授权、默认不对外监听、备份必须定期演练恢复。把这四条做到,绝大多数"删库跑路"事故都能在几分钟内善后。
进一步阅读:MySQL 8.0 参考手册、mysqldump 官方文档;定时备份可参考本站 Linux crontab 定时任务,服务器日常巡检可配合 Linux 系统实时监控。
评论 (0)
暂无评论,快来抢沙发吧!