惊!使用外键竟导致mysql无法访问!
Posted _雪辉_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了惊!使用外键竟导致mysql无法访问!相关的知识,希望对你有一定的参考价值。
一、问题复现
表结构
create table t1(id varchar(50) not null primary key, c1 int) DEFAULT CHARSET=utf8mb4;
create table t2(id int, c1 varchar(50),
KEY `idx1` (`c1`),
CONSTRAINT fk_idx1 FOREIGN KEY (`c1`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
当foreign_key_checks为ON时,外键字段无法变更COLLATE
root@localhost 16:48: [sbtest]> show variables like '%foreign_key_checks%';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| foreign_key_checks | ON |
+--------------------+-------+
1 row in set (0.01 sec)
root@localhost 16:52: [sbtest]> alter table t1 modify `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
ERROR 1833 (HY000): Cannot change column 'id': used in a foreign key constraint 'fk_idx1' of table 'sbtest.t2'
root@localhost 16:53: [sbtest]> set foreign_key_checks=off;
Query OK, 0 rows affected (0.00 sec)
root@localhost 17:08: [sbtest]>
root@localhost 17:08: [sbtest]> alter table t1 modify `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
重启实例后t2表无法访问
root@localhost 17:16: [sbtest]> select * from t1;
+----+------+
| id | c1 |
+----+------+
| a | 1 |
+----+------+
1 row in set (0.01 sec)
root@localhost 17:16: [sbtest]> select * from t2;
ERROR 1146 (42S02): Table 'sbtest.t2' doesn't exist
root@localhost 17:16: [sbtest]> show create table t2;
ERROR 1146 (42S02): Table 'sbtest.t2' doesn't exist
root@localhost 17:16: [sbtest]> show tables;
+------------------+
| Tables_in_sbtest |
+------------------+
| sbtest1 |
| t1 |
| t2 |
+------------------+
3 rows in set (0.00 sec)
root@localhost 17:18: [sbtest]> select * from information_schema.tables where table_schema='sbtest';
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
| def | sbtest | sbtest1 | BASE TABLE | InnoDB | 10 | Dynamic | 63158 | 374 | 23642112 | 0 | 2359296 | 7340032 | NULL | 2021-06-03 11:19:49 | NULL | NULL | utf8mb4_general_ci | NULL | | |
| def | sbtest | t1 | BASE TABLE | InnoDB | 10 | Dynamic | 0 | 0 | 16384 | 0 | 0 | 0 | NULL | 2021-06-20 17:09:43 | NULL | NULL | utf8mb4_general_ci | NULL | | |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
2 rows in set (0.00 sec)
二、问题分析
查看错误日志
2021-06-20T17:16:18.633707+08:00 2 [Warning] InnoDB: Load table `sbtest`.`t2` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
2021-06-20T17:16:20.359356+08:00 2 [Warning] InnoDB: Load table `sbtest`.`t2` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
2021-06-20T17:16:20.359391+08:00 2 [Warning] InnoDB: Cannot open table sbtest/t2 from the internal data dictionary of InnoDB though the .frm file for the table exists. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.
从错误日志得出家在数据无法加载,尝试关闭foreign_key_checks解决;尽管表frm存在,但是无法从数据字典打开表。
root@localhost 17:35: [sbtest]> set foreign_key_checks=off;
Query OK, 0 rows affected (0.00 sec)
root@localhost 17:35: [sbtest]> select * from information_schema.tables where table_name='t2' and table_schema='sbtest';
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
| def | sbtest | t2 | BASE TABLE | InnoDB | 10 | Dynamic | 0 | 0 | 16384 | 0 | 16384 | 0 | NULL | 2021-06-20 16:48:21 | NULL | NULL | utf8mb4_general_ci | NULL | | |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------------+
1 row in set (0.00 sec)
root@localhost 17:35: [sbtest]> show create table t2;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t2 | CREATE TABLE `t2` (
`id` int(11) DEFAULT NULL,
`c1` varchar(50) DEFAULT NULL,
KEY `idx1` (`c1`),
CONSTRAINT `fk_idx1` FOREIGN KEY (`c1`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
结论:关闭foreign_key_checks后,修改外键字段COLLATE导致重启后加载字典信息无法完成,无法完成整个innodb表的load操作。从而在查询这个表的时候报表不存在。
解决方案:
- 关闭foreign_key_checks(不推荐)
- 修改COLLATE为一致(推荐)
以上是关于惊!使用外键竟导致mysql无法访问!的主要内容,如果未能解决你的问题,请参考以下文章