“Gelecekte” MySQL InnoDB günlüğünden çıkmanın daha iyi bir yolu var mı?


16

MySQL 5.0 bu InnoDB hatası var. Mysqld temiz bir şekilde durduruldu, ancak daha sonra ib_logfile0 & ib_logfile1 kaybetmeyi başardım. Şimdi temiz bir başlangıçtan sonra, InnoDB "çökme kurtarma" yaptı. İnnodb_force_recovery = 4 işinden geçtim, asılı bir MyISAM tablosunu tamir ettim ve şimdi çoğaltma buna hazır. Büyük sayılar duyuruldu:

111116 15:49:36  InnoDB: Error: page 393457 log sequence number 111 561,760,232
InnoDB: is in the future! Current system log sequence number 70 3,946,969,851.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html
InnoDB: for more information.

Bu bir bağımlı sunucuda. Yukarıdaki hata yüzlerce artmaktadır. Bu cevabı buldum: "64 GB değerinde veri ekle ve sil, böylece günlük sıra numarası yeterince şişirilecek".

http://forums.mysql.com/read.php?22,50163,50163#msg-50163

Bu 64GB'lik sihirli sayı 4GB * 16'dan geliyor, burada o adamın innodb günlüğü "büyük sayı" 0'dan 15'e çıkarılması gerekiyordu. Bu 5 gün sürecek. Senaryomumu hızlandırmak ve bunu hızlandırmak için paralel olarak çalıştırmak için çalışmaya devam edeceğim. Bu arada, başka birinin daha iyi bir cevabı olduğunu umuyorum. Bu aptalca.


Umut verici bir cevap: "Eğer bir bağımlı sunucu ise, en iyi çözüm gerçekten veritabanını bir kenara taşımak ve master'dan yeni bir anlık görüntü yüklemek olacaktır." Ne yazık ki 25 veritabanında 20.000 tablo var, MyISAM ve InnoDB'nin bir karışımı, 24x7 üretimde. Çoğaltmayı yeniden başlatmadan önce tüm bunları kapatmak ve yeni bir tam çoğaltma yapmak çok uzun sürecektir.
IcarusNM

4
Şimdi bu 8 çekirdekli makinenin dizlerinde, 164 gig veri oluşturmak ve silmek için anlamsız bir yarış var. Duyduğum tek alternatif, bu köle üzerindeki her şeyi nuke ve sıfırdan başlamak. Hepsi etkili bir şekilde iki dosyada bir sayıyı değiştirmek için. Elbette profesyonel bir ipucu ile bazı InnoDB mühendisi var. Herkes Emacs'ta ib_logfile0'ı açtı, sihirli sayıyı onaltılı olarak buldu ve değiştirdi mi?
IcarusNM

İşte bunu yapmanın birkaç yolu hakkında harika bir makale. Percona kesinlikle MySQL'in otoritesidir. percona.com/blog/2013/09/11/…
jbrahy

Yanıtlar:


10

Bu oldukça nadir bir durumdu. Umarım bir daha asla bitmez, InnoDB ile "log sıra numarası gelecekte!" hata. Özel bilgilerim nedeniyle, sunucumun verilerini yeniden oluşturmak / geri yüklemek son çare oldu. Yardım etmek için bazı hileler iyi fikirlerdi, ama sonunda Perl betiğimi bu aptalca oyunu oynamak ve geliştirebildiğim kadar çok saat / saat çalmak için geliştirmeye karar verdim. Ne halt, iyi bir sistem stres testi.

Unutmayın: hedef ib_logfile0 ve ib_logfile1 başlıklarında bir yerde saklanan tek bir sayacı ("log sıra numarası") artırmaktır . Bu InnoDB'yi sahte yapmaktır, böylece görünür bir zaman sıçramasını görmezden gelir ve hayata devam eder. Ancak kimse bu numarayı nasıl düzenleyeceğini bilmiyor. Ya da biliyorlarsa, kimse konuşmuyor.

İşte son ürünüm. YMMV, ancak dahili olarak veri oluşturmak için mysql'in REPEAT işlevini kullanmak oldukça verimlidir.

 #!/usr/bin/perl
 use DBI;
 $table = shift || die;
 $dbh = DBI->connect("DBI:mysql:junk:host=localhost", "user", "pass"); #Edit "junk" (DB name), user, and pass to suit.
 $dbh->do("DROP TABLE IF EXISTS $table");
 $dbh->do("CREATE TABLE $table (str TEXT) ENGINE=INNODB");
 $sth = $dbh->prepare("INSERT INTO $table (str) VALUES (REPEAT(?,1000000))");
 foreach (1..50) {
    $sth->execute('0123456789');   # 10 MB
 }
 $dbh->do("DELETE FROM $table");

