MariaDB / Ubuntu・Windowsでデータ保存先を変更する方法

MariaDBのデータ保存先は、サーバーを正常停止してデータディレクトリ全体をコピーし、サーバー設定のdatadirとアクセス権を変更することで移動できます。設定だけでは既存データは移動せず、稼働中の通常のファイルコピーは不整合を招くおそれがあるため、独立したバックアップと書き込みを止める作業時間を先に確保します。

対象範囲と事前準備

データディレクトリは、データベースとストレージエンジンの管理ファイルを保存するフォルダーです。現在の場所はサーバー変数datadirで確認できます。この手順は同じコンピューター・同じMariaDBバージョンの単一インスタンスを対象とします。バージョン更新、異なるOSへの移行、レプリケーション、Galeraクラスター、コンテナーボリュームの変更には別の移行計画が必要です。

管理権限のあるMariaDBアカウントで接続し、次のSQLの結果を記録します。Ubuntuの一般的なソケット認証構成ならsudo mariadb、Windowsならインストール先のbin\mariadb.exe -u root -pで接続できます。認証方式が異なる場合は、そのインスタンスの管理用アカウントを使います。

SELECT VERSION(), @@datadir, @@port;
SHOW VARIABLES WHERE Variable_name IN (
  'log_error', 'log_bin_basename', 'innodb_data_home_dir',
  'innodb_log_group_home_dir', 'aria_log_dir_path'
);
  • 独立したバックアップ:別の場所に復元可能なバックアップを用意し、運用データでは復元できることも確認します。元フォルダーの保持だけでバックアップの代わりにはしません。MariaDBのバックアップ概要で論理・物理バックアップの違いを確認できます。
  • パスと空き容量:SQLで確認した元のパスと、十分な空き容量のある移動先を記録します。以下の/var/lib/mysql/とWindowsのバージョン11.4は例なので、実際の値に置き換えます。
  • 外部ファイル:絶対パスのバイナリログ、外部テーブルスペース、暗号鍵、シンボリックリンク、Windowsの再解析ポイントは個別に確認します。datadirを変更しても、それらすべてが移動するわけではありません。
  • 作業時間:アプリ、バッチ、自動再起動を行う監視処理を停止します。検証が完了するまで外部からの書き込みを再開しません。

既存インスタンスを移動するときは、新しい場所でmariadb-install-dbを実行しません。このツールは新規初期化のためのものであり、既存データ全体のコピーとは異なります。

Ubuntuでデータディレクトリを移動する

実際の設定とマウント先を調べる

Ubuntu 24.04の一般的なパッケージ構成では/etc/mysql/mariadb.conf.d/50-server.cnfにサーバー設定がありますが、導入方法によって異なります。systemctl catで起動引数と追加設定を、mariadbd --print-defaultsでファイルから読み込む設定を確認します。機密情報が含まれる場合は出力をそのまま公開しないでください。

sudo systemctl cat mariadb
sudo mariadbd --print-defaults
sudo du -sh /var/lib/mysql
df -h /data
findmnt -T /data

/dataがなければ先に対象ディスクを準備してマウントします。dfとfindmntが意図したファイルシステムを示すことを確認します。MariaDBのオプションファイルでは、後から読む設定や起動引数が先の値を上書きし得ることが説明されています。サービスが実際に読むファイルを特定し、バックアップしてから編集します。

正常停止して全データをコピーする

例ではサービス名をmariadb、OSアカウントをmysql、移動先を/data/mariadb/とします。必要なら作業停止前にrsyncを導入します。停止後はinactiveであることとサーバープロセスの終了を確認します。非稼働時のis-activeが0以外を返すことはあります。正常終了に失敗した場合や、別のインスタンスが同じディレクトリを使っている場合はコピーしません。

sudo systemctl stop mariadb
sudo systemctl is-active mariadb
sudo systemctl status mariadb --no-pager

移動先は空である必要があります。他のインスタンスのファイルと混ぜないでください。次の命令はフォルダーを作成して所有者と権限を設定し、隠しファイルやエンジン管理ファイルも含めてコピーします。-aは所有者・権限などを保存します。cp -aでも属性を保存できますが、単純なコピーが常に同じ結果になるとは限りません。

sudo mkdir -p /data/mariadb
sudo chown mysql:mysql /data/mariadb
sudo chmod 750 /data/mariadb
sudo rsync -aHAX --numeric-ids /var/lib/mysql/ /data/mariadb/
sudo rsync -aHAXnci --numeric-ids /var/lib/mysql/ /data/mariadb/

