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
ibdata1
rosną, 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.sql
plik tekstowy (SQLData.sql
jest używany poniżej) -
Usuń wszystkie bazy danych (z wyjątkiem
mysql
iinformation_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_logfile0
iib_logfile1
) -
Wyłącz MySQL
-
Dodaj następujące wiersze do
/etc/my.cnf
(lubmy.ini
w 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_size
wynosi 25%innodb_buffer_pool_size
.Także:
innodb_flush_method=O_DIRECT
nie 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_logfile0
iib_logfile1
po 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.