Mengapa "byte volume saya digunakan" selalu meningkat di Amazon Aurora cluster saya?

11

Saya memiliki kluster Aurora DB Amazon (AWS) , dan setiap hari, [Billed] Volume Bytes Usedsemakin meningkat.

Metrik CloudWatch VolumeBytesUsed dari waktu ke waktu

Saya telah memeriksa ukuran semua tabel saya (di semua database saya di cluster itu) menggunakan INFORMATION_SCHEMA.TABLEStabel:

SELECT ROUND(SUM(data_length)/1024/1024/1024) AS data_in_gb, ROUND(SUM(index_length)/1024/1024/1024) AS index_in_gb, ROUND(SUM(data_free)/1024/1024/1024) AS free_in_gb FROM INFORMATION_SCHEMA.TABLES;
+------------+-------------+------------+
| data_in_gb | index_in_gb | free_in_gb |
+------------+-------------+------------+
| 30         | 4           | 19         |
+------------+-------------+------------+

Total: 53GB

Jadi mengapa saya ditagih hampir 75GB saat ini?

Saya mengerti bahwa ruang yang disediakan tidak pernah bisa dibebaskan, dengan cara yang sama bahwa file-file ibdata pada server MySQL biasa tidak pernah bisa menyusut; Saya setuju dengan itu. Ini didokumentasikan, dan dapat diterima.

Masalah saya adalah bahwa setiap hari, ruang yang ditagih meningkat. Dan saya yakin saya TIDAK menggunakan ruang 75GB untuk sementara. Jika saya melakukan sesuatu seperti itu, saya akan mengerti. Seolah-olah ruang penyimpanan yang saya bebaskan, dengan menghapus baris dari tabel saya, atau menjatuhkan tabel, atau bahkan menjatuhkan database, tidak pernah digunakan kembali.

Saya telah menghubungi dukungan AWS (premium) beberapa kali, dan tidak pernah bisa mendapatkan penjelasan yang bagus tentang alasan itu.
Saya telah menerima saran untuk berjalan OPTIMIZE TABLEdi tabel yang memiliki banyak free_space(per INFORMATION_SCHEMA.TABLEStabel), atau untuk memeriksa panjang riwayat InnoDB, untuk memastikan data yang dihapus tidak tetap disimpan di segmen rollback (ref: MVCC ) , dan mulai ulang instance untuk memastikan segmen rollback dikosongkan.
Tidak ada yang membantu.

Guillaume Boudreau
sumber

Jawaban:

19

