免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

MySQL 8.0.44升级登录报错1805:系统表MyISAM转InnoDB修复指南

MySQL 8.0.44升级登录报错1805:系统表MyISAM转InnoDB修复指南 1. 问题背景升级8.0.44后直接登录失败到底发生了什么先描述一下这个报错的实际场景。假设你的环境原本是MySQL 5.7或更早版本通过某种方式原地升级、逻辑迁移或冷备恢复切换到8.0.44之后执行mysql -uroot -p输入密码回车结果直接弹出一行日志级别的错误内容类似ERROR 1805 (HY000): Function mysql_native_password is deprecated. The server is not running with the system tables using the MyISAM storage engine.实际上8.0.44的登录报错在终端里看起来更直接一些MySQL服务可能仍然在运行但任何账号都无法通过正常通道登录。有的朋友打算用mysqld --skip-grant-tables先绕过认证结果进去之后发现mysql库里的表全都坏了想改密码、改权限、创建用户全部报同样的MyISAM错误。先说结论这不是密码错误也不是认证插件配置错误而是系统表mysql库下的表比如user表、db表、tables_priv表等的存储引擎结构和8.0.44版本的服务端程序预期不一致。升级过程中系统表没有被正确迁移到InnoDB或者部分表仍然保留了MyISAM物理结构导致8.0.44的代码在访问这些表时直接拒绝执行。群里很多人遇到这个问题第一反应是把data目录重新初始化这确实能解决但代价是你原来的用户、权限、所有库表数据可能全部丢失而且数据目录重新初始化之后还需要手动重建所有账号和授权。对于一个生产环境来说这是非常痛苦的一条路。这篇博文我会把问题拆开讲清楚把背后的原理、安全修复步骤、以及如何避免下次升级再踩同样的坑全部过一遍。2. 为什么MySQL 8.0.44对系统表的存储引擎这么敏感2.1 从MySQL 5.7升级而来的历史包袱MySQL 5.7及之前的版本系统表mysql库默认使用MyISAM存储引擎。用户表、权限表、日志表几乎都是MyISAM。这个设计在早期版本里问题不大因为MyISAM结构简单、读取快、占用内存少但它的短板也很明显不支持事务、不支持行级锁、崩溃后容易损坏。到了MySQL 8.0官方彻底改变了策略把所有系统表统一改成InnoDB并且在代码层面做了硬性检查——服务端启动时、访问授权表时都会检查这些表的结构类型。如果检查到系统表还是MyISAM就拒绝在这个表上执行任何操作哪怕这个操作只是登录验证。8.0.44这个版本更加严格它甚至在MySQL Server启动阶段就检查mysql库下的表引擎元数据。如果你的data目录是从5.7直接拷贝过来的或者升级过程中mysql_upgrade这一步没有正确执行系统表就依然是MyISAM结构。这个时候服务端可能能启动因为--daemonize启动的进程不一定立刻访问授权表但当你尝试登录时服务端读取mysql.user表发现这个表不是InnoDB直接抛出错误。2.2 MySQL 8.0把插件和参数也绑定到了系统表结构上这里还有一个容易被忽视的细节MySQL 8.0默认的认证插件是caching_sha2_password而5.7时代普遍用的是mysql_native_password。8.0.44版本里官方对mysql_native_password做了弃用标记但兼容模式仍然是可用的前提是系统表结构正确升级到InnoDB。我自己在测试环境里模拟过一次把5.7.42的data目录整体拷贝到8.0.44的datadir路径下然后启动8.0.44服务端日志里会出现一条警告[Warning] [MY-010901] [Server] The mysql_native_password authentication plugin is deprecated. Please consider using caching_sha2_password instead.这条警告一般不会阻止登录但如果mysql.user表还是MyISAM8.0.44就会把登录流程卡死在验证阶段错误信息里明确出现system tables和MyISAM这两个关键词。另外8.0.44里如果启用了mysql_native_passwordON这类参数而又碰上了系统表不一致错误信息还会额外提示Function mysql_native_password is deprecated导致很多人误以为是密码插件问题结果去改default_authentication_plugin改完依然登录失败白白浪费时间。2.3 正确理解系统表不支持MyISAM存储引擎这句话很多运维朋友看到报错里的不支持三个字第一反应是MySQL 8.0.44不支持MyISAM了。这话不完全对。MySQL 8.0.44仍然支持MyISAM存储引擎你完全可以在自己的业务库里建MyISAM表虽然我不建议这么做只是系统表mysql库下的表不允许再使用MyISAM。也就是说这个限制是针对系统表这一类特殊的表不是针对MyISAM这个引擎本身。打个比方一个公司规定核心资产必须存放在保险柜里结果你从旧办公室搬过来时把核心资产放在普通储物柜里就搬进去了。保安MySQL服务端检查后发现储物柜不符合规定于是拒绝让你使用保险柜里的任何东西。储物柜本身不是违禁品你自家的东西放储物柜没问题但核心资产系统表必须进保险柜InnoDB。所以我后面给的解决方案里有一条核心思路就是把普通储物柜里的东西全部搬进保险柜——也就是把mysql库下所有MyISAM表改成InnoDB。3. 三种解决思路从保守到彻底你自己选3.1 方案一用skip-grant-tables临时进入原地转换系统表引擎这是最保守、数据最不折腾的方案前提是你的data目录必须是完全拷贝自5.7或者升级过程没有损坏文件。操作步骤如下第一步先停掉MySQL服务。用systemd管理的话systemctl stop mysqld或者老一点的init脚本/etc/init.d/mysql stop第二步确认没有残留进程ps aux | grep mysqld有残留就kill掉否则后面改表的时候会锁冲突。第三步修改配置文件/etc/my.cnf在[mysqld]段加入跳过授权表参数skip-grant-tables同时为了让8.0.44能容忍旧的插件配置建议再加一行mysql_native_passwordON这个参数在8.0.44里可能已经不生效版本越新弃用越彻底但加上的影响不大至少不会因为插件问题多一道坎。实测中8.0.44里这个参数会被识别为未知变量并给出警告但不影响跳过授权表的方式启动。第四步启动MySQL服务然后不输入密码直接登录systemctl start mysqld mysql -uroot这个时候已经能进到MySQL命令行里了。但因为系统表还是MyISAM你执行任何ALTER USER、CREATE USER、GRANT操作都会报错。我们需要做的是把mysql库下所有MyISAM表全部改成InnoDB。登录后执行SELECT table_name, engine FROM information_schema.tables WHERE table_schema mysql;这条语句会列出mysql库下所有表及它们的存储引擎。正常情况下5.7迁移过来的环境里user、db、tables_priv、columns_priv、procs_priv、proxies_priv、servers、func、event、slow_log、general_log这堆表应该都是MyISAM或CSV后两个日志表默认是CSV也有部分表可能是InnoDB比如innodb_table_stats、innodb_index_stats。对所有MyISAM表执行转换可以写一个存储过程批量操作也可以手动一条条执行。我这边给一个比较稳妥的SQL拼接写法不会写存储过程的直接用这个SELECT CONCAT(ALTER TABLE mysql., table_name, ENGINEInnoDB;) FROM information_schema.tables WHERE table_schema mysql AND engine MyISAM;这个查询的结果是一组ALTER TABLE语句复制出来逐条执行即可。注意slow_log和general_log这两张日志表默认引擎可能是CSVCSV不支持转换为InnoDB但日志表不属于授权类系统表8.0登录时不会强制要求它们用InnoDB所以可以跳过。第五步确认所有授权关键表都已经是InnoDB后先退出MySQL把配置文件里的skip-grant-tables注释掉再重启服务恢复正常登录。这里有一个重要的细节一定要在重启之前把skip-grant-tables去掉。否则你重启之后每次登录都不需要密码任何人都可以直接进入风险极高。3.2 方案二保留旧数据原地重新初始化系统库推荐这个方案是实际生产环境里最推荐的做法。它比方案一更干净因为方案一只是改引擎而如果升级过程中某些系统表的数据本身已经损坏了比如5.7的mysql.user表某些行结构异常光是改引擎可能不够登录时还是会报别的错。方案二的思路是保留你的业务数据也就是information_schema里除了mysql库之外的其他数据库但把mysql库完全丢弃让8.0.44重新生成一套全新的系统表。操作步骤第一步停掉MySQL服务备份data目录下所有业务库的数据文件。如果你不知道业务库有哪些先看目录结构ls -l /var/lib/mysql/除了mysql、performance_schema、sys、information_schema这个不落盘之外其他目录基本就是你的业务库。把这些目录全部复制到备份路径cp -rp /var/lib/mysql/mydb /backup/mydb注意-p参数保留权限属主否则恢复时MySQL进程可能因为文件属主不对而拒绝读取。第二步把旧的mysql系统库目录删掉或者整个datadir备份后清空再新建一个空datadir。推荐后者因为你无法确定哪些系统表文件还残留着mv /var/lib/mysql /var/lib/mysql_bak_$(date %F) mkdir -p /var/lib/mysql chown mysql:mysql /var/lib/mysql chmod 750 /var/lib/mysql第三步用mysqld初始化新的数据目录mysqld --initialize-insecure --usermysql --datadir/var/lib/mysql--initialize-insecure表示初始化时root账号无密码方便后续登录。如果不想裸奔可以用--initialize它会在日志里生成一个临时密码但后面登录要先去日志里找密码稍微麻烦一点。实际运维里我经常先用insecure初始化进去改完密码再锁权限。第四步启动MySQL服务确认能正常登录systemctl start mysqld mysql -uroot这个时候你登录的是全新的mysql系统库8.0.44会自动建好所有InnoDB系统表登录流程完全正常。第五步把业务数据目录复制回新datadir。复制之前先确认新datadir下的路径结构cp -rp /backup/mydb /var/lib/mysql/mydb chown -R mysql:mysql /var/lib/mysql/mydb注意业务库目录下如果有*.frm、*.ibd文件拷贝回来后MySQL需要在启动时重新识别表结构。8.0.44直接读数据字典data dictionary里的元数据但如果你的业务库表是5.7版本创建的InnoDB表8.0可以自动识别因为InnoDB表的物理格式在5.7到8.0之间是兼容的。如果你的业务表是MyISAM8.0也完全支持读取前面讲过MyISAM本身没有被移除所以不用担心。第六步重启MySQL检查所有业务表是否可见SHOW DATABASES; USE mydb; SHOW TABLES; SELECT COUNT(*) FROM your_table;这个方法的核心逻辑就是用一个全新的8.0.44系统表环境去承载旧业务数据绕开升级过程中任何系统表层面的脏状态。我多次用这个方法救过线上环境比任何修补方式都可靠。3.3 方案三完整逻辑迁移适合有时间重建权限的场景如果你的环境允许停机时间足够长或者你手头有mysqldump导出的SQL备份那么方案三更省心——完全抛开旧data目录直接用SQL文件重建整个实例。操作流程从5.7环境导出业务数据排除mysql库和sys库mysqldump -uroot -p --single-transaction --set-gtid-purgedOFF --databases mydb1 mydb2 all_business.sql初始化8.0.44数据目录同上一步的--initialize-insecure。导入业务数据mysql -uroot -p all_business.sql手动重建所有业务账号和授权因为系统表是全新的之前所有账号都不在了。这个方案的缺点非常明显权限体系需要全部重建而且如果有大量存储过程、触发器、定时事件导入时需要额外确认兼容性。5.7的存储过程在8.0.44里有可能因为字符集或sql_mode差异而创建失败。但优点是系统表绝对干净后续不会再出现任何MyISAM相关问题。4. 登录报错背后的底层逻辑授权表被硬编码校验4.1 MySQL 8.0的授权表读取链路MySQL 8.0把授权信息从MyISAM表改成了内存InnoDB双层结构。你执行登录时服务端会经历这样一条链路客户端发送用户名、密码、目标库。服务端在内存中的账号缓存里查找用户是否存在。这个缓存是从mysql.user表加载过来的。如果缓存没有命中服务端直接去读mysql.user表。读表时服务端会检查这个表的存储引擎是否在允许列表里。8.0的允许列表只有InnoDB实际上还会检查表的row format、collation等属性。检查不通过返回错误。实际代码里这个检查是通过数据字典层完成的。MySQL 8.0引入了新的数据字典Data Dictionary系统表的元数据不再存放在.frm文件里而是统一由数据字典表管理。数据字典表本身在InnoDB存储引擎下有一个独立表空间mysql.ibd这个文件在你5.7的data目录里是不存在的。升级后如果系统表文件还是5.7的老结构没有对数据字典做转换那么8.0.44启动时倒不至于直接崩溃但访问授权表时会发现元数据映射不上进而报错。这也就解释了为什么单纯改default_authentication_plugin没有用——问题根本不在插件而在系统表结构。4.2 general_log和slow_log也需要特殊关注有时候系统表引擎列表里除了mysql.user、mysql.db还会出现mysql.slow_log和mysql.general_log。这两张表在5.7和8.0里默认都是CSV引擎但它们的特殊性在于CSV引擎不允许索引也不能直接ALTER到InnoDB。如果你在方案一里尝试转换这两张日志表会报错ERROR 1067 (42000): Invalid default value for event_time或者ERROR 1846 (HY000): Cannot change column event_time: used in a generated column实际上你不用管它们因为登录校验用不到日志表。真正必须转成InnoDB的是下面这张表清单表名用途不转换的后果user用户账号和密码登录直接失败db库级权限登录后选择数据库失败tables_priv表级权限操作具体表时报权限错误columns_priv列级权限精细权限不可用procs_priv存储过程权限调用存储过程失败proxies_priv代理用户权限代理认证失败servers联邦服务器信息FEDERATED引擎不可用func自定义函数函数注册失败event定时事件事件调度器报错建议在转换前先只对这张表清单执行ALTER TABLE ... ENGINEInnoDB转换完成后再核对剩余表。多余的表里如果有MyISAM残留大多数不影响登录但为了干净能转的尽量转。4.3 为什么单独设置mysql_native_password不能解决问题网上很多教程让你在my.cnf里加default_authentication_pluginmysql_native_password这个参数在5.7时代有效因为当时认证插件可以从配置层面全局指定。但到了8.0.44这个参数已经被移除或者只是作为兼容参数存在。即便你用--default-authentication-pluginmysql_native_password启动服务端在读取mysql.user表时依然会先做存储引擎校验MyISAM表这个坎过不去后面的认证插件选择根本轮不到执行。我做过一个小实验在一台干净的8.0.44实例上把mysql.user表改成MyISAM然后再设置default_authentication_pluginmysql_native_password重启服务登录报错依旧。所以如果你遇到了这个问题不要浪费时间在这个参数上直接进入系统表转换流程。5. 升级前的防御策略如何避免下一次踩坑5.1 升级前必须执行的检查和备份写到这里我认为最有价值的部分不是报错后怎么修而是怎么在升级前就知道会出问题。在从5.7升级到8.0.44之前你要先检查组件的兼容性。MySQL官方提供了一个升级检查工具mysqlcheck在5.7版本中内置mysqlcheck -uroot -p --all-databases --check-upgrade这个命令会扫描所有表并尝试检测是否有8.0不兼容的结构。如果输出里有Status: OK说明表结构层面没有大的问题。但注意mysqlcheck在5.7版本里对系统表的引擎检查并不严格它不会主动提示MyISAM系统表升级后会失败。更可靠的方法是手动检查mysql库下所有表的引擎SELECT table_name, engine FROM information_schema.tables WHERE table_schema mysql ORDER BY table_name;只要发现任何授权表user、db、tables_priv、columns_priv、procs_priv等是MyISAM升级前就应该用方案一的ALTER语句把它们转成InnoDB在5.7环境里先完成转换再做升级。这比升级到8.0之后再处理要安全得多。5.2 升级方法的选择原地升级 vs 逻辑迁移原地升级就是直接用高版本mysqld启动旧datadir对系统表的转换要求最高。MySQL官方提供了一条升级路径5.7的mysqld在首次启动时会自动执行升级脚本把系统表从MyISAM迁移到InnoDB。但这个自动迁移动作并不可靠特别是在特殊字符集、sql_mode配置、旧数据损坏等情况下很容易做到一半中断。相对稳定的方式是逻辑迁移在5.7实例上导出业务数据和权限数据。全新安装8.0.44。手工导入数据。手工重建权限。这种方式虽然繁琐但每一步都有回滚余地不会出现系统表停在半迁移状态这种尴尬局面。5.3 定期检查系统表健康状态即使你不做跨大版本升级8.0.44运行一段时间后也可能因为异常断电、磁盘空间满、表损坏等导致系统表出问题。建议把下面这条命令写进巡检脚本mysqlcheck -uroot -p --systemmysql --check它能快速检查mysql库下所有表的完整性任何存储引擎层面的异常都会在输出里显示。如果发现某个授权表报错别等它变成登录故障趁早修复。6. 实操复盘一次完整的修复记录6.1 模拟故障环境我做了一个模拟环境专门复现这个问题。环境信息如下源环境MySQL 5.7.44CentOS 7.9datadir路径/var/lib/mysql目标环境MySQL 8.0.44CentOS 7.9未初始化datadir先把5.7的整个data目录打包复制到8.0.44环境的临时目录tar -czf mysql57_data.tar.gz /var/lib/mysql scp mysql57_data.tar.gz rootnewserver:/tmp/在8.0.44服务器上解压mkdir -p /tmp/mysql57_data tar -xzf /tmp/mysql57_data.tar.gz -C /tmp/mysql57_data然后把解压后的数据目录挪到MySQL 8.0.44的默认datadirrm -rf /var/lib/mysql/* cp -rp /tmp/mysql57_data/var/lib/mysql/* /var/lib/mysql/ chown -R mysql:mysql /var/lib/mysql启动服务systemctl start mysqld查看日志tail -100 /var/log/mysql/error.log日志里能看到[ERROR] [MY-011036] [Server] Table mysql.user is not in the right format. [ERROR] [MY-010946] [Server] Failed to initialize ACL. [ERROR] [MY-010954] [Server] Aborting有些场景下服务端直接Aborting有些场景服务端能启动但无法登录区别在于日志表是否能被正常加载。我的模拟环境属于后者——服务端进程存活但任何登录尝试都失败。6.2 使用skip-grant-tables完成系统表转换参照前面方案一的步骤我在/etc/my.cnf中添加[mysqld] skip-grant-tables重启MySQLsystemctl restart mysqld mysql -uroot进到MySQL命令行后执行引擎查询SELECT table_name, engine FROM information_schema.tables WHERE table_schemamysql;结果里user、db、tables_priv等表全部显示MyISAM。然后拼接ALTER语句SELECT CONCAT(ALTER TABLE mysql., table_name, ENGINEInnoDB;) FROM information_schema.tables WHERE table_schemamysql AND engineMyISAM AND table_name NOT IN (slow_log, general_log);执行输出的每一条ALTER语句直到所有授权表都变成InnoDB。这个过程在模拟环境里大概2分钟跑完因为mysql库表数据不大。改表结束后我又额外执行了一条刷新授权缓存命令FLUSH PRIVILEGES;这条命令在skip-grant-tables模式下可以执行但只影响内存里的缓存不影响磁盘结构。不过执行一下无妨确保下一步登录时ACL缓存不是旧状态。然后退出把my.cnf里的skip-grant-tables注释掉重启服务systemctl restart mysqld mysql -uroot -p这次正常轮到密码验证了。输入原账号密码成功登录。6.3 模拟环境的差异化表现skip-grant-tables模式下的坑在skip-grant-tables模式里有一个行为需要特别提醒在这种模式下任何账号只要用户名匹配就能登录密码验证被完全绕过。所以如果你在会话里执行了ALTER USER rootlocalhost IDENTIFIED BY newpassword;有时不生效因为服务端处于skip模式时不会更新认证相关的缓存。正确的做法是不要在skip模式下尝试改密码把所有系统表引擎转换做完之后退出、恢复配置、正常登录再用ALTER USER修改密码。如果你在skip模式下改密码而且服务端竟然成功执行了那么等正常重启后这个新密码可能有效也可能因为缓存和磁盘数据不同步而显示为旧密码。为了避免这种混乱强烈建议skip模式只做表结构变更不做任何账号和密码操作。7. 常见问题与排查技巧实录7.1 常见问题速查表症状可能原因处理方式登录报错包含MyISAM、system tables关键词系统表未升级到InnoDBskip-grant-tables进入批量ALTER表引擎升级后服务启动即崩溃日志显示ACL初始化失败mysql.user表损坏或格式不兼容备份业务库后重新初始化datadir登录成功但SELECT业务数据表报错业务表本身结构或数据文件损坏用mysqlcheck检查业务库必要时从备份恢复个别表执行ALTER TABLE mysql.user ENGINEInnoDB时报权限错误skip-grant-tables未生效确认配置文件无语法错误重启服务修改密码后依然登录失败skip模式下改密码导致缓存不一致重启服务再次走正常登录流程重新ALTER USER8.0.44登录报错同时出现deprecated plugin提示mysql_native_password被标记弃用不影响登录前提下忽略若影响改用caching_sha2_password插件7.2 一个容易忽视的细节默认认证插件切换升级完成后登录虽然成功了但在8.0.44里新创建的用户默认使用caching_sha2_password认证插件。如果你的客户端是旧版本比如5.7时代的PHP mysqli扩展、老版本Navicat、部分JDBC驱动可能出现能连接但认证失败的情况。这时需要在MySQL端给对应账号修改插件ALTER USER appuser% IDENTIFIED WITH caching_sha2_password BY password;或者允许旧插件除非必要不建议ALTER USER appuser% IDENTIFIED WITH mysql_native_password BY password;注意mysql_native_password插件在8.0.44里仍然存在但官方已经不推荐。新客户端建议直接适配caching_sha2_password。7.3 备份文件里的MyISAM表也要检查还有一类隐蔽场景你从5.7导出了mysqldump备份文件然后在8.0.44里导入。这种情况下系统表是新的InnoDB登录没问题但备份文件里的业务表可能带有ENGINEMyISAM创建语句。8.0.44支持这些表所以能正常导入但后续如果在这些表上做ALTER操作可能遇到一些与MySQL 8.0严格模式相关的兼容性问题。建议导入后对关键表执行一次OPTIMIZE TABLE your_table;这能重新整理表碎片和索引同时在8.0.44里把这些表彻底纳入新的数据字典管理。7.4 如何快速判断系统表是否需要修复提供一个快速判断命令不需要进入MySQLls -l /var/lib/mysql/mysql/*.ibd | head -20如果mysql目录下没有user.ibd、db.ibd这些文件而只有user.MYD、user.MYI说明系统表还是MyISAM物理文件。这种状态下8.0.44几乎必然会出登录问题。如果mysql目录下只有mysql.ibd这个单独文件8.0的数据字典表并且能看到user.ibd、db.ibd等单独的InnoDB表空间文件说明系统表已经正常在InnoDB下运行。7.5 不建议用的两种土办法网上有些人会建议直接把5.7的data目录里的user.MYD和user.MYI文件删掉让8.0重建。这个方案我强烈反对因为删掉授权表文件之后8.0.44在启动时可能直接宕掉而不是自动重建。MySQL 8.0的系统表重建只能通过初始化流程完成不支持无文件自动创建。还有人建议用REPAIR TABLE mysql.user来修复这在MyISAM表时代有效但8.0.44的授权表已经是InnoDB引擎而且REPAIR在InnoDB表上只是重建统计信息不能解决存储引擎不匹配的问题。所以看到这个建议直接跳过。8. 修复完成后的验证清单系统表转换完成、登录恢复正常之后我建议做一轮完整的验证避免隐藏问题影响后续业务。第一检查所有系统表引擎SELECT table_name, engine FROM information_schema.tables WHERE table_schemamysql AND engine NOT IN (InnoDB, CSV, MyISAM);正常情况下这个查询返回空集。如果有返回说明还有残留表需要处理。第二验证权限操作CREATE USER test_upgradelocalhost IDENTIFIED BY Temp1234!; GRANT SELECT ON *.* TO test_upgradelocalhost; SHOW GRANTS FOR test_upgradelocalhost; DROP USER test_upgradelocalhost;这一串操作在旧系统表环境下都是报错的现在应该全部正常执行。第三检查caching_sha2_password插件是否可用SELECT plugin, status FROM information_schema.plugins WHERE plugin_name caching_sha2_password;状态应为ACTIVE。如果显示DISABLED需要检查配置文件里是否有skip_ssl或者插件加载异常。第四确认数据字典状态SELECT * FROM performance_schema.dict_object_count;或者用官方更直接的命令mysqlcheck -uroot -p --check-upgrade --all-databases输出里应该看不到任何error级别的内容。9. 个人实操中的几点体会MySQL 8.0.44对系统表存储引擎的严格要求本质上是把数据库的基础设施推向更可靠的方向。MyISAM作为系统表引擎的服役年限足够久了它简单高效但不适合承载认证和权限这类高并发、强一致性的关键数据。InnoDB的事务能力和崩溃恢复能力才是系统表在断电、磁盘故障等场景下保命的根本。我在处理过多起类似问题后团队里已经形成了一条铁律任何跨大版本升级之前先检查系统表引擎先转换再升级不要指望升级工具帮我们自动处理。这条铁律帮我挡掉了后面很多次半夜紧急修复。再分享最后一个细节。在8.0.44环境里如果你用mysqldump导出的SQL文件不含SET GLOBAL.GTID_PURGED这类GTID语句导入新实例后主从复制的GTID集合可能对不上这在搭建从库时特别容易踩。所以如果你升级之前的主库开着GTID导出时建议加上--set-gtid-purgedOFF然后手动设置GTID_PURGED或者直接跳过GTID约束否则复制同步时会碰到幺蛾子。这次的坑从登录报错背后的系统表引擎问题出发一路牵出了升级路径选择、数据字典机制、认证插件兼容性等多个连环话题。如果你在升级8.0.44时也遇到了类似的MyISAM报错按文中的方案一或方案二操作基本都能恢复。如果操作过程中还有其他奇怪报错欢迎带着日志片段来讨论。
返回列表