Jak odzyskać tabelę InnoDB, której pliki zostały przeniesione

13

Mam więc testowy serwer db skonfigurowany w strumieniu replikacji. Nad nazwą pojawił się optymalizator, który szybko zapełnił miejsce w katalogu danych o niewolnikach. Mysql sumiennie tylko czekał na więcej miejsca.

Ten datadir to system plików używany TYLKO jako datadir mysql, więc nie było nic więcej do zwolnienia.

Miałem 4-gigabajtową tabelę testową innodb, która nie była częścią strumienia replikacji, więc pomyślałem, że spróbuję czegoś, aby sprawdzić, czy to zadziała, a będąc środowiskiem testowym, nie martwiłem się zbytnio, gdyby coś poszło nie tak.

Oto kroki, które podjąłem

  1. Opróżniłem stół, który miałem przenieść
  2. Umieściłem na nim blokadę odczytu (mimo że nic do niej nie zapisywało i nie było jej w strumieniu replikacji)
  3. Skopiowałem .frm i .ibd do systemu plików w / wolnym pokoju
  4. Odblokowano stół
  5. Obcięto tę tabelę - zwolniło to wystarczająco dużo miejsca, aby optymalizacja mogła zakończyć się, a replikacja zacznie ponownie łączyć.
  6. Zatrzymaj mysql slave / shutdown
  7. Skopiuj plik z tmp z powrotem do katalogu danych
  8. Uruchom ponownie mysql

Nic nie pojawia się w dzienniku .err, wszystko wygląda dobrze. Łączę się i używam mydb; i zobacz tabelę, z którą się bałam w tabelach pokazów. Ale jeśli spróbuję

select * from testtable limit 10;

Dostaję błąd

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

Z tego, co do tej pory mogę powiedzieć, mogę dobrze odczytać ze wszystkich innych tabel, a replikacja rozpoczęła tworzenie kopii zapasowej bez żadnych skarg.

Czy jest coś, co mogę zrobić, aby odzyskać od tego momentu? Mogę go odbudować od podstaw, jeśli zajdzie taka potrzeba, ale byłem ciekawy, co inni myślą o tym przedsięwzięciu w ogóle. Czy w serii kroków, które podjąłem, było coś, co doprowadziłoby do bezbłędnych rezultatów?

Co jeśli to nie był serwer testowy, nie mógłbym po prostu „zrobić tego na żywo” i zobaczyć, co się stanie? Jaki byłby najlepszy sposób na tymczasowe zwolnienie miejsca na produkcyjnym niewolniku, gdybym musiał to lubić?

atxdba
źródło

Odpowiedzi:

15

Najważniejszą rzeczą, o której większość ludzi zapomina o TRUNCATE TABLE, jest to, że TRUNCATE TABLE to DDL, a nie DML . W InnoDB metadane w ibdata1 zawierają numerowaną listę tabel InnoDB. Użycie TRUNCATE TABLE powoduje przesunięcie wewnętrznego identyfikatora metadanych tabeli InnoDB. Dzieje się tak, ponieważ TRUNCATE TABLE skutecznie wykonuje następujące czynności:

Przykład: Aby obciąć tabelę InnoDB o nazwie mydb.mytb

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

Nowy mytb miałby zatem inny wewnętrzny identyfikator metadanych.

Po skopiowaniu pliku .ibd w inne miejsce plik .ibd zawiera w sobie oryginalny wewnętrzny identyfikator metadanych. Samo przywrócenie pliku .ibd nie powoduje uzgodnienia wewnętrznego identyfikatora metadanych z identyfikatorem tego w ibdata1.

Co powinieneś zrobić, to:

Skopiuj plik .ibd tabeli InnoDB. Następnie uruchom to

ALTER TABLE tablename DISCARD TABLESPACE;

Aby przywrócić go później, skopiuj plik .ibd z powrotem do datadir, a następnie uruchom

ALTER TABLE tablename IMPORT TABLESPACE;

Pozwoliłoby to zachować wewnętrzny identyfikator metadanych.

Upewnij się, że plik .frm jest zawsze obecny.

Kiedyś pomogłem klientowi przywrócić 30 tabel InnoDB, które ukrywał w ten sam sposób. Musiałem użyć innego serwera DB i grać w niektóre gry z dodawaniem i upuszczaniem tabel InnoDB, aby wyśledzić poprawny wewnętrzny identyfikator metadanych.

Klient znalazł ten artykuł: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Wykorzystaliśmy go i bardzo nam pomogło. Mam nadzieję, że Ci to pomoże.

RolandoMySQLDBA
źródło
1
Mam 2 bazy danych, w których wszystkie tabele mówią Table 'X' doesn't exist in engine. Czy muszę wykonać powyższą metodę dla każdej tabeli, czy są lepsze sposoby, aby to naprawić?
papanito
-2

Doświadczyłem na moim komputerze Mac, zanim sprzedałem znajomemu, po prostu skopiuj folder XAMPP tylko na mój dysk twardy. (NIE SUKCES) Niestety, przysparzało mi to kłopotów, ponieważ próbowałem następujących kroków: - Instaluję świeżego XAMPP i kopiuję całe \ httdocs i var \ mysql na mój nowy Mac, te db tylko z .frm i .ibd, NIE DZIAŁA, nadal nie mogę uzyskać dostępu do tabel w PHPMyAdmin ... - Próbowałem zainstalować tę samą wersję xampp i powtórzyć powyższe kroki, nadal NIE DZIAŁA. - Postanowiłem iść spać.

(SUKCES) - Dziś rano przyniosłem dysk z kopią zapasową i wypróbowałem system Windows 7. - Zainstaluj świeżą najnowszą wersję XAMPP dla systemu Windows, c: \ xampp - Mam jedną stronę internetową (folder) z kopii zapasowej \ httdocs i odpowiedni folder bazy danych wewnątrz \ var \ mysql są GOTOWE w moim systemie Windows 7, chcę tylko spróbować z jedną witryną, a następnie wypróbować resztę, ponieważ mam wiele projektów w httdocs \ i \ var \ mysql - kopiuję folder httdocs \ do Windows c: \ xampp \ httdocs i skopiuj \ var \ mysql do c: \ xampp \ mysql \ data

NIE OSTATNIO JESZCZE Kopiuję plik ib_logfile0, ib_logfile1, ibdata1 z mojego pliku kopii zapasowej do systemu Windows xampp c: \ xampp \ mysql \ data

Odświeżam http: // localhost / mywebsite

WOW WOW DONE ... działa ...

Armindo
źródło