【Day 35】Linux-Mysql错误总结

(一)MySQL 基础操作与服务故障类

连接层错误(客户端与服务器的连接建立失败)

解决 socket 路径、文件存在性及服务可用性问题。

1、MySQL 客户端连接失败(报错 "Can't connect to local MySQL server throgh socket...")

  • ①确认mysql启动②查找实际socket路径(在mysql配置文件中)
  • grep 'socket' /etc/mysql/my.cnf /etc/my.cnf /etc/mysql/mysql.conf.d/mysqld.cnf
  • ③ 如果 socket 文件位置与客户端默认查找的位置不一致则手动指定
  • mysql -u 用户名 -p --socket=/实际的socket路径
  • ④确保 MySQL 进程,客户端有权限创建和访问 socket 文件。msyql:mysql
  • ls -ld /var/run/mysqld/
  • ls -l /var/run/mysqld/mysqld.sock

2、多路径存在 mysql.sock 的情况确认

①搜索系统中所有名为 mysql.sock 的文件

  • sudo find / -name "mysql.sock" 2>/dev/null //

②方法一:确认当前 MySQL 实例实际使用的 socket 路径

  • grep -r "socket" /etc/mysql/ /etc/my.cnf /etc/mysql/mysql.conf.d/ 2>/dev/null

方法二:登录 MySQL 实例查询

  • SHOW VARIABLES LIKE 'socket';

③多 socket 文件的原因

  • 多个 MySQL 实例共存:系统中可能运行着多个 MySQL 服务(如官方版与第三方包、不同版本),每个实例生成独立的 socket 文件。
  • 历史残留文件 :旧版本 MySQL 卸载不彻底,遗留了未删除的 mysql.sock
  • 配置修改后未清理:修改 socket 路径后,旧路径的 socket 文件未删除。
  • 权限问题导致的残留:MySQL 服务异常退出时,可能未自动清理 socket 文件。

④ 停止多余的服务(假设服务名为 mysql2) 删除对应的 socket 文件

  • sudo systemctl stop mysql2
  • sudo rm -f /path/to/unused/mysql.sock

统一客户端与服务端的 socket 路径(在 客户端配置文件**)**

