Ad esempio, ho emesso un'istruzione ALTER TABLE per creare un indice su un campo MEDIUMTEXT in una tabella InnoDB con 134k righe in cui la dimensione dell'indice era 255 byte e la dimensione media dei dati nel campo è 30k. Questo comando è in esecuzione da 15 minuti circa (ed è l'unica cosa in esecuzione sul database). C'è un modo per me per determinare se sta per finire in più vicino a 5 minuti, 5 ore o 5 giorni?C'è un modo per vedere l'avanzamento di un'istruzione ALTER TABLE in MySQL?
risposta
Questa è una richiesta piuttosto comune apparentemente - richiesta già nel 2005 su bugs.mysql.com. Esiste già in Oracle ed è elencato come utile, ma "it is not a simple thing to do, so don't expect it to be implemented soon.". Anche se era il 2005 :)
Detto questo, il tizio che ha posto la domanda originale ha rilasciato successivamente un patch per MySQL 5.0, backported a 4.1, che potrebbe aiutarti.
Sono stato in grado di eseguire queste 2 query e capire quante righe restano da spostare.
select count(*) from `myoriginalrable`;
select count(*) from `#sql-1e8_11ae5`;
questo era il modo più utile di confronto tra la dimensione del file sul disco, perché si passa da MyISAM a InnoDB ecc cambia la dimensione di riga.
Nel caso di tabelle InnoDB, è possibile utilizzare SHOW ENGINE INNODB STATUS
per trovare la transazione eseguendo ALTER TABLE e controllare il numero di blocchi di riga in possesso della TX. Questo è il numero di righe elaborate. Ha spiegato in dettaglio qui:
http://gabrielcain.com/blog/2009/08/05/mysql-alter-table-and-how-to-observe-progress/
MariaDB 5.3 e poi ha anche la funzione di segnalare i progressi per alcune operazioni (tra cui ALTER TABLE). Vedere:
pt-online-schema-cambiamento Percona mostra restante stima tempo. Di default stampa la stima del tempo rimanente e la percentuale di avanzamento ogni 30 secondi.
Ha anche funzioni aggiuntive rispetto al solo esecuzione del comando ALTER da solo.
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
Ho fatto una query che stima il tempo di finire un comando ALTER su una tabella InnoDB. Devi eseguirlo almeno due volte nella stessa sessione poiché confronta le statistiche delle esecuzioni consecutive per effettuare la stima. Non dimenticare di cambiare <tableName> al nome tabella corretto sulla quarta riga. Ti dà due stime. La stima locale utilizza solo i dati tra le esecuzioni mentre la stima globale utilizza l'intero tempo di transazione.
select
beginsd now, qRuns, qTime, tName, trxStarted, trxTime, rows, modified, locked, hoursLeftL, estimatedEndL, modifiedPerSecL, avgRows, estimatedEndG, modifiedPerSecG, hoursLeftG
from (
select
(@tname:='<table>') tName,
@beginsd:=sysdate() beginsd,
@trxStarted:=(select trx_started from information_schema.innodb_trx where trx_query like concat('alter table %', @tname, '%')) trxStarted,
@trxTime:=timediff(@beginsd, @trxStarted) trxTime,
@rows:=(select table_rows from information_schema.tables where table_name like @tname) rows,
@runs:=(ifnull(@runs, 0)+1) qRuns,
@rowsSum:=(ifnull(@rowsSum, 0)[email protected]),
round(@avgRows:=(@rowsSum/@runs)) avgRows,
@modified:=(select trx_rows_modified from information_schema.innodb_trx where trx_query like concat('alter table %', @tname, '%')) modified,
@rowsLeftL:=(cast(@rows as signed) - cast(@modified as signed)) rowsLeftL,
round(@rowsLeftG:=(cast(@avgRows as signed) - cast(@modified as signed)), 2) rowsLeftG,
@locked:=(select trx_rows_locked from information_schema.innodb_trx where trx_query like concat('alter table %', @tname, '%')) locked,
@endsd:=sysdate() endsd,
--
time_to_sec(timediff(@endsd, @beginsd)) qTime,
@modifiedInc:=(cast(@modified as signed) - cast(@p_modified as signed)) modifiedInc,
@timeInc:=time_to_sec(timediff(@beginsd, @p_beginsd)) timeInc,
round(@modifiedPerSecL:=(@modifiedInc/@timeInc)) modifiedPerSecL,
round(@modifiedPerSecG:=(@modified/time_to_sec(@trxTime))) modifiedPerSecG,
round(@minutesLeftL := (@rowsLeftL/@modifiedPerSecL/60)) minutesLeftL,
round(@minutesLeftG := (@rowsLeftG/@modifiedPerSecG/60)) minutesLeftG,
round(@hoursLeftL := (@minutesLeftL/60), 2) hoursLeftL,
round(@hoursLeftG := (@minutesLeftG/60), 2) hoursLeftG,
(@beginsd + INTERVAL @minutesLeftL MINUTE) estimatedEndL,
(@beginsd + INTERVAL @minutesLeftG MINUTE) estimatedEndG,
--
@p_rows:[email protected],
@p_modified:[email protected],
@p_beginsd:[email protected]
) sq;
Percona Server, che è una versione derivata di MySQL con alcuni miglioramenti, ha questa caratteristica.
È possibile osservare colonne aggiuntive in SHOW PROCESSLIST per ROWS_SENT e ROWS_EXAMINED. Ad esempio, se la tua tabella ha 1000000 righe e vedi ROWS_EXAMINED di 650000, significa che è finito al 65%.
Vedi http://www.percona.com/doc/percona-server/5.6/diagnostics/process_list.html
Come hai ottenuto il nome della tabella temporanea che il comando alter crea? – fixxxer
Il nome della tabella temporanea si trova nel file system con il resto delle tabelle. – carillonator
la migliore risposta di tutti loro, grazie! – Enerccio