FAQ のバックアップ(No.8)




MySQLインストール

mysqld が最低必要とする物

  • basedir/share/ ディレクトリ以下(shareファイル。errmsg.sys や charsets/)
  • datadir/mysql/ (mysql 権限データベース、テーブル)

権限テーブルや charsets/ がなければ mysqld は起動しない。
errmsg.sys はバージョンによって数が違うので、違うバージョンの errmsg.sys を使用していると mysqld が起動しない。
これらが起きた場合、.err ファイルにエラーが記録されないことが多い。



バイナリファイル

  • mysql-バージョン-ベンダ-OS-CPUアーキテクチャ.tar.gz
    Unix, Unixライク用のバイナリ。
    basedir は /usr/local/mysql/
    datadir は /usr/local/mysql/var/
    としてコンパイルされている
    展開して、/usr/local/mysql/ にする。

  • mysql-バージョン-win-noinstall.zip , mysql-noinstall-バージョン-win32.zip
    ms-win用。
    展開して、C:\mysql\ にする。
    NT系列の場合、サービスに登録したければ、mysqld-nt --install を使う。
    basedir は c:/mysql/
    datadir は c:/mysql/data/
    MySQL は Windows のレジストリには依存せず、コピーするだけで動く。

  • mysql-バージョン-win.zip , mysql-バージョン-win32.zip , mysql-essential-バージョン-win32.msi
    ms-win用。インストーラー付き。
    インストーラーがおかしいことがあるので、こちらはあまり使わない。
    mysql-バージョン-win-noinstall.zip (mysql-noinstall-バージョン-win32.zip) の方を使う。

Windows 用のバイナリ mysqld ファイル

4.1バイナリ名named-pipeBDB
mysqld.exe95系用--
mysqld-max.exemysqld.exe の、フル機能バージョン-O
mysqld-debug.exe--debug オプションを有効にして作ったバイナリOO
mysqld-nt.exeNT/XP 系用。named-pipe が使用できるO-
mysqld-max-nt.exemysqld-nt の、フル機能バージョンOO

MySQL サーバーの起動には、

  • サービスで起動するか
  • コマンドプロンプトで、直接 mysqld.exe を実行するか
  • winmysqladmin.exe で起動するか

の方法がある。

起動しない場合は、

  • c:\mysql\data\mysqld.err ファイルの中身を確認
  • c:\mysql\share\ がちゃんとあるのか確認
  • c:\mysql\data\ がちゃんとあるのか確認

Windows サービス

  • 登録
c:\mysql\bin\mysqld-max-nt.exe --install サービス名

mysqld のオプションを指定したい場合は:

c:\mysql\bin\mysqld-max-nt.exe --install サービス名 --defaults-file=c:/mymy.txt

のように、指定したいオプションをサービス名の後につける。

  • 削除
c:\mysql\bin\mysqld-max-nt.exe --remove サービス名

登録と削除は同じバイナリで。




MySQL運用

OS選択

  • 本格運用には、Unix, Unixライク OS を選ぶ。
  • Linux は glibc 2.3 使用。



ストレージエンジン??

MySQL は、データの保存形式を複数持っています。 その保存形式により、機能や特徴、パフォーマンスが変わります。 これをストレージエンジンと呼んでいます。

このモデルの利点は:

  • 用途にあったストレージエンジンを選択することで、特別なチューニングを施すことなく、その目的に合った能力を得ることができる。
  • 古いバージョンのMySQLで作成したファイルは、MySQLをバージョンアップをしてもそのまま使い続けることができる。 MySQL のバージョンアップに際して、データの吸い上げ、入れ直しは発生しない。
  • 新しい手法が登場したとき、簡単にその手法を取り入れ、よりよい環境を提供できる。
  • あるストレージエンジンは他のストレージエンジンに影響を及ぼさない。 このため、バグの影響が少ない

実際の使い方は

CREATE TABLE ..... (.....) TYPE=InnoDB;

のようにするだけ。

ALTER TABLE .... TYPE=MyISAM;

