このトラブルの原因として最も多いのが、SELinuxのファイルコンテキスト(ラベル)の設定漏れです。RHEL 9・Rocky Linux 9 など SELinux が Enforcing モードで動作している環境では、新しいパスに正しいラベルがなければ mysqld はアクセスを拒否されて起動できません。単純にファイルをコピーするだけでは不十分なのです。
この記事では、Linux サーバー上の MySQL 8.0 を対象に、datadir を別ディスクへ移設する全手順を解説します。動作確認環境は Rocky Linux 9.4(MySQL 8.0.36)です。
この記事のポイント
・datadir 変更後に SELinux ラベルを付け直さないと mysqld は起動しない
・semanage fcontext -a -t mysqld_db_t でラベル登録、restorecon -Rv で実際に適用する
・データコピーは rsync -av /var/lib/mysql/ /data/mysql/ で実施(末尾スラッシュ必須)
・作業前に mysqldump で全データのバックアップを取ってから進めること
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜdatadirを別ディスクに移設するのか
MySQL のデータファイル(テーブルデータ・バイナリログ・InnoDB ログ)はデフォルトで/var/lib/mysql に格納されます。初期構築時には問題なくても、運用を続けると次のような事情で datadir の移設が必要になります。・OS ディスクの残量逼迫:データが増えてシステム領域を圧迫し、他のプロセスに影響が出る
・I/O 分離によるパフォーマンス向上:DB 専用の高速ディスクに切り出してスループットを改善する
・バックアップ分離:LVM スナップショットで DB ボリュームだけを素早く保護できる
SELinux が無効な環境であれば設定変更だけで済みますが、現場のサーバーは多くの場合 Enforcing モードで稼働しています。「設定を変えただけなのに起動しない」という失敗の大半は SELinux ラベルの付け直しを忘れたことが原因です。この記事では SELinux が有効な状態での手順を前提に解説します。
移設の全体像と事前確認
移設作業の流れは次の通りです。・手順1:現在の datadir とディスク使用量を確認する
・手順2:新ディスクをパーティション作成・フォーマットしてマウントする
・手順3:MySQL を停止してデータを新ディスクへコピーする
・手順4:/etc/my.cnf の datadir を変更する
・手順5:SELinux のファイルコンテキストを付け直す
・手順6:MySQL を起動して動作確認する
作業前にまず現状を把握しておきます。
# 現在の datadir を確認する mysql -u root -p -e "SELECT @@datadir;" # 出力例 +------------------+ | @@datadir | +------------------+ | /var/lib/mysql/ | +------------------+ # MySQL データの使用量を確認する(本番サーバー db01.example.internal での実測値) du -sh /var/lib/mysql 4.8G /var/lib/mysql # SELinux の状態を確認する getenforce Enforcing
getenforce が Enforcing を返す場合は、後述の SELinux ラベル再設定が必須です。また、移設作業前に必ず mysqldump で全データベースのバックアップを取得してください。万一の際に復旧できる状態を作ってから進めることがプロとしての基本です。
# 全データベースをバックアップ(移設前に必ず実施) mysqldump -u root -p --all-databases --single-transaction \ > /backup/mysql_full_$(date +%Y%m%d).sql # バックアップファイルのサイズを確認する ls -lh /backup/mysql_full_*.sql
新しいディスクのマウントと準備
1. パーティション作成とフォーマット
追加した新しいディスク(ここでは/dev/sdb)にパーティションを作成し、XFS でフォーマットします。# 追加されたディスクを確認する lsblk # 出力例 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 50G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 49G 0 part / sdb 8:16 0 200G 0 disk # parted でパーティションを作成する parted /dev/sdb --script mklabel gpt parted /dev/sdb --script mkpart primary xfs 0% 100% # XFS でフォーマットする mkfs.xfs /dev/sdb1
2. マウントポイントの作成と /etc/fstab 登録
新しいディスクをマウントするディレクトリを作成し、/etc/fstab に登録して再起動後も自動マウントされるようにします。# マウントポイントを作成する mkdir -p /data/mysql # UUID を確認する(fstab には UUID で記載する) blkid /dev/sdb1 # 出力例 /dev/sdb1: UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="xfs" ... # /etc/fstab を vi で開き、以下の1行を追加する # UUID は blkid で取得した実際の値に置き換えること UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 /data/mysql xfs defaults 0 0 # fstab の設定でマウントを実行する mount -a # マウントされたことを確認する df -h /data/mysql # 出力例 Filesystem Size Used Avail Use% Mounted on /dev/sdb1 200G 1.5G 199G 1% /data/mysql
/etc/fstab の書き方や mount コマンドの詳細については、mount コマンドの使い方も参考にしてください。3. MySQLを停止してデータをコピーする
MySQL サービスを停止してから、rsync でデータを新しいディスクへコピーします。稼働中のまま rsync するとデータが壊れる可能性があるため、必ずサービスを止めてから実施してください。# MySQL を停止する systemctl stop mysqld # 停止を確認する systemctl status mysqld | grep Active Active: inactive (dead) since Thu 2026-08-21 10:00:00 JST; 3s ago # データを新しいディスクへコピーする(ソース末尾のスラッシュに注意) rsync -av /var/lib/mysql/ /data/mysql/ # コピー完了後の所有者・パーミッション確認 ls -ld /data/mysql # 出力例 drwxr-x--x. 13 mysql mysql 4096 Aug 21 10:05 /data/mysql # もし所有者がずれていた場合は修正する chown -R mysql:mysql /data/mysql chmod 750 /data/mysql
rsync のソース末尾スラッシュ(/var/lib/mysql/)を忘れると、/data/mysql/mysql/ という二重ディレクトリになってしまいます。必ず末尾スラッシュをつけてください。datadir変更とSELinuxラベルの再設定
1. /etc/my.cnf の datadir を変更する
MySQL の設定ファイル/etc/my.cnf を開いて、datadir の値を新しいパスに変更します。# 現在の datadir 設定を確認する grep -i datadir /etc/my.cnf /etc/my.cnf.d/*.cnf 2>/dev/null # 出力例 /etc/my.cnf:datadir=/var/lib/mysql # vi で /etc/my.cnf を開き、datadir の行を書き換える vi /etc/my.cnf # 変更前 datadir=/var/lib/mysql # 変更後 datadir=/data/mysql # 変更後に設定を確認する grep -i datadir /etc/my.cnf datadir=/data/mysql
2. SELinuxのファイルコンテキストを付け直す
ここが移設作業のポイントです。SELinux は
/var/lib/mysql に mysqld_db_t というラベルを付けて、mysqld プロセスからのアクセスを許可しています。rsync でコピーしたファイルは default_t などのラベルが付くため、mysqld から見るとアクセス拒否になります。まず元のディレクトリと新しいディレクトリのラベルを比較します。
# 元のディレクトリの SELinux コンテキストを確認する ls -Z /var/lib/mysql/ | head -4 # 出力例(mysqld_db_t ラベルが付いている) system_u:object_r:mysqld_db_t:s0 auto.cnf system_u:object_r:mysqld_db_t:s0 binlog.000001 system_u:object_r:mysqld_db_t:s0 ib_buffer_pool system_u:object_r:mysqld_db_t:s0 ibdata1 # 新しいディレクトリの SELinux コンテキストを確認する ls -Z /data/mysql/ | head -4 # 出力例(default_t になっている - これが起動失敗の原因) unconfined_u:object_r:default_t:s0 auto.cnf unconfined_u:object_r:default_t:s0 binlog.000001 unconfined_u:object_r:default_t:s0 ib_buffer_pool unconfined_u:object_r:default_t:s0 ibdata1
default_t になっているファイルには mysqld がアクセスできません。semanage fcontext で新しいパスに mysqld_db_t ラベルを登録し、restorecon で実際に適用します。# semanage fcontext で /data/mysql 配下にラベルを登録する # (policycoreutils-python-utils パッケージが必要) semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" # restorecon でラベルを実際に適用する restorecon -Rv /data/mysql # 出力例 Relabeled /data/mysql from unconfined_u:object_r:default_t:s0 to system_u:object_r:mysqld_db_t:s0 Relabeled /data/mysql/auto.cnf from unconfined_u:object_r:default_t:s0 to system_u:object_r:mysqld_db_t:s0 Relabeled /data/mysql/ibdata1 from unconfined_u:object_r:default_t:s0 to system_u:object_r:mysqld_db_t:s0 ... # ラベルが正しく付いたか確認する ls -Z /data/mysql/ | head -4 # 出力例(mysqld_db_t に変わっていれば完了) system_u:object_r:mysqld_db_t:s0 auto.cnf system_u:object_r:mysqld_db_t:s0 binlog.000001 system_u:object_r:mysqld_db_t:s0 ibdata1
semanage コマンドが見つからない場合は policycoreutils-python-utils をインストールしてください。dnf install -y policycoreutils-python-utils
3. MySQLを起動して動作確認する
SELinux のラベルを付け直したら MySQL を起動し、datadir が変わったことを確認します。# MySQL を起動する systemctl start mysqld # 起動状態を確認する systemctl status mysqld # 出力例(active (running) であれば成功) * mysqld.service - MySQL 8.0 database server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; preset: disabled) Active: active (running) since Thu 2026-08-21 10:20:00 JST; 5s ago Main PID: 12346 (mysqld) # datadir が新しいパスになったことを確認する mysql -u root -p -e "SELECT @@datadir;" # 出力例 +--------------+ | @@datadir | +--------------+ | /data/mysql/ | +--------------+ # 既存のデータベースが見えることを確認する mysql -u root -p -e "SHOW DATABASES;" # 出力例 +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | myapp_db | +--------------------+
/data/mysql/ になり、既存のデータベースが見えていれば移設完了です。トラブルシュート・エラー対処
「Can't open the mysql.plugin table」が出た場合
データのコピーが不完全な可能性があります。元のディレクトリとコピー先のファイル数を比較してください。# 元のディレクトリと新しいディレクトリのファイル数を比較する find /var/lib/mysql -type f | wc -l find /data/mysql -type f | wc -l # 数が一致しない場合は MySQL を停止して再度 rsync する systemctl stop mysqld rsync -av --delete /var/lib/mysql/ /data/mysql/
ジャーナルに「Permission denied」が記録されて起動しない場合
SELinux の AVC 拒否が原因の可能性があります。ausearch で監査ログを確認してください。# SELinux の AVC 拒否ログを確認する ausearch -m avc -ts recent # 出力例(mysqld_t が default_t にアクセス拒否されている) type=AVC msg=audit(1724209200.123:456): avc: denied { read } for pid=12346 comm="mysqld" name="ibdata1" dev="sdb1" ino=12345 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0 # AVC 拒否が出た場合は semanage と restorecon を再実行する semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" restorecon -Rv /data/mysql systemctl start mysqld
ソケットファイルに関するエラーが出る場合
MySQL のsocket オプションが旧 datadir のパスを指している場合があります。既存アプリケーションとの互換性を維持するため、シンボリックリンクで対応する方法もあります。# socket の設定を確認する grep -i socket /etc/my.cnf # 旧パスへのシンボリックリンクを作成する場合 ln -s /data/mysql/mysql.sock /var/lib/mysql/mysql.sock
本記事のまとめ
MySQL の datadir を別ディスクへ移設する手順をまとめます。| やること | 主なコマンド・操作 |
|---|---|
| 事前確認 | mysql -e "SELECT @@datadir;" / getenforce |
| バックアップ | mysqldump --all-databases --single-transaction |
| 新ディスク準備 | parted / mkfs.xfs / /etc/fstab に UUID で追記 |
| データコピー | systemctl stop mysqld → rsync -av /var/lib/mysql/ /data/mysql/ |
| datadir 変更 | /etc/my.cnf の datadir=/data/mysql に書き換え |
| SELinux ラベル付け | semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" → restorecon -Rv /data/mysql |
| 起動確認 | systemctl start mysqld → mysql -e "SELECT @@datadir;" |
semanage fcontext + restorecon)を忘れると mysqld は起動できません。この2つのコマンドをセットで実行するのが、datadir 移設成功の鍵です。Linux サーバー上の MySQL 運用では、datadir 移設のほかにもレプリケーション設定やバイナリログ管理など、体系的に覚えるべき実務ノウハウが数多くあります。セミナーでは実機を使って MySQL 運用を含む Linux サーバー構築・運用スキルを習得できます。
無料の「Linuxサーバー構築入門マニュアル(図解60ページ)」をプレゼントしています。
コマンドを「なんとなく打つ」段階から卒業したい方は、ぜひ受け取ってみてください。
無料マニュアルを受け取る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:mysqlbinlogでMySQLをポイントインタイムリカバリする方法|誤操作直前まで戻す復旧手順
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます