MySQLのデータディレクトリを別ディスクへ移設する手順|datadir変更とSELinuxラベルの再設定

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtipsデーターベース管理 > MySQLのデータディレクトリを別ディスクへ移設する手順|datadir変更とSELinuxラベルの再設定
「MySQLのデータディレクトリを別ディスクへ移設したら、起動しなくなった」

このトラブルの原因として最も多いのが、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 で全データのバックアップを取ってから進めること


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜ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

getenforceEnforcing を返す場合は、後述の 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/mysqlmysqld_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 | +--------------------+

datadir が /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 mysqldrsync -av /var/lib/mysql/ /data/mysql/
datadir 変更 /etc/my.cnfdatadir=/data/mysql に書き換え
SELinux ラベル付け semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?"restorecon -Rv /data/mysql
起動確認 systemctl start mysqldmysql -e "SELECT @@datadir;"
SELinux のラベル再設定(semanage fcontext + restorecon)を忘れると mysqld は起動できません。この2つのコマンドをセットで実行するのが、datadir 移設成功の鍵です。

Linux サーバー上の MySQL 運用では、datadir 移設のほかにもレプリケーション設定やバイナリログ管理など、体系的に覚えるべき実務ノウハウが数多くあります。セミナーでは実機を使って MySQL 運用を含む Linux サーバー構築・運用スキルを習得できます
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、
無料の「Linuxサーバー構築入門マニュアル(図解60ページ)」をプレゼントしています。
コマンドを「なんとなく打つ」段階から卒業したい方は、ぜひ受け取ってみてください。
無料マニュアルを受け取る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。