realpath()
の呼び出しの機能が完全でないシステムではテーブルのシンボリックリンクを行わないでください。(少なくとも、Linux
と Solaris では
realpath()
がサポートされています)。SHOW
VARIABLES LIKE
'have_symlink'
ステートメントを発行することで、ユーザーのシステムがシンボリックリンクをサポートするか確認できます。
MySQL 4.0 では MyISAM
テーブルでのみシンボリックリンクが完全サポートされています。これ以外のテーブル型で上記のコマンドを使用すると、予想外の問題の発生の恐れがあります。
MySQL 4.0 での MyISAM
テーブルのシンボリックリンクの処理は次のように機能します。
データディレクトリには常にテーブル定義ファイル
(.frm
)
、データファイル
(.MYD
)
およびインデックスファイル
(.MYI
)
がある。データファイルとインデックスファイルは、別の場所に移動し、データディレクトリ内でシンボリックリンクによって置換できる。定義ファイルはこれができない。
データファイルとインデックスファイルは、それぞれ独立して別のディレクトリにシンボリックリンクを作成できる。
シンボリックリンクは、オペレーティングシステムレベル
(mysqld が実行されていない場合)、または SQL
で CREATE TABLE
に
DATA DIRECTORY
および INDEX
DIRECTORY
オプションを指定して実行できる。詳しくは項8.1.17. 「CREATE TABLE
構文」を参照してください。あるいは、シンボリックリンクは
ln -s
を使用してコマンドラインから手動で行えますが、これは
mysqld
が作動していない場合にかぎります。
MySQL 5.1.24
以降では、DATA
DIRECTORY
オプションまたは
INDEX DIRECTORY
オプション、あるいはその両方で使用されるパスに
MySQL data
ディレクトリが含まれない場合があります。(Bug#32167)
myisamchk
は、データファイルやインデックスファイルのシンボリックリンクを置き換えない。myisamchk
はリンクで指し示されているファイルに直接作用する。一時ファイルはすべてデータファイルやインデックスファイルが配置されているのと同じディレクトリに作成されます。同様のことが
ALTER
TABLE
、OPTIMIZE
TABLE
、そして
REPAIR
TABLE
ステートメントでいえます。
シンボリックリンクを使用しているテーブルを削除すると、シンボリックリンクとシンボリックリンクが指しているファイルの両方が削除される。このため、root
として mysqld
を実行すべきではなく、また、MySQL
データベースディレクトリへの書き込みアクセスをユーザーに許可するべきでもない。
ALTER TABLE ... RENAME
または RENAME
TABLE
を使用してテーブルの名前を変更し、テーブルを別のデータベースに移動しない場合、データベースディレクトリのシンボリックリンクの名前が新しい名前に変更され、データファイルとインデックスファイルもそれに従って名前が変更される。
ALTER TABLE ... RENAME
または RENAME
TABLE
を使用してテーブルを別のデータベースに移動すると、テーブルが別のデータベースディレクトリに移動される。テーブルの名前を変更した場合、新しいデータベースディレクトリのシンボリックリンクの名前が新しい名前に変更され、データファイルとインデックスファイルもそれに従って名前が変更される。
シンボリックリンクを使用していない場合は、mysqld
に
--skip-symbolic-links
オプションを指定して使用し、確実にだれもデータディレクトリの外でファイルの削除や名前の変更を行う
mysqld
を使用できないようにする。
サポートされていないテーブルシンボリックリンクオペレーション
ALTER TABLE
では DATA DIRECTORY
と INDEX DIRECTORY
テーブルオプションが無視される。
BACKUP
TABLE
と
RESTORE
TABLE
ではシンボリックリンクが考慮されない。
.frm
ファイルはシンボリックリンクにすることがまったくできない
(前述のように、データファイルとインデックスファイルのみシンボリックリンクにできる)。これを実行した場合
(同義語作成など)、正しい結果が得られなくなる。MySQL
データディレクトリにデータベース
db1
があり、このデータベースにはテーブル
tbl1
が、db1
ディレクトリには
tbl1
を指すシンボリックリンク
tbl2
があるとする。
shell>cd
shell>/path/to/datadir
/db1ln -s tbl1.frm tbl2.frm
shell>ln -s tbl1.MYD tbl2.MYD
shell>ln -s tbl1.MYI tbl2.MYI
あるスレッドで
db1.tbl1
が読み取られ、別のスレッドで
db1.tbl2
が更新されると、問題が発生する。
クエリキャッシュが「欺かれ」(tbl1
が更新されていないと判断され、最新でない結果が返される)。
tbl2
に対する
ALTER
ステートメントもエラーになる。