MariaDB
 sql >> Teknologi Basis Data >  >> RDS >> MariaDB

Database MySQL Saya Kehabisan Ruang Disk

Ketika server MySQL kehabisan ruang disk, Anda akan melihat salah satu kesalahan berikut di aplikasi Anda (serta di log kesalahan MySQL):

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

Untuk log biner, pesan kesalahannya seperti ini:

[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.

Untuk log relai, pesan kesalahannya seperti ini:

[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.

Untuk log kueri lambat, Anda akan melihat pesan kesalahan seperti ini:

[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.

Untuk InnoDB terlihat seperti ini:

[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 ./#

Mereka semua melaporkan nomor kode kesalahan yang sama yaitu 28. Atau, kita dapat menggunakan kode kesalahan untuk melihat kesalahan yang sebenarnya dengan perintah perror:

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

Di atas berarti server MySQL kehabisan ruang disk, dan sebagian besar waktu MySQL dihentikan atau terhenti pada saat ini. Dalam posting blog ini, kita akan mencari cara untuk memecahkan masalah ini untuk MySQL yang berjalan di lingkungan berbasis Linux.

Pemecahan Masalah

Pertama-tama, kita harus menentukan partisi disk mana yang penuh. MySQL dapat dikonfigurasi untuk menyimpan data pada disk atau partisi yang berbeda. Lihatlah jalur seperti yang dinyatakan dalam kesalahan untuk memulai. Dalam contoh ini, direktori kita terletak di lokasi default, /var/lib/mysql yang berada di bawah partisi /. Kita dapat menggunakan perintah df dan menentukan path lengkap ke datadir untuk mendapatkan partisi tempat data disimpan:

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

Di atas berarti kita harus mengosongkan beberapa ruang di partisi root.

Solusi Sementara

Solusi sementara adalah mengosongkan beberapa ruang disk sehingga MySQL dapat menulis ke disk dan melanjutkan operasi. Hal-hal yang dapat kita lakukan jika menghadapi masalah seperti ini berkaitan dengan:

  • Penghapusan file yang tidak perlu
  • Membersihkan log biner
  • Menjatuhkan tabel lama, atau membangun kembali tabel yang sangat besar

Hapus File yang Tidak Diperlukan

Ini biasanya merupakan langkah pertama yang harus dilakukan jika server MySQL sedang down atau tidak responsif, atau Anda tidak mengaktifkan log biner. Misalnya, file di bawah /var/log/ biasanya merupakan tempat pertama untuk mencari file yang tidak perlu:

$ 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

Contoh di atas menunjukkan cara mengambil file yang lebih besar dari 5MB. Kita dapat dengan aman menghapus file log yang diputar yang biasanya dalam format {filename}.{number}, misalnya dari audit.log.1 hingga audit.log.6. Hal yang sama dapat dikatakan tentang cadangan besar yang lebih tua yang disimpan di server. Jika Anda telah melakukan pemulihan melalui Percona Xtrabackup atau Cadangan MariaDB, semua file yang diawali dengan xtrabackup_ dapat dihapus dari direktori data MySQL, karena tidak lagi diperlukan untuk pemulihan. File xtrabackup_logfile biasanya merupakan file terbesar karena berisi semua transaksi yang dieksekusi saat proses xtrabackup menyalin datadir ke tujuan. Contoh berikut menunjukkan semua file terkait dalam datadir 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

Oleh karena itu, file-file tersebut aman untuk dihapus. Mulai layanan MySQL setelah setidaknya ada 10% lebih banyak ruang kosong.

Bersihkan Log Biner

Jika server MySQL masih responsif dan log biner diaktifkan, misalnya, untuk replikasi atau pemulihan point-in-time, kami dapat menghapus file log biner lama dengan menggunakan pernyataan PURGE dan memberikan selang. Dalam contoh ini, kami menghapus semua log biner sebelum 3 hari yang lalu:

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

Untuk Replikasi MySQL, aman untuk menghapus semua log yang telah direplikasi dan diterapkan pada slave. Periksa nilai Relay_Master_Log_File di server:

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

Dan hapus file log yang lebih lama misalnya binlog.000007 dan yang lebih lama. Ini praktik yang baik untuk me-restart server MySQL untuk memastikan bahwa ia memiliki sumber daya yang cukup. Kami juga dapat membiarkan rotasi log biner terjadi secara otomatis melalui variabel expired_logs_days (

mysql> SET GLOBAL expire_logs_days = 3;

Kemudian, tambahkan baris berikut ke dalam file konfigurasi MySQL di bawah bagian [mysqld]:

expire_logs_days=3

Di MySQL 8.0, gunakan binlog_expire_logs_seconds sebagai gantinya, di mana nilai defaultnya adalah 2592000 detik (30 hari). Dalam contoh ini, kami menguranginya menjadi hanya 3 hari (60 detik x 60 menit x 24 jam x 3 hari):

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

SET PERSIST akan memastikan konfigurasi dimuat di restart berikutnya. Konfigurasi yang diatur oleh perintah ini disimpan di dalam /var/lib/mysql/mysqld-auto.cnf.

Lepaskan Tabel Lama / Bangun Kembali Tabel

Perhatikan bahwa operasi DELETE tidak akan mengosongkan ruang disk kecuali OPTIMIZE TABLE dijalankan sesudahnya. Jadi, jika Anda telah menghapus banyak baris, dan Anda ingin mengembalikan ruang kosong kembali ke OS setelah operasi DELETE yang besar, jalankan OPTIMIZE TABLE, atau bangun kembali. Misalnya:

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

Kami juga dapat memaksa untuk membangun kembali tabel dengan menggunakan pernyataan ALTER:

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

Perhatikan bahwa operasi DDL di atas dilakukan melalui DDL online, artinya MySQL mengizinkan operasi DML bersamaan saat pembangunan kembali sedang berlangsung. Cara lain untuk melakukan operasi defragmentasi adalah dengan menggunakan mysqldump untuk membuang tabel ke file teks, menjatuhkan tabel, dan memuatnya kembali dari file dump. Pada akhirnya, kita juga dapat menggunakan DROP TABLE untuk menghapus tabel yang tidak digunakan atau TRUNCATE TABLE untuk menghapus semua baris dalam tabel, yang akibatnya mengembalikan ruang kembali ke OS.

Solusi Permanen untuk Masalah Ruang Disk

Solusi permanen tentu saja menambahkan lebih banyak ruang ke disk atau partisi yang sesuai, atau menerapkan aturan retensi yang lebih pendek untuk menyimpan file yang tidak perlu di server. Jika Anda menggunakan sistem penyimpanan file yang dapat diskalakan, Anda harus dapat meningkatkan sumber daya tanpa terlalu banyak kerumitan, atau dengan gangguan dan waktu henti minimal pada layanan MySQL. Untuk mempelajari lebih lanjut tentang cara mengukur penyimpanan Anda dan memahami perencanaan kapasitas MySQL dan MariaDB, lihat entri blog ini.

Ringkasan

Masalah database terkait disk adalah salah satu masalah paling umum tentang administrator database MySQL dan pengembang yang bekerja dengan RDBMS sama - namun, sementara masalah itu mungkin lazim, ada juga banyak cara untuk menyelesaikannya - dan menyelesaikannya untuk selamanya. Cara untuk mengatasi masalah seperti itu mungkin tidak selalu mudah, namun, semuanya dapat diselesaikan dengan sedikit usaha dan bantuan yang disediakan oleh alat seperti ClusterControl.

Dengan kemampuan pemantauan proaktif ClusterControl, masalah terkait database seharusnya tidak menjadi kekhawatiran Anda:Anda akan mendapatkan pemberitahuan dalam bentuk peringatan ketika ruang disk telah mencapai 80%, dan pemberitahuan dalam bentuk peringatan kritis jika Anda penggunaan disk mencapai 90% atau lebih. Kami berharap posting blog ini memungkinkan Anda menyelesaikan setidaknya beberapa masalah yang terkait dengan penggunaan ruang disk MySQL, menikmati penggunaan ClusterControl Anda, dan sampai jumpa di blog berikutnya.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Mengembalikan Elemen dari JSON Array di MariaDB

  2. Menggunakan Sysbench untuk Menghasilkan Data Uji untuk Tabel Sharded di MySQL

  3. Bagaimana CEILING() Bekerja di MariaDB

  4. Bagaimana ACOS() Bekerja di MariaDB

  5. Migrasi dari Oracle Database ke MariaDB - Yang Harus Anda Ketahui