Oto pełniejsza odpowiedź w odniesieniu do InnoDB. Jest to trochę długi proces, ale może być wart wysiłku.
Pamiętaj, że /var/lib/mysql/ibdata1 to najbardziej zajęty plik w infrastrukturze InnoDB. Zwykle zawiera sześć rodzajów informacji:
- Dane tabeli
- Indeksy tabel
- MVCC (kontrola współbieżności w wielu wersjach)
Dane
- Segmenty wycofywania
- Cofnij spację
- Metadane tabeli (słownik danych)
- Podwójny bufor zapisu (zapisywanie w tle, aby zapobiec uzależnieniu od buforowania systemu operacyjnego)
- Wstaw bufor (zarządzanie zmianami w nieunikalnych indeksach pomocniczych)
- Zobacz
Reprezentacja graficzna z ibdata1
Architektura InnoDB

Wiele osób tworzy wiele ibdata pliki mają nadzieję na lepsze zarządzanie przestrzenią dyskową i wydajność, jednak ta wiara jest błędna.
Czy mogę uruchomić OPTYMALIZUJ TABELA
?
Niestety, uruchamiam OPTYMALIZUJ TABELĘ
względem tabeli InnoDB przechowywanej we wspólnym pliku przestrzeni tabel ibdata1 robi dwie rzeczy:
- Sprawia, że dane i indeksy tabeli są ciągłe wewnątrz
ibdata1 - Sprawia, że
ibdata1rosną, ponieważ ciągłe strony danych i indeksu są dołączone doibdata1
Możesz jednak oddzielić dane tabeli i indeksy tabel od ibdata1 i zarządzaj nimi niezależnie.
Czy mogę uruchomić OPTYMALIZUJ TABELA
z innodb_file_per_table
?
Załóżmy, że chcesz dodać innodb_file_per_table
do /etc/my.cnf (my.ini) . Czy możesz wtedy po prostu uruchomić OPTYMALIZUJ TABELĘ
we wszystkich tabelach InnoDB?
Dobra wiadomość :Po uruchomieniu OPTYMALIZUJ TABELĘ
z innodb_file_per_table
włączone, spowoduje to utworzenie pliku .ibd plik dla tej tabeli. Na przykład, jeśli masz tabelę mydb.mytable z katalogiem danych /var/lib/mysql , wygeneruje to:
/var/lib/mysql/mydb/mytable.frm/var/lib/mysql/mydb/mytable.ibd
.ibd będzie zawierać strony danych i strony indeksu dla tej tabeli. Świetnie.
Złe wieści :Wszystko, co zrobiłeś, to wyodrębnienie stron danych i stron indeksu mydb.mytable z życia w ibdata . Wpis słownika danych dla każdej tabeli, w tym mydb.mytable , nadal pozostaje w słowniku danych (Patrz Pictorial Representation of ibdata1
). NIE MOŻESZ PO PROSTU USUNĄĆ ibdata1 W TYM MIEJSCU !!! Pamiętaj, że ibdata1 wcale się nie skurczył.
Oczyszczanie infrastruktury InnoDB
Zmniejszenie ibdata1 raz na zawsze musisz wykonać następujące czynności:
-
Zrzuć (np. za pomocą
mysqldump) wszystkie bazy danych do pliku.sqlplik tekstowy (SQLData.sqljest używany poniżej) -
Usuń wszystkie bazy danych (z wyjątkiem
mysqliinformation_schema) OSTRZEŻENIE :Na wszelki wypadek uruchom ten skrypt, aby mieć absolutną pewność, że wszystkie uprawnienia użytkowników są na swoim miejscu:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants -
Zaloguj się do mysql i uruchom
SET GLOBAL innodb_fast_shutdown =0;(To całkowicie usunie wszystkie pozostałe zmiany transakcyjne zib_logfile0iib_logfile1) -
Wyłącz MySQL
-
Dodaj następujące wiersze do
/etc/my.cnf(lubmy.iniw systemie Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G(Uwaga:niezależnie od zestawu dla
innodb_buffer_pool_size, upewnij się, żeinnodb_log_file_sizewynosi 25%innodb_buffer_pool_size.Także:
innodb_flush_method=O_DIRECTnie jest dostępna w systemie Windows) -
Usuń
ibdata*iib_logfile*, Opcjonalnie możesz usunąć wszystkie foldery w/var/lib/mysql, z wyjątkiem/var/lib/mysql/mysql. -
Uruchom MySQL (spowoduje to odtworzenie
ibdata1[domyślnie 10 MB] iib_logfile0iib_logfile1po 1G każdy). -
Importuj
SQLData.sql
Teraz ibdata1 będzie nadal rosła, ale będzie zawierać tylko metadane tabeli, ponieważ każda tabela InnoDB będzie istnieć poza ibdata1 . ibdata1 nie będzie już zawierać danych i indeksów InnoDB dla innych tabel.
Załóżmy na przykład, że masz tabelę InnoDB o nazwie mydb.mytable . Jeśli zajrzysz do /var/lib/mysql/mydb , zobaczysz dwa pliki reprezentujące tabelę:
mytable.frm(Nagłówek silnika pamięci masowej)mytable.ibd(Dane i indeksy tabeli)
Z innodb_file_per_table opcja w /etc/my.cnf , możesz uruchomić OPTIMIZE TABLE mydb.mytable oraz plik /var/lib/mysql/mydb/mytable.ibd faktycznie się skurczy.
Robiłem to wiele razy w mojej karierze jako DBA MySQL. W rzeczywistości, gdy zrobiłem to po raz pierwszy, zmniejszyłem o 50 GB ibdata1 plik do zaledwie 500 MB!
Spróbuj. Jeśli masz dodatkowe pytania na ten temat, po prostu zapytaj. Zaufaj mi; to zadziała zarówno w krótkim okresie, jak i na dłuższą metę.
OSTRZEŻENIE
W kroku 6, jeśli mysql nie może się ponownie uruchomić z powodu mysql schemat został usunięty, spójrz wstecz na krok 2. Utworzyłeś fizyczną kopię mysql schemat. Możesz go przywrócić w następujący sposób:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Wróć do kroku 6 i kontynuuj
AKTUALIZACJA 04.06.2013 11:13 EDT
W odniesieniu do ustawienia innodb_log_file_size do 25% innodb_buffer_pool_size w kroku 5 ta ogólna zasada jest raczej stara.
Powrót 03 lipca 2006 , Percona miała fajny artykuł dlaczego wybrać właściwy innodb_log_file_size . Później, 21 listopada 2008 , Percona opublikowała kolejny artykuł na temat jak obliczyć właściwy rozmiar w oparciu o szczytowe obciążenie pracą, zachowując jednogodzinną wartość zmian
.
Od tego czasu napisałem posty w DBA StackExchange o obliczaniu rozmiaru dziennika i o tym, gdzie odwołuję się do tych dwóch artykułów Percona.
27 sierpnia 2012:Właściwe dostrojenie do 30 GB tabeli InnoDB na serwerze z 48 GB RAM17 stycznia 2013:MySQL 5.5 – Innodb – innodb_log_file_size większy niż 4 GB łącznie?
Osobiście nadal stosowałbym zasadę 25% przy początkowej konfiguracji. Następnie, ponieważ obciążenie może być dokładniej określane w czasie w środowisku produkcyjnym, można zmienić rozmiar dzienniki podczas cyklu konserwacji w ciągu kilku minut.