たとえば、ALTER TABLEステートメントを発行して、インデックスのサイズが255バイトで、フィールドのデータの平均サイズが30kである134k行のInnoDBテーブルのMEDIUMTEXTフィールドにインデックスを作成しました。このコマンドは過去15分ほど実行されています(データベースで実行されているのはこれだけです)。5分、5時間、または5日近くで終了するかどうかを判断する方法はありますか?
9 に答える
これら 2 つのクエリを実行して、移動する必要がある行がいくつ残っているかを把握できました。
select count(*) from `myoriginalrable`;
select count(*) from `#sql-1e8_11ae5`;
myisam から innodb などに変更すると行サイズが変わるため、これはディスク上のファイル サイズを比較するよりもはるかに役立ちました。
InnoDB テーブルの場合SHOW ENGINE INNODB STATUS
、ALTER TABLE を実行しているトランザクションを見つけ、TX が保持している行ロックの数を確認するために使用できます。これは、処理された行の数です。ここで詳しく説明しました:
http://gabrielcain.com/blog/2009/08/05/mysql-alter-table-and-how-to-observe-progress/
また、MariaDB 5.3 以降には、一部の操作 (ALTER TABLE を含む) の進行状況を報告する機能があります。見る:
これは明らかにかなり一般的なリクエストです-bugs.mysql.comで2005年までさかのぼってリクエストされました。これはすでにOracleに存在し、便利なものとしてリストされていますが、「これは簡単なことではないので、すぐに実装されるとは思わないでください」。。それは2005年でしたが:)
そうは言っても、元の質問をしたチャップは後でMySQL 5.0のパッチをリリースし、4.1にバックポートしました。これはあなたを助けるかもしれません。
innodb テーブルでの変更コマンドの完了時間を見積もるクエリを作成しました。連続実行の統計を比較して推定を行うため、同じセッションで少なくとも 2 回実行する必要があります。4 行目の<tableName>を正しいテーブル名に変更することを忘れないでください。それはあなたに2つの見積もりを与えます。ローカル推定では実行間のデータのみが使用されますが、グローバル推定ではトランザクション時間全体が使用されます。
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;
Perconaによるpt-online-schema-changeは、残り時間の見積もりを示しています。デフォルトでは、残り時間の見積もりと進捗率が30秒ごとに出力されます。
また、ALTERコマンドを単独で実行する場合と比較して、追加の機能もあります。
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
誰かが bash ソリューションを必要とする場合: (SQL が機能していませんでした)
cd /var/lib/mysql/mydb
TABLEFILE="MYTABLE.ibd"
TEMPFILE="\#*ibd"
ls -lah $TABLEFILE;
ls -lah $TEMPFILE; # make sure you have only one temp file or modify the above TEMPFILE
SIZE_TOTAL=$(stat -c %s $TABLEFILE);
# other ways to get 1st size and time
#SIZE1=1550781106; TIME1=1550781106;
#SIZE1=$(stat -c %s $TEMPFILE); TIME1=$(stat -c %Z $TEMPFILE); sleep 10;
SIZE1=0; TIME1=$(stat -c %X $TEMPFILE); # use file create time
echo "SIZE1=$TIME1; TIME1=$TIME1";
SIZE2=$(stat -c %s $TEMPFILE); TIME2=$(stat -c %Z $TEMPFILE);
DELTA_SIZE=$(( $SIZE2 - $SIZE1 ))
DELTA_TIME=$(( $TIME2 - $TIME1 ))
# debug last numbers should not be zero:
echo $SIZE1 $SIZE2 $SIZE_TOTAL $DELTA_SIZE;
echo $TIME1 $TIME2 $DELTA_TIME;
SIZE_PER_SECOND=$( awk "BEGIN {print $DELTA_SIZE / $DELTA_TIME }" );
SIZE_LEFT=$(($SIZE_TOTAL - $SIZE2));
TIME_LEFT_SECONDS=$( awk "BEGIN { print ( $SIZE_LEFT / $SIZE_PER_SECOND) }" );
TIME_LEFT_MINUTES=$( awk "BEGIN { print $TIME_LEFT_SECONDS /60 }" );
TIME_LEFT=$( awk "BEGIN { printf \"%d:%02d:%2d\", int($TIME_LEFT_MINUTES /60), int($TIME_LEFT_MINUTES % 60), int($TIME_LEFT_SECONDS % 60 ) }" );
echo "TIME_LEFT = $TIME_LEFT";
echo "SIZE_LEFT = $SIZE_LEFT" "MB=" $(( $SIZE_LEFT/1024/1024 )) ;
awk "BEGIN { if( $SIZE_TOTAL == $SIZE2 ) print \"mysql finished\" }" ;
free -h # check free memory, sometimes it is full and it makes it slow
結論: 時間がかかります。
RAMが空いていることを確認してください。そしてフリースペース。たとえば、メモリの 50% が mysql によって使用されていません。
低RAMはシステム全体の動作を非常に低くします
いくつかの拡張機能を備えた MySQL の分岐バージョンであるPercona Serverには、この機能があります。
ROWS_SENT および ROWS_EXAMINED の SHOW PROCESSLIST で余分な列を確認できます。たとえば、テーブルに 1000000 行があり、ROWS_EXAMINED が 650000 である場合、65% 完了しています。
http://www.percona.com/doc/percona-server/5.6/diagnostics/process_list.htmlを参照してください。