it-swarm.asia

Adakah jalan keluar yang lebih baik dari log MySQL InnoDB "di masa depan"?

Saya mendapatkan kesalahan InnoDB ini di MySQL 5.0. Mysqld dihentikan dengan bersih, tetapi saya berhasil kehilangan ib_logfile0 & ib_logfile1 sesudahnya. Sekarang setelah startup yang bersih, InnoDB telah melakukan "crash recovery". Saya telah melalui bisnis innodb_force_recovery = 4, memperbaiki tabel MyISAM yang digantung, dan sekarang replikasi siap digunakan, terlepas dari ini. Jumlah besar yang disetujui:

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.

Ini ada di server slave. Kesalahan di atas memuntahkan ratusan. Saya menemukan jawaban ini: "masukkan dan hapus data senilai> 64 GB, sehingga nomor urut log menjadi cukup besar".

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

Angka ajaib 64GB itu berasal dari 4GB * 16 di mana innodb orang itu mencatat "angka besar" yang diperlukan untuk meningkat dari 0 menjadi 15. Tambang ini bergerak dari 70 menjadi 111 = 164 GB. Ini akan memakan waktu 5 hari. Saya akan terus berupaya mempercepat skrip saya, dan menjalankannya secara paralel untuk mempercepat skrip ini. Sementara itu, saya berharap orang lain memiliki jawaban yang lebih baik. Ini konyol.

16
IcarusNM

Ini adalah situasi yang sangat langka. Saya berharap untuk tidak pernah berakhir di sana lagi, dengan InnoDB "nomor urut log di masa depan!" kesalahan. Karena detail khusus saya, membangun kembali/memulihkan data server saya adalah pilihan terakhir. Beberapa kecurangan dalam membantu itu adalah ide yang bagus, tetapi pada akhirnya, saya memutuskan untuk terus meningkatkan skrip Perl saya untuk memainkan permainan konyol ini dan melakukan sebanyak mungkin pertunjukan/jam. Apa-apaan, ini adalah tes stres sistem yang baik.

Ingat: tujuannya adalah untuk meningkatkan penghitung tunggal ("nomor urut log") yang disimpan di suatu tempat di header ib_logfile dan ib_logfile1. Ini untuk memalsukan InnoDB sehingga akan mengabaikan waktu yang jelas dan melanjutkan hidup. Tapi tidak ada yang tahu cara mengedit nomor itu. Atau jika mereka tahu, tidak ada yang berbicara.

Ini produk akhir saya. YMMV, tetapi menggunakan fungsi REPEAT mysql untuk menghasilkan data secara internal sangat efisien.

 #!/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");

Resep yang saya sarankan:

  1. Buat database 'sampah'
  2. Simpan skrip Perl di atas sebagai junk.pl.
  3. Jalankan junk.pl data1, dan junk.pl data2, dan junk.pl data, dll. Sekaligus, untuk sebanyak mungkin inti CPU sebagai server database Anda, untuk memulai. Buka beberapa shell dan bungkus setiap run dalam Bash loop: while true; do date; junk.pl dataX; done.

Lihat LSN Anda tumbuh, mungkin di loop lain:

 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

Angka besar adalah 32-bit INT yang tidak ditandatangani yang akan membungkus pada 4GB, meningkatkan jumlah yang lebih kecil setiap kali. Dalam kasus di atas, ia baru saja bergulir dari 124 menjadi 125. Tujuan Anda tersembunyi di mysqld.log yang mengirimi Anda Googling untuk solusi konyol ini sejak awal. Setelah Anda melewati garis finish, itu saja! Tiuplah klakson! Lepaskan confetti!

Bilah Samping: Ini menemukan bug yang menarik di mysqld 5.0 w/REPEAT: jika Anda pergi ke 20 MB, itu membalik beberapa penghitung internal dan berguling ke ~ 96 KB. Tidak ada peringatan atau kesalahan di mana pun. Saya tidak akan membuang waktu untuk melacaknya. 10 MB bekerja dengan sangat baik. Jika Anda mencapai batas lain, itu mungkin mengeluh. Saya memiliki berbagai innodb buffer meningkat dari standar. Bumbui secukupnya. Seperti biasa, tonton mysqld.log di satu jendela.

10
IcarusNM

Anda memiliki tiga (3) opsi:

OPSI 01: Lakukan rsync dari Master to Slave (Waktu Henti pada Master)

  • Langkah 01: Jalankan reset master; pada master (Zaps Binary Logs)
  • Langkah 02: service mysql stop pada master
  • Langkah 03: service mysql stop pada slave
  • Langkah 04: rsync/var/lib/mysql dari master ke slave
  • Langkah 05: service mysql start pada master
  • Langkah 06: Gunakan log biner pertama pada master sebagai log untuk memulai replikasi. Gunakan ukuran file dari log itu sebagai posisi untuk memulai replikasi
  • Langkah 07: service mysql stop --skip-slave-start pada slave
  • Langkah 08: Jalankan CHANGE MASTER TO perintah untuk mengatur replikasi dari log dan posisi dipastikan dari Langkah 06
  • Langkah 09: Jalankan start slave; pada slave dan biarkan replikasi menyusul

