Ubuntu 14.04 MySQL 5.5 安装配置实战指南
1. 项目概述:为什么在 Ubuntu 14.04 上装 MySQL 还值得认真对待?
你点开这个标题,大概率不是为了怀旧——没人会主动选一个 2014 年发布的、2019 年就结束标准支持的 Ubuntu 版本去搭新服务。但现实很具体:手头那台跑着老旧 ERP 系统的物理服务器,它 BIOS 锁死在 UEFI Legacy 模式,换系统要重写驱动;实验室里那套工业数据采集终端,固件只认 Ubuntu 14.04 的内核 ABI;甚至有些嵌入式网关设备,出厂预装的就是这个版本,连 apt update 都得手动配镜像源。MySQL 在这类场景里不是“数据库选项”,而是整个业务逻辑的底层血管。一旦装不上、启不动、连不了,下游所有报表、告警、导出功能全卡死。我去年帮一家做智能电表的客户排查故障,问题根源就是运维同事照着网上最新教程,在 Ubuntu 14.04 上硬装 MySQL 8.0,结果 mysqld 进程启动后立刻 segfault——因为 8.0 强依赖 glibc 2.17+,而 14.04 自带的是 2.19,表面能装,实际运行时动态链接器一加载就崩。所以这不是一个“过时技术”的怀旧操作,而是一场精准的版本对齐工程:你要的不是“装上 MySQL”,而是“让 MySQL 在这个特定发行版的 libc、openssl、systemd(哦对,14.04 用的是 upstart)生态里,稳稳当当地呼吸、响应、存取”。关键词里反复出现的 “mysql安装教程”“mysql下载安装教程”“mysql安装配置教程”,背后全是真实存在的断点:apt 源失效、依赖包冲突、默认密码策略不兼容、SELinux 不存在但 AppArmor 规则没关……这些都不是文档里一句“sudo apt-get install mysql-server”能覆盖的。这篇文章写给三类人:第一类是还在维护老系统的运维工程师,你需要知道哪些坑必须绕、哪些配置必须改;第二类是备考数据库方向面试的学生,Ubuntu 14.04 + MySQL 5.5/5.6 是很多传统企业笔试题的默认环境;第三类是想搞懂“Linux 发行版与软件生命周期如何咬合”的技术爱好者——你看,一个 apt-get install 命令背后,其实是内核版本、C 运行时、初始化系统、包管理器四层栈的精密协同。现在我们开始拆解。
2. 整体设计思路与方案选型:为什么必须放弃“一键安装”幻觉?
2.1 核心矛盾:Ubuntu 14.04 的软件栈底座 vs MySQL 的演进节奏
Ubuntu 14.04(代号 Trusty Tahr)发布于 2014 年 4 月,其核心组件版本如下:内核 3.13.x,glibc 2.19,OpenSSL 1.0.1f,upstart 1.12,apt 1.0.1。而 MySQL 官方从 5.7 版本起,明确要求 OpenSSL 1.0.1g+(修复 Heartbleed 漏洞),并逐步强化对 systemd 的集成。更关键的是,MySQL 5.7 默认启用 validate_password 插件,强制密码复杂度,而 Ubuntu 14.04 的 mysql-server 包(来自官方仓库)版本是 5.5.62,它压根不识别这个插件——如果你强行从官网下载 5.7 的 .deb 包安装, dpkg -i 会报 dependency problems ,因为它的 libmysqlclient18 依赖和系统自带的 libmysqlclient18 冲突。我试过直接 dpkg -i --force-depends 强装,结果 mysqld 启动时报 symbol lookup error: /usr/sbin/mysqld: undefined symbol: SSL_CTX_set_alpn_select_cb ,原因就是 OpenSSL 版本太低,缺少 ALPN 协议支持函数。所以方案选型的第一条铁律是: 必须使用 Ubuntu 14.04 官方仓库提供的 MySQL 5.5 分支 。这是唯一经过完整 ABI 兼容性测试的组合。有人会问:“那编译源码呢?”可以,但代价巨大:你需要先升级 cmake 到 2.8.12+(14.04 自带 2.8.11),再手动编译 OpenSSL 1.0.2u(注意不能用 1.1.x,因为 MySQL 5.5 不支持),最后编译 MySQL 时指定 -DWITH_SSL=/path/to/openssl 。我实测过,整个过程耗时 47 分钟,且编译出的二进制文件在 /etc/init.d/mysql 脚本里无法被 upstart 正确识别状态。所以,放弃源码编译,拥抱官方包管理,是这里最务实的选择。
2.2 方案路径对比:APT 安装 vs 手动 DEB 安装 vs Docker 隔离
| 方案 | 操作步骤 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|---|
| APT 安装(推荐) | sudo apt-get update && sudo apt-get install mysql-server |
依赖自动解决,配置文件模板标准化,upstart 集成完善,安全更新通道畅通 | 版本锁定为 5.5.62,无法启用新特性如 JSON 字段、窗口函数 | 95% 的生产维护场景,追求稳定性和可维护性 |
| 手动 DEB 安装 | 下载 mysql-server-5.5_5.5.62-0ubuntu0.14.04.1_amd64.deb , dpkg -i ,手动处理依赖 |
可精确控制安装路径,便于多实例部署 | dpkg -i 后需手动运行 mysql_install_db , /etc/mysql/my.cnf 需重写,upstart job 文件需手动注册 |
需要自定义 datadir 或 port 的特殊部署,如开发测试机 |
| Docker 隔离 | docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123 mysql:5.5 |
彻底规避系统依赖冲突,版本自由切换,环境可复现 | 容器内进程由 docker daemon 管理,与宿主 upstart 无关,日志需额外收集,性能有微小损耗 | 快速验证 SQL 逻辑,或作为 CI/CD 流水线中的临时数据库 |
提示:不要尝试
pip install mysql或npm install mysql——这两个命令安装的是 Python/Node.js 的 MySQL 客户端驱动(即mysql-connector-python或mysql2库),它们不提供mysqld服务进程,也无法创建数据库实例。网络热词里频繁出现的pip install和npm install,恰恰反映了新手常犯的混淆:把“连接数据库的工具”和“数据库服务本身”当成一回事。
2.3 关键决策点:为什么必须关闭 AppArmor?为什么不能跳过 mysql_secure_installation ?
Ubuntu 14.04 默认启用 AppArmor,这是一个 Linux 内核安全模块,通过配置文件限制程序行为。MySQL 的 AppArmor 配置文件 /etc/apparmor.d/usr.sbin.mysqld 在 14.04 中存在一个已知缺陷:它硬编码了 /var/lib/mysql/ 的访问权限,但如果你在安装后修改了 my.cnf 中的 datadir (比如指向 /data/mysql ),AppArmor 会阻止 mysqld 访问新路径,导致启动失败,日志里只显示 Starting MySQL database server: mysqld failed! ,没有任何具体错误。我踩过的坑是:先按教程改了 datadir ,再执行 mysql_secure_installation ,结果脚本卡在“Set root password”环节,因为 mysqld 根本没起来。解决方案是:安装完成后,立即执行 sudo aa-disable /usr/sbin/mysqld 临时禁用,或编辑 /etc/apparmor.d/usr.sbin.mysqld ,在 #include <abstractions/mysql> 下添加 /data/mysql/** rwk, (假设你的新 datadir 是 /data/mysql ),然后 sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld 重载。另一个关键点是 mysql_secure_installation 。很多教程说“可以跳过”,但这是危险操作。该脚本实际执行四件事:1)设置 root 密码(否则默认空密码,极不安全);2)删除匿名用户( ' ' @'localhost' );3)禁止 root 远程登录(只保留 'root'@'localhost' );4)删除 test 数据库及对它的访问权限。跳过它等于把一个裸奔的数据库暴露在公网——我见过太多案例,黑客用 nmap -p 3306 ip 扫到开放端口,再用 mysql -h ip -u root 直接登录,删库跑路。所以, mysql_secure_installation 不是可选项,是上线前的强制安检步骤 。
3. 核心细节解析与实操要点:从 apt 更新到 root 密码设置的每一步真相
3.1 apt 源配置:为什么 sudo apt-get update 会失败?如何修复?
Ubuntu 14.04 的官方源 archive.ubuntu.com 在 2022 年已停止服务,现在访问会返回 404。直接运行 sudo apt-get update 会看到大量 Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/... 错误。解决方案是切换到 old-releases.ubuntu.com 镜像源。操作步骤如下:
# 备份原 sources.list
sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
# 使用 sed 命令批量替换(注意:trusty 是 14.04 的代号)
sudo sed -i 's/archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
# 验证替换结果(应看到所有 archive.ubuntu.com 和 security.ubuntu.com 都变成了 old-releases.ubuntu.com)
cat /etc/apt/sources.list | grep "old-releases"
注意:不要手动编辑
sources.list文件并逐行修改,因为其中包含trusty-updates、trusty-security等多个子源,漏掉任何一个都会导致apt-get update失败。sed -i命令确保全局替换。替换后,sudo apt-get update应该能成功获取mysql-server的包信息。如果仍失败,检查网络是否能 ping 通old-releases.ubuntu.com,或临时关闭防火墙:sudo ufw disable。
3.2 安装过程详解: mysql-server 包到底包含了什么?
执行 sudo apt-get install mysql-server 时,APT 实际安装了以下核心组件:
mysql-server-5.5:MySQL 5.5 服务端主程序,包含mysqld守护进程、mysql_install_db初始化脚本。mysql-client-5.5:客户端命令行工具,提供mysql、mysqladmin、mysqldump等命令。libmysqlclient18:MySQL C 客户端库,供 PHP、Python 等语言扩展调用。mysql-common:通用配置文件和启动脚本,包括/etc/mysql/my.cnf主配置、/etc/init.d/mysqlupstart 脚本。
安装过程中,系统会自动执行 mysql_install_db ,该脚本的作用是:1)创建 /var/lib/mysql/ 目录结构;2)生成 mysql 系统数据库(含 user 、 db 、 tables_priv 等权限表);3)初始化 root 用户记录。你可以在安装日志中看到类似 Installing MySQL system tables... OK 的输出。如果这一步失败,常见原因是 /var/lib/mysql/ 目录权限不对(应属 mysql:mysql 用户组),或磁盘空间不足(至少需要 200MB)。此时不要慌,手动执行: sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql ,然后 sudo chown -R mysql:mysql /var/lib/mysql 。
3.3 配置文件 my.cnf 的关键参数解析
Ubuntu 14.04 的 MySQL 配置文件 /etc/mysql/my.cnf 是一个分段式文件,核心段落如下:
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address = 127.0.0.1
其中最关键的三个参数是:
bind-address = 127.0.0.1:这是 MySQL 默认绑定地址,意味着只接受本地回环连接。如果你想从其他机器连接(比如用 Navicat 远程管理),必须将其改为0.0.0.0或具体 IP(如192.168.1.100),然后重启服务:sudo service mysql restart。但请注意:改完后必须同步配置防火墙放行 3306 端口,否则连接仍会被拒绝。datadir = /var/lib/mysql:数据文件存储路径。如需迁移到大容量磁盘(如/data分区),步骤是:1)停服务sudo service mysql stop;2)sudo rsync -av /var/lib/mysql/ /data/mysql/;3)sudo chown -R mysql:mysql /data/mysql;4)修改my.cnf中datadir为/data/mysql;5)启动服务。 切勿直接mv移动,因为rsync能保持文件属性和权限 。max_connections = 151:最大并发连接数。Ubuntu 14.04 默认值是 151,对于高并发 Web 应用可能不够。可提升至 500,但需同步调整系统级限制:echo 'mysql soft nofile 65535' | sudo tee -a /etc/security/limits.conf,否则 MySQL 会报Too many open files错误。
实操心得:每次修改
my.cnf后,务必用sudo mysqld --verbose --help | grep "Default options"验证配置是否被正确加载。如果看到Default options are read from the following files in the given order:后列出/etc/mysql/my.cnf,说明配置生效;如果没列出来,说明路径错了或文件名拼写错误。
3.4 mysql_secure_installation 的交互式操作全记录
该脚本是 MySQL 安装后最易出错的环节。以下是完整交互流程及每个选项的真实含义:
# 运行脚本
sudo mysql_secure_installation
# Step 1: Enter current password for root (enter for none)
# 问题:输入当前 root 密码(直接回车表示无密码)
# 真相:Ubuntu 14.04 的 `mysql-server` 包安装后,root 密码为空。所以直接按回车。
# 如果你之前设过密码却忘了,只能停服务、跳过权限检查重置:sudo mysqld_safe --skip-grant-tables &,然后 mysql -u root,UPDATE mysql.user SET Password=PASSWORD('newpass') WHERE User='root'; FLUSH PRIVILEGES;
# Step 2: Set root password? [Y/n]
# 问题:是否设置 root 密码?
# 真相:必须选 Y。空密码是重大安全隐患。密码强度无强制要求(5.5 不校验),但建议用大小写字母+数字组合。
# Step 3: Remove anonymous users? [Y/n]
# 问题:是否删除匿名用户?
# 真相:选 Y。匿名用户 `' '@'localhost'` 允许任何人无需用户名密码登录,仅用于测试,生产环境必须删除。
# Step 4: Disallow root login remotely? [Y/n]
# 问题:是否禁止 root 远程登录?
# 真相:默认 Y。这意味着 root 只能从本机(localhost)登录。如果你想用 Navicat 远程管理,这里必须选 n,然后手动授权:mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password' WITH GRANT OPTION; FLUSH PRIVILEGES;"
# Step 5: Remove test database and access to it? [Y/n]
# 问题:是否删除 test 数据库及访问权限?
# 真相:选 Y。test 数据库是 MySQL 安装时创建的示例库,无业务价值,且默认允许任何用户访问,构成风险。
# Step 6: Reload privilege tables now? [Y/n]
# 问题:是否立即重载权限表?
# 真相:选 Y。这会执行 `FLUSH PRIVILEGES`,使前面的权限变更立即生效。不选会导致新设置不生效。
注意:如果脚本执行到一半卡住(比如在 Step 2 输入密码后无响应),通常是
mysqld进程未运行。用sudo service mysql status检查,若显示stop/waiting,则sudo service mysql start启动后再重试。
4. 实操过程与核心环节实现:从零开始的完整安装复现
4.1 环境准备与前置检查
在开始安装前,必须确认系统状态。这不是形式主义,而是避免后续 80% 的失败。打开终端,依次执行:
# 1. 检查 Ubuntu 版本(确认是 14.04)
lsb_release -a
# 输出应包含:Distributor ID: Ubuntu,Description: Ubuntu 14.04.6 LTS
# 2. 检查磁盘空间(/var/lib/mysql 至少需要 500MB)
df -h /var/lib/mysql
# 如果空间不足,清理 apt 缓存:sudo apt-get clean && sudo apt-get autoremove
# 3. 检查端口占用(3306 是否被其他程序占用)
sudo netstat -tulpn | grep :3306
# 如果有输出,记下 PID,用 `sudo kill -9 PID` 结束进程,或改 MySQL 端口
# 4. 检查 AppArmor 状态(确认已禁用或配置正确)
sudo aa-status | grep mysql
# 如果输出包含 `usr.sbin.mysqld` 且状态为 `enforce`,说明 AppArmor 正在限制 MySQL,需按 2.3 节方法处理
提示:网络热词中出现的
command 'nvidia-smi' not found或sudo apt install nvidia-340,与 MySQL 安装完全无关。那是显卡驱动问题,发生在 GPU 服务器上,而 MySQL 服务通常部署在无 GPU 的数据库服务器上。遇到这类错误,不要试图用apt install解决,应单独排查显卡驱动。
4.2 完整安装命令流与预期输出
以下是在一台纯净 Ubuntu 14.04 虚拟机上的真实操作记录(已脱敏),每一步都附带解释:
# Step 1: 更新 apt 源(修复 404 错误)
$ sudo sed -i 's/archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
$ sudo sed -i 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
$ sudo apt-get update
# 预期输出:Hit http://old-releases.ubuntu.com trusty InRelease ... Reading package lists... Done
# Step 2: 安装 MySQL 服务端
$ sudo apt-get install mysql-server
# 预期输出:Setting up mysql-server-5.5 (5.5.62-0ubuntu0.14.04.1) ... Installing MySQL system tables... OK ... Starting MySQL database server: mysqld.
# Step 3: 验证服务状态
$ sudo service mysql status
# 预期输出:mysql start/running, process 1234 (process 后的数字是 PID)
# Step 4: 本地登录测试(使用空密码)
$ mysql -u root -p
# 输入密码时直接回车
# 预期输出:Welcome to the MySQL monitor. Commands end with ; or \g. ... mysql>
# Step 5: 运行安全加固脚本
$ sudo mysql_secure_installation
# 按照 3.4 节的交互流程操作,全部选 Y(Step 4 如需远程登录则选 n)
# Step 6: 创建测试数据库和用户(验证功能完整)
$ mysql -u root -p -e "CREATE DATABASE testdb CHARACTER SET utf8 COLLATE utf8_general_ci;"
$ mysql -u root -p -e "CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'TestPass123';"
$ mysql -u root -p -e "GRANT ALL PRIVILEGES ON testdb.* TO 'testuser'@'localhost'; FLUSH PRIVILEGES;"
$ mysql -u testuser -p -e "USE testdb; SHOW TABLES;"
# 预期输出:Empty set (0.00 sec),证明用户权限和数据库创建成功
4.3 连接性验证:从本地到远程的三层测试法
安装完成不等于可用。必须进行三层连接性验证:
-
第一层:本地 socket 连接
mysql -u root -p—— 使用 Unix socket 文件/var/run/mysqld/mysqld.sock连接。这是最快、最安全的方式,适用于 PHP-FPM、Python 应用在同一台机器上访问数据库。 -
第二层:本地 TCP/IP 连接
mysql -h 127.0.0.1 -u root -p—— 强制走 TCP/IP 协议(而非 socket)。这能验证bind-address和端口监听是否正常。如果失败,检查netstat -tulpn | grep :3306是否有mysqld进程监听。 -
第三层:远程 TCP/IP 连接
从另一台机器执行:mysql -h 192.168.1.100 -u root -p(192.168.1.100 是 Ubuntu 14.04 服务器 IP)。如果失败,按顺序排查:1)服务器my.cnf中bind-address是否为0.0.0.0;2)服务器防火墙是否放行:sudo ufw allow 3306;3)root 用户是否授权远程访问(见 3.4 节 Step 4);4)客户端网络能否 ping 通服务器 IP。
实操心得:Navicat 连接失败时,90% 的原因是没开防火墙或没授权远程用户。不要一上来就怀疑 MySQL 配置,先用
telnet 192.168.1.100 3306测试端口连通性。如果telnet能连上,说明网络和防火墙没问题,问题一定在 MySQL 权限或bind-address。
4.4 性能与安全加固:让 MySQL 在 14.04 上真正“生产就绪”
安装只是起点,让 MySQL 稳定运行才是关键。以下是我在多个客户现场验证过的加固项:
-
内存优化 :Ubuntu 14.04 默认内存较小(2GB),MySQL 5.5 的
innodb_buffer_pool_size默认是 128MB,对于稍大点的表(>100MB)会频繁刷盘。建议设为物理内存的 50%-70%。例如 4GB 内存,加到/etc/mysql/my.cnf的[mysqld]段:innodb_buffer_pool_size = 2G innodb_log_file_size = 256M修改后需停服务、删除旧日志文件、再启动:
sudo service mysql stop && sudo rm /var/lib/mysql/ib_logfile* && sudo service mysql start。 -
日志轮转 :MySQL 错误日志
/var/log/mysql/error.log默认不轮转,长期运行会撑爆磁盘。启用 logrotate:echo '/var/log/mysql/*.log { daily missingok rotate 14 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 }' | sudo tee /etc/logrotate.d/mysql -
备份策略 :
mysqldump是最可靠的逻辑备份工具。写一个每日备份脚本/root/backup_mysql.sh:#!/bin/bash DATE=$(date +%Y%m%d) mysqldump -u root -p'YourRootPassword' --all-databases --single-transaction > /backup/mysql_full_$DATE.sql gzip /backup/mysql_full_$DATE.sql find /backup -name "mysql_full_*.sql.gz" -mtime +7 -delete加入 crontab:
0 2 * * * /root/backup_mysql.sh,每天凌晨 2 点执行。
5. 常见问题与排查技巧实录:那些文档里不会写的“血泪教训”
5.1 经典错误代码速查表
| 错误代码/现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' |
mysqld 进程未运行,或 socket 文件路径不匹配 |
sudo service mysql status , ls -l /var/run/mysqld/ |
sudo service mysql start ;如果 socket 文件不存在,检查 my.cnf 中 socket 路径是否与 ls 结果一致 |
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) |
root 密码错误,或用户权限表损坏 | sudo mysqld_safe --skip-grant-tables & , mysql -u root |
进入后执行 UPDATE mysql.user SET Password=PASSWORD('newpass') WHERE User='root'; FLUSH PRIVILEGES; |
Starting MySQL database server: mysqld . . . . . . . . . . . . . . failed! |
AppArmor 阻止、磁盘满、 datadir 权限错误 |
sudo tail -50 /var/log/mysql/error.log , sudo aa-status |
查日志定位具体错误;AppArmor 问题按 2.3 节处理;磁盘满用 df -h ;权限问题 sudo chown -R mysql:mysql /var/lib/mysql |
Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111) |
网络不通、防火墙拦截、 bind-address 未设为 0.0.0.0 |
telnet xxx.xxx.xxx.xxx 3306 , sudo ufw status |
telnet 成功则查 MySQL 权限;失败则查防火墙和 bind-address |
5.2 “MySQL 自动忽略大小写?”——字符集与排序规则的真相
网络热词里频繁出现这个问题,其实是个误解。MySQL 本身不“忽略大小写”,而是由 列的排序规则(Collation) 决定比较行为。Ubuntu 14.04 的 MySQL 5.5 默认字符集是 latin1 ,默认排序规则是 latin1_swedish_ci ,其中 _ci 表示 case-insensitive(大小写不敏感)。所以 SELECT * FROM users WHERE name = 'John' 会匹配 'john' 、 'JOHN' 。解决方案是:
- 建表时指定 :
CREATE TABLE users (name VARCHAR(50) COLLATE utf8_bin);,utf8_bin是二进制比较,严格区分大小写。 - 修改现有表 :
ALTER TABLE users CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; - 全局修改 (不推荐):在
my.cnf中加collation-server = utf8_bin,但这会影响所有数据库,可能导致应用异常。
注意:
utf8在 MySQL 5.5 中实际是utf8mb3,最多支持 3 字节 UTF-8 字符(不支持 emoji)。如需完整 UTF-8,需用utf8mb4,但 5.5 对utf8mb4支持不完善,建议升级到 5.6+。
5.3 “MySQL 设置唯一已经有重复数据库”——数据迁移时的冲突处理
当你从旧系统导入数据到新 MySQL 5.5 实例时,如果 INSERT IGNORE 或 REPLACE INTO 仍报 Duplicate entry ,说明唯一索引(UNIQUE KEY)已存在冲突记录。正确做法是:
- 先查出重复数据:
SELECT column_name, COUNT(*) c FROM table_name GROUP BY column_name HAVING c > 1; - 手动清理或合并重复行(如保留最新时间戳的那条)。
- 删除唯一索引:
ALTER TABLE table_name DROP INDEX index_name; - 导入数据。
- 重建唯一索引:
ALTER TABLE table_name ADD UNIQUE KEY index_name (column_name);
提示:不要用
INSERT ... ON DUPLICATE KEY UPDATE代替清理,因为这会掩盖数据质量问题。线上数据库的“重复”往往是业务逻辑漏洞的体现,必须人工确认。
5.4 学生课程成绩信息实体表设计实战
这是数据库课程设计高频题。基于 MySQL 5.5 的能力,一个健壮的设计应包含:
-- 学生表
CREATE TABLE students (
student_id INT PRIMARY KEY AUTO_INCREMENT,
student_no VARCHAR(10) NOT NULL UNIQUE, -- 学号,唯一
name VARCHAR(20) NOT NULL,
gender ENUM('M','F') DEFAULT 'M',
birth_date DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 课程表
CREATE TABLE courses (
course_id INT PRIMARY KEY AUTO_INCREMENT,
course_code VARCHAR(10) NOT NULL UNIQUE, -- 课程代码,如 CS101
course_name VARCHAR(50) NOT NULL,
credit INT DEFAULT 2
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 成绩表(关联学生和课程)
CREATE TABLE scores (
score_id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
course_id INT NOT NULL,
score DECIMAL(5,2) CHECK (score >= 0 AND score <= 100),
exam_date DATE DEFAULT (CURDATE()),
FOREIGN KEY (student_id) REFERENCES students(student_id) ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES courses(course_id) ON DELETE CASCADE,
UNIQUE KEY uk_student_course (student_id, course_id) -- 防止同一学生同一课程重复录入
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
关键点:1)使用 ENGINE=InnoDB 支持外键和事务;2) UNIQUE KEY uk_student_course 确保成绩不重复;3) ON DELETE CASCADE 实现级联删除,删学生时自动删其成绩;4) CHECK 约束保证分数在合理范围(MySQL 5.5 支持 CHECK,但不强制执行,仅作注释)。
6. 后续演进与替代方案思考:当 Ubuntu 14.04 终将退出历史舞台
写到这里,必须坦诚:Ubuntu 14.04 已进入“维护模式”,官方不再提供安全更新。继续使用它运行 MySQL,就像在悬崖边修房子——能用,但风险在累积。那么,下一步该怎么走?我的建议不是“立刻升级”,而是分三步走:
-
短期(0-3个月) :在现有 14.04 环境上,严格遵循本文的加固方案,尤其是开启日志审计、限制 root 远程访问、实施每日备份。同时,用
mysqldump --all-databases > backup_1404.sql导出全量数据,作为迁移基线。 -
中期(3-6个月) :搭建 Ubuntu 20.04 或 22.04 的测试环境,安装 MySQL 8.0,用
mysqlsh工具进行兼容性检查:mysqlsh --sql -u root -p -h 127.0.0.1 -e "SELECT VERSION(); SELECT @@sql_mode;",对比 5.5 和 8.0 的 SQL 模式差异(如STRICT_TRANS_TABLES是否启用),修改应用中不兼容的 SQL(如GROUP BY必须包含所有非聚合字段)。 -
长期(6个月以上) :制定迁移计划。MySQL 5.5 到 8.0 是跨大版本升级,不能直接
apt-get upgrade。正确路径是:14.04 上的 5.5 → 导出逻辑备份 → 22.04 上的 5.7(作为中间版本)→ 导入并运行mysql_upgrade→ 再升级到 8.0。这样能平滑过渡,避免语法和权限模型的剧烈变化。
我个人
更多推荐




所有评论(0)