MySQL InnoDB utracił tabele, ale pliki istnieją

33

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

Problemem stało bo usunięte te trzy pliki: ibdata1, ib_logfile0iib_logfile1

ponieważ miałem problemy z uruchamianiem mysql, a przeczytałem je, aby je usunąć, ponieważ MySQL po prostu je zregeneruje (wiem, że powinienem je utworzyć, ale tego nie zrobił).

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
Zejdź z mojego trawnika
źródło
Czy próbowałeś przywrócić te pliki? Pliki dziennika mogą pozostać usunięte. Naprawdę nie powinieneś był usuwać ibdata1
Ramhound
Skopiowałem plik ze starej wersji mysql, w której plik się znajdował, ale tabele się nie wyświetlają.
Get Off My Lawn

Odpowiedzi:

36

Oto dlaczego MySQL nie widzi tych plików: Systemowy obszar tabel (ibdata1) ma słownik danych specyficzny dla silnika pamięci, który pozwala InnoDB odwzorować potencjalne użycie tabeli:

Architektura InnoDB

Przenoszenie tabel InnoDB z jednego miejsca do drugiego wymaga poleceń takich jak

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

Oto część dokumentacji MySQL 5.5 wyjaśniająca, co należy wziąć pod uwagę

Zagadnienia dotyczące przenośności plików .ibd

Nie można swobodnie przenosić plików .ibd między katalogami baz danych, jak w przypadku plików tabel MyISAM. Definicja tabeli przechowywana we współdzielonym obszarze tabel InnoDB obejmuje nazwę bazy danych. Identyfikatory transakcji i numery sekwencji dziennika przechowywane w plikach obszaru tabel również różnią się między bazami danych.

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

ZMIEŃ TABELĘ db1.tbl_name TO db2.tbl_name; Jeśli masz „czystą” kopię zapasową pliku .ibd, możesz przywrócić go do instalacji MySQL, z której pochodzi:

Tabela nie może zostać usunięta ani obcięta od czasu skopiowania pliku .ibd, ponieważ spowoduje to zmianę identyfikatora tabeli przechowywanego w obszarze tabel.

Wydaj tę instrukcję ALTER TABLE, aby usunąć bieżący plik .ibd:

ALTER TABLE tbl_name DISCARD TABLESPACE; Skopiuj plik kopii zapasowej .ibd do odpowiedniego katalogu bazy danych.

Wydaj tę instrukcję ALTER TABLE, aby poinformować InnoDB o użyciu nowego pliku .ibd dla tabeli:

ALTER TABLE nazwa_bloku tbl 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 żadnych niezatwierdzonych modyfikacji w wyniku transakcji.

W pliku .ibd nie ma nie połączonych wpisów bufora wstawiania.

Purge usunęło wszystkie zaznaczone do usunięcia rekordy indeksu z pliku .ibd.

mysqld opróżnił 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 działania

W tym przykładzie spróbujmy przywrócić tagstabelę do mydbbazy danych

KROK 1

Upewnij się, że masz kopie zapasowe tych .frmi .ibdplików/tmp/innodb_data

KROK 2

Pobierz CREATE TABLE tagsinstrukcję i wykonaj ją jako CREATE TABLE mydb.tags .... Upewnij się, że ma dokładnie taką samą strukturę jak oryginałtags.frm

KROK 3

Usuń puste tags.ibdza pomocą MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

KROK 4

Przynieś kopię zapasową tags.ibd

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

KROK 5

Dodaj tagstabelę do słownika danych InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

KROK 6

Przetestuj dostępność stołu

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

Jeśli otrzymasz normalne wyniki, gratulacje importujesz tabelę InnoDB.

KROK 7

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

Spróbuj !!!

Rozmawiałem już o takich sprawach

CAVEAT

Co jeśli nie znasz struktury tabeli tags?

Istnieją narzędzia do uzyskania instrukcji CREATE TABLE przy użyciu samego .frmpliku. Napisałem również o tym post: Jak wyodrębnić schemat tabeli tylko z pliku .frm? . W tym poście skopiowałem plik .frm na maszynę z systemem Windows z systemu Linux, uruchomiłem narzędzie Windows i otrzymałem CREATE TABLEinstrukcję.

RolandoMySQLDBA
źródło
Dzięki za niesamowitą odpowiedź! Nadal jestem w trakcie importowania jednego stołu, ponieważ ciągle stwarzam problemy, ale w końcu się tam dostanę i dam wam znać, jak to działa! Dzięki!
Get Off My Lawn
1
Po uruchomieniu tworzenia otrzymuję: ERROR 1813 (HY000): Obszar tabel dla tabeli ” weblyize. tags„istnieje. ODRZUCAJ obszar tabel przed IMPORTEM. Więc najpierw próbuję uruchomić obszar tabel alter i otrzymuję ten błąd: ERROR 1146 (42S02): Tabela „weblyize.tags” nie istnieje . Co mogę zrobić?
Get Off My Lawn
Dzięki! Aby naprawić błąd, utworzyłem nową bazę danych, uruchomiłem, CREATE TABLE ...a następnie postępowałem zgodnie z instrukcjami! Uratowałeś mnie przed koniecznością przepisywania ich w 100% od zera! Nie zaimportował kluczy obcych, ale nie ma problemu, mogę to zrobić sam! Jeszcze raz dzięki!
Get Off My Lawn
Co jeśli mam 100 tabel, które należy naprawić w ten sposób. Nie będę wykonywać operacji dla każdego stołu ręcznie. Jak można to zautomatyzować?
Oleg Abrazhaev
10

Mam tę samą sytuację, nie mogę upuścić ani utworzyć określonej nazwy tbl. Moja procedura naprawy to:

  1. Zatrzymaj MySQL.

    service mysql stop
    
  2. Usuń ib_logfile0 i ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Usuń pliki tblname. OSTRZEŻENIE: TO PONOWNIE USUNĄ TWOJE DANE

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Uruchom MySQL.

    service mysql start
    
użytkownik293871
źródło
1
Dzięki, naprawiłem mój problem, nie zrobiłem kroku 3, po prostu usunąłem pliki dziennika i uruchomiłem kopię zapasową mysql.
Jeff Wilbert,
Jesteś absolutnie fantastyczny! Rozwiązałem mój problem.
Alex GP
2

Też miałem ten problem. Usunąłem ibdata1przypadkowo i wszystkie moje dane zostały utracone.

Po 1-2 dniach wyszukiwania 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. wziąć kopię zapasową z /var/lib/mysql

  2. odzyskać schemat tabeli z .frmpliku z dbsake (była inna opcja! mysqlfrm . ale to nie działało dla mnie)

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

  2. odrzuć nowe dane tabeli za pomocą tego polecenia:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. skopiuj dane starej tabeli i wklej ją zamiast nowej i ustaw dla niej odpowiednie uprawnienia.
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
  1. importuj 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-namea jeśli istnieją dane ( .ibdplik) dla starej tabeli, usuń ją.
rm tbl.ibd
  1. i wreszcie zmień nazwę nowej tabeli na oryginalną
ALTER TABLE `tbl-new` RENAME `tbl`;
mostafaznv
źródło