原理
MySQL的InnoDB引擎,数据库data目录下的.ibd文件存储数据,frm文件存放表结构
基本步骤
- 备份数据库data目录下的所有文件
- 创建同名数据库
- 创建同名表结构
- 导出表空间
- 恢复原.ibd文件
- 导入表空间
导出结构
使用frm文件恢复数据表DDL
工具:mysqlfrm (不推荐使用) - dbsake(推荐使用)
curl -s get.dbsake.net > dbsake
chmod u+x dbsake
mv dbsake /usr/bin/
通过frm文件恢复DDL如下
dbsake frmdump /path/to/frmfile
#通过-r可以指定目录,就可以批量解析DDL
dbsake frmdump -r /path/to/datapath/
自动化脚本
功能:导出表空间
、 恢复原.ibd文件
、 导入表空间
<?php
global $argv;
if (count($argv) !== 3) {
echo "缺少参数" . PHP_EOL;
exit(1);
}
//解析命令行参数
[$start_file, $database, $password] = $argv;
$username = 'root';
const ORIGIN = '/www/backup/recovery/';
$worker = __DIR__ . DIRECTORY_SEPARATOR;
$table = $worker . $database . '.sql';
is_file($table) and unlink($table);
//导出表结构
shell_exec(sprintf('dbsake frmdump -r %s%s >> %s', ORIGIN, $database, $table));
$sql = file_get_contents($table);
//正则替换ROW_FORMAT = COMPACT
const SEP = '{{SEP}}';
$regex = '#ENGINE=InnoDB(.+?);#';
$sql = str_replace('CREATE TABLE', SEP . 'CREATE TABLE', $sql);
$sqlArray = explode(SEP, $sql);
foreach ($sqlArray as &$item) {
$matches_format = [];
if (preg_match($regex, $item, $matches_format)) {
$item = str_replace($matches_format[1], $matches_format[1] . ' ROW_FORMAT = COMPACT', $item);
}
}
file_put_contents($table, implode('', $sqlArray));
//正则提取表名称
$regex = '#CREATE TABLE `(?P<name>.+?)`#';
preg_match_all($regex, $sql, $matches);
//生成批量操作脚本
if (!empty($matches['name'])) {
$existInnoDB = false;
$existMyISAM = false;
$sh = '#!/bin/bash' . PHP_EOL;
$discard = '';
$cp = '';
$import = '';
foreach ($matches['name'] as $tableName) {
//是否存在 InnoDB
if (is_file(sprintf('%s%s/%s.ibd', ORIGIN, $database, $tableName))) {
$existInnoDB = true;
$discard .= sprintf('mysql -D%s -u%s -p%s -e "ALTER TABLE %s DISCARD TABLESPACE;"', $database, $username, $password, $tableName) . PHP_EOL;
$import .= sprintf('mysql -D%s -u%s -p%s -e "ALTER TABLE %s IMPORT TABLESPACE;"', $database, $username, $password, $tableName) . PHP_EOL;
}
//是否存在 MyISAM
if (is_file(sprintf('%s%s/%s.MYD', ORIGIN, $database, $tableName))) {
$existMyISAM = true;
}
}
if ($existInnoDB) {
$cp .= sprintf('cp %s%s/*.ibd /www/server/data/%s/', ORIGIN, $database, $database) . PHP_EOL;
}
if ($existMyISAM) {
$cp .= sprintf('cp %s%s/*.MYD /www/server/data/%s/', ORIGIN, $database, $database) . PHP_EOL;
$cp .= sprintf('cp %s%s/*.MYI /www/server/data/%s/', ORIGIN, $database, $database) . PHP_EOL;
}
$cp .= sprintf('chown mysql:mysql -R /www/server/data/%s/', $database) . PHP_EOL;
$cp .= sprintf('chmod 760 -R /www/server/data/%s/', $database) . PHP_EOL;
file_put_contents($worker. $database . '.sh', $sh . $discard . $cp);
file_put_contents($worker . $database . '_import.sh', $sh . $import);
}
echo 'ok' . PHP_EOL;
版权属于:大卫科技Blog
本文链接:https://www.iyuu.cn/archives/495/
转载时须注明出处