UPDATE: tl; dr: Masalahnya adalah MySQL menggunakan TMPDIR
saat membuat indeks. Dan saya TMPDIR
adalah orang yang kehabisan ruang disk.
Q asli:
Saya mencoba menambahkan indeks ke tabel InnoDB, dan mendapatkan table is full error
. Saya memiliki ruang disk yang cukup dan konfigurasi MySQL memiliki file-per-table = 1. Tabel data adalah 85GB dan saya berasumsi indeksnya akan sekitar 20GB - 30GB dan saya memiliki lebih banyak ruang disk dari itu. Saya juga menggunakan ext3 jadi saya tidak merasa ada masalah dengan batas ukuran file dari sudut pandang OS.
Kesalahan yang dicatat terlihat seperti ini:
140616 13:04:33 InnoDB: Error: Write to file (merge) failed at offset 3 1940914176.
InnoDB: 1048576 bytes should have been written, only 970752 were written.
InnoDB: Operating system error number 0.
InnoDB: Check that your OS and file system support files of this size.
InnoDB: Check also that the disk is not full or a disk quota exceeded.
InnoDB: Error number 0 means 'Success'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html
140616 13:04:33 [ERROR] /usr/libexec/mysqld: The table 'my_table' is full
Apa yang menyebabkan ini dan bagaimana saya bisa menyelesaikannya?
Tabel buat:
`CREATE TABLE `my_table` (
`uid_from` bigint(11) NOT NULL,
`uid_to` bigint(11) NOT NULL,
`counter` int(11) NOT NULL,
`updated` date NOT NULL,
PRIMARY KEY (`uid_to`,`uid_from`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8`
Seperti Data 87.4GB dan saya memperkirakan ada sekitar 1,5B baris.
SHOW GLOBAL VARIABLES LIKE 'tmpdir';
Variable_name Value
tmpdir /tmp
[root@web ~]# df -h /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 40G 24G 14G 64% /
Jawaban:
Tolong jangan tertipu oleh pesan kesalahan
The table 'my_table' is full
. Skenario langka ini sama sekali tidak ada hubungannya dengan ruang disk. Kondisi lengkap tabel ini berkaitan dengan pipa ledeng internal InnoDB.Pertama, lihat diagram Arsitektur InnoDB ini
Harap dicatat bahwa tablespace sistem (file ibdata) hanya memiliki 128 Rollback Segments dan 1023 Rollback Slots Per Rollback Segment. Ini membatasi ukuran kapasitas kemunduran transaksi. Dengan kata lain, jika satu segmen rollback membutuhkan lebih dari 1023 slot untuk mendukung transaksi, transaksi akan mencapai
table is full
kondisi itu.Pikirkan restoran Red Lobster di New Jersey . Mungkin memiliki kapasitas 200 orang. Jika restoran penuh, barisan orang mungkin pergi ke luar untuk menunggu. Jika orang-orang di telepon menjadi tidak sabar, mereka mungkin pergi karena restoran penuh. Jelas, solusinya tidak akan membuat New Jersey lebih besar (atau mendapatkan lebih banyak ruang disk). Solusinya adalah membuat restoran Red Lobster lebih besar. Dengan begitu Anda dapat meningkatkan kapasitas tempat duduk, katakanlah, 240. Bahkan dengan itu, garis dapat terbentuk di luar jika lebih dari 240 orang memutuskan untuk datang ke Red Lobster.
Sebagai contoh, saya punya klien dengan 2TB sistem tablespace dan innodb_file_per_table dinonaktifkan. (346G untuk ibdata1, reset untuk ibdata2). Saya menjalankan kueri ini
Selanjutnya, saya mengurangi InnoDBDataIndexSpace dari jumlah filesizes untuk ibdata1 dan ibdata2. Saya mendapat dua hal yang mengejutkan saya
Table is Full
kondisi yang samaIni berarti bahwa 106GB digunakan untuk pipa internal InnoDB. Klien menggunakan ext3 pada saat itu.
Solusi bagi saya adalah menambahkan ibdata3. Saya membahas ini di posting lama saya. Bagaimana mengatasi "Tabel ... sudah penuh" dengan "innodb_file_per_table"?
Saya telah membahas ini di postingan lain juga
Mar 31, 2014
: direktori mysql tumbuh menjadi 246G setelah satu kueri, yang gagal karena tabel penuhNov 25, 2011
: ERROR 1114 (HY000) pada baris 6308 dalam file & Tabel user_analysis penuhPerlu diingat bahwa kondisi ini dapat terjadi bahkan jika innodb_file_per_table diaktifkan. Bagaimana? Rollbacks dan Undo Logs adalah sumber lonjakan yang tidak terkontrol adalah pertumbuhan untuk ibdata1 .
PERTANYAAN SEBENARNYA
Karena Anda menambahkan indeks ke tabel dan mendapatkan
Table is Full
, tabel tersebut harus besar dan tidak dapat masuk ke dalam segmen rollback tunggal. Anda harus melakukan hal berikut:LANGKAH 01
Dapatkan data ke dalam file dump
LANGKAH 02
Login ke MySQL dan jalankan ini
LANGKAH 03
Muat tabel dengan indeks tambahan dengan data
Itu saja.
Lihat, masalahnya adalah bahwa ALTER TABLE akan mencoba menyuntikkan semua baris dalam tabel besar Anda sebagai satu transaksi. Menggunakan mysqldump akan memasukkan data ke dalam tabel (sekarang dengan indeks baru) ribuan baris sekaligus, tidak semua baris dalam satu transaksi.
Jangan khawatir tentang
what if this doesn't work?
Tabel asli akan dinamaimytable_old
jika ada sesuatu. itu bisa berfungsi sebagai cadangan. Anda dapat menjatuhkan cadangan saat Anda tahu tabel baru berfungsi untuk Anda.Cobalah !!!
UPDATE 2014-06-16 11:13 EDT
Jika Anda khawatir tentang dump data yang lebih besar, cukup gzip saja.
Anda bisa melakukan langkah yang sama, tetapi sebagai berikut
LANGKAH 01
Dapatkan data ke dalam file dump
LANGKAH 02
Login ke MySQL dan jalankan ini
LANGKAH 03
Muat tabel dengan indeks tambahan dengan data
atau
UPDATE 2014-06-16 12:55 EDT
Saya hanya memikirkan aspek lain berkenaan dengan masalah ini.
Karena Anda melakukan DDL dan bukan DML, ada kemungkinan bahwa ini bukan pipa saluran internal InnoDB. Karena DDL tidak dapat mengembalikan untuk InnoDB , masalahnya harus menjadi saluran pipa eksternal. Di mana pipa eksternal ini tersumbat? Saya curiga folder temp untuk OS. Mengapa?
Lihat
disk quota exceeded
? Di mana kuota disk ini diberlakukan?Jalankan kueri ini
Anda mengatakan itu
/var/lib/mysqltmp
Sekarang, jalankan ini di OS
Sesuatu memberi tahu saya bahwa ruang untuk
/var/lib/mysqltmp
kehabisan Setelah semua, Anda hanya memiliki 14G gratis. Di mata DDL (untuk membuat indeks), kemunduran terjadi, bukan pada file ibdata1, tetapi ditmpdir
lokasi. Jika/var/lib/mysqltmp
tidak dipasang di mana saja, maka data temp sedang ditulis di partisi root. Jika/var/lib/mysqltmp
dipasang di suatu tempat, maka mount itu sedang diisi dengan data baris. Dalam kedua kasus, tidak ada cukup ruang untuk menyelesaikan DDL.Anda memiliki dua opsi di sini
PILIHAN 1
Anda juga bisa membuat disk besar (mungkin dengan 100 + GB) dan pasang
/var/lib/mysqltmp
di disk besar itu.PILIHAN 2
Saran 3 langkah saya akan tetap berfungsi, bahkan dengan ruang disk terbatas yang Anda miliki
KOMENTAR
Sayang sekali pesan kesalahan yang Anda posting mengatakan
Ini berarti OS baik-baik saja. Itu juga tidak ada nomor kesalahan terkait untuk situasi ini.
Ada hal lain yang harus Anda ketahui. Dokumentasi MySQL mengatakan bahwa Pembuatan Indeks Cepat untuk InnoDB masih masuk ke disk :
UPDATE 2014-06-16 13:58 EDT
Pastikan
/mnt/cbsvolume1/var/lib/mysql
memiliki 100G atau lebih gratissumber