Załóżmy, że chcesz dodać innodb_file_per_tabledo /etc/my.cnf (my.ini). Czy możesz po prostu uruchomić OPTIMIZE TABLEwszystkie tabele InnoDB?
Dobra wiadomość : Kiedy uruchomisz OPTIMIZE TABLEz innodb_file_per_tablewłączoną, utworzy to .ibdplik dla tej tabeli. Na przykład, jeśli masz tabelę z mydb.mytabledatadir o wartości /var/lib/mysql, zwróci to:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibdBędą zawierać stron danych i indeksowanie stron dla tej tabeli. Wspaniały.
Złe wieści : wszystko, co zrobiłeś, to wyodrębnienie stron danych i stron indeksu mydb.mytablez miejsca zamieszkania ibdata. Wpis słownika danych dla każdej tabeli, w tym mydb.mytable, nadal pozostaje w słowniku danych (patrz reprezentacja graficzna ibdata1 ). NIE MOŻESZ PO PROSTU SKASOWAĆ W ibdata1TYM PUNKCIE !!! Należy pamiętać, że ibdata1wcale się nie skurczył.
Oczyszczanie infrastruktury InnoDB
Aby zmniejszyć się ibdata1raz na zawsze, wykonaj następujące czynności:
Zrzuć (np. Z mysqldump) wszystkie bazy danych do .sqlpliku tekstowego ( SQLData.sqljest używane poniżej)
Usuń wszystkie bazy danych (z wyjątkiem mysqli information_schema) OSTRZEŻENIE : Zapobiegawczo uruchom ten skrypt, aby upewnić się, że masz wszystkie uprawnienia użytkowników:
Zaloguj się do mysql i uruchom SET GLOBAL innodb_fast_shutdown = 0;(to całkowicie opróżni wszystkie pozostałe zmiany transakcyjne z ib_logfile0i ib_logfile1)
Zamknij MySQL
Dodaj następujące wiersze do /etc/my.cnf(lub my.iniw systemie Windows)
(Uwaga: niezależnie od tego, do czego masz zestaw innodb_buffer_pool_size, upewnij się, że innodb_log_file_sizejest to 25% innodb_buffer_pool_size.
Ponadto: innodb_flush_method=O_DIRECTnie jest dostępny w systemie Windows)
Usuń ibdata*i ib_logfile*opcjonalnie możesz usunąć wszystkie foldery z /var/lib/mysqlwyjątkiem /var/lib/mysql/mysql.
Rozpocznij MySQL (Spowoduje to odtworzenie ibdata1[10MB domyślnie] a ib_logfile0i ib_logfile1na każdy 1G).
Import SQLData.sql
Teraz ibdata1będzie nadal rosnąć, ale będzie zawierać tylko metadane tabeli, ponieważ każda tabela InnoDB będzie istnieć poza ibdata1. ibdata1nie będzie już zawierał danych InnoDB i indeksów dla innych tabel.
Na przykład załóżmy, że masz tabelę InnoDB o nazwie mydb.mytable. Jeśli zajrzysz do /var/lib/mysql/mydbśrodka, zobaczysz dwa pliki reprezentujące tabelę:
mytable.frm (Nagłówek pamięci masowej)
mytable.ibd (Dane tabeli i indeksy)
Dzięki innodb_file_per_tableopcji w /etc/my.cnfmożesz uruchomić, OPTIMIZE TABLE mydb.mytablea plik /var/lib/mysql/mydb/mytable.ibdfaktycznie się zmniejszy.
Robiłem to wiele razy w swojej karierze jako administrator MySQL. W rzeczywistości, gdy to zrobiłem po raz pierwszy, zmniejszyłem plik 50 GBibdata1 do zaledwie 500 MB!
Spróbuj. Jeśli masz dalsze pytania, po prostu zapytaj. Zaufaj mi; będzie to działać zarówno w perspektywie krótkoterminowej, jak i długoterminowej.
PRZESTROGA
Jeśli w kroku 6, jeśli mysql nie może zostać ponownie uruchomiony z powodu mysqlupuszczenia schematu, spójrz wstecz na krok 2. Wykonałeś fizyczną kopię mysqlschematu. Możesz go przywrócić w następujący sposób:
Osobiście nadal stosowałbym zasadę 25% przy początkowej konfiguracji. Następnie, ponieważ obciążenie pracą można dokładniej określić w czasie w produkcji, można zmienić rozmiar dzienników podczas cyklu konserwacji w zaledwie kilka minut.
Użyłem również opcji innodb_file_per_table ze świetnym efektem, mając 200 baz danych z 200 tabelami każda na jednym serwerze, byłem w stanie połączyć bazy danych z różnicami symbolicznymi na różnych partycjach, tym samym używając więcej buforów IO i wrzecion, które w innym przypadku byłyby dostępne :)
Dave Rix
2
@SeanDowney BTW pamiętaj, aby podnieść, innodb_open_tablesjeśli to konieczne. Wartość domyślna to 300.
RolandoMySQLDBA
2
@ giorgio79 musisz ustawić wstawianie zbiorcze na większą wartość. To jest dobra uwaga. Do mojej odpowiedzi dodam istotę Twojego pytania.
RolandoMySQLDBA
3
W systemach 32-bitowych wartość 4 Gb dla innodb_buffer_pool_size jest niedozwolona. Mysql uruchomi się dyskretnie z wyłączonym innodb, a przywrócone tabele zostaną zmienione na myisam. Użyj nieco mniejszej wartości, aby to naprawić.
David
5
Mój Boże. Chcę tylko powiedzieć, że to chyba jedna z najlepszych odpowiedzi, jakie kiedykolwiek widziałem na TAK Cholernie dobra robota, sir. Pomogło mi znaleźć rozwiązanie mojego problemu, kiedy otrzymywałem ERROR 2013 (HY000) podczas importowania 154g db. Dzięki za doskonałą odpowiedź!
Josh Brown
4
Silnik InnoDB nie przechowuje usuniętych danych. Podczas wstawiania i usuwania wierszy niewykorzystane miejsce jest przydzielane w plikach magazynu InnoDB. Z czasem ogólna przestrzeń nie zmniejszy się, ale z czasem „usunięta i zwolniona” przestrzeń zostanie automatycznie ponownie wykorzystana przez serwer DB.
Możesz dalej dostrajać i zarządzać przestrzenią używaną przez silnik poprzez ręczną reorganizację tabel. Aby to zrobić, zrzuć dane z tabel, których dotyczy problem, za pomocą mysqldump, usuń tabele, uruchom ponownie usługę mysql, a następnie utwórz tabele ponownie z plików zrzutu.
Odpowiedzi:
Oto pełniejsza odpowiedź dotycząca InnoDB. To trochę długotrwały proces, ale może być wart wysiłku.
Należy pamiętać, że
/var/lib/mysql/ibdata1
jest to najbardziej obciążony plik w infrastrukturze InnoDB. Zwykle zawiera sześć rodzajów informacji:Pictorial Representation of ibdata1
Architektura InnoDB
Wiele osób tworzy wiele
ibdata
plików w nadziei na lepsze zarządzanie miejscem na dysku i lepszą wydajność, jednak to przekonanie jest błędne.Czy mogę biegać
OPTIMIZE TABLE
?Niestety, działanie
OPTIMIZE TABLE
z tabelą InnoDB przechowywaną we współużytkowanym pliku obszaru tabelibdata1
powoduje dwie rzeczy:ibdata1
ibdata1
rosną, ponieważ sąsiednie danych i indeksów stron są dołączane doibdata1
Możesz jednak oddzielić dane tabeli i indeksy tabel od
ibdata1
i zarządzać nimi niezależnie.Czy mogę biegać
OPTIMIZE TABLE
zinnodb_file_per_table
?Załóżmy, że chcesz dodać
innodb_file_per_table
do/etc/my.cnf (my.ini)
. Czy możesz po prostu uruchomićOPTIMIZE TABLE
wszystkie tabele InnoDB?Dobra wiadomość : Kiedy uruchomisz
OPTIMIZE TABLE
zinnodb_file_per_table
włączoną, utworzy to.ibd
plik dla tej tabeli. Na przykład, jeśli masz tabelę zmydb.mytable
datadir o wartości/var/lib/mysql
, zwróci to:/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
Będą zawierać stron danych i indeksowanie stron dla tej tabeli. Wspaniały.Złe wieści : wszystko, co zrobiłeś, to wyodrębnienie stron danych i stron indeksu
mydb.mytable
z miejsca zamieszkaniaibdata
. Wpis słownika danych dla każdej tabeli, w tymmydb.mytable
, nadal pozostaje w słowniku danych (patrz reprezentacja graficzna ibdata1 ). NIE MOŻESZ PO PROSTU SKASOWAĆ Wibdata1
TYM PUNKCIE !!! Należy pamiętać, żeibdata1
wcale się nie skurczył.Oczyszczanie infrastruktury InnoDB
Aby zmniejszyć się
ibdata1
raz na zawsze, wykonaj następujące czynności:Zrzuć (np. Z
mysqldump
) wszystkie bazy danych do.sql
pliku tekstowego (SQLData.sql
jest używane poniżej)Usuń wszystkie bazy danych (z wyjątkiem
mysql
iinformation_schema
) OSTRZEŻENIE : Zapobiegawczo uruchom ten skrypt, aby upewnić się, że masz wszystkie uprawnienia użytkowników:Zaloguj się do mysql i uruchom
SET GLOBAL innodb_fast_shutdown = 0;
(to całkowicie opróżni wszystkie pozostałe zmiany transakcyjne zib_logfile0
iib_logfile1
)Zamknij MySQL
Dodaj następujące wiersze do
/etc/my.cnf
(lubmy.ini
w systemie Windows)(Uwaga: niezależnie od tego, do czego masz zestaw
innodb_buffer_pool_size
, upewnij się, żeinnodb_log_file_size
jest to 25%innodb_buffer_pool_size
.Ponadto:
innodb_flush_method=O_DIRECT
nie jest dostępny w systemie Windows)Usuń
ibdata*
iib_logfile*
opcjonalnie możesz usunąć wszystkie foldery z/var/lib/mysql
wyjątkiem/var/lib/mysql/mysql
.Rozpocznij MySQL (Spowoduje to odtworzenie
ibdata1
[10MB domyślnie] aib_logfile0
iib_logfile1
na każdy 1G).Import
SQLData.sql
Teraz
ibdata1
będzie nadal rosnąć, ale będzie zawierać tylko metadane tabeli, ponieważ każda tabela InnoDB będzie istnieć pozaibdata1
.ibdata1
nie będzie już zawierał danych InnoDB i indeksów dla innych tabel.Na przykład załóżmy, że masz tabelę InnoDB o nazwie
mydb.mytable
. Jeśli zajrzysz do/var/lib/mysql/mydb
środka, zobaczysz dwa pliki reprezentujące tabelę:mytable.frm
(Nagłówek pamięci masowej)mytable.ibd
(Dane tabeli i indeksy)Dzięki
innodb_file_per_table
opcji w/etc/my.cnf
możesz uruchomić,OPTIMIZE TABLE mydb.mytable
a plik/var/lib/mysql/mydb/mytable.ibd
faktycznie się zmniejszy.Robiłem to wiele razy w swojej karierze jako administrator MySQL. W rzeczywistości, gdy to zrobiłem po raz pierwszy, zmniejszyłem plik 50 GB
ibdata1
do zaledwie 500 MB!Spróbuj. Jeśli masz dalsze pytania, po prostu zapytaj. Zaufaj mi; będzie to działać zarówno w perspektywie krótkoterminowej, jak i długoterminowej.
PRZESTROGA
Jeśli w kroku 6, jeśli mysql nie może zostać ponownie uruchomiony z powodu
mysql
upuszczenia schematu, spójrz wstecz na krok 2. Wykonałeś fizyczną kopięmysql
schematu. Możesz go przywrócić w następujący sposób:Wróć do kroku 6 i kontynuuj
UPDATE 2013-06-04 11:13 EDT
Jeśli chodzi o ustawienie innodb_log_file_size na 25% innodb_buffer_pool_size w kroku 5, ta ogólna reguła jest raczej stara.
Wracając
July 03, 2006
, Percona miała fajny artykuł, dlaczego wybrać właściwy innodb_log_file_size . PóźniejNov 21, 2008
Percona kontynuowała kolejny artykuł o tym, jak obliczyć właściwy rozmiar w oparciu o szczytowe obciążenie pracą, przy zachowaniu godzinnych zmian .Od tego czasu napisałem posty w DBA StackExchange na temat obliczania rozmiaru dziennika i odniesienia do tych dwóch artykułów Percona.
Aug 27, 2012
: Odpowiednie dostrojenie tabeli 30GB InnoDB na serwerze z 48GB RAMJan 17, 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 pracą można dokładniej określić w czasie w produkcji, można zmienić rozmiar dzienników podczas cyklu konserwacji w zaledwie kilka minut.
źródło
innodb_open_tables
jeśli to konieczne. Wartość domyślna to 300.Silnik InnoDB nie przechowuje usuniętych danych. Podczas wstawiania i usuwania wierszy niewykorzystane miejsce jest przydzielane w plikach magazynu InnoDB. Z czasem ogólna przestrzeń nie zmniejszy się, ale z czasem „usunięta i zwolniona” przestrzeń zostanie automatycznie ponownie wykorzystana przez serwer DB.
Możesz dalej dostrajać i zarządzać przestrzenią używaną przez silnik poprzez ręczną reorganizację tabel. Aby to zrobić, zrzuć dane z tabel, których dotyczy problem, za pomocą mysqldump, usuń tabele, uruchom ponownie usługę mysql, a następnie utwórz tabele ponownie z plików zrzutu.
źródło