2013-11-13 14:52:59 +0000 2013-11-13 14:52:59 +0000
33
33

MySQL InnoDB stracił tabele, ale pliki istnieją

Mam MySQL InnoDB, który ma wszystkie pliki tabel bazy danych, ale MySQL nie widzi ich i nie ładuje ich.

Problem wystąpił, ponieważ usunąłem te trzy pliki: ibdata1, ib_logfile0 i ib_logfile1

ponieważ miałem problemy z uruchomieniem mysql, a to, co przeczytałem, to usunięcie ich, ponieważ MySQL po prostu je zregeneruje (wiem, że powinienem był zrobić kopię zapasową, ale nie zrobiłem tego).

Co mogę zrobić, aby MySQL ponownie zobaczył tabele?

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

Odpowiedzi (3)

36
36
36
2013-11-14 15:34:22 +0000

Oto dlaczego MySQL nie widzi tych plików: Systemowa przestrzeń tabel (ibdata1) posiada specyficzny dla Storage-Engine słownik danych, który pozwala InnoDB mapować potencjalne użycie tabel:

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

Przeniesienie tabel InnoDB z jednego miejsca w inne wymaga poleceń takich jak

ALTER TABLE mydb.tags DISCARD TABLESPACE;

Oto fragment Dokumentacja MySQL 5.5 wyjaśniający, co należy wziąć pod uwagę

Portability Considerations for .ibd Files

Nie można swobodnie przenosić plików .ibd między katalogami bazy danych, tak jak można to robić z plikami tabel MyISAM. Definicja tabeli przechowywana we współdzielonej przestrzeni tabel InnoDB zawiera nazwę bazy danych. Identyfikatory transakcji i numery sekwencji dziennika przechowywane w plikach przestrzeni tabel również różnią się między bazami danych.

Aby przenieść plik .ibd i powiązaną z nim tabelę z jednej bazy danych do drugiej, użyj polecenia RENAME TABLE:

RENAME TABLE db1.tblname TO db2.tblname; Jeśli posiadasz “czystą” kopię zapasową pliku .ibd, możesz przywrócić go do instalacji MySQL, z której pochodzi, w następujący sposób:

Tabela nie może być upuszczona lub obcięta od czasu skopiowania pliku .ibd, ponieważ robienie tego zmienia identyfikator tabeli przechowywany wewnątrz przestrzeni tabel.

Wydaj to polecenie ALTER TABLE, aby usunąć bieżący plik .ibd:

ALTER TABLE tbl_name DISCARD TABLESPACE; Skopiuj zapasowy plik .ibd do właściwego katalogu bazy danych.

Wydaj to polecenie ALTER TABLE, aby powiedzieć InnoDB, aby użył nowego pliku .ibd dla tabeli:

ALTER TABLE tbl\name IMPORT TABLESPACE; W tym kontekście “czysta” kopia zapasowa pliku .ibd to taka, dla której spełnione są następujące wymagania:

W pliku .ibd nie ma niezaangażowanych modyfikacji przez transakcje.

W pliku .ibd nie ma żadnych niezamkniętych wpisów bufora insertów.

Oczyszczanie usunęło wszystkie oznaczone do usunięcia rekordy indeksu z pliku .ibd.

mysqld przepłukał wszystkie zmodyfikowane strony pliku .ibd z puli buforów do pliku.

Biorąc pod uwagę te zastrzeżenia i protokoły, oto sugerowany sposób postępowania

Dla tego przykładu spróbujmy przywrócić tabelę tags do bazy danych mydb

KROK #1

Upewnij się, że masz kopie zapasowe tych plików .frm i .ibd w /tmp/innodb_data

KROK #2

Pobierz instrukcję CREATE TABLE tags i wykonaj ją jako CREATE TABLE mydb.tags .... Upewnij się, że jest to dokładnie ta sama struktura, co oryginalna tags.frm

KROK #3

Usuń puste tags.ibd używając MySQL

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

KROK #4

Wprowadź kopię zapasową tags.ibd

.
ALTER TABLE mydb.tags IMPORT TABLESPACE;

KROK #5

Dodaj tabelę tags do słownika danych InnoDB

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

KROK 6

Przetestuj dostępność tabeli

Jeśli uzyskasz normalne wyniki, gratuluję, że importujesz tabelę InnoDB.

KROK 7

W przyszłości nie usuwaj ibdata1 i jego logów

Spróbuj !!!

Omawiałem już takie rzeczy wcześniej

CAVEAT

Co zrobić, jeśli nie znasz struktury tabeli tags ?

Istnieją narzędzia do uzyskania instrukcji CREATE TABLE po prostu używając pliku .frm. Napisałem również post na ten temat : Jak wyodrębnić schemat tabeli tylko z pliku .frm? . W tym poście skopiowałem plik .frm na maszynę Windows z pudełka Linux, uruchomiłem narzędzie Windows i uzyskałem oświadczenie CREATE TABLE.

10
10
10
2014-01-28 02:08:22 +0000

Mam taką samą sytuację, nie mogę upuścić lub utworzyć określonej nazwy tbl. Moja procedura naprawcza to:

  1. Zatrzymaj MySQL.

  2. Usuń ib_logfile0 i ib_logfile1.

  3. Usuń pliki tblname. UWAGA: TO PERMANENTNIE USUNIE TWOJE DANE

  4. Uruchom MySQL.

2
2
2
2019-03-27 11:19:13 +0000

Ja też miałem ten problem. Usunąłem ibdata1 przypadkowo i wszystkie moje dane zostały utracone.

Po 1-2 dniach szukania w google i SO, w końcu znalazłem rozwiązanie, które uratowało mi życie (miałem tak wiele baz danych i tabel z ogromnymi rekordami).

  1. Zrób kopię zapasową z pliku /var/lib/mysql

  2. Odzyskaj schemat tabeli z pliku .frm za pomocą dbsake (była jeszcze inna opcja! mysqlfrm. ale nie zadziałała dla mnie)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. Utwórz nową tabelę (z nową nazwą) z wyeksportowanym schematem.

  2. odrzuć dane nowej tabeli za pomocą tej komendy:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. skopiuj dane starej tabeli i wklej je w miejsce nowej oraz ustaw dla niej odpowiednie uprawnienia.
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. zaimportuj dane do nowej tabeli.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. w porządku! mamy dane w nowej tabeli i możemy usunąć starą.
DROP TABLE `tbl`;
  1. sprawdź /var/lib/mysql/database-name i jeśli są tam dane (plik .ibd) dla starej tabeli, usuń je.
rm tbl.ibd
  1. i na koniec zmieniamy nazwę nowej tabeli na oryginalną
ALTER TABLE `tbl-new` RENAME `tbl`;
```.