我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何进行MySQL ERROR 1146 Table doesnt exist的解析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何进行MySQL ERROR 1146 Table doesnt exist的解析

本篇文章为大家展示了如何进行MySQL ERROR 1146 Table doesnt exist的解析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

☉源码版本 5.7.14

在MYSQL使用innodb的时候我们有时候会看到如下报错:

ERROR 1146 (42S02): Table 'test.test1bak' doesn't exist

首先总结下原因:

  1. 缺少frm文件

  2. innodb数据字典不包含这个表

我们重点讨论情况2,因为情况1是显而易见的。

在使用innodb存储引擎的时候某些时候我们show tables能够看到这个表,但是如果进行任何操作会报错如下:

mysql> show tables;    | test1bak          |    mysql> desc test1bak ;    ERROR 1146 (42S02): Table 'test.test1bak' doesn't exist

也许你会说我明明能够看到这个表啊,为什么访问还会报错呢?其实要清楚innodb有自己的数据字典,只要有frm 文件存在show  tables就能看到,但是最终是否能够正常打开表结构在innodb中还依赖于innodb的数据字典,主要的包含:

1、INNODB_SYS_columns

2、INNODB_SYS_FIELDS

3、INNODB_SYS_TABLES

4、INNODB_SYS_INDEXES

如果报错出现我们需要首先查看的是INNODB_SYS_TABLES是否包含了这个表的信息。也许在这些数据字典中也许某些列并显示并不是那么明确,比如

mysql> select * from information_schema.innodb_sys_tables where name='test/kkkkm1';    +----------+-------------+------+--------+-------+-------------+------------+---------------+------------+    | TABLE_ID | NAME        | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE |    +----------+-------------+------+--------+-------+-------------+------------+---------------+------------+    |      374 | test/kkkkm1 |   33 |      6 |   540 | Barracuda   | Dynamic    |             0 | Single     |    +----------+-------------+------+--------+-------+-------------+------------+---------------+------------+

比如这里的FLAG列为33,他实际上是一个位图表示方式,分别表示如下信息:

    #define DICT_TF_WIDTH_COMPACT       1         #define DICT_TF_WIDTH_ZIP_SSIZE     4         #define DICT_TF_WIDTH_ATOMIC_BLOBS  1         #define DICT_TF_WIDTH_DATA_DIR      1         #define DICT_TF_WIDTH_SHARED_SPACE  1

接下来我们分析一下为什么是FLAG是33如下:

33的二进制为00100001从低位开始
1:从源码注释来看本位COMPACT/COMPRESSED/DYNAMIC均为1
0000: ZIP_SSIZE flag 这四位用于支持压缩功能如COMPRESSED
1:ATOMIC_BLOBS flag 这一位是COMPACT和DYNAMIC主要区别所在,请看源码注释
0:DATA DIRECTORY and innodb-file-per-table flag为了支持DATA DIRECTORY语法
0:SHARED tablespace flag为了支持TABLESPACE语法

然后我们测试一下:

如果我们建立如下的表:   
CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table   
DATA DIRECTORY = '/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/mysqld.1';   
其type为97二进制为  01100001:使用DATA DIRECTORY建立使用ATOMIC_BLOBS且无压缩则DYNAMIC格式   
详见:15.5.5 Creating a File-Per-Table Tablespace Outside the Data Directory   
如果我们建立如下的表:   
CREATE TABLESPACE tt1 ADD DATAFILE '/root/mysql5.7.14/tt1.ibd';   
CREATE TABLE tsh (c1 INT ) TABLESPACE tt1 ROW_FORMAT=COMPACT ;   
其type为129二进制为 10000001:使用TABLESPACE语法建立不使用ATOMIC_BLOBS且无压缩则为COMPACT格式   
详见:15.5.9 InnoDB General Tablespaces

我们可以看到使用8位一个字节而已就可以表示出大量的信息,这也是位图的优势,其他比如 MTYPE/PRTYPE也是这种表示方式

接下来我们回到主题,需要看看这个错到底是哪里报错来的?进行trace后如下,我们来看看主要部分:

注意这里的trace是mysql debug版本下查看函数调用的主要方法参考官方文档26.5.1.2 Creating Trace Files502  T@2: | | | | | | | | | | | >ha_innobase::open_dict_table

