MySQL报错:SQL错误[1146][42s02]: Table 'tablename' doesn't exist(记一次以为自己删库的经历)

先说一下这篇文章包含的知识点:bin_log服务查询,bin_log文件转为SQL文件,MySQL重启,MySQL磁盘不足报错,MySQL表名大小写配置

事情起因:

操作数据库的是我们的萌新妹子,不太懂MySQL数据库这些东西,只会用,不会修,今天一开工她就给我说之前一直都可以访问的表访问不了,应该是被某人删除了,而且是一大半的表都不见了!!!让我找找原因,刚刚收到这个消息的时候我是真滴是慌,删库跑路的剧情要发生在年纪轻轻的我身上了吗??之前也没有过恢复数据的经验,没办法,只好硬着头皮一个人单干,我是项目的主要负责人之一那自然就得找出问题所在咯,我的MySQL客户端用的是Linux上的DBeaver,下面请大家欣赏一下MySQL报错的界面截图。

MySQL报错:SQL错误[1146][42s02]: Table 'tablename' doesn't exist(记一次以为自己删库的经历)_第1张图片

org.jkiss.dbeaver.model.sql.DBSQLException: SQL 错误 [1146] [42S02]: Table 'vm-cmgxbs-industry-spider.zbyinformation' doesn't exist
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:134)
	at org.jkiss.dbeaver.model.impl.jdbc.struct.JDBCTable.readData(JDBCTable.java:186)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.lambda$0(ResultSetJobDataRead.java:111)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:170)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.run(ResultSetJobDataRead.java:109)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetViewer$17.run(ResultSetViewer.java:3580)
	at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:103)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: java.sql.SQLSyntaxErrorException: Table 'vm-cmgxbs-industry-spider.zbyinformation' doesn't exist
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:790)
	at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:675)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.execute(JDBCStatementImpl.java:338)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:131)
	... 7 more

这里报错的关键字是:Table 'tablename' doesn't exist,妹子也给我说这个表被删了所以有点被误导了,以为表真的被别人给删了,就往恢复数据那个方向去想了,刚好我们这个MySQL开启了bin_log服务,会自动备份,下面是查看MySQL有没有开启bin_log服务的查询语句。

show variables like '%log_bin%';

MySQL报错:SQL错误[1146][42s02]: Table 'tablename' doesn't exist(记一次以为自己删库的经历)_第2张图片

看到这个大大的ON没有,ON就是bin_log服务打开了!

然后我上去服务器/var/lib/mysql/目录看了一下,确实有巨多bin_log文件,心里就瞬间踏实了,以下请大家欣赏一下我数据库中的bin_log文件:

MySQL报错:SQL错误[1146][42s02]: Table 'tablename' doesn't exist(记一次以为自己删库的经历)_第3张图片

我就想着把这些bin_log文件转为SQL语句,看一下哪里执行了删表语句,也就是DROP语句嘛,心想找到了删表语句然后把删表语句以及后面的操作都删掉以后不就得到了恢复数据的SQL语句了吗?心里不禁泛起一阵欣喜,下面请大家欣赏一下bin_log文件转SQL语句的命令:

mysqlbinlog -d databasesname mysql-bin.000001 >001bin.sql

下面是赠品,附赠一条数据库全备份命令:

mysqldump -h192.168.xxx.xxx -p3306 -uroot -p123456 --all-databases > /data/backup/all_db.sql

 

 

不看不知道,一看吓一跳,转换后的sql文件里面根本就没有DROP语句,也就是说没有表被删除了,那么为什么MySQL会报错为表不存在呢???

真的是一脸懵逼啊,于是我上服务器的数据库目录/var/lib/mysql/databsesname/看了一下,不看不知道,一看吓一跳,发现里面的表都在啊!都是有数据的!坑爹啊为什么表数据都在为什么会报错啊!!!

我想了很久,突然灵机一动,出现奇葩问题先来个重启,于是我运行了MySQL服务重启命令,下面有请大家欣赏MySQL服务重启命令:

service mysqld restart

MySQL重启的时候是会先把MySQL服务给关掉再重新启动的,呆呆地在屏幕前等待服务关闭在启动,嗯,服务关闭成功,大大的绿色OK打印在了屏幕上,等了一会,屏幕上打印出了一串英文,MySQL服务启动失败!!!一般年轻人嘛都比较莽,我又运行了几次MySQL重启命令,结果还是一样,关闭服务是成功的,启动服务是失败的!

哎,大哥,你启动失败怎么没有报错啊,很不讲道理啊你,于是我就找到了MySQL报错日志,这个报错日志是在/etc/my.cnf配置文件中配置的,我的服务器是这个路径log-error=/var/log/mysqld.log,cat了一下日志,发现了几个报错,下面有请大家欣赏一下我的报错信息:

