MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

W bazie danych MySQL brakuje miejsca na dysku

Gdy serwerowi MySQL zabraknie miejsca na dysku, zobaczysz jeden z następujących błędów w swojej aplikacji (jak również w dzienniku błędów MySQL):

ERROR 3 (HY000) at line 1: Error writing file '/tmp/AY0Wn7vA' (Errcode: 28 - No space left on device)

W przypadku dziennika binarnego komunikat o błędzie wygląda tak:

[ERROR] [MY-000035] [Server] Disk is full writing './binlog.000019' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

W przypadku dziennika przekaźnika komunikat o błędzie wygląda tak:

[ERROR] [MY-000035] [Server] Disk is full writing './relay-bin.000007' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

W przypadku powolnego dziennika zapytań zobaczysz komunikat o błędzie, taki jak:

[ERROR] [MY-011263] [Server] Could not use /var/log/mysql/mysql-slow.log for logging (error 28 - No space left on device). Turning logging off for the server process. To turn it on again: fix the cause, then either restart the query logging by using "SET GLOBAL SLOW_QUERY_LOG=ON" or restart the MySQL server.

W przypadku InnoDB wygląda to tak:

[ERROR] [MY-012144] [InnoDB] posix_fallocate(): Failed to preallocate data for file ./#innodb_temp/temp_8.ibt, desired size 16384 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/8.0/en/operating-system-error-codes.html
[Warning] [MY-012638] [InnoDB] Retry attempts for writing partial data failed.
[ERROR] [MY-012639] [InnoDB] Write to file ./#innodb_temp/temp_8.ibt failed at offset 81920, 16384 bytes should have been written, only 0 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
[ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'
[Warning] [MY-012145] [InnoDB] Error while writing 16384 zeroes to ./#

Wszystkie zgłaszają ten sam kod błędu, który wynosi 28. Alternatywnie możemy użyć kodu błędu, aby zobaczyć rzeczywisty błąd za pomocą polecenia perror:

$ perror 28
OS error code  28: No space left on device

Powyższe oznacza po prostu, że serwer MySQL nie ma miejsca na dysku i przez większość czasu MySQL jest w tym momencie zatrzymany lub zablokowany. W tym poście na blogu przyjrzymy się sposobom rozwiązania tego problemu dla MySQL działającego w środowisku opartym na Linuksie.

Rozwiązywanie problemów

Przede wszystkim musimy określić, która partycja dysku jest pełna. MySQL można skonfigurować do przechowywania danych na innym dysku lub partycji. Na początek spójrz na ścieżkę podaną w błędzie. W tym przykładzie nasz katalog znajduje się w domyślnej lokalizacji /var/lib/mysql, która znajduje się pod partycją /. Możemy użyć polecenia df i określić pełną ścieżkę do katalogu danych, aby uzyskać partycję, na której przechowywane są dane:

$ df -h /var/lib/mysql
Filesystem      Size Used Avail Use% Mounted on
/dev/sda1        40G 40G 20K 100% /

Powyższe oznacza, że ​​musimy zwolnić trochę miejsca na partycji głównej.

Tymczasowe obejścia

Tymczasowe obejście polega na wyczyszczeniu części miejsca na dysku, aby MySQL mógł zapisywać na dysku i wznowić operację. Rzeczy, które możemy zrobić, jeśli napotkamy tego rodzaju problem, są związane z:

  • Usuwanie niepotrzebnych plików
  • Czyszczenie dzienników binarnych
  • Upuszczanie starych stołów lub odbudowywanie bardzo dużego stołu

Usuń niepotrzebne pliki

Jest to zwykle pierwszy krok, który należy wykonać, jeśli serwer MySQL nie działa lub nie odpowiada, albo nie masz włączonych dzienników binarnych. Na przykład pliki w katalogu /var/log/ są zwykle pierwszym miejscem wyszukiwania niepotrzebnych plików:

$ cd /var/log
$ find . -type f -size +5M -exec du -sh {} +
8.1M ./audit/audit.log.6
8.1M ./audit/audit.log.5
8.1M ./audit/audit.log.4
8.1M ./audit/audit.log.3
8.1M ./audit/audit.log.2
8.1M ./audit/audit.log.1
11M ./audit/audit.log
8.5M ./secure-20190429
8.0M ./wtmp

Powyższy przykład pokazuje, jak odzyskać pliki większe niż 5 MB. Możemy bezpiecznie usunąć rotowane pliki dziennika, które zwykle są w formacie {nazwa pliku}.{numer}, na przykład od audit.log.1 do audit.log.6. To samo można powiedzieć o wszelkich dużych starszych kopiach zapasowych przechowywanych na serwerze. Jeśli przywracanie odbywało się za pomocą Percona Xtrabackup lub MariaDB Backup, wszystkie pliki z prefiksem xtrabackup_ można usunąć z katalogu danych MySQL, ponieważ nie są już potrzebne do przywrócenia. Plik xtrabackup_logfile jest zwykle największym plikiem, ponieważ zawiera wszystkie transakcje wykonane podczas procesu xtrabackup kopiowania katalogu datadir do miejsca docelowego. Poniższy przykład pokazuje wszystkie powiązane pliki w katalogu danych MySQL:

$ ls -lah /var/lib/mysql | grep xtrabackup_
-rw-r-----.  1 mysql root   286 Feb 4 11:30 xtrabackup_binlog_info
-rw-r--r--.  1 mysql root    24 Feb 4 11:31 xtrabackup_binlog_pos_innodb
-rw-r-----.  1 mysql root    83 Feb 4 11:31 xtrabackup_checkpoints
-rw-r-----.  1 mysql root   808 Feb 4 11:30 xtrabackup_info
-rw-r-----.  1 mysql root  179M Feb 4 11:31 xtrabackup_logfile
-rw-r--r--.  1 mysql root     1 Feb 4 11:31 xtrabackup_master_key_id
-rw-r-----.  1 mysql root   248 Feb 4 11:31 xtrabackup_tablespaces

Dlatego wspomniane pliki są bezpieczne do usunięcia. Uruchom usługę MySQL, gdy będzie co najmniej 10% więcej wolnego miejsca.

Wyczyść dzienniki binarne

Jeśli serwer MySQL nadal odpowiada i ma włączony dziennik binarny, np. do celów replikacji lub odzyskiwania do określonego momentu, możemy wyczyścić stare pliki dziennika binarnego, używając instrukcji PURGE i podając interwał. W tym przykładzie usuwamy wszystkie logi binarne sprzed 3 dni:

mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);
mysql> SHOW BINARY LOGS;