のように、テーブルのストレージエンジンを ALTER TABLE 文で変えることも可能。(TYPEのかわりに ENGINE キーワードでも OK)

代表的なストレージエンジン:

  • MyISAM : 検索に強い
  • InnoDB : トランザクション
  • NDB : クラスター
  • HEAP(MEMORY) : メモリ内で動作するテーブル

標準のストレージエンジンは MyISAM。 すなわち、TYPE とか ENGINE を指定しなければ、テーブルの型は MyISAM になるということ。



複数のMySQLを同居させるには/MySQLを違うディレクトリで動かすには

mysqld --basedir=/usr/local/mysql-4.0.22 --datadir=/usr/local/mysql-4.0.22/data --socket=/tmp/sock4.0.22 --port=4022 &

もしくは

/usr/local/mysql-4.0.22/my.cnf に

[mysqld]
basedir=/usr/local/mysql-4.0.22
datadir=/usr/local/mysql-4.0.22/data
socket=/tmp/sock4.0.22
port=4022

と書いて

mysqld --defaults-file=/usr/local/mysql-4.0.22/my.cnf &



I/O分散

MyISAMの場合

CREATE TABLE .... (...) DATA DIRECTORY = '/path/to/directory/MYD'  INDEX  DIRECTORY = '/path/to/directory/MYI'

InnoDB の場合1

[mysqld]
innodb_data_home_dir =
innodb_data_file_path=/path/to/file1:10M;/path/to/file2:50M

InnoDBの場合2

[mysqld]
innodb_file_per_table

OSでの対処の場合

  • データベースは単なるディレクトリなので、違うdiskをそのディレクトリにマウント
  • データベースのディレクトリをどこかに移動して、シンボリックリンクを張る



ログとリカバリ

log-bin (バイナリ更新ログ) が肝です。

# 3.22 までは、log-update (更新ログ) を使います。

log-bin 採取開始時のデータに対して、log-bin の内容(テキストのSQL文) を順に全て当てていけば、現在のデータになります。
もちろん、ログの途中まであてれば、その時までの状態になります。
roll forward リカバリですね。

どういう運用ができるかはあなたのアイデア次第。

  • max_binlog_size : 1つのバイナリ更新ログファイルの最大サイズ。これに達すると、自動でローテート
  • log-bin=名前 : バイナリ更新ログファイルの名前の指定。ディレクトリを含めることが出来る。 log-bin=/disk1/logfile とすると、/disk1/logfile.###### ファイルになる。


mysqlbinlog

バージョン 4.1 の mysqlbinlog には、バイナリ更新ログの切り出しに便利なオプションがあります。

  • --start-datetime=
  • --stop-datetime=
  • --start-position=
  • --stop-position=



日本語環境の設定

標準のキャラクターセットが日本語になっていないバイナリを使用するときは、設定をしておきます。

[mysqld]
default-character-set = ujis

[mysqldump]
default-character-set = ujis

[mysql]
default-character-set = ujis

なお、language = の指定は、日本語が扱える、扱えないには、全く関係ありません。設定しても無意味。
たんにエラーメッセージが日本語になるだけで、クエリやデータを日本語扱いにするという意味ではありません。
エラーメッセージが日本語になっても邪魔くさい(変な文だし、文字化けするかも)ので、通常は language は指定しません。

また、全てのアプリが my.cnf を読むわけではありません。勘違いしないように。
my.cnf を読むのは、原則、MySQL 付属のコマンドだけと思ってください。
それ以外は、アプリ側で読むようにコーディングする必要があります。
(この FAQ の「MySQL連携」を参照。)



my.cnf ファイルの読み込み順番

Unix系列の場合、
/etc/my.cnf → データディレクトリ/my.cnf → --defaults-extra-file=で指定されたファイル → ~/.my.cnf

なお、「データディレクトリ/my.cnf」 は、コンパイル時に指定されたデータディレクトリ固定です。

MS-Windows 系列の場合
%WINDIR%\my.ini → C:\my.cnf → --defaults-extra-file=で指定されたファイル



4.1以上の壁