client\] socket = /var/run/mysqld/mysqld.sock # 与服务端配置一致 ⑥ **重启 MySQL 服务确保 socket 正确生成** sudo systemctl restart mysql # 验证 socket 文件是否存在 ls -l /var/run/mysqld/mysqld.sock **服务层错误(MySQL 服务自身启动 / 运行失败)** 聚焦服务启动 / 重启失败,核心是权限和配置正确性。 **1、MySQL 服务启动失败(报错 "权限不够(Error: 13)")** ①找到权限不足的具体文件或目录(在错误日志中) * sudo tail -f /var/log/mysql/error.log `Can't create/write to file '/path/to/file' (Errcode: 13 - Permission denied)` ②查看数据目录权限 # 正确的权限应为:属主和属组都是 mysql,权限至少为 700 * ls -ld /var/lib/mysql/ ③排查 SELinux/AppArmor 等安全机制的限制、检查 MySQL 运行用户 **2、MySQL 停服改配置后重启卡住的处理** * sudo tail -f /var/log/mysql/error.log //查看 MySQL 错误日志 配置修改不当(如参数冲突、权限错误)导致服务重启时进程阻塞。 **3、MySQL 首次启动自动初始化规则及目录修改触发条件** 首次启动时自动初始化数据目录、系统表等,目录修改可能触发重新初始化逻辑。 **4、其他触发 MySQL 初始化的操作(删关键文件 /--initialize 参数)** 删除数据目录关键文件或使用初始化参数,会触发服务重新初始化,可能影响服务启动。 **权限验证错误(连接已建立,但权限校验失败)** 围绕账号、密码、主机匹配及权限授予展开。 **1、MySQL 登录被拒(报错 "Access denied for user 'root'@'[localhost](https://localhost/ "localhost")'")** ① 密码是否正确 ② 检查登录主机是否匹配 ③重置 root 密码(忘记密码或密码错误) 停止 MySQL 服务步骤--跳过权限验证启动 MySQL--无密码登录并修改密码--重启 MySQL 服务 ④MySQL 8.0 默认使用 `caching_sha2_password` 认证插件,而部分旧客户端(如 Navicat 旧版本)不支持,会导致登录失败。可修改为旧插件 ⑤检查用户是否被锁定 * SELECT user, host, account_locked FROM mysql.user WHERE user='root'; # 若 account_locked 为 Y,执行解锁 * ALTER USER 'root'@'localhost' ACCOUNT UNLOCK; FLUSH PRIVILEGES; **2、****从库复制权限不足****(ERROR 1227: Access denied,普通用户执行 STOP SLAVE)** ① 使用 REPLICATION SLAVE ADMIN 权限 * mysql -u root -p * GRANT REPLICATION SLAVE ADMIN ON \*.\* TO 'username'@'%'; * FLUSH PRIVILEGES; //授权时尽量指定具体主机(如 `'username'@'192.168.1.100'`),避免使用 `%` 允许所有主机访问。 **3、主从复制时出现 ERROR 1045 (28000): Access denied for user 'repl'@'slave_ip' (using password: YES) 错误** ① 检查主库复制账号是否存在及密码是否正确 * SELECT user, host, authentication_string FROM mysql.user WHERE user = 'repl'; ② 在从库测试连接主库 (登录失败,说明密码错误或账号不存在,需在主库重新配置) * mysql -h 主库IP -u repl -p ③检查从库复制配置中的账号密码 * STOP SLAVE; * CHANGE MASTER TO MASTER_HOST = '主库IP', MASTER_USER = 'repl', MASTER_PASSWORD = '正确的密码', MASTER_LOG_FILE = '主库当前binlog文件',MASTER_LOG_POS = 主库当前binlog位置; * START SLAVE; * SHOW SLAVE STATUS\\G ④ DNS 反向解析, * SET GLOBAL skip_name_resolve = ON; //主库执行:临时关闭 DNS 反向解析 * 在从库重新执行 `START SLAVE`,若错误消失,说明是反向解析问题 * 修改主库配置文件 * \[mysqld\] skip_name_resolve = ON # 添加此行,禁用 DNS 反向解析 ⑤确保网络和防火墙允许从库访问主库 3306 端口 **4、健康检查用户连接错误(monitor 用户连接后端库被拒)** * 原因:monitor 账号不存在、密码错误、主机权限未开放,或网络 / 防火墙限制。 **配置层错误(参数配置不当导致功能异常)** 服务已启动且连接正常,但因配置参数错误导致功能失效 关注参数生效规则、版本兼容性及系统变量特性。 **1、GTID 配置不生效(gtid_mode=OFF,改配置未重启)** * 原因:修改 GTID 模式后未重启服务,导致参数未生效。 **validate_password 变量含义 / 配置解读(MEDIUM 策略)** 说明:密码验证插件的参数配置,控制密码强度要求(如长度、复杂度)。 **validate_password 变量格式区别(. 与_,版本兼容性)** 说明:不同 MySQL 版本中密码验证变量的命名格式差异,影响配置生效。 带_的 validate_password 变量能否删除(系统兼容项,不可删) ### (二)MySQL 数据备份与恢复类 **1、备份 SQL 文件导入无效果(文件空 / 损坏 / 路径错 / SQL 语法错)** ①**文件为空或损坏** * ls -lh backup.sql * head -n 10 backup.sql ②**文件路径错误**:使用绝对路径导入,确保 MySQL 进程有权限读取文件 ③SQL 语法错误:查看错误日志定位具体错误行:grep "ERROR" /var/log/mysql/error.log **2、误删数据后的备份与恢复方法(备份剩余数据 + 备份 / 二进制日志 / 第三方工具)** (1)利用全量备份 + 二进制日志恢复 ①**恢复全量备份到故障前状态** # 假设全量备份为 full_backup.sql mysql -u root -p 数据库名 \< full_backup.sql ②找到全量备份对应的二进制日志位置 grep "CHANGE MASTER TO" full_backup.sql ③导出从备份点到误删前的二进制日志 mysqlbinlog --start-position=154 --stop-datetime="2024-08-27 10:00:00" /var/log/mysql/binlog.000003 \>增量日志.sql ④导入增量日志 mysql -u root -p 数据库名 \< 增量日志.sql (2)无备份但开启二进制日志:直接通过 binlog 恢复 ①mysql -u root -p -e "SHOW BINARY LOGS;" # 分析日志内容,定位误删语句 mysqlbinlog /var/log/mysql/binlog.000003 \| grep -i "DELETE FROM 表名" ②生成反向 SQL(跳过误删操作或执行反向语句): * 若为 DELETE,可提取对应 INSERT 语句恢复; ### (三)MySQL 表结构与约束类 **文件与存储引擎类(核心:表文件含义、缺失与结构关联)** **1、表空间缺失(报错 "Tablespace is missing",.ibd 文件丢失 / 损坏)** 解释:InnoDB 表的表空间文件(`.ibd`)丢失或损坏,导致 MySQL 无法加载表数据。`.ibd` 是 InnoDB 独立表空间文件,存储表数据和索引,若误删、磁盘损坏或迁移时遗漏该文件,会触发此错误。 **外键约束类(核心:外键创建 / 删除 / 数据操作的约束冲突)** **1、删除表因外键约束失败(报错 "referenced by a foreign key constraint")** 解释:要删除的表是 "主表",有其他 "子表" 通过外键关联它(子表外键引用主表主键),MySQL 为保证数据一致性,禁止直接删除被引用的主表,需先删除子表或解除外键约束。 **2、创建外键报错 "incompatible"(tid 字段 UNSIGNED 属性不一致)** 解释:外键字段与引用的主键字段 "数据属性不兼容"------ 子表外键 `tid` 若为 `UNSIGNED`(无符号),主表被引用的 `tid` 必须也是 `UNSIGNED`;若一方有、一方无,MySQL 判定类型不匹配,拒绝创建外键。 **3、添 / 更数据报错 "cannot add or update a child row"(子表外键值主表不存在)** 解释:子表插入 / 更新数据时,外键字段的值在主表中不存在(违反 "外键引用完整性")。例如:子表(订单表)外键 `user_id=100`,但主表(用户表)中无 `user_id=100` 的记录,MySQL 阻止操作以避免数据孤立。 **表设计与数据操作类(核心:建表、插数、查询的具体实现)** **语法转换与错误修正类(核心:跨数据库语法适配、建表 / 查询错误修复)** ### (四)MySQL 查询与 SQL 语法类 #### 1. 语法报错 * 先查关键字 / 命令格式:确认命令结构完整无多余空格、关键字拼写正确、标点为英文格式; * 再查对象名匹配性:核对表 / 字段名与数据库实际结构一致,别名在查询中已定义且作用域正确,含特殊字符的对象名用反引号包裹; * 最后查查询结构逻辑:确保 SELECT/FROM/WHERE/GROUP BY 等子句完整,GROUP BY 与 SELECT 字段匹配,子查询返回结果符合关联要求。 **(1)关键字 / 命令格式错误(语法规则违反)** **① 命令关键字空格 / 拼写错误** **示例:** SHOW SLAVE Hosts; 报错(多余空格 + 关键字小写)、show database user 报错(语法结构错误)。 **原因:**MySQL 关键字需遵循固定格式:无多余空格、命令结构完整(如查看用户需 SELECT user FROM mysql.user,而非 show database user),且关键字大小写不敏感但格式需规范。 **② 标点符号错误** **示例:** 字段列表多逗号(如 SELECT id, name, FROM student)、中文标点(如用 "," 代替 ","、"()" 代替 "()")、占位符 / 括号不匹配。 **原因:**MySQL 仅识别英文标点,且语法解析对 "逗号、括号" 敏感 。 多逗号会导致解析中断,中文标点被判定为非法字符,最终触发 1064 语法错。 **③ 注释特殊字符干扰** **示例:** 注释中含 # -- 外的特殊字符(如 /\* 注释内容@# \*/)导致 SQL 解析失败。 **原因:**MySQL 注释格式有严格限制(# 单行注释、-- 单行注释需加空格、/\* \*/ 多行注释),注释内若含未转义的特殊字符,可能被误认为 SQL 语句一部分,引发解析错误。 **(2)对象名(表 / 字段 / 别名)错误(标识符无法识别)** **① 字段名拼写 / 格式错误** **示例:** "查卖笔记本商店 ID" 报错(实际字段为 ID,写为 "商品 ID" 含空格)、Unknown column 's. 商店 ID'(字段名含空格未用反引号包裹)。 **原因:**字段名若含空格、特殊字符(如中文),需用反引号 \` 包裹(如 \`商店 ID\`);直接写 "商品 ID" 会被 MySQL 拆分为 "商品" 和 "ID" 两个未知字段,触发 1054 未知列错误。 **② 表 / 别名未定义 / 不匹配** **示例:** 表别名未定义(如 SELECT t.name FROM student 中 t 未关联表)、子查询用外部表别名(如子查询中用 t.TID,但 t 是外部查询的表别名,子查询内未定义)、子查询改原表名仍报错(如未关联 tutors 表却用其字段)。 **原因:**表别名需在 FROM/JOIN 中定义(如 FROM tutors t),且作用域仅限当前查询层级 ------ 子查询无法直接使用外部查询的别名,未关联的表其字段也无法被识别,均会触发 1054 错误。 **③ 字段 / 表名混淆** **示例:** "查卖笔记本商店 ID" 中,误将 "商品表" 字段写为 "商店表" 字段(如实际商品表存商品类型,却从商店表查 "笔记本" 相关字段)、表名拼写错(如 FROM studnet 代替 student)。 **原因:**查询时引用的表 / 字段与实际数据库结构不匹配,MySQL 无法在指定表中找到对应字段,或无法找到指定表,导致报错。 **(3)查询结构不完整 / 逻辑错误(语法逻辑违反)** **① 查询核心子句缺失** **示例:** 查询结构缺 FROM(如 SELECT id, name WHERE age\>18)、子查询缺 FROM(如 SELECT (SELECT name WHERE id=1))。 **原因:**SELECT 查询需 FROM 子句指定数据来源表(除非是无表查询如 SELECT 1+1),缺失 FROM 会导致 MySQL 无法定位数据,直接报错。 **②GROUP BY 用法错误** **示例:** GROUP BY 单独使用(无 SELECT 对应字段)、未按非聚合字段分组(如 SELECT t.TID, t.Tname, SUM(score) FROM test GROUP BY t.TID,缺 t.Tname 分组)、HAVING 子句处理不当(如 HAVING score\>90 中 score 未聚合且非分组字段)。 **原因:**MySQL 开启 ONLY_FULL_GROUP_BY 模式时,SELECT 中非聚合字段必须全部在 GROUP BY 中;GROUP BY 需配合 SELECT 聚合 / 分组字段使用,单独使用或字段不匹配会触发语法错,且可能导致结果逻辑错误(如未分组字段返回随机值)。 **③ 子查询逻辑错误** **示例:** 子查询 HAVING 子句返回多列(如 SELECT \* FROM student WHERE EXISTS (SELECT id, name FROM score HAVING avg\>80))、子查询结果与外部查询不匹配(如用 = 关联返回多列的子查询)。 **原因:**HAVING 子句用于过滤分组结果,需配合 GROUP BY 且返回单值;子查询若用 = 与外部字段关联,需确保子查询仅返回一列一行,多列 / 多行会导致语法解析失败。 #### 2. 查询逻辑与结果异常 **(1)索引使用异常:联合索引失效** 核心是未遵循联合索引的使用规则,导致索引无法生效、查询效率下降。 当联合索引(如`idx_col1_col2_col3`)遇到以下情况时会失效: * 未遵循 "最左前缀原则"(如仅用右侧列`col2`/`col3`过滤,跳过左侧`col1`); * 对索引列使用函数(如`DATE(col1)='2024-01-01'`),破坏索引结构; * 发生隐式类型转换(如索引列`col1`为`INT`,查询用`col1='123'`字符串匹配),无法匹配索引格式。 **(2)查询结果不符合预期:数据 / 条件匹配错误** 此类问题均因 "查询条件不精准" 或 "数据关联异常",导致结果与业务需求偏差,具体分两类 **① 结果范围过大(返全部 / 多余数据)** 如 "查卖笔记本商店 ID 返全部""商店 1 有铅笔库存返 1-3",本质是筛选条件未精准锁定目标: * 要么 "商品标识错误"(如笔记本 / 铅笔的 ID / 名称写错,匹配到所有商品); * 要么 "数据关联异常"(如库存表中所有商店都关联了目标商品,或未加商店 ID 筛选条件); * 或 "子查询逻辑错误"(子查询未返回有效筛选结果,导致主查询无法过滤)。 **② 结果缺失(部分数据无值)** 如 "查询部分课程无平均分",核心是左连接的特性与数据缺失共同导致: * 用 "课程表左连接成绩表" 时,若某课程在成绩表中无记录,左连接会保留课程信息,但成绩字段为NULL; * 而AVG()函数会忽略NULL,最终该课程无平均分结果,表现为 "结果缺失"。 #### **3. SQL 函数与语法知识** **(1)函数用法类** 1. **SUM 函数写法与大小写** * 写法:`SUM(列名/表达式)`,函数名与括号间可加空格(如 `SUM (price*num)`),括号内支持列名或计算表达式(如统计总金额 `SUM(price*quantity)`)。 * 大小写:MySQL 中不强制函数名大写,`SUM()` 与 `sum()` 效果一致,仅为代码规范建议大写以区分关键字。 2. **SELECT 1 返回 TRUE 与 WHERE TRUE 含义** * `SELECT 1`:查询结果返回一个值为 `1` 的单列数据,本质是返回 "逻辑真"(非空结果即代表条件成立),常用于 `EXISTS` 子查询中判断 "是否存在满足条件的记录"。 * `WHERE TRUE`:`WHERE` 子句中条件恒为真,会查询表中所有记录(类似 `WHERE 1=1`),常用于动态拼接 SQL 时避免开头多逗号的问题(如后续可灵活追加 `AND 条件`)。 **(2)条件查询与逻辑运算符类** 1. **NOT EXISTS 定义 / 语法 / 原理 / 场景** * 定义:判断子查询是否 "无满足条件的记录",若子查询返回空,则 `NOT EXISTS` 结果为 `TRUE`,否则为 `FALSE`。 * 语法:`SELECT 列 FROM 主表 WHERE NOT EXISTS (子查询);`。 * 原理:子查询不返回具体数据,仅判断 "是否存在记录",效率高于 `NOT IN`(避免 `NULL` 值影响)。 * 场景:查询 "无关联数据的记录",如 "未下单的用户"(`SELECT * FROM user u WHERE NOT EXISTS (SELECT 1 FROM order o WHERE o.user_id = u.id)`)。 2. **NOT 逻辑运算符用法** * 作用:对条件结果取反,仅作用于单个布尔条件(如 `NOT (price > 10)` 等价于 `price <= 10`)。 * 常见场景:结合 `IN`(`NOT IN`,查 "不在指定范围内的记录")、`EXISTS`(`NOT EXISTS`)、`BETWEEN`(`NOT BETWEEN`)等,如 `SELECT * FROM product WHERE NOT category IN ('文具', '玩具')`。 ### (五)ProxySQL 相关问题类 #### **ProxySQL 连接与命令报错类** **1. ProxySQL 管理端连接报错** * **问题现象** :使用 `mysql -uadmin` 连接管理端时,系统默认寻找本地 socket 文件,导致连接失败。 * **原因与解决** :ProxySQL 管理端默认监听端口 **6032** ,需显式指定端口,正确命令为 `mysql -uadmin -P6032 -h127.0.0.1`(需补充密码时加 `-p`)。 **2. mysql_server_connect_log 查询报错** * **问题现象** :查询连接日志表 `mysql_server_connect_log` 时,使用 `time_start` 或 `time` 字段提示不存在。 * **原因与解决** :该表中存储时间的字段实际名为 **time_start_us**(微秒级时间戳),需用此字段查询。 **3. stats_mysql_query_digest 查询报错** * **问题现象** :执行查询时提示 `Unknown database 'stats'`。 * **原因与解决** :`stats_mysql_query_digest` 属于 `stats` 数据库下的表,需先显式指定数据库(如 `USE stats;`),再执行查询。 #### **ProxySQL 核心配置与表结构类** **1. mysql_users 表核心字段含义** | 字段名 | 作用 | |--------------------------|-------------------------------------------------------------------------------| | `active` | 控制用户是否启用:值为 1 表示用户可用于连接 ProxySQL,0 表示禁用该用户。 | | `transaction_persistent` | 控制事务路由一致性:值为 1 时,同一事务的所有 SQL 会路由到同一后端节点,避免事务跨节点问题,与 `active`(用户启用状态)无关联,需区分开。 | **2. ProxySQL 用户与主库用户关系** * **核心规则** :ProxySQL 中配置的用户(`mysql_users` 表),其用户名、密码需与后端主库的用户 **完全一致**。 * **影响**:若不一致,ProxySQL 转发连接请求时会因主库身份验证失败,导致客户端连接报错。 **3. ProxySQL 不支持的操作** * 不支持 `DESCRIBE` 命令:查看表结构需用 `SHOW COLUMNS FROM 表名;` 替代。 * 无 `information_schema.columns` 表:ProxySQL 不兼容 MySQL 原生的 `information_schema` 库,需通过 `SHOW COLUMNS` 查看字段信息。 **4. 不同 LOAD/SAVE 命令区别** * 作用:用于将配置在 "磁盘文件""运行时内存""管理端内存" 间同步,对应不同配置模块: * 规则类(如 `mysql_query_rules`):`LOAD MYSQL QUERY RULES FROM DISK/RUNTIME`;`SAVE MYSQL QUERY RULES TO DISK/RUNTIME`; * 变量类(如全局变量):`LOAD MYSQL VARIABLES FROM DISK/RUNTIME`;`SAVE MYSQL VARIABLES TO DISK/RUNTIME`; * 管理配置(如 `mysql_users`):`LOAD MYSQL USERS FROM DISK/RUNTIME`;`SAVE MYSQL USERS TO DISK/RUNTIME`。 #### ProxySQL 路由与查询分析类 **1. 路由规则修改问题** * **问题场景** :向 `mysql_query_rules` 表插入路由规则后发现错误(如规则条件写错)。 * **解决方式** :ProxySQL 无 "修改规则" 的直接命令,需先通过 `DELETE FROM mysql_query_rules WHERE 条件;` 删除错误规则,或用 `UPDATE` 修正字段值,再执行 `LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;` 生效。 #### MySQL 从库问题类 1、从库 IO 线程启动失败(Slave_IO_Running: No) * **问题现象** :查看从库状态(`SHOW SLAVE STATUS\G`)时,`Slave_IO_Running` 字段值为 No,IO 线程未启动。 * **常见原因** :`master_log_file` 配置错误,即从库指定的主库二进制日志文件名前缀错误(如主库实际日志为 `mysql-bin.000001`,从库误写为 `master-bin.000001`)。 * **解决方向** :重新在从库执行 `CHANGE MASTER TO` 命令,指定正确的 `master_log_file` 和 `master_log_pos`(主库当前日志位置),再启动从库线程(`START SLAVE;`)。 ### (六)版本差异类 MySQL 5.X(以 5.7 为代表)与 8.0 在**用户创建** 和**授权**上的核心区别,主要源于 8.0 对权限管理逻辑的重构(更严格的权限分离、默认加密升级等),具体可从 4 个关键维度简单解释: **1. 操作逻辑:"创建用户" 与 "授权" 是否可合并** * **MySQL 5.X** :支持 "创建用户" 与 "授权" 合并为一条命令,无需先单独创建用户。 示例:直接通过授权语句自动创建用户(若用户不存在) -- 5.X 支持:创建 test 用户并授权,无需提前 CREATE USER GRANT SELECT ON db1.* TO 'test'@'localhost' IDENTIFIED BY '123456'; * **MySQL 8.0** :强制 "先创建用户,再授权",不允许通过 `GRANT` 直接创建用户(`IDENTIFIED BY` 无法在 `GRANT` 中使用)。 示例:必须分两步执行 -- 8.0 必须先创建用户 CREATE USER 'test'@'localhost' IDENTIFIED BY '123456'; -- 再执行授权 GRANT SELECT ON db1.* TO 'test'@'localhost'; **2. 默认认证插件:密码加密方式不同** * **MySQL 5.X** :默认使用 `mysql_native_password` 插件,密码加密算法较简单(基于 SHA-1)。 (若需兼容旧客户端,5.X 通常无需额外配置插件) * **MySQL 8.0** :默认使用 `caching_sha2_password` 插件,密码加密算法更安全(基于 SHA-256),但可能存在**旧客户端兼容问题** (如低版本 Navicat、JDBC 驱动)。 若需兼容 5.X 客户端,需手动指定旧插件: -- 8.0 创建兼容 5.X 的用户(指定 mysql_native_password) CREATE USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; **3. 权限回收:`REVOKE` 对 "隐式创建用户" 的处理** * **MySQL 5.X** :若用户是通过 `GRANT` 隐式创建的(未手动 `CREATE USER`),执行 `REVOKE ALL` 后,用户会被**自动删除**(因无独立用户记录)。 * **MySQL 8.0** :因强制 "先创建用户",用户是独立存在的,`REVOKE` 仅回收权限,**不会删除用户** ;需单独执行 `DROP USER` 才能删除用户。 **4. 角色功能:官方角色支持差异** * **MySQL 5.X**:无官方 "角色" 功能(无法创建角色并批量授权),若需批量管理权限,需手动维护相同权限的用户,操作繁琐。 * **MySQL 8.0** :新增**官方角色功能** ,可创建角色、给角色授权,再将角色赋予用户,简化批量权限管理。 示例: -- 8.0 创建角色并授权 CREATE ROLE 'read_role'; -- 创建角色 GRANT SELECT ON db1.* TO 'read_role'; -- 给角色授权 GRANT 'read_role' TO 'test'@'localhost'; -- 将角色赋予用户