MySQL Data Recovery with TwinDB Undrop for InnoDB

Transcription

MySQL Data Recovery with TwinDB Undrop for InnoDB
MySQL Data Recovery with
TwinDB Undrop for InnoDB
Aleksandr Kuzminsky
TwinDB
Agenda
●
●
●
●
InnoDB files and their formats
Recovery corrupted databases
Recovery after DROP TABLE
Recovery compressed InnoDB tables
2
InnoDB files and their formats
ibdata1
●
InnoDB dictionary:
○
○
●
Undo
○
●
●
Table name -> index_id
Table structure (duplicates .frm)
Old versions of modified fields
Double write buffer
Pre-innodb_file_per_table tables
InnoDB Index
InnoDB page format
Size, bytes
FIL_HEADER
38
PAGE_HEADER
56
INFINUM+SUPREMUM RECORDS
varies
User records
varies
Free space
Page directory
FIL_TRAILER
varies
fixed
FIL_HEADER
Field
Size Offset
Comment
FIL_PAGE_SPACE
4
0 Space ID the page is in or checksum
FIL_PAGE_OFFSET
4
4 ordinal page number from start of space
FIL_PAGE_PREV
4
8 offset of previous page in key order
FIL_PAGE_NEXT
4
0C offset of next page in key order
FIL_PAGE_LSN
8
10 log serial number of page's latest log record
2
18 current defined types are: FIL_PAGE_INDEX,
FIL_PAGE_UNDO_LOG, FIL_PAGE_INODE,
FIL_PAGE_IBUF_FREE_LIST
8
1A "the file has been flushed to disk at least up to
this lsn" (log serial number), valid only on the
first page of the file
4
22 /* starting from 4.1.x this contains the
space id of the page */
FIL_PAGE_FILE_FLUSH_LSN
PAGE_HEADER (Part I)
Field
Size Offset Comment
PAGE_N_DIR_SLOTS
2
26 number of directory slots in the Page
Directory part; initial value = 2
PAGE_HEAP_TOP
2
28 record pointer to first record in heap
PAGE_N_HEAP
2
2A number of heap records; initial value = 2
PAGE_FREE
2
2C record pointer to first free record
PAGE_GARBAGE
2
2E "number of bytes in deleted records"
PAGE_LAST_INSERT
2
30 record pointer to the last inserted record
PAGE_DIRECTION
2
32 either PAGE_LEFT, PAGE_RIGHT, or
PAGE_NO_DIRECTION
PAGE_HEADER (Part II)
Field
PAGE_N_DIRECTION
PAGE_MAX_TRX_ID
Size
Offset
Comment
2
34 number of consecutive inserts in the same direction,
e.g. "last 5 were all to the left"
2
36 number of user records
8
38 the highest ID of a transaction which might have
changed a record on the page (only set for secondary
indexes)
2
40 level within the index (0 for a leaf page)
8
42 identifier of the index the page belongs to
PAGE_BTR_SEG_LEAF
10
4A "file segment header for the leaf pages in a B-tree"
(this is irrelevant here)
PAGE_BTR_SEG_TOP
10
54 "file segment header for the non-leaf pages in a Btree" (this is irrelevant here)
Record format (REDUNDANT)
Record format (COMPACT)
●
Recovery corrupted databases
InnoDB dictionary
●
SYS_TABLES
○
●
SYS_INDEXES
○
●
table_id => index_id
SYS_COLUMNS
○
●
human-readable name => table_id
table_id => table fields
SYS_FIELDS
○
index_id => index fields
Recover table structure (mysqlfrm)
find . -name '*.frm' | \
xargs mysqlfrm --basedir /usr/ --port 3000 | \
grep -v ^# | \
sed 's/^$/;/' | \
sed -e 's/\\(^) ENGINE=.*\\)/\\1;/' -e 's/^;$//' | \
sed -e 's/CREATE \\(.*VIEW.*\\)/CREATE \1;/'";
Recover table structure (sys_parser)
./sys_parser -u root -d test sakila/actor
CREATE TABLE `actor`(
`actor_id` SMALLINT UNSIGNED NOT NULL,
`first_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL,
`last_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL,
`last_update` TIMESTAMP NOT NULL,
PRIMARY KEY (`actor_id`)
) ENGINE=InnoDB;
stream_parser
Find InnoDB pages in stream of bytes:
./stream_parser -f /var/lib/mysql/ibdata1
./stream_parser -f /var/lib/mysql/sakila/actor.ibd
./stream_parser -f /dev/sda
c_parser
Fetch records from InnoDB page
./c_parser -6
-f pages-actor.ibd/FIL_PAGE_INDEX/0000000000000015.page \
-t sakila/actor.sql
●
Recovery after DROP TABLE
Recovery after DROP
Same as corrupted except:
1.
Records in the dictionary are deleted. Use -D with c_parser
2.
.ibd files will be deleted
3.
.frm files will be deleted
Undelete dictionary records
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.
page \
-t dictionary/SYS_TABLES.sql \
> dumps/default/SYS_TABLES \
2> dumps/default/SYS_TABLES.sql
DROP and innodb_file_per_table
●
Keep MySQL files on a separate partition!
○
○
●
Easy to remount it read-only
No need to take image, ready to use
stream_parser -f /dev/sdb
Recovery structure
.frm file is gone, check sys_parser slide.
●
Recovery compressed InnoDB tables
Recovery compressed tables
●
●
Decompress each page
Recover as normal page
https://code.launchpad.net/~akuzminsky/percona-data-recovery-tool-for-innodb/decompress
https://recovery.twindb.com
Section Information