503  T@2: | | | | | | | | | | | | >dict_table_open_on_name       504  T@2: | | | | | | | | | | | | | dict_table_open_on_name: table: 'test/test1bak'       505  T@2: | | | | | | | | | | | | | >dict_table_check_if_in_cache_low       506  T@2: | | | | | | | | | | | | | | dict_table_check_if_in_cache_low: table: 'test/test1bak'       507  T@2: | | | | | | | | | | | | | <dict_table_check_if_in_cache_low 125       508  T@2: | | | | | | | | | | | | | >dict_load_table       509  T@2: | | | | | | | | | | | | | | dict_load_table: loading table: 'test/test1bak'       510  T@2: | | | | | | | | | | | | | | >dict_table_check_if_in_cache_low       511  T@2: | | | | | | | | | | | | | | | dict_table_check_if_in_cache_low: table: 'test/test1bak'       512  T@2: | | | | | | | | | | | | | | <dict_table_check_if_in_cache_low 125       513  T@2: | | | | | | | | | | | | | | >dict_load_table_one       514  T@2: | | | | | | | | | | | | | | | dict_load_table_one: table: test/test1bak       515  T@2: | | | | | | | | | | | | | | | >dict_table_check_if_in_cache_low       516  T@2: | | | | | | | | | | | | | | | | dict_table_check_if_in_cache_low: table: 'SYS_TABLES'       517  T@2: | | | | | | | | | | | | | | | <dict_table_check_if_in_cache_low 125       518  T@2: | | | | | | | | | | | | | | | >btr_cur_search_to_nth_level       519  T@2: | | | | | | | | | | | | | | | <btr_cur_search_to_nth_level 2005       520  T@2: | | | | | | | | | | | | | | <dict_load_table_one 3084       521  T@2: | | | | | | | | | | | | | <dict_load_table 2882       522  T@2: | | | | | | | | | | | | <dict_table_open_on_name 1292       523  T@2: | | | | | | | | | | | <ha_innobase::open_dict_table 6676       524  T@2: | | | | | | | | | | | >sql_print_warning       525  T@2: | | | | | | | | | | | | >error_log_print       526  T@2: | | | | | | | | | | | | | >print_buffer_to_file       527  T@2: | | | | | | | | | | | | | | enter: buffer: InnoDB: Cannot open table test/test1bak 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.       528  T@2: | | | | | | | | | | | | | <print_buffer_to_file 2332       529  T@2: | | | | | | | | | | | | <error_log_print 2357       530  T@2: | | | | | | | | | | | <sql_print_warning 2384

☉其实大概步骤就是

1、Checks if a table is in the dictionary cache

根据dict_sys->table_hash寻找

2、Loads a table definition and also all its index definitions.

通过扫描字典的B+树进行加载

3、如果不能找到则报错

这样也就解释了为什么show tables能够看到但是select却报错Table doesn't exist ,而从原理上讲show  tables只是查看了frm文件。

另外这里也提一个案列,曾经有一个朋友问我他将整个库目录都拷贝了,但是表能看到但是一操作就报Table doesn't  exist,显然他没有拷贝ibdata1,数据字典的引导信息都存在这里面文件的第7个page中,其b+树也是存在其中,用源码解释一下:

          dict_hdr_t*          dict_hdr_get(                        mtr_t*  mtr)              {              buf_block_t*    block;              dict_hdr_t* header;               block = buf_page_get(page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO),                           univ_page_size, RW_X_LATCH, mtr);              header = DICT_HDR + buf_block_get_frame(block);               buf_block_dbg_add_level(block, SYNC_DICT_HEADER);               return(header);          }

注意这里的 DICT_HDR_SPACE, DICT_HDR_PAGE_NO分别是宏定义

    #define DICT_HDR_SPACE      0       #define DICT_HDR_PAGE_NO    FSP_DICT_HDR_PAGE_NO     #define FSP_DICT_HDR_PAGE_NO        7   

space  0就是ibdata1的space_no,7当然就是引导块,这哥们连ibdata1都没拷贝,当然innodb数据字典自然不包含这些表了。其实也是上面描述的原理  。

&emsp;那么正确的拷贝的方式一定是停机后,整个数据目录进行拷贝,而不是仅仅拷贝需要的库的目录,否则innodb数据字典是不能正常加载的。

附带space 0的部分块解释

       #define FSP_XDES_OFFSET         0          #define FSP_IBUF_BITMAP_OFFSET      1                                 #define FSP_FIRST_INODE_PAGE_NO     2                                 #define FSP_IBUF_HEADER_PAGE_NO     3          #define FSP_IBUF_TREE_ROOT_PAGE_NO  4                                 #define FSP_TRX_SYS_PAGE_NO     5          #define FSP_FIRST_RSEG_PAGE_NO      6          #define FSP_DICT_HDR_PAGE_NO        7          ********

上述内容就是如何进行MySQL ERROR 1146 Table doesnt exist的解析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何进行MySQL ERROR 1146 Table doesnt exist的解析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何进行Spring MVC的解析

这期内容当中小编将会给大家带来有关如何进行Spring MVC的解析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用
2023-06-17

如何进行Python脚本的解析

如何进行Python脚本的解析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。脚本是使用一种特定的描述性语言,因为Python脚本在执行时多了一道翻译的过程,所以
2023-06-17

如何进行域名的解析与绑定

今天就跟大家聊聊有关如何进行域名的解析与绑定,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。那么有了注册了域名和购买了虚拟主机以后,怎么样才能在IE里输入你的域名就能打开你的站呢?这就
2023-06-08

如何进行C++开发环境的解析

今天就跟大家聊聊有关如何进行C++开发环境的解析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。大多数企业用的开发语言,莫过于C++了,但是随着科技地发展,其他的编程语言也在慢慢的进入
2023-06-17

如何进行Python 操作符风格的解析

今天就跟大家聊聊有关如何进行Python 操作符风格的解析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。调用方法会影响可读性。尽管 assertEqual() 方法名能够表明要测试两
2023-06-17

如何进行VS2005软件的理解与分析

如何进行VS2005软件的理解与分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。看来是WebDeployment本身有一定的bug,笔者猜想可能是编码问题造成的,WebDep
2023-06-17

如何进行SAP BW/4 HANA亮点的解析

这篇文章将为大家详细讲解有关如何进行SAP BW/4 HANA亮点的解析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。本篇文章给大家分享的是有关如何进行SAP BW/4 HANA亮点的解析,
2023-06-05

如何进行Visual Basic对象的全面解析

如何进行Visual Basic对象的全面解析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Visual Basic还是比较常用的,于是我研究了一下Visual Basic
2023-06-17

编程热搜

目录