YII2を使用して大規模なリモートデータベースのバックアップコピーを作成する

最近、私は1つの小さくて興味深い順序を実現する機会がありました。その本質は、リモートデータベースサーバーからボタンを押してデータベース(おおよそのサイズは約800Mb)をテストサーバーにコピーし、テーブル構造にいくつかの変更を加えることでした。







簡単なことは何もないように思われます。リモートサーバーでフォームのリクエストを実行します。







mysqldump -uLogin -pPassword db_name > db_name.sql
      
      





その後、ファイルを取得しますが、私の場合はそこからファイルをダウンロードできないデータベースサーバーであることが判明したので、YII2を使用してこのリモートデータベースからエクスポートメカニズムを考案して作成する必要がありましたが、当時はあまりよくありませんでした。







まず、 views / db / index.phpファイルに記述され、図1に示す単純なインターフェースを実装しました。







図1.-外観

図1.-外観







便宜上、すべてのアクションは3つの部分に分けられました。







  1. DBエクスポート;
  2. インポートDB;
  3. 変更を適用する
  4. バックアップファイルを削除します。


右側には、操作の進行状況に関する情報を表示するためのブロックがあります。







次に、 web / js / common.jsファイルのjQueryスクリプトについて説明しました







マスターデータをコンソールに詳細に記録する必要性を判断するために、定数DEBUG = falseがグローバルに定義されました。







変数dbExportAll、dbImportAllもグローバルに定義されているため、インポートおよびエクスポートプロセスの完了を正確に判断できます。







便宜上、定数URL_TABLES、URL_EXPORT、URL_IMPORT、URL_REMOVE、URL_MIGRATEが初期化されました。 views / db / index.phpファイルに記述されている値から:59







サービス目的で、次のJS関数が説明されています。







  1. isTrue-dbExportAll、dbImportAll配列のすべての要素がtrueかどうかを確認します。
  2. startDB-ボタンのクリック処理の開始に先行し、ページ上のそれ以降のすべてのアクションをブロックします。
  3. finishFailDB-アクションを完了できない場合に呼び出されます。
  4. finishSuccessDB-ボタンをクリックした後、すべてのアクションが正常に完了した場合に呼び出されます。
  5. count-同じ関数PHPの類似物;
  6. logMess-配列をログに出力します。
  7. logMessStr-行を記録します。


輸出する



最後に、私たちはなぜ機能を開始したのか、



 $('body').on('click', '#dbExportAll', function () {});
      
      





作業の開始時に、リモートデータベース内のすべてのテーブルのリストの要求を送信し、受信したデータをdbExportAll配列に入力します。 次に、受信したテーブルのリスト全体を調べてリクエストを送信し、各テーブルのバックアップを個別に作成して、リクエストが時間をかけすぎないようにします。 受信したリクエストはすべてで処理されます



 DbController()->actionExport()
      
      





そして



 DbWrap::export($table, $date)
      
      





リクエストの期間の例を図2に示します。図2から、このような大きなテーブルのエクスポートには最低134秒(2.2分)が必要であり、リクエストが実行キューにあった時間は考慮されていません。







図2.-misテーブルのエクスポートに関する情報

図2.-misテーブルのエクスポートに関する情報







ただし、ログ(図3)を見ると、ほとんどのテーブルでエクスポートに必要な時間は非常に短く、1秒未満です。









図3.-ログのエクスポート

図3.-ログのエクスポート







図4から、すべてのテーブルをエクスポートするには7分で十分であることは明らかです。







図4.-エクスポートのタイミング

図4.-エクスポートのタイミング







インポート



インポートする前に、まだエクスポートしていない場合、またはバックアップファイルが削除されている場合は、エクスポートする必要があります。









インポート作業は、関数で説明されているJSスクリプトの開発からも始まります



 $('body').on('click', '#dbImportAll', function () {});
      
      





エクスポートと同様に、すべてのテーブルのリストが取得され、dbImportAll変数が初期化されます。 さらに、テーブルはインポートによって個別に送信されます。







 DbController()->actionImport()
      
      





そして



 DbWrap::importAll($table)
      
      





この場所のスクリプトのロジックは単純です。最新のファイルを見つけて、「mysql -uroot -pPass db <file.sql」という形式のコマンドを実行します(パスワードが空の場合、パスワードを指定せずにコマンドを送信します)。







図5から、インポートの完了に5分かかることがわかります。







図5.-タイミングのインポート

図5.-タイミングのインポート







変更を適用



変更の適用は、JS機能の開発から始まります







 $('body').on('click', '#dbMigrate', function () {...});
      
      





ここで、DbControllerコントローラーとそのactionMigrateメソッドにリクエストを送信し、DbWrap :: migrate($ mess)を呼び出します。 移行機能は、一連のテーブル変更要求が送信されるトランザクションを記述します。







変更の適用を実行した後、エラーの場合には詳細な説明(この場合、エラーは変更がすでに適用されているという事実による)またはそれを完了するのにかかる時間とともに、対応するメッセージが表示されます(図6を参照)。







図6-移行

図6-移行







削除する



そして、削除はJS関数の開発から始まります







 $('body').on('click', '# dbRemove, function () {});
      
      





ここで、DbControllerコントローラーとそのactionRemoveメソッドにリクエストを送信します。



 DbWrap::remove()
      
      





m remove関数は、PHPスクリプトが実行されているオペレーティングシステムのファミリの定義を記述し、OSに応じてrm –rfまたはRD / S / qコマンドを実行します。







結果



その結果、3回のクリックでテストサーバーに変更をすばやく適用するか、データベースが落ちた場合にデータベースを上げることができました。 さらに、他の長期のリクエストには空白があります。その主な原則は







分割して征服する


公平には、すべての測定は、比較的強力なプロセッサと1.5GbのRAMを備えたPHP7を実行しているローカルサーバーで行われたことに注意する価値があります。 したがって、このスクリプトのパフォーマンスは、脆弱なサーバーとホスティングでは低下する可能性があります。










ソースを詳細に理解したい人のために、ソースコードはBitbucket入手できます。










参照:







  1. http://sitear.ru/material/mysql-backups
  2. http://www.yiiframework.com/doc-2.0/yii-db-connection.html
  3. http://php.net/manual/ru/function.fopen.php
  4. http://php.net/manual/ru/function.fwrite.php
  5. http://php.net/manual/ru/function.shell-exec.php
  6. https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
  7. http://sc-blog.ru/import-export-base-mysql-console/



All Articles