数据库内核月报 - 2015 / 09-MySQL · 捉虫动态 · 建表过程中crash造成重建表失败

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

问题描述

主库的create table语句传到备库,备库SQL线程执行过程中报错:

Error 'Can't create table 'XXX.XX' (errno: -1)' on query. Default database: 'XXX'. Query: 'CREATE TABLE XX (  column_a char(32) NOT NULL,  column_b int(10) DEFAULT NULL,  column_c int(10) DEFAULT NULL,  PRIMARY KEY (column_a),  KEY expiry (column_b)) ENGINE=HEAP DEFAULT CHARSET=gbk'

备库 error log:

InnoDB: Error number 17 means 'File exists'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-	codes.html
InnoDB: The file already exists though the corresponding table did not
InnoDB: exist in the InnoDB data dictionary. Have you moved InnoDB
InnoDB: .ibd files around without using the SQL commands
InnoDB: DISCARD TABLESPACE and IMPORT TABLESPACE, or did
InnoDB: mysqld crash in the middle of CREATE TABLE?You can
!!!InnoDB: resolve the problem by removing the file '...'
InnoDB: under the 'datadir' of MySQL.

从error log中可以看出,数据目录中已存在 .ibd 文件,推测是在建表过程中发生 crash。

数据目录下存在 .ibd,不存在 .frm,创建.ibd 文件的时间:

-rw-rw---- 1 mysql mysql    65536 Sep  5 14:41 XXX.ibd

.ibd 文件创建时间 150905 14:41,对应时间的 error log:

150905 14:41:58 mysqld_safe Number of processes running now: 0
150905 14:41:58 mysqld_safe mysqld restarted

之后也出现了和该创建失败的表相关的错误记录:

150905 14:59:45  InnoDB: Error: table `XXX`.`XX` does not exist in the InnoDB internal

问题分析

执行如下语句,模拟建表

create table test.t3 (id int);

create table 时,由函数mysql_create_frm创建 .frm 文件,mysql_create_frm 调用栈如下:

#0  mysql_create_frm
#1  rea_create_table
#2  mysql_create_table_no_lock
#3  mysql_create_table
#4  mysql_execute_command
#5  mysql_parse

t3.frm 文件生成后,实例 crash(函数mysql_create_frm 执行完毕后kill mysqld),在数据库中show tables可以看到 test.t3,但是无法插入,数据目录下 t3.frm 文件依然存在。

drop table报错

ERROR 1051 (42S02): Unknown table 'test.t3'

之后数据目录下的t3.frm不存在,show tables 无法看到t3表,可以重新创建t3表。

.ibd 文件由函数fil_create_new_single_table_tablespace创建,fil_create_new_single_table_tablespace调用栈如下:

#0  fil_create_new_single_table_tablespace
#1  dict_build_table_def_step
#2  dict_create_table_step
#3  que_thr_step
#4  que_run_threads_low
#5  que_run_threads
#6  row_create_table_for_mysql
#7  create_table_def
#8  ha_innobase::create
#9  handler::ha_create
#10 ha_create_table
#11 rea_create_table
#12 create_table_impl
#13 mysql_create_table_no_lock
#14 mysql_create_table
#15 mysql_execute_command
#16 mysql_parse

t3.ibd 文件生成后,实例 crash(函数fil_create_new_single_table_tablespace执行完毕后kill mysqld),在数据库中show tables可以看到 test.t3,无法插入数据,在数据目录下存在文件 t3.frm 和 t3.ibd。

drop table依然可以移除 t3.frm 并使show tables无法看到 t3 表。但无法移除 t3.ibd,并在重建 t3 表时报错:

ERROR 1813 (HY000): Tablespace for table '`test`.`t3`' exists. Please DISCARD the tablespace before IMPORT.

在数据目录中删除 t3.ibd ,可以正常重建 t3 表。

这个 bug 的主要原因是 MySQL 的建表过程不是原子操作。如果建表过程正在进行的时候实例 crash,可能会造成一些在实例重启后无法自动恢复的问题。就像这个问题当中的文件残留,无法通过 MySQL 客户端中的操作解决,只能手动删除文件。如果用户是远程连接数据库,又没有登录服务器操作数据文件的权限,就会影响数据库的可用性。

MySQL 5.7 的实验室版本正在设计和实现新版本的数据字典来解决这一问题。这个版本主要由以下几个特性:

  • 数据字典将实现事务存储,首先利用 InnoDB 存储,其他存储引擎可能会跟进开发;
  • 把分布式系统中的字典信息统一成一个整体;
  • 使用统一的规则存储字典信息,给字典对象定义统一的API;
  • 避免文件系统特性带来的问题。

详细信息参见MySQL Server Blog

问题解决

通过问题分析,判断备库无法建表是由于在执行create table语句时备库实例crash,且crash时.ibd 文件已存在。用户发现表创建失败,企图重建表依然失败,之后执行了drop table语句,移除了.frm文件,但.ibd文件依然存在,无法重建表。
将数据目录下的.ibd文件移到其他文件夹作为备份,在备库start slave后建表成功,主备复制正常。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
114 1
|
2天前
|
SQL 数据库 数据库管理
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
68 11
|
2天前
|
存储 关系型数据库 MySQL
{MySQL} 数据库约束& 表的关系& 新增&&删除& 修改& 查询
{MySQL} 数据库约束& 表的关系& 新增&&删除& 修改& 查询
21 0
|
2天前
|
存储 关系型数据库 MySQL
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL】——用SQL语句实现数据库和基本表的创建
【MySQL】——用SQL语句实现数据库和基本表的创建
90 3
【MySQL】——用SQL语句实现数据库和基本表的创建
|
2天前
|
SQL 存储 关系型数据库
Mysql内核查询成本计算
Mysql内核查询成本计算
|
2天前
|
XML Java 数据库连接
|
2天前
|
关系型数据库 MySQL 数据库
MySQL员工打卡日志表——数据库练习
MySQL员工打卡日志表——数据库练习
137 0
|
2天前
|
SQL 关系型数据库 MySQL
MySQL | 数据库的表的增删改查【进阶】【万字详解】(二)
MySQL | 数据库的表的增删改查【进阶】【万字详解】(二)
|
2天前
|
存储 关系型数据库 MySQL
MySQL | 数据库的表的增删改查【进阶】【万字详解】(一)
MySQL | 数据库的表的增删改查【进阶】【万字详解】(一)

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多