Възтановяване на InnoDB таблици в MySQL

Възтановяване на innodb таблици в MySQLПривет,

Наскоро един наш MySQL сървър крашна (заради спиране на тока) и след като запали, наблюдавахме много проблеми с InnoDB таблици от типа:

 

11:43:59 mentos mysqld: 160607 11:43:59 [Warning] InnoDB: Cannot open table finance/users from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.

Стигне ли се до тук, най-лесното възтановяване става от dump на базата и restore. Обаче ако нямаме такъв става весело!
В този пост ще споделя как оправих подобен проблем с бази които нямаха бекъп, чрез mysql-utilities.

  1. Инсталирах mysql-apt-config от сайта на MySQL (задължително трябва да е най-новата версия, че старите правиха проблеми) – нужен е заради mysqlfrm
  2. Направих копие на /var/lib/mysql/ в /root/mysql/
  3. Следвах следните стъпки:

В моят случай базата finance беше счупена – нито една нейна таблица не работеше. За възтановяването беше нужно да изкарам структурата на всяка една от тези таблици. Това става по следния начин:

root@mysql-niki-test:/var/lib/mysql/finance# mysqlfrm --basedir /usr --port 3316 --user=root --verbose /root/mysql/finance/users.frm
# Spawning server with --user=root.
# Starting the spawned server on port 3316 ... done.
# Reading .frm files
#
# Reading the users.frm file.
#
# CREATE statement for /root/mysql/finance/users.frm:
#

CREATE TABLE `finance`.`users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`names` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`is_admin` tinyint(4) NOT NULL DEFAULT '0',
`department_id` int(11) NOT NULL,
`active` tinyint(4) NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`),
KEY `department_id` (`department_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Така вече имах структурата – следва и самото възтановяване:

mysql> use finance;
Database changed
mysql> drop table users;
Query OK, 0 rows affected (0.00 sec)

mysql> ^DBye


root@mysql-niki-test:/var/lib/mysql/finance# rm users.ibd

mysql> use finance;
mysql> CREATE TABLE `finance`.`users` (
-> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> `names` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
-> `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
-> `password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
-> `is_admin` tinyint(4) NOT NULL DEFAULT '0',
-> `department_id` int(11) NOT NULL,
-> `active` tinyint(4) NOT NULL,
-> `remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
-> PRIMARY KEY (`id`),
-> UNIQUE KEY `users_email_unique` (`email`),
-> KEY `department_id` (`department_id`)
-> ) ENGINE=InnoDB ROW_FORMAT=compact DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
-> ;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table users discard tablespace;
Query OK, 0 rows affected (0.01 sec)

mysql> ^DBye

копирах информацията на таблиците от бекъпа:

root@mysql-niki-test:/var/lib/mysql/finance# cp /root/mysql/finance/users.* . -rpf

и приложих:

mysql> use finance;
mysql> alter table users import tablespace;
Query OK, 0 rows affected, 1 warning (0.01 sec)

Резултата – вече виждах информацията от таблица users. Същото сторих и с останалите таблици, като така успях да възтановя всичко!

Това е!

 

PS. При грешка от типа : Schema mismatch (Table has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.) 

е нужно да се добави ROW_FORMAT=compact в заявката за създаване на таблицата. Повече инфо тук.