MySQL InnoDB втратив таблиці, але файли існують


33

У мене є MySQL InnoDB, який містить усі файли таблиць бази даних, але MySQL їх не бачить і не завантажує.

Проблема сталася тому , що я видалив ці три файли: ibdata1, ib_logfile0іib_logfile1

тому що у мене виникли проблеми з запуском mysql, і те, що я прочитав, - це видалити їх, тому що MySQL просто відновить їх (я знаю, я повинен був створити резервну копію, але цього не зробив).

Що я можу зробити, щоб MySQL знову побачив таблиці?

about_member.frm                              site_stories.frm
about_member.ibd                              site_stories.ibd
db.opt                                        stories.frm
FTS_00000000000000bb_BEING_DELETED_CACHE.ibd  stories.ibd
FTS_00000000000000bb_BEING_DELETED.ibd        story_comments.frm
FTS_00000000000000bb_CONFIG.ibd               story_comments.ibd
FTS_00000000000000bb_DELETED_CACHE.ibd        story_likes.frm
FTS_00000000000000bb_DELETED.ibd              story_likes.ibd
FTS_00000000000000f5_BEING_DELETED_CACHE.ibd  story_tags.frm
FTS_00000000000000f5_BEING_DELETED.ibd        story_tags.ibd
FTS_00000000000000f5_CONFIG.ibd               story_views.frm
FTS_00000000000000f5_DELETED_CACHE.ibd        story_views.ibd
FTS_00000000000000f5_DELETED.ibd              story_view_totals.frm
member_favorites.frm                          story_view_totals.ibd
member_favorites.ibd                          tags.frm
members.frm                                   tags.ibd
members.ibd

Ви намагалися відновити ці файли? Файли журналу можуть залишатися видаленими. Ви дійсно не повинні були видалити ibdata1
Ramhound

Я скопіював файл зі старої версії mysql, де файл знаходився, але таблиці не відображаються.
Вийди з моєї галявини

Відповіді:


36

Ось чому MySQL не може бачити ці файли: У системному просторі таблиць (ibdata1) є специфічний словник даних Storage-Engine, який дозволяє InnoDB відображати потенційне використання таблиці:

Архітектура InnoDB

Для переміщення таблиць InnoDB з одного місця в інше потрібні такі команди

ALTER TABLE tblname DISCARD TABLESPACE;
ALTER TABLE tblname IMPORT TABLESPACE;

Ось частина документації MySQL 5.5, що пояснює, що потрібно враховувати

Міркування про переносимість файлів .ibd

Ви не можете вільно переміщувати .ibd файли між каталогами баз даних, як це можливо з файлами таблиць MyISAM. Визначення таблиці, що зберігається у спільному просторі таблиць InnoDB, включає ім'я бази даних. Ідентифікатори транзакцій та порядкові номери журналів, що зберігаються у файлах простору таблиць, також відрізняються між базами даних.

Щоб перемістити файл .ibd та пов’язану таблицю з однієї бази даних в іншу, використовуйте оператор RENAME TABLE:

RENAME TABLE db1.tbl_name TO db2.tbl_name; Якщо у вас є "чиста" резервна копія файлу .ibd, ви можете відновити його до установки MySQL, з якої він походив, таким чином:

Після копіювання файлу .ibd таблиця не повинна бути відкинута або врізана, оскільки це змінює ідентифікатор таблиці, що зберігається всередині простору таблиць.

Видаліть цей ALTER TABLE оператор, щоб видалити поточний файл .ibd:

ALTER TABLE tbl_name DISCARD TABLESPACE; Скопіюйте файл резервного копіювання .ibd у відповідний каталог баз даних.

Випустіть цей оператор ALTER TABLE, щоб сказати InnoDB використовувати новий .ibd файл для таблиці:

ALTER TABLE tbl_name IMPORT TABLESPACE; У цьому контексті "чиста" резервна копія файлу .ibd - це вимога, щодо якої задовольняються наступні вимоги:

Немає невідомих модифікацій транзакцій у файлі .ibd.

У файлі .ibd немає запису, що не ввімкнено.

Purge видалив усі записи, позначені видаленням, з індексу .ibd-файлу.

mysqld видалив всі змінені сторінки .ibd-файлу з буферного пулу в файл.

Враховуючи ці застереження та протоколи, ось запропонований курс дій

Для цього прикладу спробуємо відновити tagsтаблицю в mydbбазі даних

КРОК 1

Переконайтеся, що у вас є резервні копії цих .frmта .ibdфайлів/tmp/innodb_data

