欢迎访问我的博客,你的支持,是我最大的动力!

MySQL管理工具集 MySQL Utilities | 利用frm和ibd文件恢复表数据

Mysql-笔记 马从东 286℃ 评论
目录:
[显示]

MySQL Utilities是官方提供的MySQL管理工具集
下载地址:https://downloads.mysql.com/archives/utilities/
当前版本1.6.5 https://downloads.mysql.com/archives/get/file/mysql-utilities-1.6.5-1.el7.noarch.rpm
二进制包:https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz
二进制包:https://downloads.mysql.com/archives/get/file/mysql-utilities-1.6.5.tar.gz

MySQL Utilities是基于python编写的,不需要安装其他任何工具和库
提供一组命令行工具用于维护和管理MySQL服务器:
数据库层面:复制、比较、差异、导出、导入
审核日志层面:
服务器层面:实例克隆、实例信息
系统层面:磁盘使用情况、冗余索引、搜索元数据、进程
高可用层面:主从复制、故障转移、主从同步

安装

尽量不要用 yum 来安装 mysql-utilities 1.6.5版本的mysql-utilites和mysql-connector-python有兼容性问题
实测,可以使用 yum 安装 1.3.6的mysql-utilites和1.1.6的mysql-connector-python

# 安装 1.3.6 版本 yum方式
yum install https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/Packages/m/mysql-connector-python-1.1.6-1.el7.noarch.rpm
yum install https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/Packages/m/mysql-utilities-1.3.6-1.el7.noarch.rpm
# 卸载
yum -y remove mysql-connector-python
# 安装 1.6.5 版本 二进制方式
# 最新版本 1.6.5 建议使用二进制安装(tar包中自带connector无需单独安装)
wget https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz
tar zxf mysql-utilities-1.6.5.tar.gz
cd mysql-utilities-1.6.5
python ./setup.py build
python ./setup.py install

连接MySQL服务器

login-paths(.mylogin.cnf)

推荐方式,加密的,不会暴露连接信息
mysql_config_editor set --login-path=mysql_77 --host=192.168.1.77 --user=root --port=3306 --password
mysql_config_editor是mysql自带工具,执行如上命令后会在家目录生成加密文件.mylogin.cnf
查看文件内容:
mysql_config_editor print --login-path=mysql_77
[mysql_77]
user = root
password = *****
host = 192.168.1.77
port = 3306
使用:
mysqlserverinfo --server=mysql_77 --format=vertical
mysql --login-path=mysql_77

使用配置文件

/etc/my.cnf 中[client]段
[client]
port = 3306
socket = /tmp/mysql.sock
user=root
password=root123
使用:
mysqlserverinfo --server=/etc/my.cnf[client] --format=vertical

命令行参数

该方式最不安全
<user>[:<passwd>]@<host>[:<port>][:<socket>]
使用:
mysqlserverinfo --server=root:root123@192.168.1.77:3306 --format=vertical

数据库层面

以下工具工作在数据库级别,用于管理一个或多个服务器的数据库

mysqldbcompare
- 比较两个服务器或同个服务器上的数据库
- 比较定义文件和数据
- 产生差异报告
- 生成差异性的转换SQL语句
mysqldbcopy
- 服务器之间复制数据库
- 在同一服务器上克隆数据库
- 支持重命名
mysqldbexport
- 从一个或多个数据库导出元数据或数据
- 支持格式:SQL CSV TAB Grid Vertical
mysqldbimport
- 从一个或多个文件导入元数据或数据
- 支持mysqldbexport的各种格式
mysqldiff
- 比较对象的定义
- 产生差异报告

mysqldbcompare

mysqldbcompare --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1:db2

比较两个数据库对象的差异,包括表、视图、触发器、存储过程、函数、事件
比较检测的步骤:
1、数据库定义,确保数据库存在,若不存在,不需要下一步检测
2、数据库对象,--skip-object-compare跳过
3、对象定义,比较create语句,--skip-diff跳过
4、检测表行数,仅检查行数是否一致,--skip-row-count跳过
5、表数据一致性,先全表checksum校验,然后找出不同 --skip-checksum-table跳过表校验,--skip-data-check跳过数据检查

--diff-style 定义输出风格:
unified 默认,统一格式
context 上下文格式
differ differ-style格式
sql 转换语句
--format 显示行丢失或改变的输出
grid 默认,网格化
vertical 类似\G
csv 、tab
--changes-for 控制差异报告(默认)还是转换报告(需要--difftype=sql)

