it-swarm.it

Qualche modo migliore per uscire dal log di MySQL InnoDB "in futuro"?

Ho questo errore InnoDB in MySQL 5.0. Mysqld è stato fermato in modo pulito, ma sono riuscito a perdere ib_logfile0 e ib_logfile1 in seguito. Ora dopo un avvio pulito, InnoDB ha eseguito il "ripristino di emergenza". Ho esaminato il business innodb_force_recovery = 4, riparato una tabella MyISAM sospesa e ora la replica è pronta, a parte questo. Grandi numeri commessi:

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.

Questo è su un server slave. L'errore sopra riportato sputa a centinaia. Ho trovato questa risposta: "inserisci ed elimina> 64 GB di dati, in modo che il numero di sequenza del registro si gonfia abbastanza grande".

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

Quel numero magico di 64 GB proviene da 4 GB * 16 dove il "numero maggiore" del registro innodb di quel ragazzo doveva aumentare da 0 a 15. Il mio va da 70 a 111 = 164 GB. Ci vorranno 5 giorni. Continuerò a lavorare per accelerare la mia sceneggiatura ed eseguirla in parallelo per accelerarla. Nel frattempo, spero che qualcun altro abbia una risposta migliore. Questo è sciocco.

16
IcarusNM

Questa era una situazione piuttosto rara. Spero di non finire mai più lì, con un InnoDB "il numero di sequenza del registro è nel futuro!" errore. A causa dei miei particolari dettagli, la ricostruzione/il ripristino dei dati del mio server è stata l'ultima risorsa. Alcuni trucchi per aiutare erano buone idee, ma alla fine, ho deciso di continuare a migliorare il mio script Perl per giocare a questo gioco sciocco e sfornare quanti più concerti/ora possibile. Che diamine, è un buon stress test del sistema.

Ricorda: l'obiettivo è aumentare un singolo contatore ("numero sequenza log") che è memorizzato da qualche parte nelle intestazioni di ib_logfile e ib_logfile1. Questo per falsificare InnoDB in modo da ignorare un apparente distorsione temporale e andare avanti con la vita. Ma nessuno sa come modificare quel numero. O se lo sanno, nessuno parla.

Ecco il mio prodotto finale. YMMV, ma l'utilizzo della funzione REPEAT di mysql per generare i dati internamente è altamente efficiente.

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

La mia ricetta suggerita:

  1. Crea un database "indesiderato"
  2. Salvare lo script Perl sopra come junk.pl.
  3. Esegui junk.pl data1 e junk.pl data2, e junk.pl data, ecc. Tutti in una volta, per altrettanti core della CPU come il tuo database server, per iniziare. Apri più shell e avvolgi ciascuna corsa in un loop Bash: while true; do date; junk.pl dataX; done.

Guarda crescere il tuo LSN, magari in un altro ciclo:

 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

Il numero più grande è un INT a 32 bit senza segno che andrà a finire a 4 GB, aumentando ogni volta il numero più piccolo. In questo caso sopra è appena passato da 124 a 125. Il tuo obiettivo è nascosto nel mysqld.log che ti ha inviato su Google per questa soluzione ridicola in primo luogo. Una volta superato il traguardo, il gioco è fatto! Blow the horns! Rilascia i coriandoli!

Barra laterale: questo ha scoperto un bug interessante in mysqld 5.0 con REPEAT: se vai a 20 MB, lancia un contatore interno e passa a ~ 96 KB. Nessun avviso o errore ovunque. Non avevo intenzione di perdere tempo a rintracciarlo. 10 MB funzionano alla grande. Se raggiungi un altro limite, potresti lamentarti. Ho diversi innodb buffer aumentati di default. Condire a piacere. Come sempre, guarda mysqld.log in una finestra.

10
IcarusNM

Hai tre (3) opzioni:

OPZIONE 01: Esegui rsincronizzazione da Master a Slave (Downtime sul Master)

  • Passaggio 01: Esegui reset master; sul master (registri binari Zaps)
  • Passaggio 02: service mysql stop sul master
  • Passaggio 03: service mysql stop sullo slave
  • Passaggio 04: rsync/var/lib/mysql dal master allo slave
  • Passaggio 05: service mysql start sul master
  • Passaggio 06: utilizzare il primo registro binario sul master come registro da cui iniziare la replica. Utilizzare la dimensione del file di quel registro come posizione da cui iniziare la replica
  • Passaggio 07: service mysql stop --skip-slave-start sullo slave
  • Passaggio 08: eseguire il comando MODIFICA MASTER TO per impostare la replica dal registro e dalla posizione accertati dal passaggio 06
  • Passaggio 09: Esegui start slave; sullo slave e consentire la replica