MySQL 4.0 までは、3.X から 4.0 に upgrade しても、そのまんまなんの影響もなく古いデータを使えました。特にダンプしてリストアしなくても良かったし、ALTER TABLE も必要ありませんでした。

ところが、4.1 以上に upgrade するときは、我々日本語キャラクターセットを使う人間は、注意しなくてはならない点が複数存在します。
4.1 は、5.0pre だと思ってもいいぐらいの開きがあります。(4.0 と 4.1 を同じバージョン 4 だとは思わない方がいいという意味で。)


4.1 では何が変わったの?

  • CHAR(10) は 10 バイトから 10 文字に変わった。
  • データベース、テーブル、フィールド、それぞれ個別にキャラクターセットを指定できるようになった。
  • 文字コードの自動変換機能が追加された。
  • パスワードの保存形式が変わった。(長くなった)
  • mysqldump の標準キャラクターセットがどうコンパイルしても utf8 になる
  • sub query の追加
  • NDB クラスターの追加
  • GIS追加
  • utf8 キャラクターセットの追加
  • データベース名、テーブル名は、OS 上では utf8 コードに直されて保存されるように変わった(ディレクトリ名、ファイル名が、utf8のコードで書かれるようになったということ)。4.0 まではバイナリ列がそのままデータベース名(=ディレクトリ名)、テーブル名(=ファイル名)になっていた。
  • char() に、全てのバイト列が入らなくなった。例えば、ujis のフィールドには、EUC-JP に定義されるコード空間のバイトしか INSERT できない。全てを入れるパッチは http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib
  • timestamp 型の表示フォーマットが変わった。4.0 までは 「20050116214504」 であったが、4.1 では 「2005-01-16 21:45:50」。アプリの作り方に注意。
  • HEAP(MEMORY) テーブルのインデックスに、BTREE が加わった。4.0 までの HEAP テーブルは HASH のみ。(i int, INDEX USING BTREE (i)) TYPE=MEMORY;


CHAR の定義の違いによる弊害

これは 3.X, 4.0 から 4.1 に upgrade したときに遭遇する問題です。
3.X, 4.0 で char(10) と定義していたフィールドが、 4.1 に uprade した瞬間に、char(3) もしくは char(5) 扱いになってしまいます。
なぜか?

  • ujis は、最大で 3バイトを使用して 1文字を表現する。sjis は最大で 2バイトを使用して sjis 1文字を表現する。
  • 4.0 で CHAR(10) と定義した。これは 10 バイト。
  • 4.1 に upgrade したら、10バイトを、X文字にしなければならない。
  • そこで、ujis の場合は、10バイト -> 3(ujis)文字となる。


文字コードの自動変換機能による弊害

4.0 までは、キャラクターセットはサーバーだけが設定するものであり、クライアントがサーバーのキャラクターセットに自動的に合せて動作していました。

ところが

4.1 になってから、サーバー、クライアントがそれぞれのキャラクターセットで動作するようになりました。

例えば、

  • クライアントが sjis で動作
  • サーバーが ujis で動作

している場合、サーバーは、クライアントに対しては常に sjis のデータを送るようになります。

サーバーは ujis のデータを sjis に変換して、クライアントに送るのです。

これは一見便利です。

が、落とし穴があります。

  1. 変換できないキャラクターセットの組み合わせの場合
  2. 変換しきれない文字があった場合

こういう場合は、文字が ? になったり、期待外れの文字になったりします。

例えば、

  • クライアントが latin1 で動作
  • サーバーが sjis で動作

の場合、どうやって sjis を latin1 の文字コードに変換できるというのでしょう?
出来るわけがないので、sjis 文字はあえなく全て ? になってしまいます。
(え、「?」にしなけりゃいいのにって?
私もそう思います。変換できなければ「?」にせず、そのままのバイトのままにしておけば クライアントが latin1 でも問題が少なかったかもしれません。が、仕様が「?」に変換なので、なんとも。)

例えば、