最初のrsyncが実コピー、2番目がチェックサムによる比較だけを行うドライランです。両方の終了コードが0であることを確認し、2番目に差分が出たら原因を解消します。元パス末尾の/はフォルダーの中身をコピーする指定です。ACL(アクセス制御リスト)や拡張属性を保存できない場合も、エラーを無視せずファイルシステムとオプションを見直します。

datadirとセキュリティ設定を変更する

サービスが読み込むサーバー用オプショングループの既存のdatadirを変更します。同じ設定を複数箇所に追加して競合させないようにします。

[mysqld]
datadir=/data/mariadb

所有者が正しくてもセキュリティポリシーで拒否されることがあります。AppArmorはLinuxでプログラムのファイルアクセスを制限する仕組みです。有効なプロファイルとカーネルログで、MariaDB実行ファイルに関するDENIEDを調べます。

sudo aa-status
sudo journalctl -k -b --no-pager

実際の強制適用プロファイルが元パスだけを許可している場合、そのローカル規則や有効なエイリアスを修正します。MariaDBの起動失敗の説明には、/etc/apparmor.d/tunables/aliasへ次の別名を追加する方法があります。対象プロファイルがこのファイルを利用することを確認してバックアップし、編集後はsudo systemctl reload apparmorの成功を確認します。配布元やパッケージで構成が異なるため、この1行をすべての環境に必須とは考えません。

alias /var/lib/mysql/ -> /data/mariadb/,

systemctl cat mariadbではReadWritePathsやProtectSystemも確認します。別ディスクならsudo systemctl edit mariadbで次の依存関係を追加できます。ディスクのフォーマットや/etc/fstabの永続マウント設定を代行するものではありません。systemdのRequiresMountsForを参照してください。

[Unit]
RequiresMountsFor=/data/mariadb

既定のサービス保護で制限される可能性があるため、この例では/homeや/rootを使いません。書き込み許可の追加が必要なら必要なパスだけを許可し、保護機構全体を無効化しないようにします。MariaDBのsystemd資料で制限の内容を確認できます。

起動して適用先を確認する

ユニット設定を変更した場合は再読み込みしてからMariaDBを起動します。SQLの結果が/data/mariadb/であることを確認します。データ保存先の移動だけでクライアントのソケットパスも変更する必要はありません。

sudo systemctl daemon-reload
sudo systemctl start mariadb
sudo systemctl status mariadb --no-pager
sudo mariadb -e "SELECT @@datadir;"

起動できない、または元パスが表示される場合はアプリを接続せず、後述の診断へ進みます。

Windowsでデータディレクトリを移動する

サービス名・アカウント・my.iniを確認する

管理者PowerShellで次を実行し、実際のサービス名、ログオンアカウントと実行引数を確認します。例のMariaDBとバージョン11.4は全箇所で置き換えます。Windows MSIの導入資料にある既定名と登録された名前が同じとは限りません。

Get-CimInstance Win32_Service |
  Where-Object { $_.PathName -match 'mariadbd|mysqld' } |
  Select-Object Name, State, StartName, PathName
sc.exe qc MariaDB

起動引数の--defaults-fileが指すmy.iniを確認します。指定がなければその実行ファイルの--help --verboseで検索先を調べ、実際のファイルと照合します。エクスプローラーの表示 → 表示 → ファイル名拡張子を有効にし、my.ini.txtと誤保存しないようにします。SQLの@@datadirを記録し、有効な設定ファイルを別の場所へバックアップします。

停止してファイルをコピーする

例ではC:\Program Files\MariaDB 11.4\dataから新しい空のC:\MariaDBへ移動します。サービスがStoppedになってからコピーします。既存の移動先がある場合は中身を調べ、別データと混ぜないようにします。

Stop-Service -Name 'MariaDB'
Get-Service -Name 'MariaDB'
New-Item -ItemType Directory -Path 'C:\MariaDB'
robocopy "C:\Program Files\MariaDB 11.4\data" "C:\MariaDB" /E /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ /XF my.ini
$copyExit = $LASTEXITCODE
if ($copyExit -ge 8) { throw "Robocopy failed: $copyExit" }

この命令はサブフォルダーを含めてコピーし、既存の場所で使い続けるmy.iniを除外します。/COPY:DATはデータ・属性・時刻をコピーし、新フォルダーの権限は次に別途設定します。/XJはジャンクションを除外するので、外部の内容は個別対応が必要です。MicrosoftのRobocopy資料では終了コード8以上は失敗です。0~7でも要約の失敗、不一致、想定外の追加ファイルを確認します。

実行アカウントの権限とdatadirを変更する

services.mscで対象サービスのプロパティ → ログオンを調べます。新フォルダーのプロパティ → セキュリティ → 編集 → 追加で実際のサービスアカウントに変更権限を付与します。SQLユーザーrootとWindowsサービスの実行アカウントは別物です。Everyoneにフルコントロールを与える必要はありません。

