mysqldumpでバックアップを取得する（DockerのMySQL）

## はじめに
### バックアップって必要だよね

ここまでに作った環境、これから使っていくことを考えると、何かあった時のためにデータのバックアップが必要。

- [Raspberry Pi 3にDockerをインストールしました](https://qiita.com/TakSus/items/4e61128278439fc6afd7)
- [Raspberry Pi 3のDockerでRedmineを立ち上げました](https://qiita.com/TakSus/items/e05c0e9471da38492228)


まずは以下の記事を見ながらお勉強。

- [第10回 Docker環境におけるバックアップ／リストアの罠 (4/4)](https://www.itmedia.co.jp/enterprise/articles/1511/11/news017_4.html)

イメージは何があるかな。
RedmineとMySQLだけ。

```terminal
$ docker images
REPOSITORY          TAG       IMAGE ID       CREATED       SIZE
redmine             latest    f2b5b69f9ad5   4 weeks ago   440MB
hypriot/rpi-mysql   latest    4f3cbdbc3bdb   2 years ago   209MB
```

立ち上がっているコンテナは何があるかな。
これもRedmineとMySQLだけ。

```terminal
$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                  CREATED        STATUS        PORTS                    NAMES
5190a7c0980c   hypriot/rpi-mysql   "/entrypoint.sh mysq…"   19 hours ago   Up 19 hours   3306/tcp                 redmine-db
a2afe2cb982a   redmine             "/docker-entrypoint.…"   19 hours ago   Up 19 hours   0.0.0.0:3000->3000/tcp   redmine
```

起動したMySQLのコンテナ（redmine-db）で稼働するMySQLデータベースは、/var/lib/mysqlディレクトリに格納されています。
中身を確認すると、色々入っているのがわかります。

```terminal
$ docker exec -it redmine-db ls -l /var/lib/mysql
total 36876
-rw-rw---- 1 mysql mysql  5242880 Jan 10 01:10 ib_logfile0
-rw-rw---- 1 mysql mysql  5242880 Jan  9 06:55 ib_logfile1
-rw-rw---- 1 mysql mysql 27262976 Jan 10 01:10 ibdata1
drwx------ 2 mysql mysql     4096 Jan  9 06:55 mysql
drwx------ 2 mysql mysql     4096 Jan  9 06:55 performance_schema
drwx------ 2 mysql mysql     4096 Jan  9 06:57 redmine
```

記事ではここから中身をtarに固めてimportして・・・とやっていますが、そこは机上での確認とさせてもらって。

Dockerでの **データボリューム** という考え方について学んだところで、redmine-dbに設定されているデータボリュームを確認します。
確認してデータボリュームがわかったけど、**docker export/importではバックアップ／リストアができない仕様** であるとのこと。（docker commitでもデータボリュームを含んでイメージ化できない）
データボリュームは、個別にバックアップ／リストアする必要がある・・・ということまでわかりました。

```terminal
$ docker inspect redmine-db
[
    {

~~~~~~~~~~~略~~~~~~~~~~~

            "Image": "hypriot/rpi-mysql",
            "Volumes": {
                "/var/lib/mysql": {}
            },

~~~~~~~~~~~略~~~~~~~~~~~

    }
]
```

### DockerのMySQLにアクセスする

DockerのMySQLにログインします。
パスワードを聞かれるので、忘れてたらログインできません。

```terminal
$ docker exec -it redmine-db mysql -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.5.60-0+deb7u1 (Debian)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

今、存在しているデータベースを確認します。

```terminal
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| redmine            |
+--------------------+
4 rows in set (0.00 sec)
```

今、存在しているRedmineのテーブル一覧を確認します。

```terminal
mysql> show tables in redmine;
+-------------------------------------+
| Tables_in_redmine                   |
+-------------------------------------+
| ar_internal_metadata                |
| attachments                         |
| auth_sources                        |
| boards                              |
| changes                             |
| changeset_parents                   |
| changesets                          |
| changesets_issues                   |
| comments                            |
| custom_field_enumerations           |
| custom_fields                       |
| custom_fields_projects              |
| custom_fields_roles                 |
| custom_fields_trackers              |
| custom_values                       |
| documents                           |
| email_addresses                     |
| enabled_modules                     |
| enumerations                        |
| groups_users                        |
| import_items                        |
| imports                             |
| issue_categories                    |
| issue_relations                     |
| issue_statuses                      |
| issues                              |
| journal_details                     |
| journals                            |
| member_roles                        |
| members                             |
| messages                            |
| news                                |
| open_id_authentication_associations |
| open_id_authentication_nonces       |
| projects                            |
| projects_trackers                   |
| queries                             |
| queries_roles                       |
| repositories                        |
| roles                               |
| roles_managed_roles                 |
| schema_migrations                   |
| settings                            |
| time_entries                        |
| tokens                              |
| trackers                            |
| user_preferences                    |
| users                               |
| versions                            |
| watchers                            |
| wiki_content_versions               |
| wiki_contents                       |
| wiki_pages                          |
| wiki_redirects                      |
| wikis                               |
| workflows                           |
+-------------------------------------+
56 rows in set (0.00 sec)
```

今、存在するユーザの一覧を確認します。

```terminal
mysql> select host,user from mysql.user;
+------+------+
| host | user |
+------+------+
| %    | root |
+------+------+
1 row in set (0.00 sec)
```

## バックアップ〜リストア
### ダンプファイルでバックアップを取得する

まず、バックアップ用にユーザを作成します。
バックアップ以外にも使うかもしれませんが・・・。

**username**にユーザ名を、**password**にパスワードを入れて実行し、ユーザを作成します。
それからGRANTで権限を付与します。
作成したユーザ（今回はruserという名前にしました）が存在することを確認します。

```terminal
mysql> create user 'username'@'%' identified by 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'ruser'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> select host,user from mysql.user;
+------+-------+
| host | user  |
+------+-------+
| %    | root  |
| %    | ruser |
+------+-------+
2 rows in set (0.00 sec)
```

```mysqldump``` でバックアップを取得します。
このコマンドに辿り着くまでに試行錯誤を繰り返しましたが、そこは割愛。

```terminal
$ docker exec -it redmine-db mysqldump redmine -uruser -ppassword > /backup/testbackup.sql
```

ちゃんと取れているか、中身を確認します。
大丈夫そうです。

```terminal
$ cat /backup/testbackup.sql 
-- MySQL dump 10.13  Distrib 5.5.60, for debian-linux-gnu (armv7l)
--
-- Host: localhost    Database: 
-- ------------------------------------------------------
-- Server version	5.5.60-0+deb7u1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

~~~~~~~~~~~略~~~~~~~~~~~

--
-- Dumping data for table `workflows`
--

LOCK TABLES `workflows` WRITE;
/*!40000 ALTER TABLE `workflows` DISABLE KEYS */;
/*!40000 ALTER TABLE `workflows` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2021-01-10 12:35:45
```

### リストアする時は

以下のコマンドでリストアできます。
ちゃんとリストアできました。

```terminal
$ docker exec -i redmine-db mysql redmine -uruser -ppassword < /backup/testbackup.sql
```

### 試行錯誤したmysqldumpなど

以下のようなコマンドでもダンプファイル取得できました。（こっちがFirst Versionで、上に記載したのがSecond Version）
色々試行錯誤して、頑張ってみたんです。

```terminal
$ docker exec -it redmine-db sh -c 'exec /usr/bin/mysqldump --all-databases -uruser -ppassword --single-transaction' > /backup/testbackup.sql
```

その他、①起動しているコンテナ確認→②コンテナ停止→③停止したこと確認→④コンテナ削除→⑤削除を確認・・・。
起動していればSTATUSが*up*、停止していれば*Exited* になります。

```terminal
$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                  CREATED        STATUS       PORTS                    NAMES
5190a7c0980c   hypriot/rpi-mysql   "/entrypoint.sh mysq…"   31 hours ago   Up 8 hours   3306/tcp                 redmine-db
a2afe2cb982a   redmine             "/docker-entrypoint.…"   31 hours ago   Up 8 hours   0.0.0.0:3000->3000/tcp   redmine
$ docker stop 5190a7c0980c a2afe2cb982a
5190a7c0980c
a2afe2cb982a
$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                  CREATED        STATUS                     PORTS     NAMES
5190a7c0980c   hypriot/rpi-mysql   "/entrypoint.sh mysq…"   31 hours ago   Exited (0) 4 seconds ago             redmine-db
a2afe2cb982a   redmine             "/docker-entrypoint.…"   31 hours ago   Exited (1) 8 seconds ago             redmine
$ docker rm 5190a7c0980c a2afe2cb982a
5190a7c0980c
a2afe2cb982a
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

## 終わりに

これで無事にバックアップが取得できるようになりました。
ちゃんとするなら、cronとかで定期的に実行するシェルを作成してバックアップするのでしょうが・・・一旦後回しで。