UTF を使用してアプリを作っている方は経験されているでしょうが、 UTF の変換マップというのは統一が取れていません。
同じことが MySQL にもおきています。
MySQL が変換するコードと、あなたが使用している環境が考えるコードと文字の形の組み合わせが一致するとは限りません。

では、クライアントが latin1 で、サーバーが ujis,sjis の状況というのは、起きうるものなのでしょうか?

困ったことに、現状では簡単にこの状態が引き起こってしまいます。

あなたが使用している PHP は、自分でコンパイルしましたか?
あなたが使用している MySQL は、ご自身の手でコンパイルしましたか?
ほとんどの方が、他の誰かがコンパイルしたものを使用していると思います。
では、あなたが使用している PHP, MySQL のライブラリ(libmysql.dll, libmysqlclient)の標準キャラクターセットは何かご存じですか?
そう、ここが問題なのです。
日本人以外のデベロッパーが作ったバイナリは、ujis,sjis を標準のキャラクターセットにしているわけがありません。
事実 MySQL AB 配布のバイナリは、latin1 が標準です。
それらのバイナリを使って PHP の MySQL モジュールを動かせば(作成すれば)、クライアント(PHP)は latin1 で動作し、サーバーは ujis,sjis で動くことになるのです。こうして日本語文字は破壊されます。

これらの問題を避けるには、方法は2つ。

  • PHP(Ruby,Perl,C,...)のアプリの変更。サーバーに接続した後にすぐ、"SET NAMES キャラクターセット名" という SQL 文を実行する
  • PHP(Ruby,Perl,C,...)の MySQL モジュールの標準キャラクターセットを、自分が使うキャラクターセットにする。これはアプリの変更はない。しかし、libmysql.dll, libmysqlclient のコンパイルし直しが発生する。



mysqldump の仕様変更の弊害

mysqldump は、3.X, 4.0 までは、コンパイルするときに指定されたキャラクターセットを標準としていました。
4.1 からは、mysqldump はコンパイル時のキャラクターセットを無視して、utf8 を標準とします。(ひどい。普通、mysqldump のキャラクターセットは、mysqlコマンドとかのキャラクターセットと同じだと思って使うよなぁ...)

これは、4.1 の文字コード自動変換機能と組合わさって、最低な状況を起こしてしまいます。

サーバーが ujis, sjis で動いていたとしても、utf8 に変換して dump します。
utf8 はご存じの通り、到底整理されているコードとは言い難く、そのため、dump した内容が壊れる可能性が高いです。

これを避けるためには、mysqldump を実行するとき、必ず default-character-set オプションを指定すべきです。

個人的には以下が好みです。

[mysqldump]
default-character-set=binary
skip-opt
hex-blob

なお、コンパイル時のキャラクターセットを mysqldump が無視しなくなる、 mysqlコマンドと同じキャラクターセットと同じにするパッチは以下にあります。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib



パスワード保存形式の変更

4.1 からは、パスワードの長さが長くなりました。

しかし、3.X, 4.0 までのパスワードはそのまま使えます。 3.X, 4.0 までの mysql データベースの内容は、そのまま引き続き使用できます。

Password
4.0まで12de31820cbc0fce
4.1*59170D1E4A5E56267B6ED9C51ED62619FB817E6B

3.X, 4.0 から 4.1 に upgrade して、mysql_fix_privilege_tables を実行しても、4.0 までの時代に設定した短いパスワードは変更されません。上記例では '12de31820cbc0fce' のままです。
4.1 であたらしくパスワードを設定した場合、'*59170D1E4A5E56267B6ED9C51ED62619FB817E6B' の形式になります。

4.1 のクライアントは、長い方のパスワードでも短い方のパスワードでも認証可能です。

4.0 までのクライアント( libmysqlclient , libmysql.dll ) と 4.1 のサーバーは、長い方のパスワードを使用したら、必ず認証失敗になります。
(「Client does not support authentication protocol requested by server;」)

4.0 までのクライアントと 4.1 のサーバー間の認証が成功する条件は、

  • 保存されているパスワードが短い方の形式である場合
  • 4.1 サーバーを4.0までのパスワード形式のみで動作させている場合 に限ります。

