【从入门到放弃-MySQL】mysql 数据恢复实战&踩坑记录

背景介绍

线下环境的两个mysql实例安装部署在同一台测试机器上使用不同端口,某天,机器硬盘故障无法启动、并且无法重装系统,需要将重要数据备份重新部署mysql并恢复

操作步骤

备份数据

首先联系pe同学通过带外方式启动故障主机并将硬盘挂载,通过scp方式将两个mysql实例的data目录下所有文件copy备份
注意 切勿仅copy MYD,MYI,frm及ibd文件

准备环境

原主机硬盘故障无法重装系统,需要到现场维修。所以新申请了一台主机使用
安装与原mysql版本一致的mysql
历史原因原主机安装的版本分别为5.1.40 和5.6.26
主机自带5.1.40版本的mysql不需要自己再安装,直接将备份的data目录覆盖copy新机器的data目录 并修改好文件权限即可

安装mysql

高版本的mysql需要重新安装 。步骤如下

下载glibc版

wget https://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz

解压并移动

tar -zxvf mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz
mv mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz /usr/local/mysql

修改权限并初始化

1
2
3
4
chown -R mysql:mysql /usr/local/mysql

cd /usr/local/mysql/bin
# 修改/usr/local/mysql/my.cnf 修改启动端口和文件存放路径
1
2
3
4

sudo ./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --lc_messages_dir=/usr/local/mysql/share --lc_messages=en_US --defaults-file=/usr/local/mysql/my.cnf
#(如忘记密码可执行以下操作免密码登录)
sudo /usr/bin/mysqld_safe --skip-grant-tables &

将原数据data目录覆盖并修改权限

登录验证

至此 mysql数据恢复工作已经完成

踩坑记录

背景

之前两台测试环境mysql分别安装在不同的主机上,其中一台为虚拟主机,硬盘容量只有50G,出现过数据不断累积导致硬盘容量不足的情况,同时因为测试机器资源紧张,考虑将两个mysql实例安装在同一台物理主机上
因物理主机上使用的mysql版本过低 所以新的mysql实例决定升级为高版本

安装时出现的问题

在mysql官网现在了最新的稳定版mysql,解压、进行安装出现以下报错

1
2
3
4
5
6
sudo ./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data  --lc_messages_dir=/usr/local/mysql/share --lc_messages=en_US --defaults-file=/usr/local/mysql/my.cnf   
./mysqld: /usr/lib64/libnuma.so.1: no version information available (required by ./mysqld)
./mysqld: /usr/lib64/libnuma.so.1: no version information available (required by ./mysqld)
./mysqld: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./mysqld)
./mysqld: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./mysqld)
./mysqld: /lib64/libc.so.6: version `GLIBC_2.10' not found (required by ./mysqld)

看报错内容是一些依赖库版本过低导致,当时准备升级版本库
在网上找到了 高版本的libstdc++ 、glibc等进行编译升级

成功安装好了高版本 libstdc++后继续编译安装glibc
编译安装好后,在删除原libc-2.5.so 更改软链为高版本libc时,悲剧出现了!
因缺少libc库,所有的ls、ln、cp、sudo等命令全都无法使用了
在网上找解决办法,可以在执行命令前使用LD_PRELOAD=/lib64/libc-2.5.so提前载入链接库来执行命令,ls、cp等命令可以用了但是使用ln命令时,发现权限不够

ok,没关系 我们在sudo前 也提前载入链接库不就行了?
执行:

??? 尴尬了 竟然不行!查阅资料发现 sudo命令因为安全原因 不能使用LD_PRELOAD的方式 。我当时是在admin用户下 也无法sudo su切换到root 用户
陷入了死循环、不切换到root用户就没权限恢复libc-2.5.so库 不恢复libc-2.5.so就没办法切换到root用户。。。
无解,只能找pe同学帮忙,通过带外的方式恢复libc-2.5.so

解决方式

系统恢复正常了,但是我们高版本的mysql还是没装上,系统库是不敢随便乱动了,那咋办呢?
查看下glibc库版本

天无绝人之路,发现有https://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz glibc2.5版本的glibc版mysql安装包
安装试试?
通过上文 “安装mysql”中的方式 安装成功
接下来修改用户密码、权限,通过mysqldump将原虚拟机中数据库的数据导入到5.6.26版本的数据库中 一台虚拟机上运行两个不同版本实例数据库大功告成~

mysql数据文件介绍

表结构 .frm

.frm文件:存储数据表的框架结构,文件名与表名相同,每个表对应一个同名frm文件,与操作系统和存储引擎无关

MyISAM数据文件

.MYD文件:即MY Data,表数据文件
.MYI文件:即MY Index,索引文件
.log文件:日志文件

InnoDB数据文件

ibdata1、ibdata2等:系统表空间文件,存储InnoDB系统信息和用户数据库表数据和索引,所有表共用
.ibd文件:单表表空间文件,每个表使用一个表空间文件(file per table),存放用户数据库表数据和索引
日志文件: ib_logfile1、ib_logfile2
在备份和恢复数据时,我发现两个不同版本的数据库,ibdata1文件的大小相差很大


查阅资料后发现原来InnoDB有两种不同的数据存储方式:
共享表空间: 某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下。 默认的文件名为:ibdata1 初始化为10M。
独占表空间: 每一个表都将会生成以独立的文件方式来进行存储(.ibd文件,这个文件包括了单独一个表的数据内容以及索引内容)。

存储内容比较

使用独占表空间之后:
每个表对应的数据、索引和插入缓冲 存放在独占表空间(.idb文件)
每个表对应的撤销(undo)信息,系统事务信息,二次写缓冲等还是存放在了原来的共享表空间内(ibdata1文件)

特点比较

具体的共享表空间和独立表空间优缺点如下:
共享表空间:
优点:
可以放表空间分成多个文件存放到各个磁盘上(表空间文件大小不受表大小的限制,如一个表可以分布在不同的文件上)。
数据和文件放在一起方便管理。
缺点:
所有的数据和索引存放到一个文件中,则将有一个很常大的文件,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日志系统这类应用最不适合用共享表空间。
独立表空间:(在配置文件(my.cnf)中设置 innodb_file_per_table)
优点:
每个表都有自已独立的表空间。
每个表的数据和索引都会存在自已的表空间中。
可以实现单表在不同的数据库中移动。
空间可以回收
对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。
a)Drop table操作自动回收表空间
b)如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。
c) 对于使innodb-plugin的Innodb使用truncate table也会使空间收缩。
5、在服务器资源有限,单表数据不是特别多的情况下, 独立表空间明显比共享方式效率更高 . 但是MySQL 默认是共享表空间 。
缺点:
单表体积可能过大,如超过100个G。
查看innodb_file_per_table配置可以看到


两个mysql的配置不一样,一个使用的共享表空间,一个使用的独占表空间,这就是为什么两个ibdata1文件大小相差很大
注意:
因为.frm、.ibd、.MYD、.MYI文件都存在于与database同名的文件夹下,我们通常会注意到
而ibdata1文件是直接在data目录下,不理解其是什么文件的情况下很容易被忽略,所以 这就是在上文备份和恢复数据中提到需要注意的地方

参考文献

http://www.jb51.net/article/134901.htm