仮想アカウントがNT SERVICE\MariaDBであることを確認した場合にだけ、次の例を使えます。サービス名やローカル・ドメインユーザーが異なる場合は実際のアカウントに置き換えます。(OI)(CI)Mは下位ファイル・フォルダーへ継承される変更権限です。Microsoftのicacls資料も参照できます。

icacls "C:\MariaDB" /grant "NT SERVICE\MariaDB:(OI)(CI)M"
icacls "C:\MariaDB"

元のmy.iniのサーバー用グループで次を変更し、同じ場所に保存します。スラッシュ表記で逆スラッシュのエスケープ問題を避けられます。--defaults-fileは元のファイルを指したままにし、設定ファイルそのものの移動を同時に行いません。

[mysqld]
datadir=C:/MariaDB

サービスを開始して接続する

開始後にクライアントで接続します。パスワードは-pの後に書かず、入力を求められてから入力します。

Start-Service -Name 'MariaDB'
Get-Service -Name 'MariaDB'
& 'C:\Program Files\MariaDB 11.4\bin\mariadb.exe' -u root -p

SELECT @@datadir;を実行し、C:\MariaDB\または同等のスラッシュ表記の新パスを確認します。Runningだけでは正しいデータが開いたとは判断できません。

既存データと書き込み・再起動後の保持を検証する

既存データベース、代表テーブルの行数や既知の値を作業前の記録と比較します。次に、以下の試験用名が未使用であることを確認して管理接続で実行します。既に存在する場合は一意の名前にすべての文を統一して変更します。業務用データベースに試験オブジェクトを作らないでください。

SELECT @@datadir;
CREATE DATABASE datadir_move_check_13862;
CREATE TABLE datadir_move_check_13862.probe (id INT PRIMARY KEY);
INSERT INTO datadir_move_check_13862.probe VALUES (1);
SELECT * FROM datadir_move_check_13862.probe;

最後の問い合わせでidが1の行が返るはずです。外部書き込みは止めたまま、もう一度正常にサービスを再起動し、再接続して次を実行します。

SELECT @@datadir;
SELECT * FROM datadir_move_check_13862.probe;

新パスと行1が維持されていれば、新しい保存先での書き込みと再起動後の読み取りを確認できたことになります。次の文で試験用データベースだけを削除し、アプリの接続と読み書きを確認してから運用を再開します。フォルダーの生成だけでInnoDB全体の移行成功とは判断しません。

DROP DATABASE datadir_move_check_13862;

検証とバックアップの保存要件を満たすまで元ディレクトリは残します。バックアップ処理と監視の対象にも新パスを反映します。

起動失敗や元パスが表示される場合の診断

  • 元のdatadirになる:別の設定ファイルを編集していないか、後の設定や起動引数が上書きしていないか、別ポート・ソケットのインスタンスへ接続していないか確認します。
  • Permission denied・試験ファイルを作れない:実行アカウント、親フォルダーを通過する権限、新しい場所の書き込み権限を確認します。UbuntuではAppArmor・systemd、Windowsでは実際のアカウントのACLも調べます。
  • システムテーブルやDBがない:余分なフォルダー階層やコピー漏れを確認します。対策として初期化したりibdata1やログを削除したりしないでください。
  • OS再起動後だけ失敗する:永続マウント、起動順序とドライブ文字の安定性を確認します。

Ubuntuでは次のログの時刻と拒否されたパスを調べます。nameiで親ディレクトリごとの権限も確認できます。

sudo journalctl -u mariadb -b -n 100 --no-pager
sudo journalctl -k -b --no-pager
namei -l /data/mariadb
sudo systemctl cat mariadb

Windowsでは設定のlog_error先、新旧のデータフォルダーの.errとイベントビューアーを確認します。1067などの一般的なサービスエラーだけで原因を決めません。MariaDB起動診断でエラー別の確認事項を参照できます。

元の場所に戻せる条件と手順

新しい場所で外部の書き込みをまだ許可していない場合は、MariaDBを停止して終了を確認し、バックアップした設定か元のdatadirを復元します。この移動で追加したAppArmorの別名・systemdのdrop-inだけを戻し、既存の別設定は保持します。ユニットを変更した場合はdaemon-reload後に起動し、元パスとデータを確認します。

新しい場所で実際の書き込みが発生した場合、残した元フォルダーは最新ではありません。単に元へ向けるとその後の変更を失うおそれがあります。書き込みを再停止して最新データをバックアップし、停止中の逆移行や復旧計画を立てます。2つのディレクトリのファイルを混ぜたり、両方を同時に起動したりしてはいけません。