权限:
对所比较的数据库,select,create temporary tables,insert
mysql数据库,select
防止比较操作被写入二进制日志,需要启用 --disable-binary-logging

mysqldbcompare --server1=mysql_78 --server2=mysql_88 db1:db2 --run-all-tests

实际上并不好用

mysqldbcopy

mysqldbcopy --source=user:pass@host:port:socket --destination=user:pass@host:port:socket orig_db:new_db

从源服务器上复制一个数据库到另一个目标服务器上,源服务器和目标服务器可以是同一台,数据库名字可相同也可不同
希望复制的新库或新的服务器改变存储引擎,在这种情况下,使用mysqldbcopy工具非常便捷

参数:
-d,--drop-first 若目录中存在,先drop
--new-storage-engine 目标使用新的引擎
--default-storage-engine 目标的默认引擎
--locking 复制过程中的锁级别:no-locks,lock-all,snaphot(默认)
--rpl-user
--rpl  直接搭建主从

权限:
源数据库,select,show view,event,trigger  同时mysql数据库要有select
目标数据库,create,alter,select,insert,update,lock tables,drop(--drop-first),super(二进制日志启用),create view,create routine,execute,event,trigger,grant option,

mysqldbcopy --source=mysql_77 --destination=mysql_77 ecard:new_ecard
mysqldbcopy --source=mysql_77 --destination=mysql_77 test:new_test -vvv --drop-first --locking=lock-all
mysqldbcopy --source=mysql_77 --destination=mysql_88 --drop-first --all  #复制整个实例

mysqldbexport

mysqldbexport --server=user:pass@host:port:socket db1, db2, db3

导出数据

选项:
--file-per-table 每个表单独保存,格式,db.table.csv
--rpl 和 --rpl-user 包含主从同步语句 --comment-rpl 注释主从语句

权限:
源服务器 select,show view mysql数据库的select

# 只导出定义语句
mysqldbexport --server=mysql_77 --format=sql ecard --export=definitions > ecard.sql
# 只导入数据 批量插入
mysqldbexport --server=mysql_77 --format=sql ecard --export=data --bulk-insert > ecard.sql
mysqldbexport --server=mysql_77 --format=sql ecard --export=data --bulk-insert --file-per-table  #一个表一个文件

若数据库中并不是所有表是innodb引擎,为确保数据一致性,需要在导入 前锁定表,加上 --locking=lock-all
# 导出结构和数据 并为当前数据库创建一个从服务器
mysqldbexport --server=mysql_77 --format=sql ecard --export=both --rpl-user=root --rpl=master > ecard.sql

mysqldbimport

mysqldbimport --server=user:pass@host:port:socket db1.csv db2.sql db3.grid

导入数据,若一个对象已经存在于目标服务器上,将先删除再导入

选项:
--format 格式
--import data definitions(默认) both
--drop-first
--no-headers 排除表头,适用于tab csv格式
--dryrun  预导入不执行,测试用。测试文件是否有效
--table
--skip-blobs --skip-rpl --skip-gtid
--skip=SKIP_OBJECTS 忽略的对象
tables, views, triggers, procedures, functions,events, grants, data, create_db

mysqldbimport --server=mysql_77 --import=definitions --format=csv data.csv
mysqldbimport --server=mysql_77 --import=data --bulk-insert --format=csv data.csv

mysqldiff

mysqldiff --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1.object1:db2.object1 db3:db4

比较对象定义是否相同,不能比较数据是否一致

mysqldiff --server1=mysql_77 test.mytest:test.t
mysqldiff --server1=mysql_77 test.mytest:test.t --difftype=sql --show-reverse -vvv

审核日志层面

审核日志是MySQL企业版的功能,必需开启审核日志插件

mysqlauditadmin
- 监控审计日志
- 复制 轮换和配置审核日志
mysqlauditgrep
- 搜索日志
- 输出不同格式的结果

mysqlauditadmin --server=user:pass@host:port --show-options
mysqlauditgrep [options] AUDIT_LOG_FILE

服务器层面

mysqlserverclone
- 克隆一个新的实例
mysqlserverinfo
- 显示服务器信息
- 搜索主机上运行的服务
- 访问在线或离线的服务

mysqlserverclone

