当前位置: 首页 > news >正文

Ubuntu 20.04部署MySQL 8.0:systemd管理、认证插件与安全配置全解析

1. 这不是“装个软件”那么简单:Ubuntu 20.04 上部署 MySQL 的真实场景与核心价值

你搜到这篇内容,大概率正卡在某个具体环节:可能是sudo apt install mysql-server执行完后连不上 localhost,也可能是mysql -u root -p死活提示Access denied,又或者刚配好远程访问,第二天发现服务自己挂了。别急,这不是你操作错了,而是 Ubuntu 20.04 对 MySQL 的管理逻辑和旧版(比如 16.04 或 18.04)有本质区别——它默认启用mysql_native_password插件的严格认证,同时用systemd彻底接管服务生命周期,连日志路径都挪到了/var/log/mysql/error.log而非传统的/var/log/mysqld.log。我过去三年帮二十多个团队搭过 Ubuntu 环境的数据库,90% 的“安装失败”其实根本不是安装问题,而是没意识到:在 Ubuntu 20.04 上,“安装 MySQL” = 配置 systemd 服务 + 调整认证插件 + 初始化安全策略 + 验证网络栈连通性,四步缺一不可。这篇内容专为真实生产环境打磨,不讲“下载安装包→双击下一步”的幻觉,只说你在终端里敲下的每一行命令背后发生了什么、为什么必须这么写、以及哪一行写错会导致后续三天排查无果。适合正在部署 Laravel 项目、Django 后端、WordPress 站点,或是准备 MySQL 面试题的开发者——所有操作均基于官方 APT 仓库的mysql-server包(当前稳定版为 8.0.33),不推荐手动编译或混用第三方源,因为 Ubuntu 20.04 的libssllibtinfo版本对二进制兼容性极其敏感,我试过用 MySQL 官网 tar.gz 包,在mysqld --initialize阶段直接报symbol lookup error,折腾六小时才定位到是libtinfo.so.6版本冲突。所以,我们从最稳妥的apt方式开始,每一步都附带验证命令和失败回滚方案。

2. 整体设计思路:为什么 Ubuntu 20.04 必须用这套流程?

2.1 不是“装软件”,而是“初始化一个受 systemd 管控的服务单元”

很多人以为apt install mysql-server就完事了,但实际执行后,系统做的远不止复制文件:它会自动生成/etc/mysql/mysql.conf.d/mysqld.cnf配置文件,创建mysql系统用户(UID 125),在/var/lib/mysql/下初始化数据目录,并最关键的是——注册一个名为mysql.service的 systemd 单元。这个单元文件藏在/lib/systemd/system/mysql.service,里面明确写了ExecStartPre=/usr/share/mysql/mysql-systemd-start pre,也就是说,每次systemctl start mysql前,都会先运行预启动脚本检查数据目录权限、磁盘空间和配置语法。如果你手动改过/etc/mysql/my.cnf却忘了sudo systemctl daemon-reloadsystemctl status mysql可能显示active (exited),但mysql -u root -p一定连不上,因为预启动脚本在语法校验阶段就静默退出了。我见过最典型的错误是把bind-address = 127.0.0.1改成bind-address = 0.0.0.0后没重启服务,结果netstat -tlnp | grep :3306根本看不到监听,因为mysqld进程压根没起来。所以整个流程的设计起点,就是把 MySQL 当作一个由 systemd 全权托管的系统级服务来对待,所有操作必须通过systemctl触发,所有配置变更必须触发daemon-reload

2.2 认证插件切换:MySQL 8.0 默认的caching_sha2_password是最大陷阱

