从MariaDB迁移至MySQL社区版后授权用户报错1805求助
解决MySQL 5.6迁移后
mysql.user表列数不匹配的问题 这个报错我之前帮同事处理过,核心原因就是MariaDB和MySQL的系统表结构存在差异——MariaDB的mysql.user表比MySQL 5.6多了2列,直接还原MariaDB的备份就会导致结构不兼容,执行授权操作时就触发了这个错误。下面是一步步的可靠修复方案:
步骤1:先备份关键数据,避免翻车
不管做什么操作,先把存储所有用户权限的核心库mysql备份好,以防操作失误丢失权限数据:
mysqldump -u root -p mysql > mysql_system_db_backup.sql
输入root密码后等待备份完成,把这个文件存到安全的位置。
步骤2:运行MySQL自带的修复工具mysql_upgrade
这个工具就是专门用来处理版本迁移或升级后系统表结构不匹配的问题,它会自动检查并修复mysql库下的所有系统表:
mysql_upgrade -u root -p
执行时会要求输入root密码,耐心等待工具运行完成,它会输出修复的日志信息,留意有没有错误提示。
步骤3:重启MySQL服务
修复完成后,必须重启服务让修改生效:
# CentOS/RHEL 7+ 系统 systemctl restart mysqld # Debian/Ubuntu 系统 service mysql restart
步骤4:验证修复结果
登录MySQL,检查mysql.user表的列数是否正确:
mysql -u root -p USE mysql; SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
如果返回结果是43,说明修复成功了,现在再尝试给新用户授权就不会报错了。
备选方案:手动修复(如果mysql_upgrade失效)
如果上面的方法没起作用,可以手动重建user表结构,但这个操作要非常小心:
- 先导出所有用户的权限数据:
-- 导出用户创建语句 SELECT CONCAT("CREATE USER '", user, "'@'", host, "' IDENTIFIED BY PASSWORD '", authentication_string, "';") FROM mysql.user; -- 导出用户授权语句 SELECT CONCAT("GRANT ", GROUP_CONCAT(DISTINCT CONCAT(privilege_type, " ON *.*")), " TO '", user, "'@'", host, "';") FROM mysql.user JOIN mysql.db ON user.user = db.user AND user.host = db.host GROUP BY user, host;
把这些查询结果复制出来,保存成一个SQL文件,这就是所有用户的权限配置。
- 删除旧的
user表,重新创建符合MySQL 5.6结构的user表:
DROP TABLE mysql.user;
执行下面的标准MySQL 5.6 user表创建语句:
CREATE TABLE `user` ( `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '', `ssl_cipher` blob NOT NULL, `x509_issuer` blob NOT NULL, `x509_subject` blob NOT NULL, `max_questions` int(11) unsigned NOT NULL DEFAULT '0', `max_updates` int(11) unsigned NOT NULL DEFAULT '0', `max_connections` int(11) unsigned NOT NULL DEFAULT '0', `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0', `plugin` char(64) COLLATE utf8_bin NOT NULL DEFAULT '', `authentication_string` text COLLATE utf8_bin NOT NULL, `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';
- 最后运行之前导出的用户权限SQL脚本,恢复所有用户的权限。
注意事项
- 生产环境操作前一定要先在测试环境验证一遍流程,避免影响业务。
- 如果操作中遇到权限问题,可以临时用
mysqld_safe --skip-grant-tables &启动MySQL,跳过权限校验进行修复,但修复完成后一定要关闭这个参数并重启服务。
内容的提问来源于stack exchange,提问作者Hadrien Huvelle
相关产品推荐
相关产品推荐