OPZIONE 02: Esegui rsincronizzazione da master a slave (downtime minimo sul master)

  • Passaggio 01: Esegui reset master; sul master (registri binari Zaps)
  • Passaggio 02: service mysql stop sullo slave
  • Passaggio 03: rsync/var/lib/mysql dal master allo slave
  • Passaggio 04: ripetere il passaggio 03 fino a quando due rsync consecutivi impiegano lo stesso tempo
  • Passaggio 05: service mysql stop sul master
  • Passaggio 06: rsync/var/lib/mysql dal master allo slave
  • Passaggio 07: service mysql start sul master
  • Passaggio 08: utilizzare il primo registro binario sul master come registro da cui iniziare la replica. Utilizzare la dimensione del file di quel registro come posizione da cui iniziare la replica
  • Passaggio 09: service mysql stop --skip-slave-start sullo slave
  • Passaggio 10: eseguire il comando MODIFICA MASTER TO per impostare la replica dal registro e dalla posizione accertati dal passaggio 08
  • Passaggio 11: Esegui start slave; sullo slave e consentire la replica

OPZIONE 03: Usa XtraBackup

Questo strumento software non solo farà una copia non invadente di un master in esecuzione, ma creerà anche i corrispondenti ib_logfiles per te. Dovresti impostare la replica

Ho pubblicato su StackExchange prima su questo argomento

Ho fatto queste cose molte volte per la società di web hosting del mio datore di lavoro. Un cliente aveva 3,7 TB da spostare e impiegava circa 16 ore. 64 GB è molto piccolo in confronto.

5
RolandoMySQLDBA

Ho scoperto che esiste forse un modo migliore per risolvere questo problema lavorando su tabelle partizionate. Avevo bisogno di eliminare le partizioni da alcuni anni e ne ho aggiunte alcune per il 2014. Quasi tutte le partizioni riportano questo errore, quindi anche quelle vecchie. Incidente molto brutto.

Quindi, mentre DROPPING vecchio e usando REORGANIZE della partizione MAXVALUE (l'ultima), creerà nuovi file che sono ok, quindi ricevo sempre meno avvisi. Nel frattempo, aiuta ad aumentare il contatore della sequenza di log, quindi non ho bisogno di inserire dati fasulli. Ho questo che succede su un server master tra ...

Così questo:

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;

E questo:

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)

Ciò eliminerà effettivamente ogni partizione nella modifica e la ricrea con una copia temporanea del contenuto di ciò che era presente. Puoi farlo per tabella se vuoi, la mia applicazione lo consente, quindi non devi preoccuparti di backup sincronizzati ecc.

Ora per il resto della tabella, dal momento che non ho toccato tutte le partizioni nel processo alcune verranno lasciate con l'avvertimento della sequenza di registro, per quelle che sono rotte ma e coperto da questa azione di riorganizzazione probabilmente eseguirò questo:

ALTER TABLE Events REBUILD PARTITION p0, p1;

o quello

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

Quindi, questo mi ha fatto pensare, potresti farlo con semplici tabelle Vanilla, aggiungere temporaneamente partizioni per hash e successivamente rimuoverlo (o tenerle, posso consigliare vivamente le partizioni).

Sto usando mariadb comunque, non mysql (quindi XtraDB)

Forse questo aiuta qualcuno. Lo sto ancora eseguendo, finora tutto bene. Anche cambiare ENGINE sembra fare il lavoro, quindi lo porto avanti/indietro tra MyIsam e loro in InnoDB.

È abbastanza logico, se cambi ENGINE, la tabella scompare da innodb, quindi non sarà più un problema.

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

sembra funzionare qui. Posso confermare alcune cose su tabelle partizionate:

  • ALTER TABLE xyz ENGINE = InnoDB è molto lento, ad Aria (mariadb) due volte più veloce, ma in generale un modo lento per incrementare il contatore della sequenza log
  • ALTER TABLE xyz REBUILD PARTITION ALL è il modo più veloce per 'riparare' le tabelle e aiutare ad aumentare il contatore
  • ALTER TABLE xyz ANALYZE PARTITION ALL è lentamente confrontato con il primo e non riscrive le partizioni che risultano essere a posto. REBUILD assicura una riscrittura in uno schema di tabella temporanea.

Ho usato gli ultimi su diversi tavoli. Gli avvisi si verificano quando si tenta di aprire i file e ce n'è uno per ogni definizione di partizione che si apre con problemi di contatore. Oggi ho quasi rotolato sul bancone per gli ultimi tavoli. Penso che una volta elaborato tutto sia necessario svuotare i registri binari.

aggiornamento: posso concludere alcune cose ora sono riuscito a risolvere questo problema.

  • Il mio crash è stato causato dalla riorganizzazione delle partizioni su un tavolo nel formato Aria (MariaDB).
  • (per me) fare una ricostruzione delle partizioni ha funzionato meglio e più velocemente per ottenere il contatore delle sequenze. Modificare il motore è lento e devi farlo due volte per influenzare innodb. la modifica a innoDB è piuttosto lenta rispetto a MyIsam o Aria.
  • Ho aggiornato a MariaDB 5.3 e non a 5.5 (era: 5.2) e funziona benissimo. Penso che ci siano troppi problemi con aria, le partizioni in 5.5 (e i bug confermati) per usare quella combinazione.
  • Dovrebbe esserci davvero un modo migliore per ripristinare il contatore della sequenza di registro.
2
Glenn Plas