OPSI 02: Lakukan rsync Master to Slave (Downtime Minimal pada Master)

  • Langkah 01: Jalankan reset master; pada master (Zaps Binary Logs)
  • Langkah 02: service mysql stop pada slave
  • Langkah 03: rsync/var/lib/mysql dari master ke slave
  • Langkah 04: Ulangi Langkah 03 sampai dua rsyncs berturut-turut mengambil jumlah waktu yang sama
  • Langkah 05: service mysql stop pada master
  • Langkah 06: rsync/var/lib/mysql dari master ke slave
  • Langkah 07: service mysql start pada master
  • Langkah 08: Gunakan log biner pertama pada master sebagai log untuk memulai replikasi. Gunakan ukuran file dari log itu sebagai posisi untuk memulai replikasi
  • Langkah 09: service mysql stop --skip-slave-start pada slave
  • Langkah 10: Jalankan CHANGE MASTER TO perintah untuk mengatur replikasi dari log dan posisi dipastikan dari Langkah 08
  • Langkah 11: Jalankan start slave; pada slave dan biarkan replikasi menyusul

OPSI 03: Gunakan XtraBackup

Alat perangkat lunak ini tidak hanya akan membuat salinan master berjalan yang tidak mengganggu, tetapi juga akan membuat ib_logfiles yang sesuai untuk Anda. Anda harus mengatur replikasi

Saya telah memposting ke StackExchange sebelumnya tentang hal ini

Saya telah melakukan hal ini berkali-kali untuk perusahaan hosting web majikan saya. Satu klien memiliki 3,7TB untuk bergerak dan butuh sekitar 16 jam. 64GB sangat kecil dibandingkan.

5
RolandoMySQLDBA

Saya menemukan mungkin ada cara yang lebih keren untuk menyelesaikan masalah ini dengan bekerja pada tabel yang dipartisi. Saya perlu menghapus partisi dari beberapa tahun yang lalu, dan harus menambahkan beberapa untuk 2014. Hampir semua partisi melaporkan kesalahan ini, begitu juga yang lama. Kecelakaan yang sangat buruk.

Jadi sementara DROPPING lama dan menggunakan REORGANIZE dari partisi MAXVALUE (yang terakhir), itu akan membuat file baru yang ok, jadi saya mendapatkan semakin sedikit peringatan. Sementara itu, ini membantu menambah penghitung urutan log, jadi saya tidak perlu memasukkan data palsu. Saya memiliki ini terjadi pada server master btw ...

Jadi ini:

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;

Dan ini:

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)

Itu akan secara efektif menjatuhkan setiap partisi dalam perubahan dan membuatnya kembali dengan salinan temporer dari konten yang ada di sana. Anda dapat melakukan ini per tabel jika Anda mau, aplikasi saya memungkinkan hal itu terjadi, jadi tidak perlu khawatir tentang cadangan yang disinkronkan dll.

Sekarang untuk sisa tabel, karena saya belum menyentuh semua partisi dalam proses beberapa akan dibiarkan dengan peringatan urutan log, untuk orang-orang yang rusak tetapi dan ditutupi oleh tindakan reorganisasi ini saya mungkin akan menjalankan ini:

ALTER TABLE Events REBUILD PARTITION p0, p1;

atau itu

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

Jadi, itu membuat saya berpikir, Anda bisa melakukan ini dengan tabel Vanilla biasa, menambahkan sementara partisi dengan hash dan kemudian menghapusnya (atau menyimpannya, saya sangat merekomendasikan partisi).

Saya menggunakan mariadb, bukan mysql (jadi XtraDB)

Mungkin ini membantu seseorang. Saya masih menjalankannya, sejauh ini sangat bagus. Mengubah ENGINE sepertinya melakukan pekerjaan itu juga, jadi saya membawanya kembali/maju antara MyIsam dan mereka kembali ke InnoDB.

Ini cukup logis, jika Anda mengubah ENGINE, tabel menghilang dari innodb, jadi itu tidak akan menjadi masalah lagi.

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

sepertinya bekerja di sini. Saya dapat mengkonfirmasi beberapa hal di tabel yang dipartisi:

  • ALTER TABLE xyz ENGINE = InnoDB sangat lambat, untuk Aria (mariadb) dua kali lebih cepat, tetapi secara umum cara lambat untuk menambah penghitung urutan log
  • ALTER TABLE xyz REBUILD PARTITION ALL adalah cara tercepat untuk 'memperbaiki' tabel dan membantu menambah penghitung
  • ALTER TABEL xYZ ANALYZE PARTITION ALL lambat kompatibel dengan yang sebelumnya dan tidak menulis ulang partisi yang dianggap ok. REBUILD memastikan penulisan ulang ke skema tabel temp.

Saya menggunakan yang terakhir di beberapa tabel. Peringatan terjadi ketika mencoba membuka file dan ada satu untuk setiap definisi partisi yang dibuka dengan masalah counter. Hampir terguling meja hari ini untuk tabel terakhir. Saya pikir setelah semuanya diproses kita perlu membersihkan log biner.

pembaruan: Saya dapat menyimpulkan beberapa hal sekarang saya berhasil menyelesaikan masalah ini.

  • Kecelakaan saya disebabkan oleh reorganisasi partisi di atas meja dalam format Aria (MariaDB).
  • (untuk saya) melakukan pembangunan kembali partisi bekerja yang terbaik dan tercepat untuk mendapatkan urutan counter. Mengubah mesin lambat dan Anda harus melakukannya dua kali untuk mempengaruhi innodb. mengubah ke innoDB cukup lambat vs. ke MyIsam atau Aria.
  • Saya memutakhirkan ke MariaDB 5.3 dan tidak ke 5.5 (adalah: 5.2) dan berfungsi dengan baik. Saya pikir ada terlalu banyak masalah dengan aria, partisi di 5.5 (dan bug yang dikonfirmasi) untuk menggunakan kombinasi itu.
  • Harus ada cara yang lebih baik untuk mengatur ulang penghitung urutan log.
2
Glenn Plas