Brakuje wierszy po konwersji online z MyISAM do InnoDB

16

Mamy dość małą bazę danych, którą chcieliśmy przekonwertować z MyISAM na InnoDB. Będąc bazą danych noob, właśnie przekonwertowaliśmy (używając tabeli zmian), nawet nie usuwając strony.

Po zakończeniu konwersji wydaje się, że brakuje sporadycznych wierszy. Czy jest to możliwe z powodu operacji podczas konwersji? A może problem jest gdzie indziej?

Yuvi
źródło
W których tabelach brakuje wierszy? Te, które przekonwertowałeś lub inne tabele?
longneck

Odpowiedzi:

20

Wykonanie polecenia ALTER w celu zmiany silników pamięci masowej nie spowoduje zniknięcia wierszy. Pozwól mi jednak udzielić porady, ponieważ w swoim pytaniu powiedziałeś, że jesteś „bazą danych noob”.

Podczas modyfikowania istniejącego schematu lub wykonywania innych czynności mogłoby wpłynąć na dane, oto kilka podstawowych porad:

  1. Najpierw wykonaj kopię zapasową.
  2. Mieć plan zmian.
  3. Przetestuj swój plan na hoście offline.
  4. Przygotuj plan testowy do porównania przed i po danych.
  5. Zaplanuj i przestań.
  6. Wykonaj kopię zapasową i migawkę natychmiast po wejściu w życie przestoju i upewnieniu się, że ruch został zatrzymany.
  7. Jeśli korzystasz z MYISAM, użyj „SPRAWDŹ TABELĘ”, aby ocenić, z czym masz do czynienia przed ZMIENIENIEM.
  8. Na wszelki wypadek skopiuj tabelę lokalnie oprócz kopii zapasowej.
  9. Postępuj ostrożnie, włącz „--show ostrzeżenia” i inne dane wyjściowe, aby mieć pełny obraz podczas wprowadzania zmian.
  10. Jeśli dane są dla Ciebie ważne, wynająć DBA, nawet jeśli tylko skonsultujesz się podczas migracji, aby mieć doświadczonego weterana u boku.

Prawdopodobnie jest o wiele więcej, ale mogę uzyskać więcej opcji, gdy coś pójdzie nie tak.

Jeśli chodzi o brakujące dane / wiersze, nie ma sposobu, aby wiedzieć w / oa „przed / po” migawce do porównania. Możesz porównać z najnowszą kopią zapasową, aby przynajmniej tyle zweryfikować.

randomx
źródło
Czytam to Dobry plan DR. Twoja odpowiedź dostaje +1 za bycie bardziej wrażliwym na pytanie niż ja oprócz planu na przyszłość.
RolandoMySQLDBA
1
@randy Oznaczono to jako ulubione pytanie ze względu na dobrą odpowiedź
techExplorer,
8

Jednym z najlepszych sposobów na konwersję MyISAM do InnoDB bez wielu przestojów jest tylko jeden warunek wstępny: Użyj Slave replikacji.

Oto plan z lotu ptaka

  1. Utwórz konfigurację Master / Slave replikacji
  2. Konwertuj każdą tabelę MyISAM na slave na InnoDB
  3. Skieruj swoją aplikację na Slave

Brzmi prosto? Za tym kryje się wiele szczegółów.

Utwórz konfigurację Master / Slave replikacji

Istnieje sprytny sposób na stworzenie Slave bez większych zakłóceń dla Mistrza. Napisałem dwa posty:

Zamiast szczegółowo korzystać z rsync, przeczytaj te dwa posty.

Konwertuj każdą tabelę MyISAM na slave na InnoDB

Na DB Slave możesz wykonać następującą instrukcję SQL:

W przypadku MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Wersja dla MySQL przed MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Korzystając z danych wyjściowych z zapytania, masz skrypt konwersji dla urządzenia podrzędnego.

Musisz umieścić te dwie linie na początku skryptu:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Skrypt najpierw wyłączy rejestrowanie binarne (jeśli skonfigurowałeś slave do binarnych logów), zatrzyma replikację i skonwertuje każdą tabelę MyISAM na InnoDB.

Oto jak utworzyć ten skrypt i wykonać go:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Skieruj swoją aplikację na Slave