W przypadku replikacji MySQL można bezpiecznie usunąć wszystkie dzienniki, które zostały zreplikowane i zastosowane na urządzeniach podrzędnych. Sprawdź wartość Relay_Master_Log_File na serwerze:

mysql> SHOW SLAVE STATUS\G
...
        Relay_Master_Log_File: binlog.000008
...

I usuń starsze pliki dziennika, na przykład binlog.000007 i starsze. Dobrą praktyką jest ponowne uruchomienie serwera MySQL, aby upewnić się, że ma wystarczającą ilość zasobów. Możemy również pozwolić, aby rotacja logów binarnych odbywała się automatycznie za pomocą zmiennej execute_logs_days (

mysql> SET GLOBAL expire_logs_days = 3;

Następnie dodaj następujący wiersz do pliku konfiguracyjnego MySQL w sekcji [mysqld]:

expire_logs_days=3

W MySQL 8.0 użyj zamiast tego binlog_expire_logs_seconds, gdzie domyślna wartość to 2592000 sekund (30 dni). W tym przykładzie skróciliśmy go do zaledwie 3 dni (60 sekund x 60 minut x 24 godziny x 3 dni):

mysql> SET GLOBAL binlog_expire_logs_seconds = (60*60*24*3);
mysql> SET PERSIST binlog_expire_logs_seconds = (60*60*24*3);

SET PERSIST upewni się, że konfiguracja zostanie załadowana przy następnym restarcie. Konfiguracja ustawiona przez to polecenie jest przechowywana w /var/lib/mysql/mysqld-auto.cnf.

Upuść stare tabele / Przebuduj tabele

Pamiętaj, że operacja DELETE nie zwolni miejsca na dysku, chyba że później zostanie wykonane polecenie OPTIMIZE TABLE. Tak więc, jeśli usunąłeś wiele wierszy i chciałbyś zwrócić wolne miejsce z powrotem do systemu operacyjnego po ogromnej operacji DELETE, uruchom OPTIMIZE TABLE lub odbuduj ją. Na przykład:

mysql> DELETE tbl_name WHERE id < 100000; -- remove 100K rows
mysql> OPTIMIZE TABLE tbl_name;

Możemy również wymusić przebudowanie tabeli za pomocą instrukcji ALTER:

mysql> ALTER TABLE tbl_name FORCE;
mysql> ALTER TABLE tbl_name; -- a.k.a "null" rebuild

Należy zauważyć, że powyższa operacja DDL jest wykonywana za pośrednictwem DDL online, co oznacza, że ​​MySQL zezwala na współbieżne operacje DML podczas trwającej odbudowy. Innym sposobem wykonania operacji defragmentacji jest użycie mysqldump do zrzucenia tabeli do pliku tekstowego, upuszczenia tabeli i ponownego załadowania jej z pliku zrzutu. Ostatecznie możemy również użyć DROP TABLE, aby usunąć nieużywaną tabelę lub TRUNCATE TABLE, aby wyczyścić wszystkie wiersze w tabeli, co w konsekwencji zwróci przestrzeń z powrotem do systemu operacyjnego.

Stałe rozwiązania problemów z miejscem na dysku

Stałym rozwiązaniem jest oczywiście dodanie większej ilości miejsca do odpowiedniego dysku lub partycji lub zastosowanie krótszej reguły przechowywania, aby zachować niepotrzebne pliki na serwerze. Jeśli korzystasz ze skalowalnego systemu przechowywania plików, powinieneś być w stanie skalować zasób w górę bez większych kłopotów lub przy minimalnych zakłóceniach i przestojach usługi MySQL. Aby dowiedzieć się więcej o tym, jak wymiarować pamięć masową i zrozumieć planowanie pojemności MySQL i MariaDB, zapoznaj się z tym wpisem na blogu.

Podsumowanie

Problemy z bazą danych związane z dyskami są jednym z najczęstszych problemów dotyczących administratorów baz danych MySQL i programistów pracujących z RDBMS – jednak, chociaż te problemy mogą być powszechne, istnieje również wiele sposobów ich rozwiązania – i rozwiązania ich na dobre. Sposoby rozwiązania tego problemu nie zawsze są proste, jednak wszystkie można rozwiązać przy odrobinie wysiłku i pomocy zapewnianej przez narzędzia takie jak ClusterControl.

Dzięki możliwościom proaktywnego monitorowania ClusterControl, problemy związane z bazą danych powinny być najmniejszym zmartwieniem:otrzymasz powiadomienie w formie ostrzeżenia, gdy miejsce na dysku osiągnie 80%, oraz powiadomienie w formie ostrzeżenia krytycznego, jeśli wykorzystanie dysku osiąga 90% lub więcej. Mamy nadzieję, że ten wpis na blogu pozwolił rozwiązać przynajmniej kilka problemów związanych z wykorzystaniem miejsca na dysku MySQL, cieszyć się korzystaniem z ClusterControl i do zobaczenia w następnym blogu.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wiele opóźnionych urządzeń podrzędnych replikacji do odzyskiwania po awarii przy niskim RTO

  2. Jak CHARSET() działa w MariaDB

  3. Funkcje JSON MariaDB

  4. Wskazówki dotyczące monitorowania replikacji MariaDB za pomocą ClusterControl

  5. MariaDB USER() Objaśnienie