問題現象
在重啟RDS MySQL執行個體後,進行表相關操作時,提示如下錯誤:
ERROR 1146 (42S02): Table 'xxx.xxx' doesn't exist同時,在error log中可見如下記錄:
[Warning] InnoDB: Load table `xxx`.`xxx` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
[Warning] InnoDB: Cannot open table xxx/xxx from the internal data dictionary of InnoDB though the .frm file for the table exists.可能原因
MySQL中添加外鍵需要滿足相應條件和限制,詳情請見官方文檔FOREIGN KEY Constraints。
MySQL的外鍵限制檢查是通過變數foreign_key_checks來控制的,該變數可以在RDS MySQL執行個體運行時修改,不需要重啟執行個體,預設值為ON。若將foreign_key_checks設為OFF,除特殊情況外(詳情請參見官方文檔FOREIGN KEY Constraints),將關閉外鍵限制檢查。
如果在關閉外鍵限制檢查後,對外鍵進行了變更使其不滿足外鍵限制,在RDS MySQL執行個體運行時不會報錯。在重啟執行個體時,由於重啟時foreign_key_checks預設開啟,InnoDB開啟表時會進行外鍵限制檢查,此時會報錯。
常見的情況有以下兩種:
更改了父表和子表外鍵相關列的字元集
MySQL 5.6、5.7、8.0允許在foreign_key_checks設定為OFF的情況下,修改父表和子表外鍵相關列的字元集。執行個體重啟以後:
MySQL 5.6、5.7會在error log中提示warning,同時無法使用父表。
MySQL 8.0不會在error log中提示warning,可以使用父表。
刪除了父表和子表外鍵相關列的索引
對於MySQL 5.7、8.0:不允許在foreign_key_checks設定為OFF的情況下,刪除父表和子表外鍵相關列的索引。
對於MySQL 5.6:允許在foreign_key_checks設定為OFF的情況下,刪除父表和子表外鍵相關列的索引。刪除相關列索引後,重啟執行個體會提示warning,同時被刪除索引的表無法使用。
解決方案
對於修改字元集導致的問題,將foreign_key_checks設定為OFF,將父表和子表外鍵相關列的字元集修改一致。
對於刪除索引導致的問題,將foreign_key_checks設定為OFF,重建索引。