Ubuntu 20.04 仓库里的 MySQL 8.0 默认使用caching_sha2_password作为 root 用户的认证插件,而绝大多数客户端工具(包括早期版本的 PHP PDO、某些 Python MySQLdb 驱动、甚至部分 MySQL Workbench 版本)根本不支持它。当你执行mysql -u root -p成功登录后,再用SELECT user, host, plugin FROM mysql.user;查看,会发现 root@localhost 的 plugin 字段是caching_sha2_password。这时候如果用 PHP 写new mysqli('localhost', 'root', 'xxx'),十有八九报错Client does not support authentication protocol requested by server。这不是密码错了,是协议不匹配。解决方案不是降级 MySQL,而是在初始化后立即切换 root 用户的认证插件为向后兼容的mysql_native_password。注意,这必须在首次登录后立刻执行,且要加FLUSH PRIVILEGES;刷新权限缓存。很多教程教你在mysqld.cnf里加default_authentication_plugin=mysql_native_password,这是无效的——该参数只影响新创建用户的默认插件,对已存在的 root 用户不起作用。真正的操作必须进入 MySQL CLI 执行 SQL 命令。我建议在apt install完成、systemctl start mysql启动服务后,立刻用sudo mysql(注意是sudo,它会绕过密码验证直连)进入,然后执行插件切换,这样能避免后续所有客户端连接问题。

2.3 安全初始化:mysql_secure_installation不是可选项,而是必经关卡

Ubuntu 20.04 的mysql-server包安装后,root 用户默认没有密码(空密码),且存在匿名用户、test 数据库、远程 root 登录等高危配置。mysql_secure_installation脚本就是为解决这些而生的,但它在 Ubuntu 20.04 上有个关键变化:它不再询问“是否设置 root 密码”,而是直接要求你输入当前 root 密码。如果你之前没用sudo mysql切换过插件,此时 root 密码为空,脚本会卡在密码输入环节。所以正确顺序必须是:apt installsystemctl startsudo mysql切换插件 →exitsudo mysql_secure_installation。这个脚本会依次处理五件事:设置 root 密码、移除匿名用户、禁止 root 远程登录、删除 test 数据库、重载权限表。其中“禁止 root 远程登录”是重点——它执行的是DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');,这意味着你后续若需远程管理,必须显式创建新用户并授权,而不是简单打开 root 的远程权限。我坚持认为这是最佳实践,因为生产环境绝不该用 root 远程登录,哪怕加了防火墙。这个设计思路的核心,是把“安装”和“加固”强制绑定,杜绝“先装上再说”的侥幸心理。

2.4 网络与防火墙:Ubuntu 20.04 的ufw默认策略是隐形杀手

很多教程忽略了一点:Ubuntu 20.04 默认启用ufw(Uncomplicated Firewall),而它的默认策略是deny incoming。即使你把mysqld.cnfbind-address改成0.0.0.0并重启了服务,telnet your-server-ip 3306依然会超时,因为请求根本没到达 MySQL 进程,被ufw拦在了系统层。验证方法很简单:sudo ufw status verbose,如果看到Status: active3306端口不在允许列表里,就必须执行sudo ufw allow 3306。更严谨的做法是限制来源 IP,比如sudo ufw allow from 192.168.1.100 to any port 3306,这样只有指定 IP 能连。我曾经帮一个电商团队排查“本地能连,线上服务器连不上”的问题,折腾两天才发现是ufw在作祟——他们用的是腾讯云轻量应用服务器,系统镜像预装了ufw且默认开启,而文档里完全没提。所以整个流程中,网络层验证必须放在服务层验证之后、应用层连接之前,即:systemctl status mysql正常 →sudo netstat -tlnp | grep :3306显示监听 →sudo ufw status确认端口放行 → 最后才用客户端测试。漏掉任何一环,都会让问题排查陷入死循环。

3. 核心细节解析与实操要点:每一步背后的原理与避坑指南

3.1 安装前的系统准备:为什么apt updateapt upgrade不可跳过?

