關於使用 Vagrant 作為開發環境,MySQL 資料庫資料存放目錄遷移的問題

Newiep發表於2017-02-07

因為現在主要的生產環境都是基於虛擬機器(vagrant)搭建的,所以在銷燬虛擬機器的時候會有一些成本問題。(上一次銷燬虛擬機器導致mysql資料丟失的慘痛教訓還歷歷在目 :tired_face:),今天實踐一下把開發環境中mysql資料儲存到宿主主機上。有一些問題需要記錄。(也有一個需要請教的問題最後再說)

遷移準備

首先檢視當前mysql資料到儲存位置。以ubuntuapt-get的安裝方式為例,預設的儲存路徑在/var/lib/mysql,可以開啟配置檔案/etc/mysql/mysql.conf.d/mysqld.cnf進行確認(自定義安裝的同學,需要找到自己的配置檔案確認位置):

[mysqld]
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
datadir     = /var/lib/mysql
log-error   = /var/log/mysql/error.log
# By default we only accept connections from localhost
bind-address    = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

其中,datadir就是指定的資料儲存目錄。

先看一下,當前資料庫的狀態:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| vagrant            |
+--------------------+
5 rows in set (0.00 sec)

開始遷移

  • 首先停止mysql服務,sudo serivce mysql stop

  • 建立新的儲存目錄,mkdir /data/

  • 移動/複製之前存放資料庫目錄檔案,到新的資料庫存放目錄位置
    sudo cp -R /var/lib/mysql/ /data/

  • 修改mysql資料庫目錄所屬(注:此處有坑!)
    chown mysql:mysql -R /data/mysql/

  • 修改配置檔案,指定資料存放目錄

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /data/mysql/
log-error       = /var/log/mysql/error.log
  • 啟動資料庫服務,檢視是否生效
vagrant@newiep:$ sudo service mysql restart

# 連結資料庫
mysql> show variables like '%dir%';

+-----------------------------------------+----------------------------+
| Variable_name                           | Value                      |
+-----------------------------------------+----------------------------+
| basedir                                 | /usr/                      |
| binlog_direct_non_transactional_updates | OFF                        |
| character_sets_dir                      | /usr/share/mysql/charsets/ |
| datadir                                 | /data/mysql/            |
| ignore_db_dirs                          |                            |
| innodb_data_home_dir                    |                            |
| innodb_log_group_home_dir               | ./                         |
| innodb_max_dirty_pages_pct              | 75.000000                  |
| innodb_max_dirty_pages_pct_lwm          | 0.000000                   |
| innodb_tmpdir                           |                            |
| innodb_undo_directory                   | ./                         |
| lc_messages_dir                         | /usr/share/mysql/          |
| plugin_dir                              | /usr/lib/mysql/plugin/     |
| slave_load_tmpdir                       | /tmp                       |
| tmpdir                                  | /tmp                       |
+-----------------------------------------+----------------------------+
15 rows in set (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| vagrant            |
+--------------------+
5 rows in set (0.00 sec)

主要過程說完啦,你以為會一帆風順?No!No!No! 解決一下坑:

坑1: 使用 vagrant 搭建的的開發環境,修改掛載出來的共享目錄許可權

如果不指定目錄所屬owner,那麼在 vagrant 啟動後是沒辦法透過 chown 命令來修改的,需要在啟動前就指定 owner
修改 Vagrantfile :

# 增加資料目錄掛載,並指定許可權
config.vm.synced_folder ".data/mysql", "/data/mysql", id: "mysql",
    owner: "mysql", group: "mysql",
    mount_options: ["dmode=775,fmode=664"]

坑2 : mysql 有個安全模式,會限制一些目錄的訪問

按理說修改 owner 後,就沒問題啦!但是還是啟動不了 mysql 服務,日誌顯示

...
2017-02-07T07:30:28.997699Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
2017-02-07T07:30:28.997857Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
2017-02-07T07:30:28.998081Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2017-02-07T07:30:29.603731Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2017-02-07T07:30:29.603776Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2017-02-07T07:30:29.603783Z 0 [ERROR] Failed to initialize plugins.
2017-02-07T07:30:29.603786Z 0 [ERROR] Aborting
...

這裡有個相關的問題:mysql on virtualbox with datadir on shared folder
簡單來說,mysql 有個配置檔案,用來指定一些目錄的訪問許可權,開啟 sudo vi /etc/apparmor.d/usr.sbin.mysqld 新增如下程式碼:

# Allow data dir access
  /var/lib/mysql/ r,
  /var/lib/mysql/** rwk,
    #下面兩行是手動新增的
  /data/mysql/ r,         
  /data/mysql/** rwk,

重新啟動mysql!

總感覺這種方式不夠完美,有更好的方法請一定告訴我!:pray: :pray: :pray:

問題來啦:現在每次啟動 vagrant,都需要重新啟動一下mysql,否則,會找不到資料庫。初步懷疑:在vagrant 啟動過程中,掛載資料目錄是在內部服務(比如mysql)啟動之後!,至於具體解決方法有緣再更新!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章