muaddiib
7/7/2017 - 6:27 AM

a script use to recover data from innodb's frm and ibd file.

a script use to recover data from innodb's frm and ibd file.

#!/bin/bash
# 
# File: find_mysql_spaceids.sh
#
# Author: huxing1985@gmail.com
# blog: www.colorfuldays.org
# 
# Purpose: This script is a part of a tool recover mysql data from .frm and .idb file.
# step 1. read files under <idbfiledir>,find the "space id",
#         export an file spaceids.txt as "<idb_file_name>  space_id".
# step 2. use the spaceids.txt sort by space_id asc,
#         then generate a script which is use to export the table's create script named export_table_schema.sh. 
#         if there aren't serial space id , the script will fill it with create tmp table sql in test database.
# step 3. generate a script dump the table file to a file named as <table_name>.data.
# 
# export_table_schema.sh use to export table schema after recovery the table schema use frm file.
# export_table_schema.sh use to export table data after recovery table data use idb file.
# 

if [[ $# -lt 3 ]]; then
    echo "find_mysql_spaceids.sh <datafiledir> <dbuser> <dbpasswd> <dbname>"
fi

datafile=$1
user=$2
passwd=$3
dbname=$4

for i in `find $datafile -name "*.ibd"`
do
    hex=`hexdump -C $i | head -n 3 | tail -n 1 | awk '{print $6$7}'`
    echo $i " " $((16#$hex)) >> spaceids.txt
done

# init file create_table.sql 
if [[ -f create_table.sql ]]; then
    echo "" > create_table.sql
fi

if [[ -f export_table_schema.sh ]]; then
    echo "" > export_table_schema.sh
fi

if [[ -f export_table_data.sh ]]; then
    echo "" > export_table_data.sh
fi

last_space_id=1
for i in `cat spaceids.txt | sort -k 2 | awk -F "/" '{print $NF}' ` 
do
    if [[ "x$i" != "x" ]]; then
        new_space_id=`awk '{print $2}' $i`;
        tablename=`awk -F "." '{print $1}' $i`
        if [[ $last_space_id -gt 1 ]]; then
            margin=`expr $new_space_id - $last_space_id`
            for (( a = 1; a < $margin; a++ )); do
                echo 'mysql -u'$user'-p'$passwd' -s -e "use test; CREATE TABLE fill_table'$i' (id bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id)) ENGINE=innodb;" >> create_table.sql' >> export_table_schema.sh
            done
        fi

        echo 'mysql -u'$user'-p'$passwd' -s -e "use '$dbname'; show create table '$tablename';" >> create_table.sql' >> export_table_schema.sh
        echo 'mysql -u'$user'-p'$passwd' -s -e "use '$dbname'; select * from '$tablename' into '$tablename'.data;" ' >> export_table_data.sh
    fi
done
#!/bin/bash;
#
# File fill_table_space.sh
#
# Author: huxing1985@gmail.com
# blog: www.colorfuldays.org
#
# Purpose: This script is a part of a tool recover mysql data from .frm and .idb file.
# This script is use to fill the table spaces.
#

if [[ $# -lt 2 ]]; then
    echo "Usage: fill_table_space.sh <num_of_space_ids> <dbuser> <dbpasswd>"
    exit;
fi

user=$2
passwd=$3
for i in `seq 1 $1`; 
do 
	mysql -u$user -p$passwd e "use test;CREATE TABLE filltmp$i (id bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id)) ENGINE=innodb "; 
done
#!/bin/bash
#
# File: create_init_sql.sh
#
# Author: huxing1985@gmail.com
# blog: www.colorfuldays.org
# 
# Purpose: This script is a part of an tool to recover mysql data from .frm and .idb file.
# This script is read the db data dir's file, generate an script to create the tables.
#
usage()
{
    echo "Usage: $0 <datafiledir> <user> <passwd> <dbname>"
    echo "<dir> is the frm directory."
    echo "<user> is the database's user."
    echo "<passwd> is the database's passwd."
    echo "<dbname> is the datafile's database name."
    echo "output files:"
    echo "create_tmp_table.sql: use to init create tables,use to recover table schema from .frm file"
    echo "discard_tablespace.sh: use to discard tablespace when recover data file."
    echo "import_tablespace.sh: use to discard tablespace when recover data file."
}

if [[ $# -lt 3   ]]; then
    usage;
    exit;
fi

dir=$1
user=$2
passwd=$3
dbname=$4

for i in `find $dir -name "*.frm"`
do
    tablename=`echo $i | awk -F "/" '{print $NF}' | awk -F "." '{print $1}'`
    if [[ "x$tablename" != "x" ]]; then
 	echo 'mysql -u'$user' -p'$passwd' -s -e "use '$dbname'; ALTER TABLE '$tablename' discard tablespace;"' >> discard_tablespace.sh
	echo 'mysql -u'$user' -p'$passwd' -s -e "use '$dbname'; ALTER TABLE '$tablename' import tablespace;"' >> import_tablespace.sh       
	echo "CREATE TABLE $tablename(id int(11) NOT NULL) ENGINE=InnoDB;" >> create_tmp_table.sql
    fi
done

case "$1" in
    -h)
       usage ;;
esac