在执行sudo apt install mysql-server前,必须先运行sudo apt update && sudo apt upgrade -y。这不是形式主义,而是 Ubuntu 20.04 的包依赖机制决定的。mysql-server包依赖mysql-client-8.0mysql-commonlibmysqlclient21等子包,而这些子包的版本号必须严格匹配。如果系统长期未更新,apt list --upgradable可能显示libmysqlclient21有新版待升级,但mysql-server的依赖关系仍指向旧版。此时直接apt install,APT 会尝试降级libmysqlclient21,导致dpkg报错dependency problems - leaving unconfigured,MySQL 服务无法启动。我遇到过最棘手的一次是某台服务器因网络问题apt update失败,管理员强行apt install mysql-server,结果安装过程卡在Setting up mysql-server-8.0 (8.0.33-0ubuntu0.20.04.2) ...三分钟不动,ps aux | grep mysql发现mysqld进程在反复 fork 后崩溃,日志里全是Can't open shared library 'libmysqlclient.so.21'。最终解决方案是先sudo apt --fix-broken install,再sudo apt full-upgrade,最后重装。所以,apt update && apt upgrade是给系统打补丁,确保所有底层库版本一致,这是 MySQL 能稳定运行的物理基础。另外,upgrade后建议重启服务器,因为内核更新(如linux-image-5.4.0-150-generic)可能影响systemd对服务的资源调度,我见过升级后mysqld内存占用突增 40% 的案例,重启后恢复正常。

3.2 配置文件路径与优先级:为什么修改/etc/mysql/my.cnf可能无效?

