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

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ę.


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
    

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 tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  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`;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.