4.1 サーバーを4.0までのパスワード形式で動作させるには

[mysqld]
old-passwords

を指定します。
これは 4.1 サーバーが生成するパスワードの形式を、4.0 までの短い方にするオプションです。



データベース名、テーブル名、フィールド名は、utf8 コードに直されて保存されるように変わったことの弊害

MySQL は、データベースをディレクトリ、テーブルを(基本的に)ファイルで表現します。フィールド名は .frm ファイルに記録されています。

4.0 まではバイナリ列がそのままデータベース名(=ディレクトリ名)、テーブル名(=ファイル名)、フィールド名になっていました。

ところが 4.1 からは、ディレクトリ名、ファイル名、フィールド名が、utf8のコードで書かれるようになったのです。
このために、4.0 までの MySQL で作成した日本語データベース名、テーブル名、フィールド名は、サーバーを 4.1 に upgrade したとたん、使えなくなります。

4.0 までに使用していた日本語のデータベース名、日本語のテーブル名、日本語のフィールド名を 4.1 に引き継ぐためには、

  • 4.0 までのデータを一度フルダンプして(ファイルのコピーじゃ駄目)、
  • 4.1 にバージョンアップしたあとに、
  • フルリストアする必要があります。



3.X,4.0 -> 4.1 以上の手順

  1. クライアントの upgrade Ruby, PHP, Perl など、C クライアントを 4.1 (以上)の libmysqlclient にリンクし直してインストール。

    なお、文字の自動変換機能による弊害が発生する可能性があるので、他のFAQを参考のこと。

  2. 念のため、mysqldump でバックアップ
  3. upgrade
    [mysqld]
    default-character-set = ujis
    old-passwords
    
    [mysqldump]
    default-character-set = ujis
    skip-opt
    
    [mysql]
    default-character-set = ujis

    old-passwords オプションは、4.1以上のサーバーの認証方法を、4.0 までの認証方法のままにするということ。

    mysqldump は、標準では全てのデータを utf8 に変換してしまうという極悪な仕様に変わったので、それを避けるために default-character-set を指定。

  4. 権限テーブル upgrade mysql_fix_privilege_tables もしくは mysql -f -uroot mysql < mysql_fix_privilege_tables.sql
  5. 全ての CHAR(), VARCHAR() を ALTER する。 4.1 以上では CHAR(10) は 10文字を意味するようになったため。 http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib 他のFAQも参照



4.1サーバーと4.0クライアント

[mysqld-4.1]
old-passwords

MySQL 4.1 サーバーを 4.0 までの認証で動かす。 こうすれば、3.X, 4.0の libmysqlclient(libmysql.dll) をリンクしているアプリケーションと 4.1 サーバーがきちんと接続できる。



version 4.1 以上の文字コード変換機能とうまくつきあうには?

MySQL version 4.1 から、utf8 が組み込まれたり、文字コードの自動変換が組み込まれたりと、けっこう文字周りがかわりました。 4.0までの MySQL とは感覚が変わるので、一応、こうした方がトラブルは少ないね、という経験上のものを書いておきます。

  • mysqldump には必ず --default-character-set= を指定すること。
  • MySQL サーバーとクライアントは、必ず同じキャラクターセットにしておくこと。
  • 4.1以上対応のアプリケーションには、必ず "SET NAMES キャラクターセット名" という SQL 文を、サーバーに接続した直後に実行すること。
  • データベース名、テーブル名、フィールド名には、マルチバイト文字は使用しないこと。
  • マルチバイトキャラクターセットと、latin1などのシングルバイトキャラクターセットを混在させないようにすること。
  • キャラクターセットはデータベース単位、テーブル単位、フィールド単位で指定できるが、フィールド単位でのキャラクターセットの指定はなるべく避けた方がよいだろう
  • 文字の自動変換機能を抑止する、--default-character-set=binary の使用が便利。
  • 既にコンパイル済みのバイナリを使うときは、そのバイナリが作成されたときに埋め込まれている、標準のキャラクターセットを知っておいた方がよい。
    • !!! MySQL AB のバイナリは latin1 が標準 !!!
  • 自分でコンパイルする場合は、binary キャラクターセットを標準に指定してコンパイルすれば、アプリの変更や設定の変更無しに、MySQL 4.0,3.23 対象のアプリが動く。
  • --init-connect='SET NAMES キャラクタセット名' は使わない。これはクライアントコマンドオプション --default-character-set= を無効にしてしまうから。
  • 4.1 の mysqldump には --hex-blob というオプションが追加されている。これは BLOB のバイナリデータを壊さずに mysqldump 可能になる。



