ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu 22.04 安装配置 MySQL 8.0:认证、远程连接与字符集实战

Ubuntu 22.04 安装配置 MySQL 8.0:认证、远程连接与字符集实战 1. 先搞清楚Ubuntu 22.04上的MySQL版本差异先说一个很多新手最容易忽略的事实Ubuntu 22.04的官方软件源里默认的mysql-server包已经是MySQL 8.0了不再像18.04、20.04时代那样给你装5.7。这意味着网上大量基于MySQL 5.7写的教程在22.04上跑起来多少都会出点状况最典型的就是root账号的认证方式。MySQL 8.0默认的认证插件是caching_sha2_password而5.7时代普遍用的是mysql_native_password。这个变化带来的直接影响是早期版本的Navicat、一些老项目的JDBC驱动连接MySQL 8.0会直接报错。另一个大坑是Ubuntu上通过apt装的MySQLroot用户默认使用auth_socket插件认证说人话就是——你装完之后根本不需要密码直接以系统root身份执行sudo mysql就能进去但你想用mysql -u root -p加密码登录反而登不进去。所以我在本文开头就把这个差异摆出来就是想让大家别照着旧教程一顿操作猛如虎结果卡在第一步。后面所有配置思路都是围绕着“Ubuntu 22.04 MySQL 8.0”这套真实环境来展开的。1.1 安装前先检查环境状态动手之前先确认系统里有没有装过MySQL或MariaDB避免端口和文件冲突。我见过不少人在旧环境上反复折腾最后发现是之前残留的配置在捣乱。用下面几条命令快速摸个底# 检查是否已有MySQL相关包 dpkg -l | grep mysql # 检查3306端口是否被占用 ss -tlnp | grep 3306 # 如果之前装过MariaDB优先卸载干净 systemctl status mariadb如果输出里能看到mysqld或者mariadbd在跑先停掉服务再处理。如果是全新的22.04系统这一步基本不会有什么输出属于正常情况。1.2 软件源加速的小建议很多教程会建议你换了国内镜像源再装。我的实际经验是数据库这类基础软件优先建议保持官方源因为官方源更新及时、依赖关系最干净。但如果你的服务器在境内apt下载速度确实慢到没法接受那可以把/etc/apt/sources.list里的archive.ubuntu.com和security.ubuntu.com替换成你所在地区的镜像域名。Ubuntu 22.04的源配置是带jammy、jammy-updates、jammy-security这些套件的换源时保持套件名不变即可。这里提醒一句换源只是解决下载速度不要同时混用多个第三方源装MySQL容易把依赖搞乱出了问题排查起来非常头疼。2. 安装流程从apt安装到服务自启2.1 一步步执行安装确认环境干净之后安装其实非常简单# 更新软件包索引 sudo apt update # 安装MySQL服务端 sudo apt install mysql-server -ymysql-server这个包会自动把mysql-client和mysql-common等依赖一起装好不需要再额外安装客户端。安装过程一般在1-2分钟内完成视网络情况而定。装完之后用mysql --version看一眼版本mysql --version正常会输出类似Ver 8.0.x for Linux on x86_64 (MySQL Community Server - GPL)。2.2 检查服务状态Ubuntu 22.04使用systemd管理服务。安装完成后MySQL通常会自动启动并设置开机自启。用以下命令确认# 查看服务运行状态 systemctl status mysql # 如果没自动启动手动拉起 sudo systemctl start mysql # 设置开机自启 sudo systemctl enable mysql这里有个小细节值得注意服务名是mysql不是mysqld。有些从CentOS转过来的朋友习惯性执行systemctl status mysqld结果提示找不到服务还以为装失败了。2.3 安装后的默认目录布局知道文件装在哪后面排查问题会省很多事。apt方式安装的MySQL 8.0几个关键位置如下用途路径配置文件主目录/etc/mysql/核心配置监听地址、字符集等/etc/mysql/mysql.conf.d/mysqld.cnf数据文件目录/var/lib/mysql/日志文件目录/var/log/mysql/socket文件/var/run/mysqld/mysqld.sock注意Ubuntu上MySQL的配置不是集中在一个my.cnf里而是采用/etc/mysql/下的多级配置文件组合方式。主配置会通过!includedir指令把conf.d和mysql.conf.d两个目录下的配置都加载进来。所以自定义配置时建议写在mysql.conf.d/mysqld.cnf里而不是直接改主配置更不要自己新建一个文件却忘了加正确的权限和归属。2.4 另一种安装途径官网APT仓库如果因为某种原因需要装指定小版本的MySQL或者想用MySQL官方维护的打包版本可以通过官方APT仓库来装。步骤如下# 下载官方仓库配置包 wget https://dev.mysql.com/get/mysql-apt-config_0.8.24-1_all.deb # 安装仓库配置期间会弹出选择界面保持默认即可 sudo dpkg -i mysql-apt-config_0.8.24-1_all.deb # 更新索引 sudo apt update # 此时再装mysql-server就会从官方仓库拉取 sudo apt install mysql-server -y这种方式的好处是版本选择更灵活、更新策略更自主坏处是仓库配置界面稍显繁琐而且下载源在国外速度可能不太乐观。个人建议如果只是学习、开发、内部使用直接走apt官方源就足够了没必要折腾。生产环境如果对版本有严格约束再用官网仓库也不迟。3. 初始安全配置与root账户处理安装完不等于能正常用。MySQL 8.0装好之后root账户默认是auth_socket认证即只有系统root用户能通过socket文件登录密码形同虚设。这一步必须处理否则后续所有通过密码登录的操作都会碰壁。3.1 跑一遍安全初始化脚本MySQL自带一个交互式安全配置工具mysql_secure_installation可以快速设置密码策略、移除匿名用户、禁用root远程登录、清理测试库。执行sudo mysql_secure_installation交互过程中有几步值得留意是否设置密码强度校验插件MySQL 8.0会询问是否启用VALIDATE PASSWORD COMPONENT。建议开发环境选No省得密码必须带大小写字母、数字、特殊符号自找麻烦生产环境建议选Yes并且选MEDIUM或STRONG级别。root密码在同一界面中设定。移除匿名用户选Yes默认的安全操作。禁止root远程登录选Yes。后续远程连接的账号单独创建而不是拿root暴露在外网口这是基本的安全素养。删除test数据库选Yes。3.2 手动修改root认证方式如果脚本跑完之后你用mysql -u root -p输入刚设置的密码仍然登录失败大概率是认证插件没切换。这时候用系统root身份进入MySQL手动把root的认证方式改掉# 以系统root身份直接进MySQL此时靠auth_socket sudo mysql # 在MySQL命令行中执行 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的新密码; FLUSH PRIVILEGES;这里的mysql_native_password是为了兼容旧客户端如果你的客户端都是新版本直接用caching_sha2_password也完全没问题。我个人建议先统一改成mysql_native_password降低连接阶段的报错概率等确认客户端都支持8.0认证方式后再逐步切换回去。毕竟手里一堆工具不是每一个都能跟上MySQL的更新节奏。3.3 创建日常使用的专用账号长期拿root账号跑业务风险非常高。一个是权限过大应用被脱库攻击时直接影响整个数据库另一个是root账号一旦密码泄露连改密码的机会可能都没有。我习惯安装配置完成后立刻建一个普通账号让应用和日常运维都用这个账号root只保留在最紧急的故障处理场景里。-- 创建一个本地使用的管理账号 CREATE USER adminlocalhost IDENTIFIED BY 强密码; -- 授予常用权限建议按需收窄这里是示例只做基本管理 GRANT ALL PRIVILEGES ON *.* TO adminlocalhost; -- 刷新权限 FLUSH PRIVILEGES;本地或者内网使用的话adminlocalhost已经足够了。如果是给某个应用建库建账号更规范的做法是只给单库权限比如CREATE DATABASE myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER myapp_userlocalhost IDENTIFIED BY 复杂密码; GRANT ALL PRIVILEGES ON myapp.* TO myapp_userlocalhost; FLUSH PRIVILEGES;这套“最小权限”的思路成本极低收益极大。后面接业务的时候不会因为权限问题到处打补丁。4. 远程连接配置让Navicat和Workbench都能连上4.1 修改监听地址MySQL 8.0默认只监听127.0.0.1也就是只允许本机连接。想远程连接第一步修改监听地址。编辑配置文件sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf找到这一行bind-address 127.0.0.1改成bind-address 0.0.0.0改完后重启服务让配置生效sudo systemctl restart mysql这里我得强调一下bind-address 0.0.0.0意味着MySQL会监听所有网卡接口包括公网接口。如果你的服务器有公网IP务必配合防火墙规则做访问控制别把数据库直接裸奔到公网上。等会儿讲防火墙的时候我再细说。4.2 确认3306端口可访问监听地址改好后先在本机验证一下端口状态ss -tlnp | grep 3306输出类似LISTEN 0 128 0.0.0.0:3306 0.0.0.0:* users:((mysqld,pidxxxx,fdxx))就说明监听正常。接着检查防火墙。Ubuntu 22.04默认使用UFW管理防火墙很多服务器还同时挂着云安全组规则比如阿里云、腾讯云的安全组。放行命令如下# 放行3306端口 sudo ufw allow 3306/tcp # 确认规则生效 sudo ufw status如果你是云服务器光在系统层面放行还不够还要去云控制台的安全组里给3306端口加一条入方向规则。两个地方都要通远程连接才能真正建立起来。这一点我踩过好几次坑每次都以为是MySQL配置问题最后发现是安全组没有配。4.3 创建远程专用用户并授权改完监听和防火墙还要在MySQL里创建允许远程连接的用户。注意root即使改了认证方式默认也是只允许localhost登录远程就用root登录还是会失败。正确的做法是新建远程账号-- 创建支持任意IP来源的远程账号 CREATE USER remote_user% IDENTIFIED WITH mysql_native_password BY 远端密码; -- 授权访问指定数据库 GRANT ALL PRIVILEGES ON myapp.* TO remote_user%; -- 或者给所有库的查询权限按需使用不建议随便给ALL -- GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO remote_user%; FLUSH PRIVILEGES;%代表不限制来源IP实际使用中如果能确定客户端IP尽量写成具体的IP或者网段比如remote_user192.168.1.%更安全。4.4 客户端连接失败的常见错误对照远程连接配置完成并不代表万事大吉客户端这端还有兼容性问题要处理。下面这张表是我整理的高频报错和对应处理思路报错信息原因分析处理方案ERROR 2059 (HY000): Authentication plugin caching_sha2_password cannot be loaded客户端版本太老不支持MySQL 8.0默认认证插件把用户的认证方式改成mysql_native_password或者升级客户端ERROR 1045 (28000): Access denied for user xxxxxx账号密码不对或该来源IP不在授权范围内检查密码检查user表的Host字段授权范围ERROR 2003 (HY000): Cant connect to MySQL server on ip (timed out)网络不通可能是防火墙或安全组拦截分别检查系统防火墙、云安全组、端口监听状态ERROR 1130 (HY000): Host xxx is not allowed to connect用户的Host匹配不上当前连接来源修改用户Host为%或对应IP网段后刷新权限结合热词里提到的error 2002 (hy000): cant connect to local mysql server through socket /tmp/mysql.sock我再多说一句2002错误是本机通过socket连接失败常见原因是socket路径不对或者mysqld没起来。Ubuntu 22.04下socket默认在/var/run/mysqld/mysqld.sock如果客户端默认找/tmp/mysql.sock会连不上。解决办法是执行mysql -h 127.0.0.1 -P 3306强制走TCP连接或者ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock建立软链接。5. 字符集与存储引擎中文乱码问题一次解决5.1 utf8mb4为什么是必选项很多人在安装完成后建表、插入中文都没问题但某天发现数据从程序里写入后变成了???或者从旧库导出来的中文乱码。这个问题的根源通常是字符集配置不对。MySQL的utf8字符集实际上最多支持3字节的Unicode编码但有些生僻汉字和emoji需要4字节。也就是说如果用utf8遇到这类字符就会截断或乱码。utf8mb4才是真正完整的UTF-8实现。MySQL 8.0的默认字符集已经改成了utf8mb4但为了保险起见还是建议大家显式配置一遍。编辑配置文件sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf在[mysqld]段追加character-set-server utf8mb4 collation-server utf8mb4_unicode_ciutf8mb4_unicode_ci是比较通用的排序规则对大小写不敏感适合大多数场景。如果你的业务对中文排序有特殊要求可以换成utf8mb4_zh_0900_as_cs但一般用不到。改完后重启sudo systemctl restart mysql重启后执行下面这条SQL验证SHOW VARIABLES LIKE character_set%;关注character_set_server应该返回utf8mb4。5.2 客户端和连接层字符集服务器端设好了不代表连接字符串不用管。程序连接MySQL时JDBC连接串要显式加上characterEncodingutf8注意Java里这里写utf8即可底层映射到utf8mb4Python的pymysql连接参数里也要设置charsetutf8mb4。如果建库时用了旧的latin1即使服务器改成了utf8mb4新数据写入时仍可能出问题。所以建库时最好显式指定CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;已经建好的库可以这样转换ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;注意这只改了库的默认字符集存量表还需要逐个转换。一条ALTER命令批量处理所有表的方法也有但转换过程会锁表生产环境务必找低峰期操作。5.3 时区问题顺便说一个和字符集一样容易被忽略的问题时区。MySQL 8.0默认时区是SYSTEM在云服务器上通常就是UTC导致NOW()函数返回的时间比北京时间慢8小时。解决办法sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf追加default-time-zone 08:00然后重启服务。或者在连接串里指定serverTimezoneAsia/ShanghaiJDBC来规避。我建议服务器端配置和服务端时区保持一致这样不管谁来连接拿到的时间都是一致的排查问题省心。6. 常见问题速查表与现场排查实录最后这一部分把我在Ubuntu 22.04上安装配置MySQL时最常遇到的问题集中整理一下。每一个都是我实际踩过的坑不是从文档里抄的。6.1 root用户登录不进MySQL现象执行sudo mysql -u root直接报错Access denied。原因某些情况下auth_socket插件对root的映射关系检查失败或者root密码认证模式和socket认证交错在一起。处理方式先停服用mysqld_safe --skip-grant-tables跳过权限表启动进入后重建root权限。这种方法比较粗暴但能救急。常规做法是sudo mysql如果进不去就用下面的恢复流程# 停止服务 sudo systemctl stop mysql # 以跳过授权表方式启动 sudo mysqld_safe --skip-grant-tables # 免密进入 mysql -u root # 在MySQL内重置root密码为空再刷新权限 FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密码; FLUSH PRIVILEGES; # 退出后重启服务 sudo systemctl restart mysql这套流程我至少用过三次非常实用。注意操作完要把进程清理干净避免跳过授权表的mysqld还在后台跑着。6.2 密码强度策略导致的设置失败MySQL 8.0默认如果启用了密码校验组件设简单密码直接提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。想临时放低策略级别先登录MySQL然后SHOW VARIABLES LIKE validate_password%; SET GLOBAL validate_password.policy LOW;或者干脆禁用它UNINSTALL COMPONENT file://component_validate_password;开发环境这样没问题生产环境还是老老实实设强密码吧。6.3 安装后MySQL服务起不来日志一片空白排查技巧遇到服务启动失败先看错误日志。sudo tail -100 /var/log/mysql/error.log常见原因包括数据目录权限不对、磁盘空间满、配置文件语法错误。/var/lib/mysql目录如果被root用户误改了归属MySQL会直接拒绝启动处理办法是把归属改回mysql:mysqlsudo chown -R mysql:mysql /var/lib/mysql6.4 低内存机器比如树莓派上的性能优化按热词的联想树莓派跑Ubuntu 22.04的场景也不少。树莓派的物理内存一般只有4GB或8GBMySQL 8.0默认的缓冲池配置会吃掉大量内存。我建议安装完顺手改一下两个参数innodb_buffer_pool_size 256M performance_schema OFF放在mysqld.cnf的[mysqld]段下重启后内存占用会明显降下来。当然这是为低配设备做出的妥协正式服务器上别乱调缓冲池太小反而影响性能。6.5 彻底卸载和清理想重装干净版本的MySQL光apt remove mysql-server是不够的配置文件、数据文件都会残留。完整卸载步骤# 停止服务 sudo systemctl stop mysql # 卸载软件包注意保留数据的话就跳过下面的删除data目录 sudo apt purge mysql-server mysql-client mysql-common -y # 删除残余目录 sudo rm -rf /etc/mysql /var/lib/mysql /var/log/mysql # 清理自动安装的依赖 sudo apt autoremove -y执行之前一定确认没有需要保留的数据。这个命令执行完你的MySQL就像从没装过一样干净。6.6 用mysqldump把远程库的表同步到本地最后说一个和“远程表同步”相关的实用操作。热词里提到“把远程库的这张表同步到本地”这个高频需求用mysqldump处理非常直接。比如你有一张在远程服务器上的表remote_db.orders要拉到本地库local_db可以这样# 在本地机器执行导出远程指定表的数据 mysqldump -h 远程IP -P 3306 -u remote_user -p远程密码 \ remote_db orders orders.sql # 导入到本地库 mysql -u local_user -p本地密码 local_db orders.sql如果只是想同步结构不要数据mysqldump加--no-data参数如果本地已经有数据想增量同步某张表可以在导出时加--where条件比如--wherecreate_time 2024-01-01。这种方式比较轻量表结构不大时完全够用。更复杂的表结构变更同步那就要考虑专门的数据库同步工具或者主从复制方案了不在本文展开。7. 我对这套流程的个人体会说点实话我在Ubuntu 22.04上装MySQL没有一百次也有八十次了。最初几次也是被auth_socket、bind-address、密码策略折磨得够呛。后来总结发现多数问题本质上是“对Ubuntu生态不熟悉”而不是“MySQL太难用”。Ubuntu对MySQL的默认配置做了很多安全加固root用socket认证、只监听localhost、默认字符集调整等等。这些设计对生产安全有利但对新用户来说很不直观。理解了这个逻辑再回头看那些报错基本都能定位到具体环节。如果你照本文操作最后仍然卡在某个奇怪的问题上我的建议是先别急着搜报错全文按这个顺序排查进程是否在跑、端口是否在监听、配置是否生效、用户授权是否匹配。八成以上问题都出在这四层里。另外再分享一个小技巧配置文件改完之后不要急着重启服务先用mysqld --verbose --help看看当前配置的实际解析结果或者直接看错误日志。很多时候配置写错了MySQL会默默忽略而不是报错导致你怎么改都没用。这个习惯能帮你省掉大量排查时间。
返回列表