Önerilen tarifim:

  1. 'Önemsiz' veritabanı oluşturma
  2. Yukarıdaki perl betiğini junk.pl olarak kaydedin .
  3. Junk.pl data1 ve junk.pl data2'yi çalıştırın ve junk.pl data3 vb kerede tüm, veritabanı sunucusu olarak birçok CPU çekirdeği olduğu gibi, başlamak için. Açık birden kabukları bir Bash döngü içinde her koşmak sarın ve: while true; do date; junk.pl dataX; done.

LSN'nizin büyümesini, belki de başka bir döngüde izleyin:

 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 3871092821
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 4209892586
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 125 85212387

Büyük sayı, her seferinde daha küçük sayıyı artırarak 4GB'de sarılacak imzasız bir 32 bit INT'dir. Bu durumda yukarıdaki 124'ten 125'e yuvarlandı. Hedefiniz bu saçma çözüm için Googling'i ilk etapta size gönderen mysqld.log'da . O bitiş çizgisini geçtikten sonra, hepsi bu! Boynuzları üfle! Konfeti serbest bırakın!

Kenar çubuğu: Bu, REPEAT ile mysqld 5.0'da ilginç bir hatayı ortaya çıkardı: 20 MB'ye giderseniz, bazı dahili sayacı çevirir ve ~ 96 KB'a kadar döner. Hiçbir yerde uyarı veya hata yok. Bunu takip etmek için zaman kaybetmek üzereydim. 10 MB harika çalışıyor. Başka bir sınıra ulaşırsanız, şikayet edebilir. Ben varsayılan artan çeşitli innodb arabellekleri var . Tatmak için mevsim. Her zaman olduğu gibi, mysqld.log dosyasını tek bir pencerede izleyin.



Teşekkürler Jonas; ilginç. Yukarıdaki yöntemime bağlı kalacağımı düşünüyorum. Muhtemelen asla risk olmaz çalışan mysqld karşı gdb kullanarak gösterir. Ama orada da iyi bilgi.
IcarusNM

Tuhaf bir nedenden dolayı, MariaDB'yi kullanarak, 'küçük sayı [boşluk] büyük sayı' günlük sıra numaralarını almıyorum - ama sadece bir 'büyük sayı', bu yüzden ne yazık ki bu yöntem benim için işe yaramadı. Tabii ki, günlük güncellenir, ne zaman duracağımı bilmiyorum!
Gwyneth Llewelyn

5

Üç (3) seçeneğiniz vardır:

SEÇENEK 01: Master to Slave rsync (Master üzerinde kesinti)

  • Adım 01: Çalıştır reset master; Master üzerinde (Zaps Binary Logs)
  • Adım 02: service mysql stopMaster'da
  • Adım 03: service mysql stopKöle
  • Adım 04: Master'dan köle rsync / var / lib / mysql
  • Adım 05: service mysql startMaster'da
  • Adım 06: Çoğaltmayı başlatmak için master olarak ilk ikili günlüğü kullanın. Çoğaltmayı başlatmak için bu günlüğün dosya boyutunu konum olarak kullanın
  • Adım 07: service mysql stop --skip-slave-startKöle
  • Adım 08: Günlüğe çoğaltma ve Adım 06'dan belirlenen konumdan çoğaltmayı ayarlamak için DEĞİŞTİR MASTER TO komutunu çalıştırın
  • Adım 09: start slave;Köle üzerinde çalıştırın ve çoğaltmanın yetişmesine izin verin

