Theo mặc định cơ sở dữ liệu MySQL sẽ được tạo ra trong thư mục /var/lib/mysql. Điều này có thể phù hợp nếu bạn đang chạy một cơ sở dữ liệu nhỏ mà không chiếm nhiều không gian. Nhưng về thực tế, đối với một cơ sở dữ liệu lớn hơn, bạn có thể không có đủ không gian dưới phân vùng root. Trong trường hợp đó, bạn có thể muốn di chuyển cơ sở dữ liệu MySQL của bạn từ phân vùng root vào một phân vùng khác. Để thay đổi thư mục MySQL, trên một mức độ cao, bạn phải thực hiện ba bước sau đây: Di chuyển các tập tin cơ sở dữ liệu MySQL từ /var/lib/mysql vào một phân vùng khác Sửa đổi tập tin my.cnf với vị trí thư mục mới Cập nhật thiết lập bảo mật để phù hợp với sự thay đổi thư mục: Trên CentOS hoặc RedHat, sửa đổi cài đặt SELinux. Trên Ubuntu hoặc Debian, sửa đổi thiết lập AppArmor. Hướng dẫn này giải thích chi tiết về làm thế nào để thực hiện ba bước trên giúp di chuyển dữ liệu MySQL của bạn vào một thư mục khác. Sao lưu MySQL hiện tại Trước khi bạn làm bất cứ điều gì, dừng cơ sở dữ liệu MySQL và sao lưu dữ liệu của cơ sở dữ liệu MySQL hiện tại của bạn. Theo mặc định MySQL lưu trữ dữ liệu ở thư mục /var/lib/mysql. Sao chép thư mục mysql này đến một vị trí khác để sao lưu. Mã: service mysqld stop mkdir -p /backup cp -r /var/lib/mysql /backup/mysql Hoặc, nếu bạn thích, bạn có thể sử dụng mysqldump để có một bản sao lưu MySQL DB. Di chuyển dữ liệu thư mục MySQL đến phân vùng khác Trong ví dụ này, phân vùng root của tôi là /dev/sda1 và không có nhiều không gian cho thư mục mặc định /var/lib/mysql. Nhưng, tôi có phân vùng dữ liệu trên /dev/sdb1, trong đó có rất nhiều không gian. Vì vậy, tôi sẽ di chuyển cơ sở dữ liệu MySQL từ phân vùng root vào phân vùng /dev/sdb1. Tạo thư mục và di chuyển dữ liệu mysql từ /var/lib tới /data/var/lib như sau: Mã: mkdir -p /data/var/lib cd /var/lib mv mysql /data/var/lib/ Những điểm cần xem xét: Nếu có thể, cố gắng sử dụng lệnh move để di chuyển các thư mục trên (thay vì sao chép). Khi bạn thực hiện các bản sao, SELinux context sẽ bị mất, và bạn phải tự thiết lập lại sau này (sẽ được giải thích dưới đây). Tuy nhiên, khi bạn di chuyển, SELinux context thích hợp cho MySQL được lưu giữ nguyên vẹn và bạn không phải lo lắng về việc thay đổi nó. Ngoài ra, nếu bạn đã sao chép các thư mục (thay vì di chuyển), chắc chắn rằng bạn thay đổi quyền sở hữu một cách thích hợp. Nếu không, bạn có thể nhận được thông báo lỗi này: l MySQL error: 1017Can’t find file: (errno: 13). Sửa lỗi bằng lệnh sau: Mã: chown -R mysql: mysql / data Sửa my.cnf và khởi động MySQL Trong tập tin /etc/my.cnf, bạn cần phải sửa đổi cả hai tham số datadir và socket trỏ vào thư mục mới như dưới đây. Mã: # vi /etc/my.cnf datadir=/data/var/lib/mysql socket=/data/var/lib/mysql/mysql.sock Cuối cùng, khởi động lại cơ sở dữ liệu MySQL. Mã: # service mysqld start Starting mysqld: [ OK ] Nếu bạn có một tham số tmpdir đã được định nghĩa trong tập tin my.cnf của bạn, thay đổi thư mục của tham số đó như sau: Mã: tmpdir=/data/var/lib/mysql Sau khi thay đổi datadir và socket trong tập tin my.cnf, nếu MySQL không bắt đầu hoặc có lỗi thông báo quyền truy cập bị từ chối, sau đó bạn cần phải thiết lập các SELinux (hoặc Apparmor) như được giải thích dưới đây. SELinux Context Type cho MySQL Sử dụng lệnh ls -Z để xem SELinux context. Trước khi di chuyển các thư mục, sau đây là SELinux context trên cơ sở dữ liệu MySQL của tôi. Trong ví dụ này, "aluhost" là cơ sở dữ liệu MySQL trong thư mục /var/lib/mysql. Như bạn thấy ở đây, mysqld_db_t là SELinux context type. Mã: # ls -Z /var/lib/mysql drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 aluhost -rw-rw----. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ibdata1 -rw-rw----. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ib_logfile0 Sau khi di chuyển thư mục đến vị trí mới, bạn sẽ thấy chính xác các SELinux như trước khi di chuyển. Mã: ls -Z /data/var/lib/mysql Lưu ý: Nếu bạn đã làm một bản sao của thư mục (thay vì di chuyển), bạn sẽ nhận thấy rằng nó đã thay đổi. Trong trường hợp đó, thay đổi SELinux như được giải thích dưới đây. Khi điều kiện SELinux là sai, bạn sẽ thấy thông báo lỗi sau đây (hoặc một cái gì đó tương tự như sau) trong nhật ký audit của bạn (hoặc /var/log/messages) Mã: # cat /var/log/audit/audit.log: type=AVC msg=audit(1447281394.928:20831): avc: denied { read } for pid=21346 comm="mysqld" name="mysql" dev=sda1 ino=5506027 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 Ngoài ra, bạn sẽ thấy những điều sau đây trong tập tin mysqld.log của bạn khi MySQL DB không để bắt đầu. Mã: # cat /var/log/mysqld.log: mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql [Warning] Can't create test file /var/lib/mysql/devdb..lower-test /usr/libexec/mysqld: Can't change dir to '/var/lib/mysql/' (Errcode: 13) [ERROR] Aborting [Note] /usr/libexec/mysqld: Shutdown complete SELinux Setup cho MySQL trên CentOS/RedHat (Lựa chọn 1) Sử dụng lệnh chcon, bạn có thể thay đổi SELinux context type trong thư mục mới như hình dưới đây. Mã: chcon -R -t mysqld_db_t /data Trong lệnh trên: -chcon là lệnh để thay đổi SELinux context. -R tùy chọn sẽ đệ quy thay đổi context cho các thư mục nhất định và tất cả các thư mục con. -t tùy chọn được sử dụng để xác định SELinux context type nên được thiết lập. Trong ví dụ này, chúng tôi đang thiết lập nó là mysqld_db_t. -/data là thư mục trên đó lệnh này sẽ được thực thi. Lưu ý: Bắt đầu thay đổi context từ các thư mục cấp cao /data (và không phải từ thư mục mysql), trong đó sẽ bao gồm thư mục mysql và tất cả các thư mục con và tập tin. SELinux Setup cho MySQL trên CentOS/RedHat (Lựa chọn 2) Sử dụng lệnh restorecon, bạn có thể khôi phục lại SELinux context đúng loại. Nhưng, trong trường hợp này, bạn nên thông báo cho SELinux context đúng bằng cách thêm mysqld_db_t đến SELinux context map. Để thêm các loại SELinux tới context map, sử dụng lệnh semanage. Cài đặt gói policycoreutils-python mà có chứa lệnh semanage. Mã: yum -y install policycoreutils-python Tiếp theo, thực hiện lệnh sau để thiết lập SELinux context map trên thư mục mới. Mã: semanage fcontext -a -t mysqld_db_t "/data(/.*)?" Trong lệnh trên, chúng tôi có thêm mysqld_db_t đến context map cho tất cả các thư mục con và các tập tin bên dưới của /datadirectory. Cuối cùng, sử dụng lệnh restorecon, nó sẽ khôi phục lại SELinux context thích hợp vào thư mục /data mới. Mã: restorecon -Rv /data Xác minh rằng việc di chuyển thư mục /data mới và thư mục con mysql có SELinux context chính xác. Mã: # ls -Z /data/var/lib/mysql drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 thegeekstuff -rw-rw----. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ibdata1 -rw-rw----. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ib_logfile0 ... Lưu ý: Bạn cũng có thể sử dụng tùy chọn -e cùng với fcontext. Điều này sẽ làm cho context label cho /data và thư mục con của nó tương tự như context label /var/lib/mysql. AppArmor Setup cho MySQL trên Ubuntu / Debian Sau khi di chuyển thư mục dữ liệu MySQL đến một vị trí mới, nếu bạn không làm như sau, trên Ubuntu, bạn sẽ nhận được lỗi này trong khi khởi động cơ sở dữ liệu mysql: “(errno: 13)” (permission denied). Sửa đổi tập tin usr.sbin.mysqld như dưới đây, và thêm hai dòng sau đây. Đừng quên dấu phẩy ở cuối dòng, đó là cần thiết. Mã: # vi /etc/apparmor.d/usr.sbin.mysqld /data/var/lib/mysql/ r, /data/var/lib/mysql/** rwk, Tiếp theo, thực hiện lệnh sau để reparse này tập tin cấu hình apparmor mới cho mysql, và khởi động lại AppArmor. Mã: apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld /etc/init.d/apparmor reload Lưu ý: Ngoài ra, bạn cũng có thể thêm một alias trong tập tin alias AppArmor như dưới đây. Một lần nữa, đừng quên dấu phẩy ở cuối dòng alias này. Mã: # vi /etc/apparmor.d/tunables/alias alias /var/lib/mysql/ -> /newpath/, MySQL Client socket Parameter Sau khi thay đổi ở trên, bạn có thể nhận được thông báo lỗi này khi kết nối từ client mysql: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2) Mã: # mysql -u root -pMyPassword ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) Nếu điều đó xảy ra, truyền các tham số -socket tới client mysql, và trỏ tới tập tin mysql.sock nằm trong thư mục mới. Mã: mysql -u root -pMyPassword --socket=/data/var/lib/mysql/mysql.sock Nếu bạn đang calling mysql client locally, bạn cũng có thể sử dụng tùy chọn -h và sử dụng 127.0.0.1 như dưới đây. Điều này cũng sẽ tránh được thông báo lỗi mysql.sock. Mã: mysql -u root -pMyPassword -h127.0.0.1