tabla - modificar un campo en mysql
¿Hay alguna forma de ver el progreso de una instrucción ALTER TABLE en MySQL? (6)
Aparentemente, esta es una solicitud bastante común, solicitada ya en 2005 en bugs.mysql.com . Ya existe en Oracle y aparece como útil, pero "no es algo sencillo de hacer, así que no espere que se implemente pronto". . Aunque eso fue 2005 :)
Dicho esto, el tipo que hizo la pregunta original más tarde publicó un parche para MySQL 5.0, con backport a 4.1, que podría ayudarlo.
Por ejemplo, emití una instrucción ALTER TABLE para crear un índice en un campo MEDIUMTEXT en una tabla InnoDB que tiene 134 filas donde el tamaño del índice era 255 bytes y el tamaño promedio de los datos en el campo es 30k. Este comando se ha estado ejecutando durante los últimos 15 minutos aproximadamente (y es lo único que se ejecuta en la base de datos). ¿Hay alguna manera de determinar si va a terminar en 5 minutos, 5 horas o 5 días más o menos?
Pude realizar estas 2 consultas y averiguar cuántas filas quedan por mover.
select count(*) from `myoriginalrable`;
select count(*) from `#sql-1e8_11ae5`;
esto fue MUY más útil que la comparación del tamaño del archivo en el disco, porque cambiar de myisam a innodb, etc. cambia el tamaño de la fila.
pt-online-schema-change de Percona muestra el tiempo estimado restante. Por defecto, imprime la estimación de tiempo restante y el porcentaje de progreso cada 30 segundos.
También tiene funciones adicionales en comparación con solo ejecutar el comando ALTER por sí mismo.
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
En el caso de las tablas InnoDB, se puede usar SHOW ENGINE INNODB STATUS
para encontrar la transacción haciendo ALTER TABLE y verificar cuántas cerraduras de fila tiene el TX. Este es el número de filas procesadas. Explicado en detalle aquí:
http://gabrielcain.com/blog/2009/08/05/mysql-alter-table-and-how-to-observe-progress/
También MariaDB 5.3 y posteriores tienen la función de informar el progreso de algunas operaciones (incluida ALTER TABLE). Ver:
Percona Server , que es una versión ramificada de MySQL con algunas mejoras, tiene esta característica.
Puede observar columnas adicionales en SHOW PROCESSLIST para ROWS_SENT y ROWS_EXAMINED. Por ejemplo, si su tabla tiene 1000000 filas, y ve ROWS_EXAMINED de 650000, entonces está terminado al 65%.
Ver http://www.percona.com/doc/percona-server/5.6/diagnostics/process_list.html
Hice una consulta que estima el tiempo para terminar un comando alter en una tabla innodb. Debes ejecutarlo al menos dos veces en la misma sesión, ya que compara las estadísticas de las ejecuciones consecutivas para realizar la estimación. No olvides cambiar <tableName> por el nombre de la tabla correcta en la cuarta línea. Te da dos estimaciones. La estimación local usa solo datos entre ejecuciones, mientras que la estimación global usa todo el tiempo de transacción.
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)+@rows),
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:=@rows,
@p_modified:=@modified,
@p_beginsd:=@beginsd
) sq;