Go to the first, previous, next, last section, table of contents.


22 Solving some common problems with MySQL

In this chapter, you will find information to solve some of the more common tasks with MySQL. This includes making backups, running more than one MySQL server daemon on a single machine, and replicating a database using the update or binary logs.

22.1 更新ログを使用したデータベースの複製

Now that master-slave internal replication is available starting in Version 3.23.15, using the update log to implement replications is not recommended. 「11 Replication in MySQL」節参照.

However, it is still possible to replicate a database by using the update log. 「23.3 更新ログ」節参照. 「23.3 更新ログ」節参照. これは、一つのデータベースがマスター(主)として動作ふるまっており (全てのデータ変更がここで行われます)、かつ、一つ以上の他のサーバーがスレーブ(従)と して動作していることを要求します。 スレーブを更新するには mysql < update_log を実行するだけです。 スレーブデータベースのホスト、ユーザー、パスワードをコマンドのオプションに与え、 マスターから取得した更新ログを入力に使用します。

もし、テーブルからなにも削除しない場合、 TIMESTAMP フィールドを使用すれば、 最後の複製時以後に、新規に挿入されたものや変更されたものだけを ミラーサーバーにコピーできます。(最後の複製を行った時間と比較すれば抽出できます)

更新ログ(削除のため)とタイムスタンプ(両側で)の両方を使用する2つの方法の 更新システムを作ることができます。しかしこの場合は、同じデータが両側で変 更された時に、あなたが衝突を操作できなければなりません。あなたはおそらく 何が更新されたかを決定するのを助けるために、古いバージョンを保持したいで しょう。

この時行う複製には SQL ステートメントで行われるため、データベースを更新す るステートメント中で次の関数は使ってはいけません。これらは他の コピー元のサーバとは違う値を返すからです:

全ての時刻関数は、必要な場合にミラーにタイムスタンプを送るようにして、安 全に使用できます。LAST_INSERT_ID() も安全に使用できます。

22.2 データベースのバックアップ

MySQL テーブルはファイルとして格納されるため、バックアップを行 うのは簡単です。矛盾のないバックアップを得るためには、 FLUSH TABLES をおこなって、LOCK TABLES を関連するテーブルで行ってください。 「7.32 LOCK TABLES/UNLOCK TABLES 構文」節参照. 読み込みロックだ けが必要なので、そのテーブルでデータベースディレクトリのファイルのコピー が行われている間も、他のスレッドはクエリを継続できます。 The FLUSH TABLE is needed to ensure that the all active index pages is written to disk before you start the backup.

もし、テーブルを SQL レベルでバックアップしたいのであれば、SELECT INTO OUTFILEBACKUP TABLE を使用できます。 「7.19 SELECT構文」節参照. 「7.13 BACKUP TABLE Syntax」節参照.

他の方法は mysqldump プログラムか mysqlhotcopy スクリプト を使用することです:

  1. フルバックアップをとるには:
    shell> mysqldump --tab=/path/to/some/dir --opt --full
    
    or
    
    shell> mysqlhotcopy database /path/to/some/dir
    
    若しサーバーがいっさいデータの変更をしないのであれば、 単に全てのテーブルファイル(`*.frm', `*.MYD', `*.MYI' ファイル)を コピーするだけでも構いません。 The script mysqlhotcopy does use this method.
  2. mysqld を止め、そして --log-update[=file_name] オプションをつけて起動します。 「23.3 更新ログ」節参照. ログファイルは、 mysqldump 実行後に行われたデータベースの変更を 複製するための情報を与えてくれます。

もしリストアをしなければならない場合、まず最初に REPAIR TABLEmyisamchk -r を実行してテーブルの修復を試みてください。 ほとんどの場合、99.9% 修復はできるはずです。 もし myisamchk が失敗した場合、以下のようにします: (This will only work if you have started MySQL with --log-update. 「23.3 更新ログ」節参照.):

  1. オリジナルの mysqldump バックアップデータをリストアします。
  2. 次のコマンドを実行して、バイナリログ内の更新を再実行します。
    shell> mysqlbinlog hostname-bin.[0-9]* | mysql
    
    更新ログを使用する場合は、次のようにできます:
    shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
    

ls は、全ての更新ログファイルを正しい順で得るために行われます。

