Lütfen hata mesajına aldanmayın The table 'my_table' is full
. Bu nadir senaryonun disk alanı ile hiçbir ilgisi yoktur. Bu tablonun tam koşulu InnoDB'nin iç tesisatıyla ilgilidir.
İlk olarak, InnoDB Mimarisinin bu şemasına bir göz atın
Sistem tablo alanında (ibdata dosyası) yalnızca 128 Geri Alma Segmenti ve Geri Alma Segmenti başına 1023 Geri Alma Yuvası bulunduğunu unutmayın. Bu, bir işlemin geri alma kapasitesinin boyutunu sınırlar. Başka bir deyişle, tek bir geri alma segmenti bir işlemi desteklemek için 1023'ten fazla yuvaya ihtiyaç duyarsa, işlem bu table is full
koşula çarpar.
New Jersey restoranı Red Lobster düşünün . 200 kişi kapasitelidir. Restoran doluysa, bir dizi insan beklemek için dışarı çıkabilir. Hatta insanlar sabırsızlanırsa, restoran dolu olduğu için ayrılabilirler. Açıkçası, çözüm New Jersey'i büyütmek (veya daha fazla disk alanı elde etmek) değildir. Çözüm Red Lobster restoranını büyütmek olacaktır. Bu şekilde oturma kapasitesini 240'a çıkarabilirsiniz. Bununla birlikte, 240'tan fazla insan Red Lobster'a gelmeye karar verirse dışarıda bir çizgi oluşabilir.
Sadece bir örnek vermek gerekirse, 2TB sistem tablo alanı olan bir istemci vardı ve innodb_file_per_table devre dışı bırakıldı. (İbdata1 için 346G, ibdata2 için sıfırlama). Bu sorguyu çalıştırdım
SELECT SUM(data_length+index+length) InnoDBDataIndexSpace
FROM information_schema.tables WHERE engine='InnoDB';
Daha sonra ibnota1 ve ibdata2 için dosya boyutlarının toplamından InnoDBDataIndexSpace öğesini çıkardım. Beni şok eden iki şeyim var
- Sistem tablo alanının içinde 106 GB kaldı.
- Bende aynı
Table is Full
durum var
Bu 106GB'ın InnoDB'nin iç tesisatında kullanıldığı anlamına geliyor. İstemci o zaman ext3 kullanıyordu.
Benim için çözüm ibdata3 eklemekti. Ben eski yazıma bu tartıştım "tablo ... dolu" "innodb_file_per_table" ile nasıl çözülür?
Bunu diğer yazılarda da tartıştım
İnnodb_file_per_table etkinleştirilmiş olsa bile bu durumun olabileceğini unutmayın. Nasıl? Geri dönüşler ve Geri Al Günlükleri, kontrolsüz ani kaynakların ibdata1 için büyümesidir .
GERÇEK SORU
Bir tabloya dizin ekleyip aldığınızdan Table is Full
, tablo çok büyük olmalı ve tek bir geri alma segmentine sığmayacaktır. Aşağıdakileri yapmanız gerekir:
ADIM 01
Verileri bir döküm dosyasına alın
mysqldump --no-create-info mydb mytable > table_data.sql
ADIM 02
MySQL'e giriş yapın ve bunu çalıştırın
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable_new ADD INDEX ... ;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
ADIM 03
Ek indeks içeren tabloyu verilerle yükleyin
mysql -Dmydb < table_data.sql
Bu kadar.
Sorun, ALTER TABLE'ın büyük tablonuzdaki tüm satırları tek bir işlem olarak enjekte etmeye çalışacağıdır. Mysqldump kullanarak, verileri tek bir işlemdeki tüm satırlara değil, aynı anda binlerce satıra (şimdi yeni bir dizinle) tabloya ekleyeceksiniz.
Endişelenme what if this doesn't work?
Orijinal tablo mytable_old
herhangi bir şey olması durumunda adlandırılacaktır . yedek olarak kullanılabilir. Yeni tablonun sizin için çalıştığını bildiğinizde yedeklemeyi bırakabilirsiniz.
Bir şans ver !!!
GÜNCELLEME 2014-06-16 11:13 EDT
Verilerin dökümünün daha büyük olması konusunda endişeleniyorsanız, sadece gzip edin.
Aynı adımları uygulayabilirsiniz, ancak aşağıdaki gibi
ADIM 01
Verileri bir döküm dosyasına alın
mysqldump --no-create-info mydb mytable | gzip > table_data.sql.gz
ADIM 02
MySQL'e giriş yapın ve bunu çalıştırın
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable_new ADD INDEX ... ;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
ADIM 03
Ek indeks içeren tabloyu verilerle yükleyin
gzip -d < table_data.sql.gz | mysql -Dmydb
veya
gunzip < table_data.sql.gz | mysql -Dmydb
GÜNCELLEME 2014-06-16 12:55 EDT
Ben sadece bu konuda başka bir yönü düşündüm.
DML yerine DDL yaptığınız için, bunun InnoDB iç tesisat olmaması mümkündür. Yana DDL InnoDB için geri alma edemez , konu harici tesisat olmak zorunda. Bu harici tesisat nerede tıkanıyor? İşletim sisteminin geçici klasöründen şüpheleniyorum. Neden?
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
Gördün disk quota exceeded
mü? Bu disk kotası nereye uygulanıyor?
Bu sorguyu çalıştır
SHOW GLOBAL VARIABLES LIKE 'tmpdir';
Dedin ki /var/lib/mysqltmp
Şimdi bunu işletim sisteminde çalıştırın
df -h /var/lib/mysqltmp
Bir şey bana alanın tükendiğini söylüyor /var/lib/mysqltmp
Sonuçta, sadece 14G boş alanınız var. DDL'nin gözünde (dizini oluşturmak için) ibdata1 dosyasında değil, tmpdir
konumda bir geri alma oldu . Eğer /var/lib/mysqltmp
herhangi bir yerde monte edilmediği, daha sonra geçici veri kök bölümü ile yazılmış ediliyor. Bir /var/lib/mysqltmp
yere monte edilirse , o montaj satır verileri ile doldurulmaktadır. Her iki durumda da DDL'yi tamamlamak için yeterli alan yoktur.
Burada iki seçeneğiniz var
SEÇENEK 1
Ayrıca büyük bir disk (belki 100 + GB ile) oluşturabilir ve /var/lib/mysqltmp
bu büyük diske takabilirsiniz .
SEÇENEK 2
3 adımlı önerilerim, sahip olduğunuz sınırlı disk alanında bile çalışmaya devam etmeli
YORUM
Gönderdiğiniz hata mesajının yazdığı bir utanç
InnoDB: Operating system error number 0.
InnoDB: Error number 0 means 'Success'.
Bu, işletim sisteminin iyi olduğu anlamına gelir. Ayrıca, bu durum için ilişkili bir hata numarası yoktur.
Bilmeniz gereken başka bir şey daha var. MySQL Belgeleri, InnoDB için Hızlı Dizin Oluşturmanın hala diske gittiğini söylüyor :
Dizin oluşturma sırasında dosyalar geçici dizine yazılır (Unix'te $ TMPDIR, Windows'ta% TEMP% veya --tmpdir yapılandırma değişkeninin değeri). Her geçici dosya, yeni dizini oluşturan bir sütunu tutacak kadar büyüktür ve her biri son dizine birleştirilir getirilmez kaldırılır.
MySQL sınırlaması nedeniyle, GEÇİCİ TABLO'da bir dizin oluşturduğunuzda tablo "Hızlı Dizin Oluşturma" kullanmak yerine kopyalanır. Bu MySQL Hata # 39833 olarak bildirildi .
GÜNCELLEME 2014-06-16 13:58 EDT
[mysqld]
datadir = /mnt/cbsvolume1/var/lib/mysql
tmpdir = /mnt/cbsvolume1/var/lib/mysql
/mnt/cbsvolume1/var/lib/mysql
100G veya daha fazla ücretsiz olduğundan emin olun