ファイルをコピーしてMySQLデータベースをコピーできますか?このファイルには正確に何が含まれていますか?

ファイルをコピーしてMySQLデータベースをコピーできますか?このファイルには正確に何が含まれていますか?

私はMySQLデータベースとUbuntu Linuxシステムを使用しています。

私のデータベース名はdb_test、次のようにパスに/var/lib/mysql/db_testサフィックスが付いたいくつかの.frmファイルがあることを確認しました。.MYD.MYI

/var/lib/mysql/db_test# ls

cars.frm 
cars.MYD 
cars.MYI

customers.frm
customers.MYD
customers.MYI

departments.frm
departments.MYD
departments.MYI

... 

.frm各、、、ファイルグループがデータベースのテーブルにマップされているようです.MYD.MYI

次の2つの質問があります。

  1. これらの3つのファイルは正確に何をしますか?

  2. /var/lib/mysql/sayというパスの下に新しいディレクトリを作成し、db_test_2ディレクトリdb_test_1内のすべてのファイルをにコピーすると、まったく同じ内容(テーブル)を含む新しいデータベースもdb_test_2作成されますか?db_test_2db_test_1

この物理データベースファイルの移動操作は、次のコマンドライン操作と同じ結果を生成しますか?

  1. db_test_1データベースダンプ

  2. 新しいデータベースの作成db_test_2

  3. その後、db_test_1データベースを新しいデータベースに再ダンプしますかdb_test_2

mysqldumpもしそうなら、ファイルを移動する方がデータベースをコピーするよりもはるかに速いようです。これについて意見がありますか?

答え1

  1. AFAIRでは、.frmはデータベーステーブル構造を記述する記述ファイル、.MYDはデータを含むファイル、.MYIはインデックスを含むファイルです。

  2. はい、コピーははるかに高速になります。しかし、問題があります。原子的ではありません。負荷が高いと、コピーされたファイルは一貫性がなく、まったく破損する可能性があります。特にInnoDBのような、より「インテリジェントな」エンジンを使用している場合は、さらにそうです。

編集する:psこのファイルは安全にコピーできますが、その前にmysqlサーバーを停止する必要があります。

答え2

以下を実行するコマンドラインツールがあります。mysqlhotcopy

myisamテーブルでは機能しますが、InnoDbテーブルでは機能しません。

lvmを使用してサーバーを構成し、/var/lib/mysqlを専用ボリュームに保存した場合は、非ブロック方式ですべてのデータベースをすばやくバックアップすることをお勧めします。

mysql -U root -p
  > flush tables with read lock;

これにより、すべてのテーブルがディスクにフラッシュされ、読み取り/書き込み操作が防止されます。

  > system "lvcreate -s -L 1G -n lvMysql_snap /dev/vg_myserver/lv_mysql" ;

構成に合わせて調整すると、データベースファイルシステムのスナップショットが作成されます。時間は必要ありません

  > unlock tables;

完了すると、R/W ジョブが再開されます。

これで、/dev/vg_myserver/lvMysql_snapをマウントしてデータベースのtarアーカイブを作成できます。

答え3

これはMyISAMでは機能しますが、InnoDBでは機能しません。バラよりhttps://serverfault.com/a/367321/57569

InnoDBに関するこの答えで判断すると、次のようになります。

.frmファイルと.ibdファイルのみをコピーしたい場合は、難しい状況になります。 InnoDBテーブルへの.frmファイルと.ibdファイルのコピーは、.ibdファイルのテーブルスペースIDがibdata1ファイルのメタデータのテーブルスペースIDエントリと正確に一致することを保証できる場合にのみ有効です。

答え4

同じマシン/mysqlサーバーで6GBデータベースを複製する方法すら遅すぎることを発見し、データベースmysqldump | mysqlのdatadirフォルダ全体をコピーして別のデータベース(同じインスタンス)の別のフォルダに貼り付けようとしました。です。 mysqlを起動すると破損しているようです。成功せずに auto_recover テーブルを設定しようとしました。

同じデータベース名でのみ機能するようです。私がしたことは、mysqlを実行する2つのDockerコンテナを作成することでした。 1つは私のプロダクションスレーブのスレーブで、もう1つはドッカーマップファイルを介した直接複製用でした。以下の私の構造を参照してください。

          +-----------+
          | Master DB |
          +-----------+
                |
 (Replication)  |
        +-----------------+
        | Slave/Master DB |
        +-----------------+
                |
                |         Cloud / Production Server
                V
======================================================================
                |
                |         My Local Computer
 (Replication)  |
          +-----------+    - Docker Container: AppDBLive.readonly
          | Slave  DB |    - DB Name: MyAppDB
          +-----------+    - READ Only (If I want to test live data)
                |          - Consistently cloning from prod slave/master
                |
  (Rsync/Copy datadir of MyAppDB)
                |
                V
        +----------------+  - Docker Container: AppDBLive.readwrite
        | No Replication |  - DB Name: MyAppDB
        +----------------+  - Can Write and mess with all the data for testing/dev
                            - clone via sh script to trigger rsync from AppDBLive.read

以下はDockerコンテナを構築するスクリプトです。

/local/path/to/AppDBLive.readonly/run.sh:

_PWD=`pwd`
docker run --name=MyAppDB \
--mount type=bind,src=$_PWD/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=$_PWD/datadir,dst=/var/lib/mysql \
--mount type=bind,src=$_PWD/logs,dst=/var/log/mysql \
-p 3336:3306 \
-d mysql/mysql-server:5.7

/local/path/to/AppDBLive.readwrite/run.sh:

_PWD=`pwd`
docker run --name=MyAppDB.dev \
--mount type=bind,src=$_PWD/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=$_PWD/datadir,dst=/var/lib/mysql \
--mount type=bind,src=$_PWD/logs,dst=/var/log/mysql \
-p 3337:3306 \
-d mysql/mysql-server:5.7

両方のコンテナのポート番号の違いに注意してください。アプリケーションが正しいポートに接続されていることを確認してください。

また、レプリケーションスクリプトを実行するときに両方のコンテナが終了することを確認してください。

関連情報