Czy można wyczyścić silnik pamięci masowej mysql innodb, aby nie przechowywał danych z usuniętych tabel?
Czy za każdym razem muszę odbudowywać nową bazę danych?
Czy można wyczyścić silnik pamięci masowej mysql innodb, aby nie przechowywał danych z usuniętych tabel?
Czy za każdym razem muszę odbudowywać nową bazę danych?
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
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.
OPTIMIZE TABLE
?Niestety, działanie OPTIMIZE TABLE
z tabelą InnoDB przechowywaną we współużytkowanym pliku obszaru tabel ibdata1
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.
OPTIMIZE TABLE
z innodb_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
z innodb_file_per_table
włączoną, utworzy to .ibd
plik dla tej tabeli. Na przykład, jeśli masz tabelę z mydb.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 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 ibdata1
TYM PUNKCIE !!! Należy pamiętać, że ibdata1
wcale się nie skurczył.
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
i information_schema
) OSTRZEŻENIE : Zapobiegawczo uruchom ten skrypt, aby upewnić się, że masz wszystkie uprawnienia użytkowników:
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 opróżni wszystkie pozostałe zmiany transakcyjne z ib_logfile0
i ib_logfile1
)
Zamknij MySQL
Dodaj następujące wiersze do /etc/my.cnf
(lub my.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 tego, do czego masz zestaw innodb_buffer_pool_size
, upewnij się, że innodb_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*
i ib_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] a ib_logfile0
i ib_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ć poza ibdata1
. 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.
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:
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
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óźniej Nov 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.
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.