2020-05-09T03:51:33.263278Z 0 [ERROR] InnoDB: Write to file ./ibtmp1failed at offset 0, 1048576 bytes should have been written, only 0 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
2020-05-09T03:51:33.263316Z 0 [ERROR] InnoDB: Error number 28 means 'No space left on device'
2020-05-09T03:51:33.263340Z 0 [Note] InnoDB: Some operating system error numbers are described at http://dev.mysql.com/doc/refman/5.7/en/operating-system-error-codes.html
2020-05-09T03:51:33.263353Z 0 [ERROR] InnoDB: Could not set the file size of './ibtmp1'. Probably out of disk space
2020-05-09T03:51:33.263370Z 0 [ERROR] InnoDB: Unable to create the shared innodb_temporary
2020-05-09T03:51:33.263382Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2020-05-09T03:51:33.764192020-05-09T03:51:33.784202Z mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

报错信息当然要先找到关键字咯,我看到的关键字是:

Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.

翻译一下就是哎呀,你的磁盘不够空间了,不够空间还想启动MySQL?吃屁吧你!

没办法,磁盘空间不够我就把一些没用的备份给删了,空出了几个g的空间后再重启MySQL服务,结果是启动成功哈哈哈哈哈!!!

有时候程序员解决问题都抱有一些神学色彩的幻想,启动成功了啊,之前的表不存在的问题会不会也解决了呢?会不会就是这个空间不够的问题啊!想想都有点兴奋呢,结果上去数据库一查,该报错的表还是报错了,和之前没有丝毫区别。我的妈,那究竟是什么问题啊...

 

 

我想了很久没有头绪。

于是我让妹子把报错的表名都给我列了一下,不看不知道,一看吓一跳!!!

表名里面居然都是大小写混着的,每个表名都有若干个小写字母,若干个大写字母!!!没有报错的表都是没有大写字母的!

突然松了一口气,嗨,这不就是表名的大小写字母的问题吗,简单,改一下配置就好。

于是我就改了一下my.cnf中的参数,我这边的my.cnf路径是/etc/my.cnf,my.cnf是MySQL的配置文件,可以配置bin_log,表名大小写和日志路径等等东西,下面有请大家欣赏一下我这边导致数据库报错的配置:

lower_case_table_names=1

对!就是这么一条小小的配置!

我们先了解一下这一个配置的不同参数的不同作用:

lower_case_table_names: 此参数不可以动态修改,必须重启数据库
lower_case_table_names = 1  表名存储在磁盘是小写的,但是比较的时候是不区分大小写
lower_case_table_names = 0  表名存储为给定的大小和比较是区分大小写的 
lower_case_table_names = 2 表名存储为给定的大小写但是比较的时候是小写的
————————————————
版权声明:本文为CSDN博主「wluckdog」的原创文章,遵循CC 4.0 BY-SA版权协议
原文链接:https://blog.csdn.net/wll_1017/article/details/55105180

 

 

注意啊,以下都是我的猜测,不严谨的,没有经过验证。

我的思路是这样的啊,我先假定是这个配置出问题了,然后我就认为妹子在建表的时候这个配置是lower_case_table_names = 0,也就是说表名存储在磁盘的是建表的时候是什么就是什么,大小写混在一起用就是混在一起用,不会给你搞花里胡哨的大小写转换。

那么假如我建表的时候表名为 testTable ,那么 lower_case_table_names = 0 的时候表名存储在磁盘中就是 testTable,而 lower_case_table_names = 1 的意思是表名存储在磁盘中的都是小写,那么当配置为 lower_case_table_names = 1 的时候我执行命令 select * from testTable; 它会给我转换为 select * from testtable; 或者 select * from TESTTABLE; 那怎么可能查询到这个表嘛,这两个表名都不存在!!!

 

 

思路有了我就屁颠屁颠 vim /etc/my.cnf 把 lower_case_table_names = 1 改为 lower_case_table_names = 0 然后重启MySQL服务,注意啊,修改完这配置一定要重启MySQL服务!

然后我又用MySQL客户端DBeaver查询了一下表,哦吼!还是原封不动地给我报错。

我真的就不信邪了,直接上服务器打开MySQL查询了一下,嗯哼!都查出数据了!!难道是你这个DBeaver的问题??

最后嘛,我把DBeaver的数据库连接断开重连后就查询成功啦!!

 

 

于是我立马跑去告诉萌新妹子,妹子,数据库恢复啦,你快上去看看!!!

可喜可贺,终于结束了。

 

最后总结一下:

1 原来一直可以用的表突然不可用了,但表名还在那里显示着的话,那就先看一下不可用的这些表名是不是有某种特征

2 如果MySQL服务关闭成功,但启动失败的话先找到日志文件所在位置,再看一下报错信息,还有可以先考虑一下是空间不足的问题

3 表名尽量用全小写!用全小写!或者是全大写!全大写!

4 数据没了先别忙着跑路啊,可能只是小问题

 

你可能感兴趣的:(MySQL,数据库)