DBを複製する方法　ダンプ/リストア

Ubuntu コンテナ DB　複製する方法　ダンプ/リストア

# はじめに
開発している中で「誰かとローカルDBの中身を合わせたい」もしくは「所有している2台のPCでローカルDBを移行したい」と思うことがあると思います。
今回実際に実施した手順について備忘録として記録しておきますので誰かの参考になれば幸いです。

また、ローカルDBからローカルDBに複製する方法だけでなく、リモートDBをローカルDB/リモートDBに複製する方法も記載しておきます。

# 目次
* [ローカル⇒ローカル](#ローカル⇒ローカル)
* [リモート⇔](#リモート⇔リモート / リモート⇔ローカル)

### 開発環境
ローカル環境
Windows 11 Pro
Ubuntu 22.04.4 LTS
(確認用コマンド：lsb_release -a)
mysql:8.4.0
(確認用コマンド：select version(); )

リモート環境
mysql 8.0.37-azure



# ローカル⇒ローカル
## ダンプの手順
まずはコンテナ対象DBコンテナに入ります。
以下コマンドにて対象DBのサービス名を確認します。
```:

docker compose ps

```
表示されたサービス名を以下コマンドにセットしてコンテナに入ります。
```:

 docker compose exec サービス名 bash

```


以下コマンドを実行し、パスワード入力が求められるので入力します。
ユーザ名やパスワードについてはご自身のプロジェクトのenvファイルを探してみてください。
```:

mysqldump --single-transaction -u ユーザ名 -p ダンプしたいDB名 > 任意のファイル名

```
lsコマンドを打つと"任意のファイル名"が作られているはずです。
以下のようなエラーが出る場合はユーザ名やパスワードが適切ではないです。
「mysqldump: Got error: 1045: Access denied for user ******** (using password: NO) when trying to connect」

コンテナ内にダンプされたファイルを以下コマンドでホストマシン側にコピーします。
```:

sudo docker cp DBコンテナ名:コンテナ内のファイルパス ホスト側の保存先パス

```
※コンテナに入る際はサービス名を指定しましたが cpコマンドの引数ではコンテナ名を使用するので注意してください。
両方ともdocker compose psコマンドで確認できます。(docker psでも可)


## リストアの手順
ダンプの逆を実施していきます。

プロジェクトルートは以下にダンプファイルを配置します。

ローカルファイルをコンテナ内にコピーします。
```:

　sudo docker cp ダンプファイル名 DBコンテナ名:任意のファイル名.sql

```

mysqlに入る

```:

docker compose exec 対象DBのサービス名 bash

```
リストア
```:

mysql -u ユーザ名 -p DB名 < コピーしたファイル名.sql

```

# リモート⇔リモート / リモート⇔ローカル

## ダンプ（エクスポート）
```:
docker run --name mydumper --rm -v /home/bk:/backups mydumper/mydumper:latest sh -c "mydumper -h <SOURCE_DB_HOST> --user <SOURCE_DB_USER> -o /backups/data/<DB_NAME> -B <DB_NAME> -v 3 -r 1000 -L /backups/mydumper.log -p '<SOURCE_DB_PASSWORD>'"
```

### 各パラメータの解説

- **`<SOURCE_DB_HOST>`**：ダンプ元のデータベースホスト名
- **`<SOURCE_DB_USER>`**：ダンプ元のデータベースユーザー名
- **`<SOURCE_DB_PASSWORD>`**：ダンプ元のデータベースパスワード
- **`<DB_NAME>`**：ダンプ対象のデータベース名
- **`<TARGET_DB_HOST>`**：リストア先のデータベースホスト名
- **`<TARGET_DB_USER>`**：リストア先のデータベースユーザー名
- **`<TARGET_DB_PASSWORD>`**：リストア先のデータベースパスワード
- **`<TARGET_DB_NAME>`**：リストア先のデータベース名。バックアップデータの復元先のデータベース名

### コマンドの解説
myloader -h <TARGET_DB_HOST>：リストア先のデータベースホストに接続。
--user <TARGET_DB_USER>：リストア先のデータベースユーザー名。
-B <TARGET_DB_NAME>：リストア先のデータベース名。
--directory /backups/data/<DB_NAME>：エクスポートされたデータファイルが保存されているディレクトリ。
-v 3：詳細度3のログ出力。
-r 1000：1000行ごとにリストア処理を分割。
-L /backups/mydumper.log：リストアログファイルの保存先（ホストの/home/bk/mydumper.logに保存）。
-p '<TARGET_DB_PASSWORD>'：リストア先のデータベースパスワード。



## リストア
```:
docker run --name mydumper --rm -v /home/bk:/backups mydumper/mydumper:latest sh -c "myloader -h <TARGET_DB_HOST> --user <TARGET_DB_USER> -B <TARGET_DB_NAME> --directory /backups/data/<DB_NAME> -v 3 -r 1000 -L /backups/mydumper.log -p '<TARGET_DB_PASSWORD>'"
```


### 各パラメータの解説

- **`<SOURCE_DB_HOST>`**：ダンプ元のデータベースホスト名
- **`<SOURCE_DB_USER>`**：ダンプ元のデータベースユーザー名
- **`<SOURCE_DB_PASSWORD>`**：ダンプ元のデータベースパスワード
- **`<DB_NAME>`**：ダンプ対象のデータベース名
- **`<TARGET_DB_HOST>`**：リストア先のデータベースホスト名
- **`<TARGET_DB_USER>`**：リストア先のデータベースユーザー名
- **`<TARGET_DB_PASSWORD>`**：リストア先のデータベースパスワード
- **`<TARGET_DB_NAME>`**：リストア先のデータベース名。バックアップデータの復元先のデータベース名

### コマンドの解説
docker run：Dockerコンテナを実行するコマンド。
--name mydumper：コンテナにmydumperという名前を付ける。
--rm：コンテナ終了後、自動でコンテナを削除。
-v /home/bk:/backups：ホストの/home/bkディレクトリを、コンテナの/backupsディレクトリにマウント。バックアップファイルの出力先。
mydumper/mydumper:latest：mydumperツールの最新イメージを使ってコンテナを実行。
sh -c "..."：コンテナ内でshを使って、指定のmydumperコマンドを実行。
コマンド内部のmydumperツールの引数は以下のとおりです：

-h <SOURCE_DB_HOST>：ダンプ元のMySQLデータベースのホスト名。
--user <SOURCE_DB_USER>：ダンプ元のデータベースユーザー名。
-o /backups/data/<DB_NAME>：ダンプファイルを保存するコンテナ内のディレクトリ（ホストの/home/bk/data/<DB_NAME>にマウントされている）。
-B <DB_NAME>：ダンプ対象のデータベース名。
-v 3：詳細度3のログ出力（詳細な情報を表示）。
-r 1000：データを1000行ごとに分割してエクスポート。
-L /backups/mydumper.log：ログファイルの保存先を指定（ホスト上では/home/bk/mydumper.logに保存）。
-p '<SOURCE_DB_PASSWORD>'：ダンプ元のデータベースのパスワード。



# 参考文献
本記事は以下情報を参考にして執筆しました。

--https://minegishirei.hatenablog.com/entry/2023/09/20/185116
https://www.sejuku.net/blog/82770