mysql|バックアップ|データ|データベース
MySQL データベースのバックアップ
[Yanzi] http://clyan.hongnet.com/index.html
データベース テーブルが失われたり破損した場合には、データベースをバックアップすることが重要です。システム クラッシュが発生した場合、データ損失を最小限に抑えながらテーブルをクラッシュ発生時の状態に復元できるようにしたいと考えるのは当然です。場合によっては、MySQL 管理者が大混乱を引き起こすこともあります。テーブルが破損していることをすでに知っている管理者が、vi や Emacs などのエディタでテーブルを直接編集しようとすることは、テーブルにとって決して良いことではありません。
データベースをバックアップする 2 つの主な方法は、
mysqldump プログラムを使用するか、データベース ファイルを直接コピーする (cp、cpio、tar などを使用する) ことです。各方法には長所と短所があります。
- mysqldump は MySQL サーバーで動作します。直接コピー方式はサーバーの外部で実行されるため、コピーしているテーブルがクライアントによって変更されないように措置を講じる必要があります。ファイル システム バックアップを使用してデータベースをバックアップする場合も、同じ問題が発生します。ファイル システムのバックアップ プロセス中にデータベース テーブルが変更されると、バックアップされたテーブル ファイルのサブジェクトが不一致になり、テーブルが今後の回復には無意味です。ファイル システムのバックアップとファイルの直接コピーの違いは、後者の場合はバックアップ プロセスを完全に制御できるため、サーバーがテーブルをそのままにしておくための措置を講じることができることです。
- mysqldump は直接コピーするよりも遅くなります。
- mysqldump は、ハードウェア構造が異なる他のマシンにも移植できるテキスト ファイルを生成します。コピーしているテーブルが MyISAM ストレージ形式を使用していない限り、ファイルを直接コピーすることは他のマシンに移植できません。 ISAM テーブルは、同様のハードウェア構造を持つマシン上でのみコピーできます。 MySQL 3.23 で導入された MyISAM テーブル ストレージ形式は、この形式がマシンに依存しないため、この問題を解決します。そのため、ファイルを直接コピーして、異なるハードウェア構造を持つマシンに移植できます。 2 つの条件が満たされている限り、もう一方のマシンも MySQL 3.23 以降を実行している必要があり、ファイルは ISAM 形式ではなく MyISAM 形式で表されている必要があります。
どのバックアップ方法を使用する場合でも、データベースを復元する必要がある場合、最良の結果を確実に得るために従うべきいくつかの原則があります:
- バックアップを定期的に実行します。計画を立ててそれを守りましょう。
- サーバーにログの更新を実行させます。変更ログは、クラッシュ後にデータを回復する必要がある場合に役立ちます。バックアップ ファイルを使用してデータをバックアップ時の状態に復元した後、更新ログでクエリを実行することで、バックアップ後に行われた変更を再適用できます。これにより、データベース内のテーブルが復元されます。衝突が起きたときの状態。
ファイル システム バックアップの用語では、データベース バックアップ ファイルは完全ダンプを表し、更新ログは増分ダンプを表します。
- 統一されたわかりやすいバックアップ ファイルの命名スキームを使用します。 backup1、buckup2 などは特に意味がありません。リカバリを実行するとき、ファイルの内容を把握するのに時間を無駄にすることになります。データベース名と日付を使用してバックアップ ファイル名を形成すると便利な場合があります。例:
%mysqldump samp_db >/usr/archives/mysql/samp_db.1999-10-02
%mysqldump menagerie >/usr/archives/mysql/menagerie.1999-10-02
これを実行するとよいでしょう。バックアップを生成した後、それらを圧縮します。通常、バックアップは巨大です。ログ ファイルを期限切れにするのと同じように、バックアップ ファイルも期限切れにして、ディスクがいっぱいになるのを防ぐ必要があります。
- ファイル システム バックアップを使用してバックアップ ファイルをバックアップします。データ ディレクトリだけでなく、データベースのバックアップが含まれているディスク ドライブもクリアされるような完全なクラッシュが発生した場合は、大きな問題に直面することになります。変更ログもバックアップしてください。
- バックアップ ファイルは、データベースに使用されているファイル システムとは異なるファイル システムに配置します。これにより、バックアップの生成によってデータ ディレクトリを含むファイル システムがいっぱいになる可能性が低くなります。
バックアップの作成に使用されるテクニックは、データベースを別のマシンにコピーする場合にも役立ちます。最も一般的には、データベースは別のホストで実行されているサーバーに移動されますが、データを同じホスト上の別のサーバーに移動することもできます。
1 mysqldump を使用してデータベースをバックアップおよびコピーします
mysqldumo プログラムを使用してデータベース バックアップ ファイルを生成すると、デフォルトで、ファイルの内容には、ダンプされるテーブルを作成する CREATE ステートメントと、行を含む INSERT ステートメントが含まれます。テーブル内のデータ。つまり、mysqldump によって生成された出力は、後でデータベースを再構築するための mysql への入力として使用できます。
次のようにデータベース全体を 1 つのテキスト ファイルにダンプできます:
%mysqldump samp_db >/usr/archives/mysql/samp_db.1999-10-02
出力ファイルの先頭は次のようになります:
# MySQL Dump 6.0# # Host: localhost Database: samp_db#---------------------------------------# Server version 3.23.2-alpha-log## Table structure for table 'absence'#CREATE TABLE absence( student_id int(10) unsigned DEFAULT '0' NOT NULL, date date DEFAULT '0000-00-00' NOT NULL, PRIMARY KEY (student_id,date));## Dumping data for table 'absence'#INSERT INTO absence VALUES (3,'1999-09-03');INSERT INTO absence VALUES (5,'1999-09-03');INSERT INTO absence VALUES (10,'1999-09-08');......
File残りの部分は、さらに INSERT ステートメントと CREATE TABLE ステートメントで構成されます。
バックアップを圧縮したい場合は、次のようなコマンドを使用します:
%mysqldump samp_db | gzip >/usr/archives/mysql/samp_db.1999-10-02.gz
巨大なデータベースが必要な場合は、出力ファイルサイズも非常に大きくなり、管理が困難になる可能性があります。必要に応じて、mysqldump コマンド ラインでデータベース名の後に個々のテーブル名をリストして、その内容をダンプすることができます。これにより、ダンプ ファイルがより小さく管理しやすいファイルに分割されます。次の例は、samp_db データベースからいくつかのテーブルを別のファイルにダンプする方法を示しています。%mysqldump samp_db student score event absence >grapbook.sql
%mysqldump samp_db member president >hist-league.sql
如果你生成准备用于定期刷新另一个数据库内容的备份文件,你可能想用--add-drop-table选项。这告诉服务器将DROP TABLE IF EXISTS语句写入备份文件,然后,当你取出备份文件并把它装载进第二个数据库时,如果表已经存在,你不会得到一个错误。
如果你倒出一个数据库以便能把数据库转移到另一个服务器,你甚至不必创建备份文件。要保证数据库存在于另一台主机,然后用管道倾倒数据库,这样mysql能直接读取mysqldump的输出。例如:你想从主机pit-viper.snake.net拷贝数据库samp_db到boa.snake.net,可以这样很容易做到:
%mysqladmin -h boa.snake.net create samp_db
%mysqldump samp_db | mysql -h boa.snake.net samp_db
以后,如果你想再次刷新boa.snake.net上的数据库,跳过mysqladmin命令,但要对mysqldump加上--add-drop-table以避免的得到表已存在的错误:
%mysqldump --add-drop-table samp_db | mysql -h boa.snake.net samp_db
mysqldump其它有用的选项包括:
2 使用直接拷贝数据库的备份和拷贝方法
另一种不涉及mysqldump备份数据库和表的方式是直接拷贝数据库表文件。典型地,这用诸如cp、tar或cpio实用程序。本文的例子使用cp。
当你使用一种直接备份方法时,你必须保证表不在被使用。如果服务器在你则正在拷贝一个表时改变它,拷贝就失去意义。
保证你的拷贝完整性的最好方法是关闭服务器,拷贝文件,然后重启服务器。如果你不想关闭服务器,要在执行表检查的同时锁定服务器。如果服务器在运行,相同的制约也适用于拷贝文件,而且你应该使用相同的锁定协议让服务器“安静下来”。
假设服务器关闭或你已经锁定了你想拷贝的表,下列显示如何将整个samp_db数据库备份到一个备份目录(
DATADIR表示服务器的数据目录):
%cd <i>DATADIR</i>%cp -r samp_db /usr/archive/mysql
单个表可以如下备份:
%cd <i>DATADIR</i>/samp_db%cp member.* /usr/archive/mysql/samp_db%cp score.* /usr/archive/mysql/samp_db ....
当你完成了备份时,你可以重启服务器(如果关闭了它)或释放加在表上的锁定(如果你让服务器运行)。
要用直接拷贝文件把一个数据库从一台机器拷贝到另一台机器上,只是将文件拷贝到另一台服务器主机的适当数据目录下即可。要确保文件是MyIASM格式或两台机器有相同的硬件结构,否则你的数据库在另一台主机上有奇怪的内容。你也应该保证在另一台机器上的服务器在你正在安装数据库表时不访问它们。
3 复制数据库(Replicating Database)
复制(Replication)类似于拷贝数据库到另一台服务器上,但它的确切含义是实时地保证两个数据库的完全同步。这个功能将在3.23版中出现,而且还不很成熟,因此本文不作详细介绍。
4 用备份恢复数据
数据库损坏的发生有很多原因,程度也不同。如果你走运,你可能仅损坏一两个表(如掉电),如果你倒霉,你可能必须替换整个数据目录(如磁盘损坏)。在某些情况下也需要恢复,比如用户错误地删除了数据库或表。不管这些倒霉事件的原因,你将需要实施某种恢复。
如果表损坏但没丢失,尝试用myisamchk或isamchk修复它们,如果这样的损坏可有修复程序修复,你可能根本不需要使用备份文件。关于表修复的过程,见《数据库维护与修复》。
恢复过程涉及两种信息源:你的备份文件和个更新日志。备份文件将表恢复到实施备份时的状态,然而一般表在备份与发生问题之间的时间内已经被修改,更新日志包含了用于进行这些修改的查询。你可以使用日志文件作为mysql的输入来重复查询。这已正是为什么要启用更新日志的原因。
恢复过程视你必须恢复的信息多少而不同。实际上,恢复整个数据库比单个表跟容易,因为对于数据库运用更新日志比单个表容易。
4.1 恢复整个数据库
首先,如果你想恢复的数据库是包含授权表的mysql数据库,你需要用--skip-grant-table选项运行服务器。否则,它会抱怨不能找到授权表。在你已经恢复表后,执行mysqladmin flush-privileges告诉服务器装载授权标并使用它们。
ls命令生成更新日志文件的一个单列列表,根据服务器产生它们的次序排序(主意:如果你修改任何一个文件,你将改变排序次序,这导致更新日志一错误的次序被运用。)
很可能你会是运用某几个更新日志。例如,自从你备份以来产生的更新日志被命名为update.392、update.393等等,你可以这样重新运行:
%mysql --one-database db_name < update.392
%mysql --one-database db_name < update.393
.....
如果你正在实施恢复且使用更新日志恢复由于一个错误建议的DROP DATABASE、DROP TABLE或DELETE语句造成丢失的信息,在运用更新日志之前,要保证从其中删除这些语句。
4.2 恢复单个表
恢复单个表较为复杂。如果你用一个由mysqldump生成的备份文件,并且它不包含你感兴趣的表的数据,你需要从相关行中提取它们并将它们用作mysql的输入。这是容易的部分。难的部分是从只运用于该表的更新日志中拉出片断。你会发觉mysql_find_rows实用程序对此很有帮助,它从更新日志中提取多行查询。
另一个可能性是使用另一台服务器恢复整个数据库,然后拷贝你想要的表文件到原数据库中。这可能真的很容易!当你将文件拷回数据库目录时,要确保原数据库的服务器关闭。