mysqlserverclone --server=user:pass@host:port:socket --new-data=/tmp/data2 --new-port=3310 --new-id=12 --root-password=root

在同一个主机上创建一个新的服务实例,创建一个新的datadir和socket文件,并启动该实例
克隆前要先删除datadir目录下文件并配置读写权限

mysqlserverclone --server=instance_3306 --new-data=/data/tmp/ --new-port=3310 --root-password=3310 --mysqld=--log-bin=mysql-bin-3310 --new-id=3310 --user=mysql -vvv

mysqlserverinfo

mysqlserverinfo --server=user:pass@host:port:socket --format=grid

选项:
-d, --show-defaults 显示config文件信息
--show-servers 若启动了多个实例 可使用该命令查看

mysqlserverinfo --server=mysql_77 -d --format=grid -vvv --show-defaults  #额外显示defaults信息
mysqlserverinfo --server=mysql_77 -d --format=grid -vvv --show-defaults --no-headers

系统层面

mysqldiskusage
- 显示数据库磁盘使用情况
- 生成报表支持 sql csv tab grid vertical
mysqlfrm
- 读取 frm 文件
- 生成表 create 语句
mysqlindexcheck
- 读取一个或多个表的索引
- 检查冗余和重复的索引
mysqlmetagrep
- 搜索元数据
- 正则表达式搜索数据库
- 搜索查询生成sql语句
mysqlprocgrep
- 搜索进程信息
- 搜索生成 sql 语句
- kill匹配到的进程
mysqluserclone
- 克隆用户
- 显示用户权限
mysqluc
- MySQL Utilities命令行客户端
- 允许长连接到MySQL服务器
- 可使用tab完成工具名称和选项
- 允许使用命令短名称 如 mysqlserverinfo -> serverinfo

mysqldiskusage

mysqldiskusage --server=user:pass@host:port:socket db1 --all

显示一个或多个数据库所使用磁盘空间大小,可显示二进制日志、慢查询日志、错误日志、查询日志、二进制中继日志、innodb表空间大小
读取文件系统失败,或者服务不在本地,那么将不能确定文件大小

选项:
-b, --binlog
-r, --relaylo
-l, --logs
-i, --innodb
-m, --empty
-a, --all

mysqldiskusage --server=mysql_77
mysqldiskusage --server=mysql_77 --format=g -a -vvv

mysqlfrm

mysqlfrm --server=[user[:<pass>]@host[:<port>][:<socket>]|<login-path>[:<port>][:<socket>]]  [path\tbl1.frm|db:tbl.frm]

恢复工具,读取frm文件并从中找到视图定义语句
注意:不能读取到外键约束和自增长序列

再生实例模式:
--basedir或--server选项连接到已经安装的实例。该过程不会改变原始frm文件,指定--port选项给再生实例使用,该端口不能与现有端口冲突,读取完frm文件后,再生实例会关闭,所有临时文件将被删除
诊断模式:
指定--diagnostic选项,byte-by-byte读取frm文件,尽可能多的恢复信息,该模式不能校验字符集

选项:
--quiet 仅显示create语句和警告、错误信息
--show-stats 统计frm文件信息

mysqlfrm --basedir=/usr ttlsa_com:data.frm --port=3333 --user=mysql -vvv
mysqlfrm --diagnostic /root/data_center  #读取data_center目录下所有frm文件
mysqlfrm --diagnostic /root/t7_data_center/t7_venue.frm

利用frm和ibd恢复数据

在某此情况下,数据库崩溃,无法启动,此时,可利用磁盘中的frm和ibd文件恢复数据,因为数据库存储的数据实际上还是存储在文件里的

myisam引擎:直接复制这三个文件即可使用,不需要恢复
xxx.frm 表结构文件
xxx.MYD 数据文件
xxx.MYI 索引文件
innodb引擎innodb某些元数据是存储在ibdata1文件中的
xxx.frm 表结构文件  -> 使用mysqlfrm获取
xxx.ibd 数据和索引文件 -> 覆盖文件

