MySQL复制出错 Last_SQL_Errno:1146的解决方法
背景:我们在做数据迁移或者拆分的时候,使用Tablespacetranscation这种解决方案时,很有可能就会遇到从库复制出错,报:Last_SQL_Errno:1146
那么具体错误内容可能会有如下:
Last_SQL_Error:Error'Table'spider.tb_city_population_rank'doesn'texist'onquery.Defaultdatabase:'spider'.Query:'altertabletb_city_population_rankdiscardtablespace'
Last_SQL_Error:Error'Table'spider.tb_city_population_rank'doesn'texist'onquery.Defaultdatabase:'spider'.Query:'altertabletb_city_population_rankimporttablespace'
那么我们遇到这样的问题的时候该如何恰当的处理呢?考虑如下几点:
1.我们整个库的容量有多大?
2.业务容忍的最大延迟时间多久?
3.我们恢复需要多久?恢复的难易程度如何?
通过考虑到以上几点,我们就可以根据实际情况做出抉择,采用什么样的办法尽快的恢复从库;对于这样的问题,简单粗暴的方案就是重建从库,当然还有别的办法,且听我慢慢道来:
首先我们先看看我们是如何通过Transporttablespace迁移数据的,大概步骤如下:
1.库A执行:showcreatetablexxx1;拿到简表语句;
2.库B执行:createtablexxx1;在从库上建立基本的表结构;
3.库B执行:altertablexxx1discardtablespace;让mysql自己删掉ibd文件;
4.库A执行:flushtablesxxxx1,xxxx2forexport;把内存的脏数据刷到磁盘,使得ibd文件数据一致;
5.库A执行:scpxxxx1.ibdxxx2.ibdxxxx1.cfgxxx2.cfgslave_host:/data/把ibd文件拷贝到从库;
6.库B执行:altertablexxx1importtablespace导入数据文件。
好了我们知道了整个迁移的具体步骤,那么我们就可以轻松的应对在迁移过程中复制出错的问题了。
那么我们首先来看一下:
Last_SQL_Errno:1146
Last_SQL_Error:Error'Table'spider.tb_city_population_rank'doesn'texist'onquery.Defaultdatabase:'spider'.Query:'altertabletb_city_population_rankdiscardtablespace'
其大概的意思就是我们在从库上没有找到这个表的完整定义信息,观察一下磁盘上的文件我们就明白了:
[root@GZ_NF_DB_RP_002spider]#ls-lhrt|greptb_city_population_rank
-rw-r-----1mysqlmysql8.3GMar3120:03tb_city_population_rank.ibd
果然没有这个表的frm文件,那么怎么办呢?由于是slave的sql_thread线程报错,那么我们可采取取巧的办法:
用超级用户登录从库,先备份一下这个ibd文件:[root@GZ_NF_DB_RP_002spider]#mvtb_city_population_rank.ibdtb_city_population_rank.ibd.bak
然后拿到这个文件的表结构,在从库上执行建表语句,这样一样来,我们从库就有了ibdfrm文件,那么此时我们开启slavesql_thread,这时就会执行时主库传过来的语句:
altertabletb_city_population_rankdiscardtablespace;那么当我们再一次的观看此盘数据文件的时候,ibd文件又不见了,此时slave也就已经出错了,其错误信息如下:
Last_SQL_Errno:1146
Last_SQL_Error:Error'Table'spider.tb_city_population_rank'doesn'texist'onquery.Defaultdatabase:'spider'.Query:'altertabletb_city_population_rankimporttablespace'
那么我们此时需要做的就是:把刚才mv的文件再mv回去,也就是说:[root@GZ_NF_DB_RP_002spider]#mvtb_city_population_rank.ibd.baktb_city_population_rank.ibd;完成这个命令后我们再执行startslavesql_thread;此时这个表就正常了,我们可以执行select*fromtb_city_population_ranklimit100;来验证一下是否可读。
那么此时,我们算完整的解决了因一个表导致的复制出错的问题,那么如果迁移了多张表(经常是),那么我们就可以按照这个解决方案,一步一步的来解决复制出错。其大概的思路就是,缺什么我们补什么,多了什么我们去掉什么。
下面是其它网友的补充,根据返回的错误信息进行调整即可。
mysql主主复制(双主复制)报错Last_SQL_Errno:1146
错误信息:
Last_Errno:1146 Last_Error:Error'Table'test.user'doesn'texist'onquery.Defaultdatabase:'test'.Query:'insertintouservalues(20,'在库')'
解决方法:
mysql>setglobalsql_slave_skip_counter=20; mysql>STOPSLAVE; mysql>STARTSLAVE;
问题解决