Ada beberapa hal yang berperan di sini ...

  1. Setiap tabel disimpan dalam tablespace sendiri

    Secara default, grup parameter untuk kelompok Aurora (bernama default.aurora5.6) mendefinisikan innodb_file_per_table = ON. Itu berarti setiap tabel disimpan dalam file terpisah, di cluster penyimpanan Aurora. Anda bisa melihat tablespace mana yang digunakan untuk masing-masing tabel Anda menggunakan kueri ini:

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    Catatan: Saya belum mencoba mengubah innodb_file_per_tableke OFF. Mungkin itu akan membantu ..?

  2. Ruang penyimpanan yang dibebaskan dengan menghapus tablespace TIDAK digunakan kembali

    Mengutip dukungan premium AWS:

    Karena desain unik dari mesin Aurora Storage untuk meningkatkan kinerjanya dan toleransi kesalahan, Aurora tidak memiliki fungsi untuk mendefragmen file tablespace tables per tabel dengan cara yang sama seperti MySQL standar.

    Saat ini Aurora sayangnya tidak memiliki cara untuk mengecilkan tablespace seperti standar MySQL dan semua ruang terfragmentasi dibebankan karena termasuk dalam VolumeBytesUsed.
    Alasan mengapa Aurora tidak dapat mengklaim kembali ruang tabel yang dijatuhkan dengan cara yang sama dengan MySQL standar adalah bahwa data untuk tabel disimpan dengan cara yang sangat berbeda dengan database MySQL standar dengan volume penyimpanan tunggal.

    Jika Anda menjatuhkan meja atau baris di Aurora, maka ruang tersebut tidak akan direklamasi pada volume gugus Auroras karena desain yang rumit ini.
    Ketidakmampuan untuk mendapatkan kembali ruang penyimpanan dalam jumlah kecil ini merupakan pengorbanan yang dilakukan untuk mendapatkan keuntungan kinerja tambahan dari volume penyimpanan cluster Auroras dan toleransi kesalahan Aurora yang meningkat pesat.

    Tetapi ada beberapa cara yang tidak jelas untuk menggunakan kembali sebagian dari ruang yang terbuang ...
    Sekali lagi, kutip dukungan premium AWS:

    Setelah kumpulan data total Anda melebihi ukuran tertentu (sekitar 160 GB), Anda dapat mulai mengklaim kembali ruang dalam 160 GB blok untuk digunakan kembali, misalnya jika Anda memiliki 400 GB dalam volume cluster Aurora Anda dan DROP 160 GB atau lebih dari tabel yang dapat dilakukan Aurora secara otomatis menggunakan kembali data 160 GB. Namun bisa lambat untuk merebut kembali ruang ini.
    Alasan untuk sejumlah besar data yang diperlukan untuk dibebaskan sekaligus adalah karena desain unik Auroras sebagai mesin DB skala perusahaan tidak seperti MySQL standar yang tidak dapat digunakan pada skala ini.

  3. MENGOPTIMALKAN TABEL itu jahat!

    Karena Aurora didasarkan pada MySQL 5.6, OPTIMIZE TABLEdipetakan ke ALTER TABLE ... FORCE, yang membangun kembali tabel untuk memperbarui statistik indeks dan membebaskan ruang yang tidak digunakan dalam indeks berkerumun. Secara efektif, bersama dengan innodb_file_per_table = ON, itu berarti menjalankan OPTIMIZE TABLEmenciptakan file tablespace baru, dan menghapus yang lama. Karena menghapus file tablespace tidak membebaskan penyimpanan yang digunakannya, itu berarti OPTIMIZE TABLEakan selalu menghasilkan lebih banyak penyimpanan yang disediakan. Aduh!

    Ref: https://dev.mysql.com/doc/refman/5.6/en/optimize-table.html#optimize-table-innodb-details

  4. Menggunakan tabel sementara

    Secara default, grup parameter untuk instance Aurora (bernama default.aurora5.6) mendefinisikan default_tmp_storage_engine = InnoDB. Itu berarti setiap kali saya membuat TEMPORARYtabel, itu disimpan, bersama dengan semua tabel reguler saya , di cluster penyimpanan Aurora. Itu berarti ruang baru disediakan untuk menampung tabel tersebut, sehingga meningkatkan total VolumeBytesUsed.
    Solusi untuk ini cukup sederhana: ubah nilai default_tmp_storage_engineparameter menjadi MyISAM. Ini akan memaksa Aurora untuk membuat TEMPORARYtabel pada penyimpanan lokal instance.
    Yang perlu diperhatikan: penyimpanan lokal instance terbatas; lihat Free Local Storagemetrik di CloudWatch untuk melihat berapa banyak penyimpanan yang dimiliki oleh instans Anda. Contoh yang lebih besar (lebih mahal) memiliki lebih banyak penyimpanan lokal.

    Ref: belum ada; dokumentasi Amazon Aurora saat ini tidak menyebutkan ini. Saya meminta tim dukungan AWS untuk memperbarui dokumentasi, dan akan memperbarui jawaban saya jika / begitu mereka lakukan.

Guillaume Boudreau
sumber
1
Ini adalah jawaban yang bagus, dan yowch , itu adalah beberapa peringatan utama. Senang saya melihat ini.
ceejayoz
Dito. Memperhatikan satu server DB hingga 300 GB, untuk basis data dengan ukuran yang dilaporkan MySQL sebesar 54 GB ... jika ruang tidak pernah direklamasi, itu adalah contoh yang baik tentang apa yang terjadi ketika Anda memiliki banyak tabel yang sering ditulis ke tabel ( misalnya tabel log, tabel indeks, dll.).
geerlingguy