CREATE TABLE .. LIKEとINSERT INTO .. SELECTを利用したコピー
mysql>use vmstat
mysql> CREATE TABLE vmstat_bak LIKE vmstat;
mysql> INSERT INTO vmstat_bak SELECT * FROM vmstat;
CREATE TABLE vmstat_bak LIKE vmstatは「vmstatテーブルと同じカラム定義とテーブル属性でvmstat_bakというテーブルを作る」という意味のステートメントです。同じカラム定義とテーブル属性を持っているvmstat_bakテーブルに、INSERT INTO vmstat_bak SELECT * FROM vmstatとすることで、「vmstatテーブルから全ての行の全てのカラムをSELECTした結果をvmstat_bakテーブルにINSERT」し、vmstat_bakテーブルはvmstatテーブルの(その時点での)完全なコピーになります。切り戻す場合はRENAME TABLE vmstat TO vmstat_old, vmstat_bak TO vmstatステートメントを実行することで、定義情報、データ全てがコピー取得時の状態に戻せます。筆者はこの方法を好んで使いますが、時にはもう少し良い方法があったりもします。
CREATE TABLE .. AS SELECT ..を利用したコピー
mysql> CREATE TABLE vmstat_bak_2 AS SELECT * FROM vmstat;
CREATE TABLE vmstat_bak2 AS SELECTクエリーは、「SELECTクエリーの結果をvmstat_bak_2テーブルとして固定化する」という意味のステートメントです。1ステートメントで済むのでこちらの方が簡単ですか? このステートメントは、「SELECTクエリーの結果を固定化する」ものなので、「SELECT結果に含まれない情報」はvmstat_bak_2テーブルにはコピーされません。端的には、オートインクリメントの値やインデックスはテーブルの属性であってクエリーの結果には含まれないので、コピーされません。SHOW CREATE TABLEステートメントでテーブル定義を確認してみると、コピー先のテーブルにはPRIMARY KEYが定義されていないことが確認できます。
mysql> SHOW CREATE TABLE vmstat\G
mysql> SHOW CREATE TABLE vmstat_bak_2\G
このテーブルの属性情報はコピーされないというのは良し悪しで、「テーブル定義を変更するのでコピーを取っておこう」という用途には使えません。ただし、「テーブル定義は変更せず、データを削除したり更新したりするだけ」であればこのコピーには問題はありません。また、インデックスは存在しないほうがテーブルへのデータの挿入は高速なため、「単にデータだけで良いコピー」が欲しい場合はこちらのほうが高速にコピー可能です。このコピーからデータを切り戻す場合は、TRUNCATE TABLE vmstatステートメントで一度vmstatテーブルの中身を空にしてから、INSERT INTO vmstat SELECT * FROM vmstat_bak_2ステートメントで行を全てコピーしなおします。
$ cd /var/lib/mysql
$ ls -l
total 176152-rw-rw----1 mysql mysql 56Oct219:05auto.cnf
-rw-rw----1 mysql mysql 79691776Oct219:34 ibdata1
-rw-rw----1 mysql mysql 50331648Oct219:34 ib_logfile0
-rw-rw----1 mysql mysql 50331648Oct219:34 ib_logfile1
drwx------2 mysql mysql 4096Oct219:05 ls
drwx------2 mysql mysql 4096Oct219:05 mysql
srwxrwxrwx 1 mysql mysql 0Oct219:05 mysql.sock
drwx------2 mysql mysql 4096Oct219:05 performance_schema
drwx------2 mysql mysql 4096Oct219:34 vmstat
drwx------2 mysql mysql 4096Oct219:08 zipcode
auto.cnf
MySQL 5.6で追加されたファイルです。MySQLサーバを一意に識別するためのserver-uuidが記録されています。datadirの初期化時(具体的には、mysql_install_dbコマンドが実行された時)にこのファイルが存在しなければ作成され、以降はファイルに記録されたserver-uuidを利用するようになります(単なるテキストファイルですので、興味があればcatコマンドなどで中身を確認してみてください)。GTIDレプリケーション関連で利用されています。
$ ls -l zipcode/
total 28796-rw-rw----1 mysql mysql 67Oct219:07 db.opt
-rw-rw----1 mysql mysql 8624Oct219:08 prefecture_kana.frm
-rw-rw----1 mysql mysql 98304Oct219:08 prefecture_kana.ibd
-rw-rw----1 mysql mysql 8824Oct219:08 zipcode.frm
-rw-rw----1 mysql mysql 29360128Oct219:09 zipcode.ibd
ALTER TABLE .. DISCARD TABLESPACEステートメントは、「このテーブルに紐づくibdファイルを削除する」というステートメントです。これにより新しく作ったテーブルからibdファイルが消去され、frmファイルだけが残ります。
FLUSH TABLES .. FOR EXPORTステートメントは、「このテーブルのibdファイルをコピーしたいので、コピー先のサーバーで共有テーブルスペースやログファイルを協調させるための情報(これがcfgファイルの正体です)を作成してibdファイルをコピー可能な状態にしてくれ」というステートメントです。これはmysqlコマンドを終了するとロックが解除されcfgファイルも削除されてしまうため、別のターミナルを用意する必要がありました。