`ERROR 1114 (HY000) tabel… sudah penuh` dengan innodb_file_per_table diatur ke autoextend

26

Saya memiliki database MySQL yang menyimpan sejumlah besar data (100-200GB - banyak pengukuran ilmiah). Sebagian besar data disimpan dalam satu tabel Sample. Sekarang saya sedang membuat replika budak dari database dan saya ingin mengambil keuntungan dari innodb_file_per_tableselama proses. Jadi saya mengatur innodb_file_per_tablekonfigurasi budak saya dan mengimpor dump database. Yang mengejutkan saya, gagal dengan

GALAT 1114 (HY000) pada baris 5602: Tabel 'Sampel' penuh

File Sample.ibdsaat ini sekitar 93GB, dengan lebih dari 600GB ruang kosong tersedia di partisi, jadi ini bukan masalah ruang bebas disk. Sepertinya itu tidak mengenai segala jenis batas sistem file (saya menggunakan ext4).

Saya akan berterima kasih atas ide apa pun yang bisa menjadi penyebabnya, atau apa yang harus diselidiki.


Pembaruan: Saya menggunakan mysql Ver 14.14 Distrib 5.1.66, for debian-linux-gnu (x86_64).

SELECT @@datadir; -- returns `/home/var/lib/mysql/`
SHOW VARIABLES LIKE '%innodb_data_file_path%'; -- ibdata1:10M:autoextend 

df -h /home/var/lib/mysql/
768G   31G  699G   5% /home
Petr Pudlák
sumber

Jawaban:

33

FAKTA

Anda bilang Anda menggunakan ext4. Batas ukuran file adalah 16TB. Jadi, Sample.ibdtidak boleh penuh.

Anda mengatakan Anda innodb_data_file_pathyaitu ibdata1:10M:autoextend. Dengan demikian, file ibdata1 itu sendiri tidak memiliki batas ukuran kecuali dari OS.

Mengapa pesan ini muncul sama sekali? Perhatikan pesannya adalah "Tabel ... sudah penuh", bukan "Disk ... sudah penuh". Kondisi penuh tabel ini dari sudut pandang logis . Pikirkan tentang InnoDB. Interaksi apa yang terjadi?

Dugaan saya adalah InnoDB berusaha memuat 93GB data sebagai satu transaksi. Dari mana Table is Fullpesan itu berasal? Saya akan melihat ibdata1, bukan dalam hal ukuran fisiknya (yang sudah Anda singkirkan), tetapi dalam hal batas transaksi apa yang sedang dicapai.

Apa yang ada di dalam ibdata1 ketika innodb_file_per_table diaktifkan dan Anda memuat data baru ke dalam MySQL?

Kecurigaan saya memberi tahu saya bahwa Undo Log dan / atau Redo Log yang harus disalahkan.

Apa log-log ini? Menurut Kitab

sxs

Bab 10: "Mesin Penyimpan" Halaman 203 Paragraf 3,4 mengatakan yang berikut:

Mesin InnoDB menyimpan dua jenis log: log undo dan log redo. Tujuan dari membatalkan log adalah untuk memutar kembali transaksi, serta untuk menampilkan versi data yang lebih lama untuk permintaan yang berjalan di tingkat isolasi transaksi yang memerlukannya. Kode yang menangani undo log dapat ditemukan di storage / innobase / buf / log / log0log.c .

Tujuan dari redo log adalah untuk menyimpan informasi yang akan digunakan dalam pemulihan kerusakan. Ini memungkinkan proses pemulihan untuk mengeksekusi kembali transaksi yang mungkin atau mungkin tidak selesai sebelum crash. Setelah melakukan kembali transaksi-transaksi tersebut, basis data dibawa ke keadaan yang konsisten. Kode yang berhubungan dengan redo log dapat ditemukan di storage / innobase / log / log0recv.c .

ANALISIS

Ada 1023 Undo Log di dalam ibdata1 (Lihat Segmen Rollback dan Undo Space) . Karena batalkan log menyimpan salinan data seperti yang muncul sebelum ulang, semua 1023 Batalkan Log telah mencapai batasnya. Dari perspektif lain, semua 1023 Undo Logs dapat didedikasikan untuk satu transaksi yang memuat Sampletabel.

