MyISAM'den InnoDB'ye çevrimiçi dönüşümden sonra satırlar eksik


16

MyISAM'den InnoDB'ye dönüştürmek istediğimiz oldukça küçük bir veritabanımız var. Veritabanı noobs olmak, biz sadece siteyi aşağı almadan bile (alter tablo kullanarak) dönüştürdü.

Şimdi dönüşüm bittiğine göre, çok sayıda aralıklı satır eksik gibi görünüyor. Bu muhtemelen dönüşüm sırasındaki işlemlerden mi kaynaklanıyor? Yoksa sorun başka bir yerde mi?


Hangi tablolarda eksik satırlar var? Dönüştürdüğünüz tablolar veya diğer tablolar?
longneck

Yanıtlar:


20

Depolama motorlarını değiştirmek için ALTER yapmak satırların kaybolmasına neden olmaz. Ancak, sorunuzda 'veritabanı notları' olduğunuzu söylediğiniz için bazı önerilerde bulunmama izin verin.

Şema mevcut veya bir şey yapıyor değiştirirken olabilir verileri etkileyebilir, burada bazı temel tavsiye:

  1. Önce bir yedek alın.
  2. Bir değişiklik planınız olsun.
  3. Planınızı çevrimdışı bir ana bilgisayarda test edin.
  4. Verilerden önce ve sonra karşılaştırmak için bir test planınız olsun.
  5. Programlayın ve çalışmama zamanını alın.
  6. Kesinti süreniz yürürlüğe girdikten ve trafiğin durduğunu doğruladıktan hemen sonra bir yedek ve anlık görüntü alın.
  7. MYISAM çalıştırıyorsanız, ALTER'den önce neler yaptığınızı değerlendirmek için 'TABLO KONTROLÜ' seçeneğini kullanın.
  8. Her ihtimale karşı yedeklemenize ek olarak tabloyu yerel olarak kopyalayın.
  9. Dikkatli ilerleyin, değişikliklerinizi yaparken tam resme sahip olmak için "--show warments" ve diğer çıktıları etkinleştirin.
  10. Veriler sizin için önemliyse, yalnızca geçiş sırasında danışmak için bile olsa bir DBA kiralayın, böylece yanınızda deneyimli bir tecrübeniz vardır.

Muhtemelen girebileceğim çok daha fazla şey var, ancak yukarıda bir şeyler ters gittiğinde size seçenekler sunacak.

Kayıp verilerinize / satırlarınıza göre, karşılaştırılacak anlık görüntüden önce / sonra "w / oa" yı bilmenin bir yolu yoktur. En azından bu kadarını doğrulamak için en son yedeklemenizle karşılaştırabilirsiniz.


Bunu okudum. İyi DR planı. Cevabınız, ileriye dönük bir plana ek olarak soruya daha duyarlı olduğu için +1 alır.
RolandoMySQLDBA

1
@randy İyi cevabınız nedeniyle bunu favori soru olarak işaretledi
techExplorer

8

Çok fazla kesinti olmadan MyISAM'i InnoDB'ye dönüştürmenin en iyi yollarından biri yalnızca bir önkoşuldur: Bir Çoğaltma Slave Kullanın.

İşte planın kuşbakışı görünümü

  1. Çoğaltma Ana / Bağımlı Kurulumu Oluştur
  2. Slave'deki her MyISAM tablosunu InnoDB'ye dönüştürün
  3. Uygulamanızı Slave'e yönlendirin

Kulağa basit mi geliyor? Bunun arkasında çok fazla ayrıntı var.

Çoğaltma Ana / Bağımlı Kurulumu Oluştur

Üstat'ı çok rahatsız etmeyen bir Köle yaratmanın kaygan bir yolu var. İki yazı yazdım:

Rsync'in nasıl kullanılacağının ayrıntıları yerine, lütfen bu iki gönderiyi okuyun.

Slave'deki her MyISAM tablosunu InnoDB'ye dönüştürün

DB Slave'de aşağıdaki SQL Bildirimi'ni yapabilirsiniz:

MySQL 5.5 için:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

MySQL 5.5'ten önceki MySQL sürümü

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Sorgudan çıktıyı kullanarak, köle için bir dönüşüm komut dosyanız var.

