Memo

メモ > サーバ > 各論: Docker > データベースの永続化

データベースの永続化
データベースをファイル共有の対象にすれば、データの永続化ができる。 ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。 ファイル共有だと、環境によっては正しく動作しなかった。 ※docker-compose.ymlでrootパスワードなどを指定している場合、変更しても永続化済みのデータには影響しない。 つまり「何故かパスワードの変更が反映されない」となるので注意。 手動でパスワードなどを変更するか、永続化済みのデータを初期化するなどする。 ※データベースを永続化していると、MySQLコンテナが完全に起動するまでの時間が短くなっているかも? 諸々のデータ作成が短縮できるから…かもしれない。 ■docker container run の場合 ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。 ファイル共有だと、環境によっては正しく動作しなかった。 -v $PWD/docker/test/data:/var/lib/mysql を追加して起動する。 /var/lib/mysql を同期すれば、MySQLのデータを保持できる。 /docker/test/data フォルダはあらかじめ作成しておく。
$ docker container run --net my_network --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7 $ docker container run --net my_network --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
■Docker Compose の場合 ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう。 ファイル共有だと、環境によっては正しく動作しなかった。 - ./database:/var/lib/mysql を追加して起動する。意味は上と同じ。 compose_test\docker-compose.yml
version: '3' networks: my_network: services: mysql: container_name: mysql volumes: - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/database:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: pass MYSQL_DATABASE: test networks: - my_network image: mysql:5.7 php: container_name: php volumes: - ./:/var/www ports: - 80:80 networks: - my_network image: php:custom
■ボリュームの削除(データベースの削除)
$ docker volume ls ... ボリュームを確認。 $ docker volume rm compose_mysql_data ... ボリュームを削除。
■トラブル 2018/01/06 にWindowsアップデートするとDockerが起動しなくなった。 再インストールで起動するようになったが、データベースの永続化ができないようになっていた。 Composeを使う使わないにかかわらず永続化できず、MariaDBの場合でも同じ。 「-d」なしで起動すると以下のようなエラーを確認できるが、原因不明のまま解決せず。 Windows側で権限管理やファイルシステムの仕様が変更されたとか?
$ docker container run --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test mysql:5.7 Initializing database 2018-01-06T17:47:41.143661Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2018-01-06T17:47:41.150773Z 0 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive 2018-01-06T17:47:41.627330Z 0 [ERROR] InnoDB: Operating system error number 22 in a file operation. 2018-01-06T17:47:41.627674Z 0 [ERROR] InnoDB: Error number 22 means 'Invalid argument' 2018-01-06T17:47:41.628023Z 0 [ERROR] InnoDB: File ./ib_logfile101: 'aio write' returned OS error 122. Cannot continue operation 2018-01-06T17:47:41.628357Z 0 [ERROR] InnoDB: Cannot continue operation.
次の手段へ。 データはbusyboxに保存するのが定番らしいので試す。
$ docker container run --net my_network --name storage -v /var/lib/mysql -d busybox $ docker container run --net my_network --name mysql --volumes-from storage -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
とすればmysqlのデータをbusyboxに保存できる。 が、mysqlコンテナを再起動してもデータは消えないが、busyboxを再起動するとデータが消える。 よってbusyboxからエクスポート&インポートする必要があるが、それだとmysqlをデータ同期無しで使っている状態と変わらない。 次の手段へ。 コンテナとローカルでデータ転送ができるらしいので試す。 以下のようにすればデータ転送ができる。 コンテナからローカルへ。
$ docker container cp mysql:/var/lib/mysql /Users/refirio/docker/backup … 絶対パスの場合。 $ docker container cp mysql:/var/lib/mysql ./docker/backup … 相対パスの場合。
ローカルからコンテナへ。
$ docker container cp /Users/refirio/docker/backup mysql:/var/lib/mysql … 絶対パスの場合。 $ docker container cp ./docker/backup mysql:/var/lib/mysql … 相対パスの場合。
が、ローカルからコンテナに転送すると所有者がrootになる。chownで所有者を変更してもmysqlからは読み込めなかった。 権限なども調整が必要かも。 非常に面倒なので、phpMyAdminのようなツールでエクスポート&インポートする方が現実的。 つまりは実質、データベースは永続化せずに作業する状態となり、かなり面倒。 ■トラブル代替案 ホストの特定のパスではなく、データボリュームになら保存できた。 むしろ、ファイルシステムや権限の問題を回避するためにも、データボリュームを使う方がいいみたい。 データボリュームに保存したデータベースをバックアップしたければ、phpMyAdminなどのツールを使う。 dockerコマンドから起動する場合。(「mysql_data」に保存。)
$ docker volume ls ... ボリュームを確認。 $ docker volume create --name mysql_data ... 明示的に作成できるが省略可。 $ docker container run --net my_network --name mysql -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7 $ docker container exec -it mysql bash $ mysql -u root -p
Docker Compose から起動する場合、以下のように指定する。(「compose_mysql_data」に保存する場合。)
services: mysql: container_name: mysql volumes: - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf - compose_mysql_data:/var/lib/mysql
ボリュームの削除は以下のようにする。
$ docker volume ls ... ボリュームを確認。 $ docker volume rm compose_mysql_data ... ボリュームを削除。
Dockerのデータ永続化関連について - Qiita https://qiita.com/onokatio/items/fcc9f8f94f8533bb030a dockerのデータボリュームとそのバックアップ方法 - Qiita https://qiita.com/74th/items/41393f506d223850f2c3 Docker Data Volume を理解する - Carpe Diem http://christina04.hatenablog.com/entry/2016/05/04/134323

Advertisement