Ubuntu 20.04 的 MySQL 配置采用分层加载机制,顺序为:/etc/mysql/my.cnf/etc/mysql/conf.d/*.cnf/etc/mysql/mysql.conf.d/*.cnf。其中/etc/mysql/my.cnf是主入口文件,它内部通过!includedir /etc/mysql/conf.d/!includedir /etc/mysql/mysql.conf.d/指令包含子目录。关键点在于:后加载的配置会覆盖先加载的同名参数。比如你在/etc/mysql/my.cnf里写max_connections = 200,又在/etc/mysql/mysql.conf.d/mysqld.cnf里写max_connections = 150,最终生效的是 150。而mysqld.cnfapt install时自动生成的,它包含了bind-addressdatadirlog_error等核心参数,且被设计为“用户可编辑的主配置”。因此,所有自定义配置都应该写在/etc/mysql/mysql.conf.d/mysqld.cnf[mysqld]段落里,而不是去动/etc/mysql/my.cnf。我曾见有人为开远程访问,在my.cnf里加bind-address = 0.0.0.0,结果systemctl restart mysqlnetstat仍只监听 127.0.0.1,因为mysqld.cnf里同一参数值是127.0.0.1,后者覆盖了前者。验证配置是否生效的唯一可靠方法是:sudo mysqld --verbose --help | grep bind-address,它会输出 MySQL 实际读取的最终值。记住,不要相信文件存在就等于配置生效,必须用命令验证。

3.3 认证插件切换的完整命令链:为什么ALTER USER必须带FLUSH PRIVILEGES

切换 root 用户认证插件的命令是:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_strong_password'; FLUSH PRIVILEGES;

这里有两个易错点。第一,IDENTIFIED WITH后面必须是插件全名mysql_native_password,不能简写为native_passwordmysql_native,否则报错Unknown authentication plugin。第二,FLUSH PRIVILEGES绝对不能省略。原因在于:MySQL 的权限系统将用户信息缓存在内存中,ALTER USER只修改了mysql.user表的磁盘数据,但内存缓存未刷新,导致后续连接仍按旧插件验证。我做过实验:执行ALTER USER后不FLUSH,用mysql -u root -p连接,输入新密码仍提示Access denied;执行FLUSH后立刻就能连上。更隐蔽的问题是,如果FLUSH后你又执行了其他CREATE USERGRANT操作,缓存会再次被污染,所以**FLUSH PRIVILEGES应该作为所有用户权限变更后的固定收尾动作**。另外,密码强度必须符合 MySQL 8.0 的默认策略(至少 8 位,含大小写字母、数字、特殊字符),否则ALTER USER会报错Your password does not satisfy the current policy requirements。临时关闭策略的命令是SET GLOBAL validate_password.policy=LOW;,但仅限测试环境,生产环境必须用强密码。

3.4mysql_secure_installation的交互式问答详解:每个选项的实际影响

运行sudo mysql_secure_installation后,它会逐项提问,以下是每项的真实含义和我的选择建议:

  1. Press y|Y for Yes, any other key for No:(是否设置密码验证组件)
    默认是Yes,它会安装validate_password插件,强制密码复杂度。我选Yes,因为弱密码是最大安全漏洞。插件会根据validate_password.length(默认 8)、validate_password.mixed_case_count(默认 1)等参数校验。

  2. New password:Re-enter new password:
    输入你要设的 root 密码。注意:这是mysql_secure_installation自己生成的密码,与前面ALTER USER设置的密码无关。它会覆盖ALTER USER的密码!所以必须先执行ALTER USER切换插件,再运行mysql_secure_installation设置密码,否则插件又变回caching_sha2_password

  3. Remove anonymous users? (Press y|Y for Yes, any other key for No)
    Y。匿名用户(''@'localhost')允许无用户名连接,是严重风险。该操作执行DELETE FROM mysql.user WHERE User='';

  4. Disallow root login remotely? (Press y|Y for Yes, any other key for No)
    Y。它会删除root用户在非本地主机的记录,只保留root@localhostroot@127.0.0.1root@::1。这是最小权限原则。

  5. Remove test database and access to it? (Press y|Y for Yes, any other key for No)
    Ytest数据库默认允许所有用户读写,是 SQL 注入的温床。

  6. Reload privilege tables now? (Press y|Y for Yes, any other key for No)
    Y。这相当于执行FLUSH PRIVILEGES;,使上述所有更改立即生效。

提示:如果某步选错,不用重装 MySQL。比如误删了root@localhost,可以用sudo mysql直连(sudo绕过认证),然后执行CREATE USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;恢复。

4. 实操过程与核心环节实现:从零到可远程连接的完整步骤

4.1 第一阶段:系统更新与 MySQL 安装(耗时约 3 分钟)

打开终端,按顺序执行以下命令。每条命令后我都标注了预期输出和失败应对方案:

# 1. 更新软件包索引(必须,否则 apt install 可能失败) sudo apt update # 预期输出:Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease ... Reading package lists... Done # 若报错 "Could not resolve 'archive.ubuntu.com'",说明 DNS 问题,执行:echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf # 2. 升级已安装包(必须,解决依赖冲突) sudo apt upgrade -y # 预期输出:0 upgraded, 0 newly installed, 0 to remove ... Processing triggers for man-db (2.9.1-1) ... # 若卡在 "Configuring linux-image-5.4.0-150-generic",按 Ctrl+C 中断,再执行:sudo dpkg --configure -a && sudo apt -f install # 3. 安装 MySQL 服务端(核心命令) sudo apt install mysql-server -y # 预期输出:Setting up mysql-server-8.0 (8.0.33-0ubuntu0.20.04.2) ... Processing triggers for systemd (245.4-4ubuntu3.21) ... # 若报错 "Errors were encountered while processing: mysql-server-8.0",立即执行:sudo apt --fix-broken install -y # 4. 验证服务状态(确认安装成功) sudo systemctl status mysql # 预期输出:Active: active (running) since ...; Main PID: XXXX; CGroup: /system.slice/mysql.service # 若显示 "inactive (dead)",执行:sudo systemctl start mysql && sudo systemctl enable mysql

注意:apt install过程中不会提示设置密码,root 用户密码为空。这是设计使然,后续由mysql_secure_installation统一处理。

4.2 第二阶段:认证插件切换与初始密码设置(耗时约 1 分钟)

此阶段目标是让 root 用户能被所有客户端工具识别。必须用sudo mysql直连,因为它利用 Unix socket 认证,不经过密码验证:

# 1. 以 root 权限直连 MySQL(关键!绕过密码验证) sudo mysql # 预期输出:Welcome to the MySQL monitor... mysql> # 2. 在 MySQL CLI 中执行插件切换(替换 your_strong_password 为实际密码) mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MyP@ssw0rd123!'; mysql> FLUSH PRIVILEGES; mysql> exit # 预期输出:Bye # 3. 验证插件是否生效 sudo mysql -u root -p # 输入上面设置的密码,应成功进入 MySQL CLI mysql> SELECT user, host, plugin FROM mysql.user WHERE user='root'; # 预期输出:root | localhost | mysql_native_password

实操心得:密码必须包含大小写字母、数字、特殊字符,长度≥8。如果ALTER USER报错Your password does not satisfy the current policy requirements,先执行SET GLOBAL validate_password.policy=LOW;降低策略,设置密码后再恢复:SET GLOBAL validate_password.policy=MEDIUM;

4.3 第三阶段:安全加固与网络配置(耗时约 2 分钟)

现在 root 用户已可用,但还处于“裸奔”状态,必须加固:

# 1. 运行安全脚本(按前述建议回答所有问题) sudo mysql_secure_installation # 2. 配置 MySQL 监听地址(允许远程连接) sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf # 找到 bind-address = 127.0.0.1 这一行,改为: bind-address = 0.0.0.0 # 保存退出(Ctrl+O, Enter, Ctrl+X) # 3. 重载 MySQL 配置(必须!否则修改不生效) sudo systemctl restart mysql # 4. 验证 MySQL 是否监听所有地址 sudo netstat -tlnp | grep :3306 # 预期输出:tcp6 0 0 *:3306 *:* LISTEN XXXX/mysqld # 若仍显示 127.0.0.1:3306,说明配置文件没改对或没重启服务 # 5. 配置 Ubuntu 防火墙(放行 3306 端口) sudo ufw status verbose # 若 Status: inactive,先启用:sudo ufw enable # 若 Status: active,检查 3306 是否在 Allow 列表 sudo ufw allow 3306 # 预期输出:Rule added

注意:bind-address = 0.0.0.0是允许所有 IP 连接,生产环境应改为具体 IP,如bind-address = 192.168.1.100,并配合ufw限制来源。

4.4 第四阶段:创建应用专用用户与权限分配(耗时约 1 分钟)

永远不要用 root 用户连接应用!创建专用用户是基本安全规范:

# 1. 用 root 登录 MySQL sudo mysql -u root -p # 2. 创建新用户(替换 your_app_user 和 your_app_password) mysql> CREATE USER 'webapp'@'%' IDENTIFIED WITH mysql_native_password BY 'WebAppP@ss2024!'; # % 表示允许从任意主机连接,如只允许本地,用 'webapp'@'localhost' # 3. 授权(授予 webapp 数据库的所有权限) mysql> CREATE DATABASE webapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql> GRANT ALL PRIVILEGES ON webapp_db.* TO 'webapp'@'%'; mysql> FLUSH PRIVILEGES; mysql> exit # 4. 从远程机器测试连接(在另一台电脑执行) mysql -h your_server_ip -u webapp -p webapp_db # 输入密码,应成功进入,且只能看到 webapp_db 数据库

实操心得:CHARACTER SET utf8mb4是必须的,它支持 emoji 和四字节 Unicode 字符,而旧的utf8在 MySQL 中实际是utf8mb3,不支持 emoji。COLLATE utf8mb4_unicode_ci提供更好的中文排序支持。

5. 常见问题与排查技巧实录:真实踩坑经验总结

5.1 问题速查表:高频故障现象与一键修复命令

故障现象根本原因诊断命令修复命令
sudo systemctl status mysql显示active (exited)mysqld.cnf配置语法错误,预启动脚本失败sudo /usr/share/mysql/mysql-systemd-start presudo nano /etc/mysql/mysql.conf.d/mysqld.cnf检查括号、分号、路径是否正确
mysql -u root -p报错Access denied for user 'root'@'localhost'root 用户插件仍是caching_sha2_passwordsudo mysql -e "SELECT user,host,plugin FROM mysql.user WHERE user='root';"sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_pass'; FLUSH PRIVILEGES;"
telnet your_ip 3306连接超时ufw防火墙未放行 3306 端口sudo ufw statussudo ufw allow 3306
sudo netstat -tlnp | grep :3306无输出bind-address未设为0.0.0.0或服务未重启sudo cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep bind-addresssudo sed -i 's/bind-address = 127.0.0.1/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf && sudo systemctl restart mysql
远程连接成功但查询中文乱码数据库/表字符集不是utf8mb4mysql -u webapp -p -e "SHOW VARIABLES LIKE 'character_set%';"mysql -u webapp -p -e "ALTER DATABASE webapp_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;"

5.2 “MySQL 启动失败”的深度排查:从日志到内核参数

systemctl start mysql失败,第一步永远是看错误日志:

sudo tail -n 50 /var/log/mysql/error.log

最常见的日志错误及对策:

  • InnoDB: The Auto-extending innodb_system data file './ibdata1' is of a different size
    这是数据文件损坏。不要慌,先备份/var/lib/mysql/目录:sudo cp -r /var/lib/mysql /var/lib/mysql_backup,然后执行sudo mysqld --initialize --user=mysql重新初始化,再sudo systemctl start mysql

  • Can't start server: Bind on TCP/IP port: Address already in use
    3306 端口被占用。查占用进程:sudo lsof -i :3306,杀掉它:sudo kill -9 <PID>,或改 MySQL 端口:在mysqld.cnfport = 3307

  • Operating system error number 13 in a file operation
    文件权限问题。MySQL 数据目录必须属mysql:mysql用户:sudo chown -R mysql:mysql /var/lib/mysql

  • Out of memoryKilled process mysqld
    服务器内存不足。Ubuntu 20.04 的oom_killer会干掉mysqld。解决方案:调低innodb_buffer_pool_size(在mysqld.cnfinnodb_buffer_pool_size = 128M),或增加 swap:sudo fallocate -l 2G /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile

5.3 “远程连接被拒绝”的三层验证法

很多教程只教改bind-address,但远程连接失败往往是多层拦截。我用三层验证法快速定位:

  1. 网络层验证:在服务器上执行curl -v telnet://localhost:3306,若返回Connected to localhost,说明 MySQL 服务本身正常监听。
  2. 系统层验证:在客户端执行nc -zv your_server_ip 3306,若返回succeeded!,说明网络和防火墙通畅;若超时,检查ufw或云服务器安全组。
  3. MySQL 层验证:在服务器上执行sudo mysql -e "SELECT user,host FROM mysql.user;",确认你的用户host字段是%或具体 IP,而非localhostlocalhost只允许 Unix socket 连接,不走 TCP)。

我踩过的最大坑:某次在阿里云 ECS 上,nc测试通了,但应用还是连不上。最后发现是阿里云的安全组规则里,入方向只放行了0.0.0.0/0TCP:3306,但出方向规则是拒绝所有,导致 MySQL 的响应包被拦截。解决方案:安全组出方向规则设为0.0.0.0/0全放行。

5.4 性能与稳定性优化:Ubuntu 20.04 下的三个关键参数

安装完成后,建议立即调整以下参数提升稳定性(编辑/etc/mysql/mysql.conf.d/mysqld.cnf):

  • max_connections = 200:Ubuntu 20.04 默认是 151,对于并发稍高的 Web 应用(如 WordPress 多用户)不够。计算公式:max_connections ≈ (RAM_in_GB * 1024) / 4,例如 4GB 内存设为 1000,但需留 20% 给系统。
  • innodb_buffer_pool_size = 512M:InnoDB 缓存池,应设为物理内存的 50%-75%。4GB 服务器设 2GB,但 Ubuntu 20.04 的systemd会限制服务内存,所以保守设 512M 更稳。
  • wait_timeout = 28800:空闲连接超时时间,默认 28800 秒(8 小时)。PHP 的mysqli连接池常因超时断开,设为28800可减少MySQL server has gone away错误。

修改后必须执行sudo systemctl restart mysql,并用sudo mysql -e "SHOW VARIABLES LIKE 'max_connections';"验证。

6. 后续维护与扩展:让 MySQL 在 Ubuntu 20.04 上长期稳定运行

装完不是终点,日常维护才是关键。我给自己服务器定的维护清单:

  • 每周自动备份:用mysqldump+cron。脚本示例:

    #!/bin/bash DATE=$(date +%Y%m%d) mysqldump -u webapp -p'WebAppP@ss2024!' webapp_db | gzip > /backup/webapp_db_$DATE.sql.gz find /backup -name "webapp_db_*.sql.gz" -mtime +7 -delete

    加入 crontab:0 2 * * 0 /path/to/backup.sh(每周日凌晨 2 点执行)。

  • 日志轮转:Ubuntu 20.04 的logrotate默认不管理 MySQL 错误日志,需手动配置:

    sudo nano /etc/logrotate.d/mysql-server # 添加内容: /var/log/mysql/error.log { daily rotate 30 missingok compress delaycompress notifempty create 640 mysql adm sharedscripts postrotate if [ -f "/var/run/mysqld/mysqld.pid" ]; then kill -USR1 `cat /var/run/mysqld/mysqld.pid` fi endscript }
  • 监控连接数:防止连接泄漏。写个简单检查脚本:

    #!/bin/bash CONN=$(mysql -u root -p'MyP@ssw0rd123!' -e "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null | awk 'NR==2 {print $2}') if [ "$CONN" -gt "180" ]; then echo "ALERT: MySQL connections ($CONN) > 180!" | mail -s "MySQL Alert" admin@example.com fi

最后分享一个小技巧:Ubuntu 20.04 的mysql命令行客户端默认不显示列名,看着费劲。永久解决方法是创建~/.my.cnf

[mysql] auto-rehash column-names

这样每次mysql -u root -p进入,查询结果都会带表头,再也不用猜第一列是啥了。这个细节虽小,但每天用几十次,累积下来能省下不少时间。

http://www.jsqmd.com/news/1068553/

相关文章:

  • llama.cpp本地大模型部署指南:从原理到实战优化
  • Lightdash:基于dbt的BI-as-Code平台,用AI与代码重构数据分析工作流
  • TRAE SOLO模式:终端原生的轻量级AI编码协作范式
  • Python列表添加操作本质:append、extend、insert的结构控制逻辑
  • Spring AOP实现数据库字段透明加解密:MyBatis/JPA敏感数据安全存储方案
  • MC68341串行与定时器模块编程实战:从寄存器配置到驱动开发
  • CentOS 7 源码编译 ngx_pagespeed 实战指南
  • 大模型研发为何没有‘灵魂缔造者’?解析GPT-4o背后的系统工程本质
  • Katoolin:在Ubuntu/Debian上一键安装Kali Linux渗透测试工具
  • 从RSA大会Semgrep Multimodal到PyTorch Lightning供应链攻击:AI时代代码安全新挑战
  • Windows本地AI交互新范式:ChatGPT 5.3桌面版深度解析
  • 嵌入式系统启动全解析:Flash编程与监控程序初始化实战
  • DeepResearch:基于LangGraph的可审计科研智能体工作流
  • React Keys不是语法糖:它是Fiber协调与状态稳定的底层契约
  • GPT-5.5不存在?解析OpenAI模型命名规范与API错误根源
  • Ansible在Ubuntu 14.04上部署PHP应用的实战指南
  • Ollama+GLM-4.7+Claude Code本地开发闭环真相
  • AES-GCM与AES-SIV加密模式实战:原理、选型与Python代码实现
  • Ansible 声明式配置管理:从 YAML 语法到生产级状态收敛
  • Go指针原理与nil安全实践:从内存模型到GC优化
  • OpenClaw:面向知识工作者的可进化AI工作流引擎
  • Ubuntu 18.04 + GitLab 13.12.15 稳定部署实战指南
  • Python自动化新选择:Playwright从入门到工程化实践指南
  • Airtable + Gatsby 构建时数据集成与 GraphQL 安全实践
  • Bottle+CentOS 7生产部署:轻量Web服务的可控落地实践
  • vLLM推理降本核心:GPU基础设施与运行时契约深度解析
  • MC9S08SF4 FDS模块实战:硬件级故障保护与嵌入式系统安全设计
  • DigitalOcean账户安全实战:TOTP、API密钥与SSH密钥全生命周期管控
  • 技术团队规模化不是堆人堆机器:识别临界失稳点的五大数据信号
  • AI道德对齐:机器决策中的价值观匹配与挑战