最近客户现场的tokudb表使用过程中报错unknown table,总结后处理步骤如下:

1. 确定问题表的数据文件

示例sql如下,假设库名为dwh_cmste,表名为cmst_servicelog

select dictionary_name, internal_file_name from  

information_schema.tokudb_file_map where table_schema='dwh_cmste' and

table_name='cmst_servicelog';

在输出中我们可以看到该表的tokudb相关文件,包括一个main文件一个status文件以及索引文件,一个索引一个文件。


2. 获取改表的建表语句


3. 移除问题表文件

将步骤1中确定的表文件以及该表的frm文件从数据目录中移走。


4. 执行drop table if exists 问题表,进行删除


5. 使用步骤2的建表语句创建一个同结构的表,表名与问题表不同,例如问题表为cmst_servicelog,新表可以叫cmst_servicelog2。


6. 确定新表的tokudb数据文件

示例sql如下

select dictionary_name, internal_file_name from  

information_schema.tokudb_file_map where table_schema='dwh_cmste' and

table_name='cmst_servicelo2';

7. 关闭数据库实例


8. 拷贝新表数据文件为问题表数据文件

到数据目录,拷贝步骤6新表的tokudb数据文件为步骤1问题表的tokudb文件,注意拷贝后的文件名要与步骤1中输出一致,然后再拷贝新表frm文件为问题表的frm文件。

然后修改新拷贝文件的属组与数据目录中其他文件相同。


9. 重启数据库实例


10. 再次删除问题表

启动数据库实例后,可以看到问题表已经恢复,这时候正常执行drop table完成该表的删除操作。


11. 删除步骤5新建的表


注意,如果是主备架构的主节点出现这个问题,需要先把它切换为从节点,然后进行上述操作,因为操作过程需要重启实例。同时需要在每次操作前执行 set session sql_log_bin=off,避免产生不必要的binlog影响主备复制。



注:步骤4并没有真正把问题表删除,因为通过步骤1的命令依然可以看到该表的信息。这时候如果创建同名的新表,会返回error 17的引擎层错误,即文件已经存在。


参考链接:https://jira.percona.com/browse/PS-932