myi恢复mysql数据库,上海这雨要下到什么时候

发布时间:2022-11-19

本文目录一览:

  1. 怎么恢复MySQL数据库
  2. mysql卸载后怎么找回原来建的数据库?
  3. 如何把.frm,.myd,myi的空间商备份的mysql数据导回mysql

怎么恢复MySQL数据库

  • xxx.frm
  • xxx.MYD
  • xxx.MYI 如果有以上三个文件,则你可以在 MySQL 中新建一个数据库,它会生成同样的三个文件,然后你用你的备份文件覆盖即可。 前提是版本一致。

mysql卸载后怎么找回原来建的数据库?

每个 DBA 是不是都有过删库的经历?删库了没有备份怎么办?备份恢复后无法启动服务什么情况?表定义损坏数据无法读取怎么办? 我曾遇到某初创互联网企业,因维护人员不规范的备份恢复操作,导致系统表空间文件被初始化,上万张表无法读取,花了数小时才抢救回来。 当你发现数据无法读取时,也许并非数据丢失了,可能是 DBMS 找不到描述数据的信息。

背景

先来了解下几张关键的 InnoDB 数据字典表,它们保存了部分表定义信息,在我们恢复表结构时需要用到。

SYS_TABLES

描述 InnoDB 表信息:

CREATE TABLE `SYS_TABLES` (
  `NAME` varchar(255) NOT NULL DEFAULT '',
  `ID` bigint(20) unsigned NOT NULL DEFAULT '0',
  `N_COLS` int(10) DEFAULT NULL,
  `TYPE` int(10) unsigned DEFAULT NULL,
  `MIX_ID` bigint(20) unsigned DEFAULT NULL,
  `MIX_LEN` int(10) unsigned DEFAULT NULL,
  `CLUSTER_NAME` varchar(255) DEFAULT NULL,
  `SPACE` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

SYS_INDEXES

描述 InnoDB 索引信息:

CREATE TABLE `SYS_INDEXES` (
  `TABLE_ID` bigint(20) unsigned NOT NULL DEFAULT '0',
  `ID` bigint(20) unsigned NOT NULL DEFAULT '0',
  `NAME` varchar(120) DEFAULT NULL,
  `N_FIELDS` int(10) unsigned DEFAULT NULL,
  `TYPE` int(10) unsigned DEFAULT NULL,
  `SPACE` int(10) unsigned DEFAULT NULL,
  `PAGE_NO` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`TABLE_ID`,`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

SYS_COLUMNS

描述 InnoDB 表的字段信息:

CREATE TABLE `SYS_COLUMNS` (
  `TABLE_ID` bigint(20) unsigned NOT NULL,
  `POS` int(10) unsigned NOT NULL,
  `NAME` varchar(255) DEFAULT NULL,
  `MTYPE` int(10) unsigned DEFAULT NULL,
  `PRTYPE` int(10) unsigned DEFAULT NULL,
  `LEN` int(10) unsigned DEFAULT NULL,
  `PREC` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`TABLE_ID`,`POS`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

SYS_FIELDS

描述全部索引的字段列:

CREATE TABLE `SYS_FIELDS` (
  `INDEX_ID` bigint(20) unsigned NOT NULL,
  `POS` int(10) unsigned NOT NULL,
  `COL_NAME` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`INDEX_ID`,`POS`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

./storage/innobase/include/dict0boot.h 文件定义了每个字典表的 index id,对应 id 的 page 中存储着字典表的数据。 这里我们需要借助 undrop-for-innodb 工具恢复数据,它能读取表空间信息得到 page,将数据从 page 中提取出来。

工具使用

安装 undrop-for-innodb

# wget
# yum install -y gcc flex bison
# make
# make sys_parser

sys_parser 读取表结构信息

sys_parser [-h] [-u] [-p] [-d] databases/table

stream_parser 读取 InnoDB page 从 ibdata1 或 ibd 或分区表

# ./stream_parser
You must specify file with -f option
Usage: ./stream_parser -f innodb_datafile [-T N:M] [-s size] [-t size] [-V|-g]
Where:
  -h         - Print this help
  -V or -g   - Print debug information
  -s size    - Amount of memory used for disk cache (allowed examples 1G 10M). Default 100M
  -T         - retrieves only pages with index id = NM (N - high word, M - low word of id)
  -t size    - Size of InnoDB tablespace to scan. Use it only if the parser can't determine it by himself.

c_parser 从 innodb page 中读取记录保存到文件

# ./c_parser
Error: Usage: ./c_parser -4|-5|-6 [-dDV] -f InnoDB page or dir -t table.sql [-T N:M] [-b external pages directory]
Where
  -f InnoDB page(s) -- InnoDB page or directory with pages(all pages should have same index_id)
  -t table.sql -- CREATE statement of a table
  -o file -- Save dump in this file. Otherwise print to stdout
  -l file -- Save SQL statements in this file. Otherwise print to stderr
  -h -- Print this help
  -d -- Process only those pages which potentially could have deleted records (default = NO)
  -D -- Recover deleted rows only (default = NO)
  -U -- Recover UNdeleted rows only (default = YES)
  -V -- Verbose mode (lots of debug information)
  -4 -- innodb_datafile is in REDUNDANT format
  -5 -- innodb_datafile is in COMPACT format
  -6 -- innodb_datafile is in MySQL 5.6 format
  -T -- retrieves only pages with index id = NM (N - high word, M - low word of id)
  -b dir -- Directory where external pages can be found. Usually it is pages-XXX/FIL_PAGE_TYPE_BLOB/
  -i file -- Read external pages at their offsets from file.
  -p prefix -- Use prefix for a directory name in LOAD DATA INFILE command

恢复场景

场景1:drop table

是否启用了 innodb_file_per_table 其恢复方法有所差异,当发生误删表时,应尽快停止 MySQL 服务,不要启动。若 innodb_file_per_table=ON,最好只读方式重新挂载文件系统,防止其他进程写入数据覆盖之前块设备的数据。 如果评估记录是否被覆盖,可以表中某些记录的作为关键字看是否能从 ibdata1 中筛选出。

# grep WOODYHOFFMAN ibdata1
Binary file ibdata1 matches

也可以使用 bvi(适用于较小文件)或 hexdump -C(适用于较大文件)工具。 以表 sakila.actor 为例:

CREATE TABLE `actor` (
  `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`actor_id`),
  KEY `idx_actor_last_name` (`last_name`)
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8

恢复表结构信息

  1. 解析系统表空间获取 page 信息:
./stream_parser -f /var/lib/mysql/ibdata1
  1. 新建一个 schema,把系统字典表的 DDL 导入:
cat dictionary/SYS_* | mysql recovered
  1. 创建恢复目录:
mkdir -p dumps/default
  1. 解析系统表空间包含的字典表信息:
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql dumps/default/SYS_TABLES 2 dumps/default/SYS_TABLES.sql
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000002.page -t dictionary/SYS_COLUMNS.sql dumps/default/SYS_COLUMNS 2 dumps/default/SYS_COLUMNS.sql
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql dumps/default/SYS_INDEXES 2 dumps/default/SYS_INDEXES.sql
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000004.page -t dictionary/SYS_FIELDS.sql dumps/default/SYS_FIELDS 2 dumps/default/SYS_FIELDS.sql
  1. 导入恢复的数据字典:
cat dumps/default/*.sql | mysql recovered
  1. 读取恢复后的表结构信息:
./sys_parser -pmsandbox -d recovered sakila/actor

由于 5.x 版本 innodb 引擎并非完整记录表结构信息,会丢失 AUTO_INCREMENT 属性、二级索引和外键约束,DECIMAL 精度等信息。 若是 mysql 5.5 版本 frm 文件被从系统删除,在原目录下 touch 与原表名相同的 frm 文件,还能读取表结构信息和数据。若只有 frm 文件,想要获得表结构信息,可使用 mysqlfrm --diagnostic /path/to/xxx.frm,连接 mysql 会显示字符集信息。

innodb_file_per_table=OFF

因为是共享表空间模式,数据页都存储在 ibdata1,可以从 ibdata1 文件中提取数据。

  1. 获取表的 table id:
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
  1. 利用 table id 获取表的主键 id:
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
  1. 知道了主键 id,就可以从对应 page 中提取表数据,并生成 sql 文件:
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t sakila/actor.sql dumps/default/actor 2 dumps/default/actor_load.sql
  1. 最后导入恢复的数据:
cat dumps/default/*.sql | mysql sakila

更多详细情况点击 网页链接

如何把.frm,.myd,myi的空间商备份的mysql数据导回mysql

把 mysql 数据库的 *.frm, *.myd, *.myi 文件导到数据的方法

  1. 最简单方法:直接拷贝到数据库的 data 下的数据库文件夹,前提是 mysql 的版本一致,字体一致。 此方法简单快捷但不是每个人都能做到。
  2. **本地安装 mysql 数据库,转换 *.frm, *.myd, .myi 文件为 .sql 文件
    • 首先安装 mysql,最好版本和服务器一致。
    • 字体也要一致(不一致导入后有后遗症-乱码)。
    • 然后用建库命令创建新的数据库:
      CREATE DATABASE name;
      
    • 然后去你安装的 mysql 目录下的 data 文件夹下就有个 name 文件夹。
    • 把你的 *.frm, *.myd, *.myi 文件统统拷贝到 data 文件夹下。
    • 然后在命令提示符下进入到 mysql 安装目录的 bin 目录下进行导出为 *.sql 文件:
      mysqldump -uroot -p name > name.sql
      

自己操作的几点体会:

  1. mysql 数据库最好安装在根目录下,这样在命令提示符时省很多事情。
  2. *.sql 倒出时最好是一个表一个表的导出,文件名最好为 dataname_tabname.sql,好记便于导入。
  3. 而且一个表的导出 *.sql 文件小。