Bu iki satırı komut dosyasının en üstüne koymalısınız:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Komut dosyası önce ikili günlüğü devre dışı bırakır (slave'i ikili günlüklere sahip olacak şekilde yapılandırdıysanız), çoğaltmayı durdurur ve her MyISAM tablosunu InnoDB'ye dönüştürür.

Bu komut dosyasını nasıl oluşturacağınız ve çalıştıracağınız aşağıda açıklanmıştır:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Uygulamanızı Slave'e yönlendirin

Slave'den SELECT sorguları gerçekleştirin. Slave'deki veri içeriğinden memnunsanız, uygulamanızı slave'e aşağıdaki gibi yönlendirmekten çekinmeyin:

  1. Köle üzerinde çalıştırın SHOW SLAVE STATUS\Gve Seconds_Behind_Master 0 olduğundan emin olun
  2. Slave'de, mysqldump -h (Slave IP) -u ... -p ... - tek işlem - yordamlar - tetikleyiciler --all-databases> MySQLBackup.sql (Hey, bir yedekleme iyi olur şimdi hakkında)
  3. Master'da çalıştırın service mysql stop(Kapalı kalma süresi başlar)
  4. Adım 1'i tekrarlayın
  5. Uygulamanızı Slave'e yönlendirin (Kapalı kalma süresi uygulamanın ilk bağlantısında sona erer)

Bu noktaya zarar vermediyseniz, TEBRİKLER !!!

EKLENDİ BONUS : Master / Slave yerine Master / Master Replication (Dairesel Replikasyon) olarak ayarlarsanız, bunun yerine bunu yapabilirsiniz:

  1. Köle üzerinde çalıştırın SHOW SLAVE STATUS\Gve Seconds_Behind_Master 0 olduğundan emin olun
  2. Slave'de, mysqldump -h (Slave IP) -u ... -p ... - tek işlem - yordamlar - tetikleyiciler --all-databases> MySQLBackup.sql (Hey, bir yedekleme iyi olur şimdi hakkında)
  3. Uygulamanızı Slave'e yönlendirin (Kapalı kalma süresi uygulamanın ilk bağlantısında başlar ve biter)
  4. Yeni Üstatta koş STOP SLAVE;
  5. Yeni Üstatta koş CHANGE MASTER TO MASTER_HOST='';

Şimdi sahip olduğunuz şey tersine Efendi / Köle. Yeni Master'ın InnoDB verileri vardır ve eski Master artık MyISAM verilerinin bir köleidir. Okumaları ve yazmaları ayırırsanız, okumalar Slave'den (okumalar MyISAM'den InnoDB'den daha hızlıdır) ve yazma işlemleri Master'a (InnoDB için işlemsel destek) gider. Hannah Montana gibi, her iki dünyanın da en iyisini elde edersiniz (Evet, şovu seven iki kızım var) !!!

BAŞKA BİR İLAVE BONUS : Master artık InnoDB olduğundan, Master'dan mysqldump'ı kesinti olmadan ve işlemlere müdahale etmeden yapabilirsiniz. Tek dezavantajı CPU ve disk I / O artırmaktır. Bu nedenle, yalnızca Master (InnoDB) üzerindeki tablo yapılarının bir mysqldump'ına ve yalnızca slave üzerindeki verilerin bir mysqldump'ına (Böyle bir dökümü InnoDB veya MyISAM'a referansları olmayacaktır. Sadece veri olacak) artı bir mysqldump köle için MyISAM düzeni tablo tablo yapıları.

Bu yeni kurulum nedeniyle olasılıklar devam edebilir ...

GÜNCELLEME 2011-08-27 19:50 EDT

Özür dilerim. Soruyu tam olarak okumadım. Dönüşümü zaten yaptınız .

Yalnızca ikili günlük kaydı açıksa ve daha önce bir yedeğiniz varsa,

  • / var / lib / mysql dosyasını / var / lib / mysql2 gibi başka bir konuma geri yükle
  • Çalıştırmak service mysql stop
  • Çalıştırmak service mysql start --datadir=/var/lib/mysql2
  • mysqldump bu yedek yerinden /root/olddata.sql için
  • / var / lib / mysql (/ var / lib / mysql2 değil) içindeki tüm ikili günlüklere karşı /root/changes.sql dosyasına yapılan son yedeklemeden bu yana mysqlbinlog komutunu çalıştırın
  • Değişiklikleri.sql dosyasını mysql'ye yükleyin (hala / var / lib / mysql2'yi işaret ettiği için)

Bu, kaydedilen her şeyi yakalamalı ve dönüşüm devreye girmelidir. Yine, tüm bunlar, son yedeklemeden önce ikili günlük kaydını açmış olduğunuz için bitişiktir . Aksi takdirde başsağlığı diliyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.