恢复前提:innodb_file_per_table = 1
若不能使用mysqlfrm工具时,要获得表结构语句[不推荐]:
1、创建同名表,create table t_access(id int);
2、使用要恢复表的frm文件替换同名frm文件,修改frm文件权限 chown mysql:mysql xxx.frm
3、flush tables;
4、show create table t_access;  #注意,此时数据库日志中会显示字段数量,如
[Warning] InnoDB: Table tt/t_access contains 1 user defined columns in InnoDB, but 4 columns
5、重新创建拥有相同字段的同名表
6、再次用要恢复的表的frm文件替换同名frm文件,修改权限
7、数据库关机
8、配置文件设置 innodb_force_recovery=6 重启数据库
9、得到表结构
显然,使用mysqlfrm工具更为方便

利用frm和ibd恢复数据操作流程

场景:因数据库损坏,ibdata1文件被误删,数据库启动后,所有innodb引擎的表能显示名称,但打开时提示表不存在
目标:需要恢复其中一张表 t7_system_nodes 可利用的文件为
/tmp/t7_system_nodes.frm -> 存储了表结构
/tmp/t7_system_nodes.ibd -> 存储了表数据

第一步:利用mysqlfrm工具恢复表结构
mysqlfrm --diagnostic /tmp/t7_system_nodes.frm --quiet
# WARNING: Cannot generate character set or collation names without the --server option.
# CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
CREATE TABLE tmp.t7_system_nodes (
id int(10) unsigned NOT NULL AUTO_INCREMENT comment '主键ID',
title varchar(150) DEFAULT NULL comment '节点名',
action varchar(60) DEFAULT NULL comment '路径名',
status tinyint(1) DEFAULT NULL comment '状态(1: 启用, 2: 禁用)',
remark varchar(765) DEFAULT NULL comment '备注',
sort smallint(4) DEFAULT NULL comment '排序',
pid int(11) DEFAULT NULL comment '父节点ID',
level tinyint(1) DEFAULT NULL comment '等级',
PRIMARY KEY PRIMARY (id)
) ENGINE=InnoDB COMMENT '系统节点表';
第二步:在任意数据库创建该表 如test库
注意,上一步的表名包含库名tmp.t7_system_nodes 创建时需要把库名去掉或改成test.t7_system_nodes
mysql> CREATE TABLE t7_system_nodes (
id int(10) unsigned NOT NULL AUTO_INCREMENT comment '主键ID',
title varchar(150) DEFAULT NULL comment '节点名',
action varchar(60) DEFAULT NULL comment '路径名',
status tinyint(1) DEFAULT NULL comment '状态(1: 启用, 2: 禁用)',
remark varchar(765) DEFAULT NULL comment '备注',
sort smallint(4) DEFAULT NULL comment '排序',
pid int(11) DEFAULT NULL comment '父节点ID',
level tinyint(1) DEFAULT NULL comment '等级',
PRIMARY KEY PRIMARY (id)
) ENGINE=InnoDB COMMENT '系统节点表';
Query OK, 0 rows affected
第三步:卸载表空间
mysql> alter table t7_system_nodes discard tablespace ;
Query OK, 0 rows affected
该操作会删除t7_system_nodes.ibd文件
第四步:复制t7_system_nodes.ibd文件
将要还原数据的t7_system_nodes.ibd文件复制到数据库目录下,并修改文件属主
cp /tmp/t7_system_nodes.ibd /data/mysql/test
chown mysql:mysql /data/mysql/test/t7_system_nodes.ibd
第五步:导入表空间
mysql> alter table t7_system_nodes import tablespace;
Query OK, 0 rows affected
第六步:检查数据是否已恢复
mysql> select count(*) from t7_system_nodes;
+----------+
| count(*) |
+----------+
| 75 |
+----------+
1 row in set
数据已经恢复!
该过程不需要重启数据库实例、不需要修改数据库配置、操作方便,推荐
mysqlindexcheck

mysqlindexcheck --server=user:pass@host:port:socket db1.table1 db2 db3.table2

识别重复的和潜在冗余的表索引
除了这些库的表mysql, INFORMATION_SCHEMA, performance_schema,可以扫描所有其他库

选项:
--show-drops 显示drop语句删除冗余索引
--show-indexes 显示每个表的索引

mysqlindexcheck --server=mysql_77 ecard
mysqlindexcheck --server=mysql_77 ecard --show-drops --show-indexes --report-indexes

mysqlmetagrep

mysqlmetagrep --server=user:pass@host:port:socket [options] pattern

搜索数据库对象

mysqlmetagrep --server=mysql_77 --pattern="d_"
mysqlmetagrep --server=mysql_77 --pattern="%school%"
mysqlmetagrep --server=mysql_77 -Gb --pattern="ent"  #-Gb正则匹配