SEÇENEK 02: Master to Slave rsync gerçekleştirin (Master'da Minimum Kesinti Süresi)

  • Adım 01:reset master; Master üzerinde koş (Zaps Binary Logs)
  • Adım 02: service mysql stopKöle
  • Adım 03: Master'dan köle rsync / var / lib / mysql
  • Adım 04: İki ardışık rsync aynı miktarda zaman alana kadar Adım 03'ü tekrarlayın.
  • Adım 05: service mysql stopMaster'da
  • Adım 06: Master'dan köle rsync / var / lib / mysql
  • Adım 07: service mysql startMaster'da
  • Adım 08: Çoğaltmayı başlatmak için master olarak ilk ikili günlüğü kullanın. Çoğaltmayı başlatmak için bu günlüğün dosya boyutunu konum olarak kullanın
  • Adım 09: service mysql stop --skip-slave-startKöle
  • Adım 10: Günlüğü ve Adım 08'den belirlenen konumu çoğaltmayı ayarlamak için DEĞİŞTİR MASTER TO komutunu çalıştırın
  • Adım 11: start slave;Köle üzerinde çalıştırın ve çoğaltmanın yakalanmasına izin verin

SEÇENEK 03: XtraBackup kullanın

Bu yazılım aracı yalnızca çalışan bir master'ın rahatsız edici olmayan bir kopyasını oluşturmakla kalmaz, aynı zamanda sizin için ilgili ib_log dosyalarını da oluşturur. Çoğaltmayı ayarlamanız gerekir

Bu konuda daha önce StackExchange gönderdim

Bu işleri işverenimin web hosting şirketi için defalarca yaptım. Bir müşterinin taşınması 3.7 TB oldu ve yaklaşık 16 saat sürdü. 64GB karşılaştırıldığında çok küçük.


SEÇENEK 02 Adım 05 de master başlatmak için söyleyin. Ne zaman durduruldu? Rsync canlı bir efendide cesur. Etkilendim. Ve neyse ki innodb_file_per_table kullanıyorum. Ama sonunda mermi ısırmalı ve çoğaltmaya başlamadan önce bir son rsync'in çalışması için ustayı yeterince durdurmalısınız. Bu başvurmak için bir olasılık, ama bu çok aktif bir DBMS. Ve bilgilerim için XtraBackup'a bakacağım.
IcarusNM

@IcarusNM: Ah, yazım hatası. Ben düzelttim. Teşekkür ederim !!!
RolandoMySQLDBA

SEÇENEK 02 muhtemelen bazı işleri kullanabilir. Örneğin, 1. adımdan önce 2. adımı uygulamanız gerekir. Muhtemelen orada bir yerlerde bir RESET SLAVE istersiniz. 4. adımda yazım hatası yapın ve 5. adımda "ilk ikili günlük" deyin, ancak gerçekten "yalnızca" veya "son" ikili günlük anlamına gelir. Ve dosya boyutunu değil günlük konumlarını belirlemek için mysqlbinlog kullanmalısınız. Ve eğer ustayı bir noktada durdurmazsanız, tüm bunlar hala işe yaramaz. Bir rsync tamamlandığında en iyi riskli bir günlük konumunu / zamanını temel alma.
IcarusNM

TeraByte ürün yelpazesinde veri bulunan DB Hosting istemcileriyle birlikte son 4 yıldır SEÇENEK 2 yapıyorum. Çalışan bir sunucuya karşı her zaman çalışır. Yapabileceğiniz tek gerçek hata köledir. Bu hata, çoğaltmanın düzgün bir şekilde ayarlanıp ayarlanmadığıdır. Ayrıca, RESET SLAVEözellikle birçok GB röle günlüğü biriktirdiyseniz yararlıdır. Rsync işlemi ve çoğaltma yeniden kurulduktan sonra, lütfen DEĞİŞTİR MASTER TO komutunun da sizin için röle günlüklerini sileceğini unutmayın.
RolandoMySQLDBA

aaa ... garip. i (her zaman olduğu gibi) xtrabackup kullanarak kölem kurmak ve hala bu günlük hataları var (percona mysql 5.5.x) ... Bu köle yanlış bir şey gitti görünüyor ve tekrar yapmak zorunda görünüyor.
12'de harald

2

Bölümlenmiş tablolarda çalışan bu sorunu çözmek için belki de daha havalı bir yol olduğunu öğrendim. Birkaç yıl önce bölümleri bırakmam gerekiyordu ve 2014 için bazı bölümler eklemek zorunda kaldım. Hemen hemen tüm bölümler bu hatayı, yani eski bölümleri bildiriyor. Çok kötü bir kaza.

Bu yüzden eski DROPPING ve MAXVALUE bölümünün REORGANIZE (sonuncusu) kullanarak, tamam yeni dosyalar oluşturur, bu yüzden daha az uyarı alırım. Bu arada, günlük dizisi sayacını artırmaya yardımcı olur, bu yüzden sahte veri eklemek gerekmez. Bu bir ana sunucu btw üzerinde oluyor ...

Yani bu:

ALTER TABLE Events DROP PARTITION p1530 , p1535 , p1540 , p1545 , 
p1550, p1555 , p1560 , p1565 , p1570 , p1575 , p1580 , p1585 , p1590 , 
p1595 , p1600 , p1605 , p1610 , p1615 , p1620 , p1625 , p1630 , p1635 , 
p1640 , p1645 , p1650 , p1655 , p1660 , p1665 , p1670 , p1675 , p1680 , 
p1685 , p1690 , p1695 , p1700 , p1705 , p1710 , p1715 , p1720 , p1725 , 
p1730 , p1735 , p1740 , p1745 , p1750 , p1755 , p1760 , p1765 , p1770 , 
p1775 , p1780 , p1785 , p1790 , p1795 , p1800 , p1805 , p1810 , p1815 , 
p1820 , p1825 , p1830 , p1835 , p1840;

Ve bu:

ALTER table Events REORGANIZE PARTITION p3000 INTO (
PARTITION p3500 VALUES LESS THAN (TO_DAYS('2013-01-01')),
PARTITION p3510 VALUES LESS THAN (TO_DAYS('2013-01-04')),
PARTITION p3520 VALUES LESS THAN (TO_DAYS('2013-01-07')),
PARTITION p3530 VALUES LESS THAN (TO_DAYS('2013-01-10'))
...
PARTITION p4740 VALUES LESS THAN (TO_DAYS('2014-01-08')),
PARTITION p9000 VALUES LESS THAN MAXVALUE)

Bu, her bölümü etkili bir şekilde değişime düşürecek ve orada bulunan içeriğin geçici bir kopyasıyla yeniden oluşturacaktır. İsterseniz bunu tablo başına yapabilirsiniz, uygulamam bunun olmasına izin verir, bu nedenle senkronize edilmiş yedeklemeler vb. İçin endişelenmenize gerek yoktur.

Şimdi tablonun geri kalanı için, süreçteki tüm bölümlere dokunmadığım için, bazıları günlük sekans uyarısı ile bırakılacak, kırık olan ve bu yeniden yapılanma eylemi kapsamında olanlar için muhtemelen bunu çalıştıracağım:

ALTER TABLE Events REBUILD PARTITION p0, p1;

yada bu

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

Yani, bu beni düşündürdü, Bunu düz vanilya masaları ile yapabilirsin, geçici olarak bölümleri ekle ve sonra kaldır (ya da onları sakla, bölümleri şiddetle tavsiye edebilirim).

Ben mariadb kullanıyorum, ancak mysql (yani XtraDB)

Belki de bu birisine yardım eder. Hala çalıştırıyorum, şimdiye kadar çok iyi. MOTOR'u değiştirmek de bu işi yapıyor gibi görünüyor, bu yüzden MyIsam ve onlar arasında InnoDB'ye geri / ileri getiriyorum.

MOTORU değiştirirseniz, tablo innodb'dan kaybolur, bu yüzden artık bir sorun olmayacaktır.

ALTER TABLE Events ENGINE=MyISAM;
ALTER TABLE Events ENGINE=InnoDB;

burada çalışıyor gibi görünüyor. Bölümlenmiş tablolarda birkaç şeyi onaylayabilirim:

  • ALTER TABLE xyz ENGINE = InnoDB çok yavaş, Aria'ya (mariadb) iki kat daha hızlı, ancak genel olarak log sekansı sayacını arttırmanın yavaş bir yolu
  • ALTER TABLE xyz REBUILD PARTITION ALL, tabloları 'düzeltmenin' ve sayacın artırılmasına yardımcı olmanın en hızlı yoludur
  • ALTER TABLE xyz ANALYZE PARTITION ALL, öncekiyle yavaş karşılaştırılır ve tamam olup olmadığını kontrol eden bölümleri yeniden yazmaz. REBUILD, geçici tablo şemasının yeniden yazılmasını sağlar.

Sonuncuyu birkaç masada kullandım. Uyarılar dosyaları açmaya çalışırken oluşur ve sayaç sorunları ile açtığı her bölüm tanımı için bir tane vardır. Son tablolar için neredeyse bugün tezgahın üzerine yuvarlandı. Sanırım hepsi işlendikten sonra ikili günlükleri yıkamak gerekiyor.

Güncelleme : Bu sorunu çözmeyi başarabildiğim birkaç şeyi sonuçlandırabilirim.

  • Çökmem Aria biçimindeki (MariaDB) bir tabloda bölümleri yeniden organize etmekten kaynaklandı.
  • (benim için) bölümleri yeniden oluşturmak dizi sayacı almak için en iyi ve en hızlı çalıştı. Motorun değiştirilmesi yavaştır ve innodb'u etkilemek için iki kez yapmanız gerekir. innoDB'yi değiştirmek MyIsam veya Aria'ya göre oldukça yavaştır.
  • MariaDB 5.3 ve 5.5 için yükseltildi (oldu: 5.2) ve iyi çalışıyor. Ben arria, 5.5 ile bölümleri (ve teyit böcek) bu kombinasyonu kullanmak için çok fazla sorun olduğunu düşünüyorum.
  • Günlük dizisi sayacını sıfırlamanın daha iyi bir yolu olmalı.

MariaDB altında, tüm tabloları USE INFORMATION_SCHEMA; SELECT CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` REBUILD PARTITION ALL;") AS MySQLCMD AS MySQLCMD FROM TABLES;(source: dba.stackexchange.com/questions/35073/… ) kullanarak hızlı bir şekilde değiştirebilir ve bir dizi komut olarak yürütülecek bir dosyaya sürükleyebilirsiniz .
Gwyneth Llewelyn
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.