SELECT * INTO OUTFILE 'file_name' FROM tbl_name での選択的バックアップと LOAD DATA FROM INFILE 'file_name' REPLACE ... でのリストアを行う こともできます。重複レコードを避けるためには、テーブル内に PRIMARY KEY or a UNIQUE が必要です。REPLACE は、'重複インデックス' 衝突があった場合、 新しいレコードを挿入する時に古いレコードが新しいものに置き換えられることを意味します。

If you get performance problems in making backups on your system, you can solve this by setting up replication and do the backups on the slave instead of on the master. 「11.1 Introduction」節参照.

If you are using a Veritas file system, you can do:

  1. Execute in a client (perl ?) FLUSH TABLES WITH READ LOCK
  2. Fork a shell or execute in another client mount vxfs snapshot.
  3. Execute in the first client UNLOCK TABLES
  4. Copy files from snapshot
  5. Unmount snapshot

22.3 同一マシン上に複数の MySQL サーバーを走らせる

同じマシン上で複数のサーバーを走らせたい場合があります。 例えば、すでに存在しているサーバーはそのままにしておいて、新しい MySQL をテストしたい場合や、 あるいは、インターネットプロバイダーを営んでいて、MySQL をそれぞれの顧客用に提供したい場合など。

複数のサーバーをたちあげる場合、簡単な方法として、 TCP/IP ポート、ソケットファイルを変えて、サーバーをコンパイルする方法があります。 「15.4 mysqld_multi, program for managing multiple MySQL servers」節参照.

そでに走っているサーバーがデフォルトのポート番号とソケットファイルで動作しているとします。 新しくサーバーを作るには、以下のように configure します:

shell> ./configure  --with-tcp-port=port_number \
             --with-unix-socket-path=file_name \
             --prefix=/usr/local/mysql-3.22.9

port_numberfile_name には、デフォルトのポート番号、ソケットファイルとは違うものを指定します。 そして --prefix を、すでに走っている MySQL のインストール先とは違うディレクトリーに指定します。

現在走っている MySQL サーバーが使用している ソケットとポートをチェックするには、以下のようにします:

shell> mysqladmin -h hostname --port=port_number variables

Note that if you specify ``localhost'' as a hostname, mysqladmin will default to using Unix sockets instead of TCP/IP.

あなたが使用しているポートに MySQL サーバーが走っていれば、 これは変更可能な MySQL 変数を(ソケットファイルの名前も含んで)出力します。

立ち上げスクリプト(おそらく `mysql.server' ファイル)を編集して 複数の MySQL サーバーを立ちあげても構いません。

この場合、 MySQL サーバーを再コンパイルする必要はありません。 safe_mysqld のオプションを指定してサーバーを起動すれば、ポートとソケットを変更できます:

shell> /path/to/safe_mysqld --socket=file-name --port=port_number

mysqld_multi can also take safe_mysqld (or mysqld) as an argument and pass the options from a configuration file to safe_mysqld and further to mysqld.

もし、他のサーバーがロギングを行っているディレクトリと同じデータベースディレクトリを、 新しいサーバーで使用するのであれば、ログファイルの名前を指定すべきです。 ( safe_mysqld--log , --log-update , --log-slow-queries を指定する) そうしないと、両方のサーバーが同じログファイルに書き込もうとするからです。

WARNING: 通常、二つサーバーに同じデータベースを操作させてはいけません! もし使用している OS が fault-free system locking をサポートしていないと、 これは悲惨なことになるでしょう!

もし二つ目のサーバーに違うデータベースディレクトリを使用させたい場合、 safe_mysqld--datadir=path オプションを指定します。

NOTE also that starting several MySQL servers (mysqlds) in different machines and letting them access one data directory over NFS is generally a BAD IDEA! The problem is that the NFS will become the bottleneck with the speed. It is not meant for such use. And last but not least, you would still have to come up with a solution how to make sure that two or more mysqlds are not interfering with each other. At the moment there is no platform that would 100% reliable do the file locking (lockd daemon usually) in every situation. Yet there would be one more possible risk with NFS; it would make the work even more complicated for lockd daemon to handle. So make it easy for your self and forget about the idea. The working solution is to have one computer with an operating system that efficiently handles threads and have several CPUs in it.

もし違うポートで走っている MySQL サーバーに、 これまた違うポートを使用するように作られたクライアントから接続したい場合、 以下のようにします:


Go to the first, previous, next, last section, table of contents.