Wykonaj zapytania SELECT z urządzenia Slave. Jeśli jesteś zadowolony z zawartości danych w Slave, możesz skierować swoją aplikację do Slave w następujący sposób:

  1. Na Slave uruchom SHOW SLAVE STATUS\Gi upewnij się, że Seconds_Behind_Master ma wartość 0
  2. W Slave mysqldump -h (IP Slave) -u ... -p ... - pojedyncze transakcje - procedury - wyzwalacze - wszystkie bazy danych> MySQLBackup.sql (Hej, kopia zapasowa byłaby dobra jakoś teraz)
  3. Na Mistrzu biegnij service mysql stop (zaczyna się przestój)
  4. Powtórz krok 1
  5. Skieruj aplikację na urządzenie Slave (przestój kończy się przy pierwszym połączeniu aplikacji)

Jeśli dotarłeś do tego punktu bez szwanku, GRATULACJE !!!

DODANY BONUS : Jeśli skonfigurujesz replikację master / master (inaczej replikacja cykliczna) zamiast master / slave, możesz to zrobić w zamian:

  1. Uruchom Slave SHOW SLAVE STATUS\Gi upewnij się, że Seconds_Behind_Master ma wartość 0
  2. W Slave mysqldump -h (IP Slave) -u ... -p ... - pojedyncze transakcje - procedury - wyzwalacze - wszystkie bazy danych> MySQLBackup.sql (Hej, kopia zapasowa byłaby dobra jakoś teraz)
  3. Skieruj aplikację na urządzenie Slave (przestój zaczyna się i kończy przy pierwszym połączeniu aplikacji)
  4. Uruchom nowego Mistrza STOP SLAVE;
  5. Uruchom nowego Mistrza CHANGE MASTER TO MASTER_HOST='';

To, co teraz masz, to Master / Slave w odwrotnej kolejności. Nowy Master ma dane InnoDB, a stary Master jest teraz slave z danymi MyISAM. Jeśli podzielisz odczyty i zapisy, odczyty mogą przejść z Slave (odczyty są szybsze z MyISAM niż InnoDB), a zapisy przejść do Master (obsługa transakcyjna dla InnoDB). Tak jak śpiewa Hannah Montana, dostajesz to, co najlepsze z obu światów (Tak, mam dwie córki, które uwielbiają serial) !!!

KOLEJNY DODATKOWY BONUS : Ponieważ Master jest teraz InnoDB, możesz zrobić mysqldump z Master bez przestojów i bez ingerencji w transakcje. Jedyną wadą jest zwiększenie wydajności procesora i dysku we / wy. Mógłbyś zatem uzyskać mysqldump struktur tabel tylko na Master (InnoDB) i mysqldump danych tylko na slave (taki zrzut nie będzie zawierał odniesień do InnoDB ani MyISAM. Będzie to tylko dane) plus mysqldump struktury tabel dla urządzenia podrzędnego, które mają układ MyISAM.

Możliwości mogą być kontynuowane dzięki tej nowej konfiguracji ...

AKTUALIZACJA 27.08.2011 19:50 EDT

Przepraszam. Nie w pełni przeczytałem pytanie. Przeprowadziłeś już rozmowę .

Tylko jeśli masz już włączone rejestrowanie binarne i masz wcześniejszą kopię zapasową, możesz to zrobić

  • przywróć / var / lib / mysql do innej lokalizacji, takiej jak / var / lib / mysql2
  • biegać service mysql stop
  • biegać service mysql start --datadir=/var/lib/mysql2
  • mysqldump bazę danych z tej kopii zapasowej do /root/olddata.sql
  • uruchom mysqlbinlog dla wszystkich dzienników binarnych w / var / lib / mysql (nie / var / lib / mysql2) od momentu od ostatniej kopii zapasowej do /root/changes.sql
  • Załaduj zmiany.sql do mysql (ponieważ wciąż wskazuje na / var / lib / mysql2)

Powinno to uchwycić wszystko, co zostało zarejestrowane, a konwersja powinna się rozpocząć. Ponownie, wszystko to jest na tyle rozsądne , że rejestrowanie binarne było już włączone przed ostatnią kopią zapasową . W przeciwnym razie moje kondolencje.

RolandoMySQLDBA
źródło