はじめに
Debian 8 (jessie)で運用していたWebサーバが故障した。幸いハードディスクのデータは無事だった。新しいWebサーバを Debian 10 (buster)上で復旧したい。
2019年11月13日の状況
うまくいきませんでした。
Debian 8 上の構成
- WordPress 5.2.4
- MariaDB 10系
バックアップの状況
- Apacheの設定ファイルはまるごと残っている(/etc 以下がまるまるある)
- WordPressの方は設置したディレクトリごとデータがある。
- MariaDBの方はデータディレクトリはある(/var/lib/mysql)。ただし、ダンプしたSQLファイルがない。
Debian 10のインストール
以下のとおり。インストール時に「Webサーバ」「SSHサーバ」を選んでいるのでApacheはインストール済み。
MariaDBのインストール
% sudo apt install mariadb-server mariadb-client
データファイルからのデータベースの復元(frm, idbファイルからの復元)
2019年11月13日現在、うまくいっていないけれども。とりあえず調べた範囲をメモ。
MySQL InnoDB lost tables but files exist - Super Userの回答によると、MySQL/MariaDBではデータファイルをコピーするだけではデータベースの復元ができない。
バックアップをとったデータベースのデータファイルが ~/my_dbにあるとする。 あるテーブルmy_tableのデータファイルはmy_table.frm, my_table.idbとしてバックアップされているとする。
~/my_db |---- my_table.frm |---- my_table.idb
多くのページでMySQL Utilitiesに含まれる mysqlfrm を用いて、frmファイルからテーブル作成のSQL文(CREATE TABLE)を取得する手順が紹介されていたが、Debian 10のPython 2.7.16では、mysqlfrmがうまく動かなかった(バックアップをとっていたfrmファイルが悪いのか、メンテナンスが終わっているので現在のpythonのバージョンが合わないのかわからない)。
Debian 10では mariadbをインストールするとデータファイルは /var/lib/mysql 以下にある。
まず、mysql上でmy_dbデータベースを作成する。mysqlの初期パスワードは”mysql”
% mysql -u root -p > CREATE DATABASE my_db; > SHOW DATABASES; > quit
すると、/var/lib/mysql/my_db というディレクトリが作成される。
つづいて、復元したいテーブルを作成する。なお、私の場合は単にテーブルを作成しただけだと、MariaDB: InnoDB File-Per-Table Tablespaces #Differing ROW_FORMAT Valuesを原因として、「ALTER TABLE tablename IMPORT TABLESPACE;」を実行すると「ERROR 1808 (HY000): Schema mismatch (Expected FSP_SPACE_FLAGS=0x21, .ibd file contains 0x0.)」というエラーがでてインポートできなかった。このため、テーブルを作成するときにROW_FORMATを指定して上げる必要があった。
参考
- MariaDB: InnoDB Row Formats Overview
- Stack Overflow: Restore table structure from frm and ibd filesのコメント。
For anyone else that comes's across the ROW_TYPE_DYNAMIC issue like I just did. You'll have to start the process over from beginning and on your create table statements add ROW_FORMAT=COMPACT after ENGINE=InnoDB so it looks like ) ENGINE=InnoDB ROW_FORMAT=COMPACT DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci for example. Then repeat the steps like normal and it should work. – Jeff Wilbert Aug 23 at 7:49
以下のようにする。なお、テーブルの内容は適当に指定した。
% mysql -u root -p my_db > SHOW TABLES; (何も表示されない) > CREATE TABLE my_table (id int) ENGINE=InnoDB ROW_FORMAT=COMPACT; > SHOW TABLES;
この時点で/var/lib/mysql/my_db以下にmy_table.frm, my_table.idbが生成される。次に作成された空のmy_table.idbを削除する。
> ALTER TABLE my_table DISCARD TABLESPACE; > quit
バックアップをとっていたmy_table.idbを/var/lib/mysql/my_db以下にコピーする。
% sudo cp -p ~/my_db/my_table.idb /var/lib/mysql/my_db % sudo chown mysql:mysql /var/lib/mysql/my_db/my_table.idb
インポートする。
% mysql -u root -p my_db > ALTER TABLE my_table IMPORT TABLESPACE; > SELECT * FROM my_table LIMIT 10;
2019年11月13日現在、テーブル1つについてはちゃんとインポートできたのだが、その後、別のテーブルをCREATE TABLEで作成しようとするとすでに存在するという主旨のエラーがでて、うまく進まなくなった。