4.1 にupgradeしたら文字が?になります / 4.1 にしたらクエリの結果がおかしいことがある

4.1 から文字の自動変換機能の追加、char() の仕様変更がありました。
なので、サーバーを 4.1 に upgrade すると、文字が ? になったり、文字が変になったり、クエリーの結果がおかしくなったりすることがあります。
4.1 に upgrade するならば、以下のようにします(アプリの変更をしないための方法)。

  1. まず、ソースから MySQL をビルドし直す。charset は binary にして。(後述、備考参照)

  2. ビルドしてできた libmysqlclient (windows の場合は libmysql.dll) を使用して、PHP, Perl, Ruby, などの MySQL モジュールをコンパイルし直す。

  3. サーバーを 4.1 にする前に、念のためバックアップを取っておく

  4. サーバーを 4.1 に upgrade する。
    /etc/my.cnf には
    [mysqld-4.1]
    old-passwords
     
    [mysqld]
    default-character-set=使用するキャラクターセット名
     
    [mysqldump]
    default-character-set=使用するキャラクターセット名
    skip-opt
    
    [mysql]
    default-character-set=使用するキャラクターセット名 

    を書いて、4.1 の サーバー起動

  5. mysql_fix_privilege_tables を実行して、mysql データベースの権限テーブルを upgrade する。
    Windows の場合は、
    mysql -f -uroot mysql < mysql_fix_privilege_tables.sql
    とする

  6. すべてのテーブルを ALTER する。
    char() の定義がおかしくなっているので、指定し直す。
    Unix の場合は、MyNA の http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib にあるシェルスクリプトを使ってもよい。

  7. また、mysql コマンド、mysqldump コマンド等は、必ず、default-character-set= を指定して使用しましょう。
    character-set はサーバーと同じにしましょう。

  • アプリのソースを変更して対応する方法:
    クライアントプログラムのソースに、'SET NAMES ' 文を追加する方法もあります。この場合は、1,2 の手順は必須ではなくなります。
    MySQL サーバーに接続した直後に、'SET NAMES クライアントのキャラクターセット名' という SQL 文を実行します。



  • 備考. ソースからのビルド:
    Unix なら ./configure --with-charset=binary にする。 Windows なら、
    include/my_config.h , include/config-win.h の
#define MYSQL_DEFAULT_CHARSET_NAME "latin1"

#define MYSQL_DEFAULT_CHARSET_NAME "binary"

に。

#define MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci"

#define MYSQL_DEFAULT_COLLATION_NAME "binary"

に。



いままでの説明の概念図

例えば、PHP のアプリケーションの場合、次のような階層構造になります。
(等幅フォントで見てね)

+---- PHPアプリ ---------+
| 例えば PHPMyAdmin など |
|                        |
| SET NAMES sjis;        | <- SET NAMES を実行するのはこの層
+------------------------+
   ↓↑
+------- PHP -------------+
| PHP エンジン            |
|  ↓↑                   |
| PHP の MySQL モジュール |
| mysql.so (UNIX)         |
| mysql.dll (Windows)     |
+-------------------------+
   ↓↑
+----------------------------+
| libmysqlclient.so (UNIX)   |      +---- MySQL サーバー ------+
| libmysql.dll (Windows)     |      |                          |
|標準キャラクターセット埋込  |  ←→ [文字コード変換ルーチン]  | <- こいつが曲者
|  例えば latin1 とする      |      |         ↓↑             |
+----------------------------+      | 内部の処理。結果を返す   |
  SET NAMES が実行されない時        |                          |
  埋込の標準charsetが使用される     | サーバー側のcharsetは    |
  これが曲者                        | 例えば sjis とすると     |
                                    | 「あ」は 0x82A0          |
                                    +--------------------------+