TAPI TUNGGU...

Anda mungkin mengatakan "Saya memuat Sampletabel kosong ". Bagaimana cara Membatalkan Log yang terlibat? Sebelum Sampletabel dimuat dengan 93GB data, itu kosong. Mewakili setiap baris yang tidak ada harus mengambil ruang pembersihan rumah di Undo Log. Mengisi 1023 Undo Log tampaknya sepele mengingat jumlah data yang dituangkan ibdata1. Saya bukan orang pertama yang mencurigai ini:

Dari Dokumentasi MySQL 4.1, perhatikan Posted by Chris Calender on September 4 2009 4:25pm:

Perhatikan bahwa pada 5.0 (pra-5.0.85) dan 5.1 (pra-5.1.38), Anda bisa menerima kesalahan "table is full" untuk tabel InnoDB jika InnoDB kehabisan slot undo (bug # 18828).

Berikut ini adalah laporan bug untuk MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828

SARAN

Saat Anda membuat mysqldump dari Sampletabel, silakan gunakan --no-autocommit

mysqldump --no-autocommit ... mydb Sample > Sample.sql

Ini akan menempatkan eksplisit COMMIT;setelah setiap INSERT. Kemudian, muat ulang tabel.

Jika ini tidak berhasil ( Anda tidak akan suka ini ), lakukan ini

mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql

Ini akan membuat setiap INSERT hanya memiliki satu baris. Mysqldump akan jauh lebih besar (10+ kali lebih besar) dan bisa memakan waktu 10 hingga 100 kali lebih lama untuk memuat ulang.

Dalam kedua kasus ini, ini akan membuat Undo Log tidak tergenang air.

Cobalah !!!

UPDATE 2013-06-03 13:05 EDT

SARAN TAMBAHAN

Jika tabel sistem InnoDB (alias ibdata1) mencapai batas filesize dan Undo Log tidak dapat digunakan, Anda bisa menambahkan tablespace sistem lain (ibdata2).

Saya baru saja mengalami situasi ini hanya dua hari yang lalu. Saya memperbarui posting lama saya dengan apa yang saya lakukan: Lihat Desain Basis Data - Membuat banyak basis data untuk menghindari sakit kepala batas pada ukuran tabel

Intinya, Anda harus mengubah innodb_data_file_path untuk mengakomodasi file tablespace sistem baru. Biarkan saya jelaskan caranya:

SKENARIO

Pada disk (ext3), server klien saya memiliki yang berikut ini:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  2 00:15 ibdata2

Pengaturannya adalah

innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M

Catatan yang ibdata2tumbuh menjadi 2196875759616 yang 2145386484M.

Saya harus menanamkan filesize ibdata2ke dalam innodb_data_file_path dan menambahkanibdata3

innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend

Ketika saya memulai kembali mysqld, itu berhasil:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql   32315015168 Jun  3 17:02 ibdata3

Dalam 40 jam, ibdata3tumbuh menjadi 31G. MySQL sekali lagi berfungsi.

RolandoMySQLDBA
sumber
Saya menduga dengan nama pemilik, klien Anda menggunakan alat pemantauan yang akan datang ... Terima kasih, ini tampaknya telah memperbaiki masalah bagi saya juga.
Steve
Saya ingin tahu apakah ini masih menjadi masalah (harap tidak)
Evan Carroll
3

Saya memiliki masalah yang sama dan saya hanya melakukan satu hal dan itu berhasil.

Anda tampaknya memiliki ukuran maksimum terlalu rendah untuk file konfigurasi innodb_data_file_pathAnda my.cnf. Cukup ubah kode di bawah ini -

innodb_data_file_path = ibdata1:10M:autoextend:max:512M

Catatan Penting Anda tidak dapat meng-host lebih 512MBdari data di semua InnoDB tabel yang digabungkan.

Anda juga dapat beralih ke skema innodb-per-tabel menggunakan innodb_file_per_table.

Joomler
sumber