КРОК №2

Отримайте CREATE TABLE tagsзаяву та виконайте її як CREATE TABLE mydb.tags .... Переконайтеся, що це точно така ж структура, як оригіналtags.frm

КРОК №3

Видаліть порожнє tags.ibdза допомогою MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

КРОК №4

Принесіть резервну копію tags.ibd

cd /var/lib/mysql/mydb
cp /tmp/innodb_data.tags.ibd .
chown mysql:mysql tags.ibd

КРОК №5

Додайте tagsтаблицю до словника даних InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

КРОК 6

Перевірте доступність таблиці

SHOW CREATE TABLE mydb.tags\G
SELECT * FROM mydb.tags LIMIT 10;

Якщо ви отримуєте нормальні результати, вітаємо, ви імпортуєте таблицю InnoDB.

КРОК 7

Надалі не видаляйте ibdata1 та його журнали

Спробувати !!!

Я обговорював такі речі раніше

КАВАТИ

Що робити, якщо ви не знаєте структури таблиці tags?

Існують інструменти для отримання оператора CREATE TABLE просто за допомогою .frmфайлу. Я написав пост про це також: Як можна витягти схему таблиці лише з файлу .frm? . На цій посаді я скопіював файл .frm на машину Windows з вікна Linux, запустив інструмент Windows і отримав CREATE TABLEзаяву.


Дякуємо за чудовий відповідь! Я все ще знаходжу одну таблицю, імпортовану, тому що я продовжую створювати проблеми, але я зрештою дістанусь, і я повідомлю вам, як це виходить! Спасибі!
Вийди з моєї галявини

1
Коли я запускаю команду create, я отримую: ERROR 1813 (HY000): Простір таблиць для таблиці ' weblyize. tags'існує. Будь ласка, відкиньте простір таблиць перед ІМПОРТ. Тоді я спершу спробую запустити простір alter таблиць і отримаю цю помилку: ПОМИЛКА 1146 (42S02): Таблиця 'weblyize.tags' не існує . Що я можу зробити?
Вийди з моєї галявини

Спасибі! Щоб виправити свою помилку, я створив нову базу даних, побіг CREATE TABLE ...і пішов за вашими кроками! Ви врятували мене від необхідності переписати їх на 100% з нуля! Він не імпортував іноземні ключі, але це нормально, я можу це зробити сам! Ще раз спасибі!
Вийди з моєї галявини

Що робити, якщо у мене є 100 таблиць, які слід виправити таким чином. Я не буду робити операцій з кожною таблицею руками. Як це можна було автоматизувати?
Олег Абражаєв

10

У мене така ж ситуація, Не можу викинути або створити конкретне tblname. Моя процедура виправлення:

  1. Зупинити MySQL.

    service mysql stop
    
  2. Видаліть ib_logfile0 та ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Видаліть файли tblname. ПОПЕРЕДЖЕННЯ: ЦЕ БЕЗПЕЧНО ВИДАЛЕ ВАШІ ДАНІ

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Запустіть MySQL.

    service mysql start
    

1
Дякую, це вирішило мою проблему, я не зробив крок 3, я просто видалив журнали і почав резервне копіювання mysql.
Джефф Вілберт

Ви абсолютно фантастичні! Вирішили мою проблему.
Alex GP

2

У мене теж була ця проблема. Я ibdata1випадково видалив, і всі мої дані були втрачені.

Після 1-2-денного пошуку в Google і SO, нарешті, я знайшов рішення, яке врятувало мені життя (у мене було стільки баз даних і таблиць з величезними записами).

  1. взяти резервну копію з /var/lib/mysql

  2. відновити схему таблиці з .frmфайлу з dbsake (був інший варіант! mysqlfrm . але він не працював для мене)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. створити нову таблицю (з новою назвою) із експортованою схемою.

  2. відкинути нові дані таблиці за допомогою цієї команди:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. скопіюйте дані старої таблиці та вставте її замість нової та встановіть для неї потрібний дозвіл.
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. імпортувати дані до нової таблиці.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. добре! у нас є дані в новій таблиці, і ми можемо скинути стару.
DROP TABLE `tbl`;
  1. перевірте, /var/lib/mysql/database-nameчи є дані ( .ibdфайл) для старої таблиці, видаліть їх.
rm tbl.ibd
  1. і нарешті перейменуйте нову таблицю в оригінальну назву
ALTER TABLE `tbl-new` RENAME `tbl`;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.