mysqlprocgrep

mysqlprocgrep --server=user:pass@host:port:socket [options]

搜索进程,并执行某些操作

选项:
--age 指定时间
--match-xxx 指定匹配条件,xxx可以是 id user host db command info state
--kill-connection
--kill-query

mysqlprocgrep --server=mysql_77
mysqlprocgrep --server=mysql_77 --match-user=root  --kill-connection --match-state=sleep  #kill掉root用户状态为sleep的进程
mysqlprocgrep --kill-connection --match-state=sleep --print-sql  #生成kill空闲进程的存储过程
mysqlprocgrep --server=mysql_77 --match-user=lepei --age=5 --kill-query

kill进程测试并不成功

mysqluserclone

mysqluserclone --source=user:pass@host:port:socket --destination=user:pass@host:port:socket joe@localhost sam:secret1@localhost

以现有数据库上的用户作为模板创作一个或多个具有相同权限的账户

选项:
-d, --dump 显示grant语句并不执行
-l, --list 列出所有用户

# 显示所有用户
mysqluserclone --source=mysql_77 --list -vvv
# 复制admin用户到3308实例,用户名为user1,密码为passwd1,主机为10.%
mysqluserclone --source=instance_3306 --destination=instance_3308 admin@localhost  user1:passwd1@10.% -vvv
# 显示用户grant语句
mysqluserclone --source=mysql_77 --dump --list

mysqluc

命令行工具,允许执行用户当前安装mysql工具的任何命令 --utildir用于指定MySQL Utilities安装路径
支持tab 支持管道

mysqluc -e "help utilities"
mysqluc -e "set SRV=mysql_77; mysqldiskusage --server=$SRV" -vvv

help
help mysqldiskusage

高可用性层面

mysqlfailover
- 提供对复制结构故障自动转移
- 使用GTID
mysqlreplicate
- 设置复制
- 从一开始 当前 特定binlog pos复制
mysqlrplms
- 提供round-robin multi-source复制
- 使用GTID
mysqlrpladmin
- 管理复制拓扑
- 允许恢复主
- 命令包括 select failover gtid health start stop switchover
mysqlrplcheck
- 检查复制配置
- 在主上测试二进制日志
mysqlrplshow
- 查看从连接到的主
- 可递归搜索
- 显示复制拓扑图或列表
mysqlrplsync
- 检查服务器之间数据一致性
- 使用GTID

mysqlfailover

mysqlfailover --master=root@localhost --discover-slaves-login=root --candidates=root@host123:3306,root@host456:3306

对复制进行健康检测和实现故障自动转移
需要gtid_mode=ON
所有从必需使用--report-host 和 --report-port 启动参数
许用户指定外部脚本在切换和故障转移命令之前或之后执行

--failover-mode
auto 执行故障自动转移到第一候选人
elect 与auto一样,但若在指定候选从列表中没有可行的,不检查剩余从,产生错误并退出
fail 产生一个错误,不进行故障转移

mysqlreplicate

mysqlreplicate --master=root@localhost:3306 --slave=root@localhost:3310 --rpl-user=rpl:passwd

在两台服务器间设置和启动复制

mysqlrplms

mysqlrplms --slave=root@localhost:3306 --masters=root@localhost:3310,root@localhost:3311 --rpl-user=rpl:passwd

设置多主单从的复制,即从多个主复制

mysqlrpladmin

mysqlrpladmin --slaves=root@localhost:3306 <command>

MySQL复制的管理工具

mysqlrplcheck

mysqlrplcheck --master=root@localhost:3306 --slave=root@localhost:3310

检查复制的先决条件

mysqlrplshow

mysqlrplshow --master=root@localhost:3306

显示主从复制关系,并绘制主的图形结构,标注每个主机名和端口

mysqlrplsync

mysqlrplsync --master=user:pass@host:port --slaves=user:pass@host:port [<db_name>[.<tbl_name>]]

对复制同步进行检查,检查主从或从从之间的数据是否一致,并报告丢失的对象以及数据

 

参考:https://blog.csdn.net/anzhen0429/article/details/78007341

转载请注明:轻风博客 » MySQL管理工具集 MySQL Utilities | 利用frm和ibd文件恢复表数据

喜欢 (0)or分享 (0)