latin1 には 0x82A0 のコードがないので、「あ」は「?」に変換されてしまう。


char(10) が char(3) になるトリック

4.0 まで  : 1 2 3 4 5 6 7 8 9 10
内部バイト: ■■■■■■■■■■
4.1(ujis) : +----+-----+-----+
               1     2     3



結局、どうしろと?

  • MySQL-4.0, 3.X を現在運用しているひとは:
    原則、今のままキープですね。
    サーバーを上げるといくつか問題に遭遇します。
    充分な検証の結果、解決の目処がたってから、サーバーをバージョンアップしましょう。

  • これから新しく導入する人は:
    はじめから 4.1 以上でも OK。
    • ただし、4.0までのアプリの資産を流用したい場合は、old-passwords や default-character-set 、SET NAMES 文に注意しましょう。
    • これから作るアプリには必ず 「SET NAMES キャラクターセット名」 を接続直後に実行しましょう。



  • 4.1以上にバージョンアップするときに
    • アプリの変更をしたくない人は:
      • MySQL サーバー、クライアント、libmysqlclient (libmysql.dll) を使用する全ての クライアントをコンパイルし直す。
    • アプリの変更をしてもかまわない人は:
      • アプリのソースに、「SET NAMES クライアントのキャラクターセット名」 SQL 文を追加する。追加する位置は、MySQL サーバーに接続直後にする。
    • old-passwords を指定しておく




MySQL連携

エスケープ

クエリに与える文字列はエスケープしますが、基本的に MySQL 側が用意しているエスケープ関数を使うべきです。
キャラクターセットに従ってエスケープしてくれるからです。
SQLインジェクション対策のためにもエスケープは必要です。



C

エスケープ

  • mysql_escape_string()
  • mysql_real_escape_string()

を使う

my.cnf を読む

mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "/etc/my.cnf");
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "groupname");



PHP

エスケープ

  • mysql_escape_string()
  • mysql_real_escape_string()

を使う

my.cnf を読む

PHP version 4 の場合
読めない。[client] に書いても無駄。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib のパッチを当てる。

PHP version 5の場合
mysqli モジュールに、my.cnf を読む関数が用意されている。

mysqli_options(connection, MYSQLI_READ_DEFAULT_FILE, "/etc/my.cnf");
mysqli_options(connection, MYSQLI_READ_DEFAULT_GROUP, "php");

NULL の扱い

  • DBのデータが NULL の場合、PHP は "" を受け取る。NULL と空文字の区別が出来ない。



Ruby

エスケープ

escape_string() メソッドを使う

my.cnf を読む

my.options(Mysql::READ_DEFAULT_FILE, "/etc/my.cnf")
my.options(Mysql::READ_DEFAULT_GROUP, "ruby")

NULL の扱い

  • DBのデータが NULL の場合、Ruby は nil を受け取る。空文字ではない



Perl

エスケープ

DBI の quote() メソッドを使う。

my.cnf を読む

$dsn = "DBI:mysql:test;mysql_read_default_group=perl;mysql_read_default_file=/etc/my.cnf";



Java

Connector/J


MySQLインターナル

追記型ですか?

いいえ

vacuumありますか?

いいえ。

かわりに

MyISAM の場合は、OPTIMIZE TABLE 文か、REPAIR TABLE 文をします。

InnoDB の場合は、ALTER TABLE () TYPE=InnoDB を実行します。

たまにやればいいでしょう

トランザクション分離レベル

InnoDBBDBNDB
READ UNCOMMITTED--
READ COMMITTED
REPEATABLE READ--
SERIALIZABLE--

InnoDB の標準は REPEATABLE READ。

InnoDBの REPEATABLE READは、phantom read は起きない実装。

ロック

InnoDB行レベルロック
NDB行レベルロック
BDBページレベルロック
MyISAMテーブルレベルのロック
  • InnoDB、NDB の場合
    • 必ずテーブルに primary key を作ります。
    • LOCK TABLES は使わないように。
    • 明示的にロックしたい場合は、InnoDB では、SELECT .... FOR UPDATE、 SELECT ..... LOCK IN SHARE MODE を使う。
    • NDB の SELECT .... LOCK IN SHARE MODE、SELECT .... FOR UPDATE は将来対応予定

マルチバージョニング

InnoDB は マルチバージョニング を実装しています




MySQL開発

aclocal 手順

aclocal
autoheader
libtoolize --automake --force
automake
autoconf

cd innobase
aclocal
autoheader
libtoolize --automake --force
automake
autoconf

libtoolize --force を実行しないと libmysqlclient.so.14 じゃなくて libmysqlclient.14 になってしまう環境がある。

bitkeeper で取る

初めて取得するとき

bk clone bk://mysql.bkbits.net/mysql-5.0 mysql-5.0

更新するとき

bk pull

コンパイラー

  • 使用禁止
    gcc-2.96, egcs-1, gcc-2.8




MySQL ドキュメント

種類

manual.texiリファレンスマニュアル
include.texiリファレンスマニュアルと internals.texi が include。定数定義
reservedwords.texiリファレンスマニュアルが include。SQL予約語一覧
is.texiINFORMATION_SCHEMA マニュアル
internals.texi内部構造マニュアル
manual.cluster.texiクラスター

bitkeeper

初めて取得するとき

bk clone bk://mysql.bkbits.net/mysqldoc mysqldoc

更新するとき

bk pull

texi の加工

  • texi ファイル -[texi2html]-> HTML ファイル
  • texi ファイル -[texi2dvi]-> dvi ファイル -[dvi2ps]-> PS ファイル -[ps2pdf]-> PDF ファイル
  • texi ファイル -[texi2db]-> DocBook形式ファイル
  • manual.texi -> HTML への変換の場合
    • manual.html ファイルができる。
    • manual.texi , include.texi , reservedwords.texi を同じディレクトリに置く。
    • texi ファイルのあるディレクトリで、
      texi2html -Verbose -nomenu manual.texi
      とすると、manual.html が出来る。
      これは 1ファイル。
      もし、章ごとにファイルを分割したい場合は
      texi2html -nomenu -split=chapter manual.texi
  • texi2html はバージョンによってオプションが違うので注意。
  • manual.texi -> dvi への変換の場合
    • manual.dvi ファイルが出来る
    • manual.texi と、texinfo.tex ファイル (TeX用の、スタイル定義ファイル) を同じディレクトリに置く。
      • texinfo.tex ファイルは、ネット上を探す
    • texi ファイルのあるディレクトリで、
      texi2dvi manual.texi
      とすると manual.dvi ができる



  • texi2html は perl スクリプト。日本の書き方やマルチバイトの事を考えていないので、頑張って修正しましょう。
  • texinfo.tex も日本語を考慮していないので、がんばって修正する。




その他

ライセンスはどうなっていますか?商用利用ではどうすべきですか?

MySQL のライセンスは単純です。 GPL か コマーシャルライセンスか。

GPL では具合が悪い、GPL では条件に合わない、GPL に納得できない場合に、コマーシャルライセンスを購入すればOK。

それは商用利用するかどうかには関係がありません。

GPL については http://www.gnu.org/home.ja.html をご覧ください。

2000〜2001年ごろに、「GPLかコマーシャルライセンスか」への移行がありましたが、それ以前のライセンス(FPL)は 別物でした。
前のライセンス条項(FPL)は現在は適用されていません(無くなっています)。
古い情報で判断しないほうがお得です。



バグ報告、質問をする場合

以下を必ず情報に含める。

  • mysqlbug の出力内容
  • my.cnf の内容
  • テーブルの構造
  • 問題となるデータ, SQL 文
  • 得られる結果、エラーメッセージ、.err ファイルの出力
  • なにを、どうした時に、なにが起きるか、を書く

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS