Thứ tư, 30/08/2017 | 00:00 GMT+7

Cách cấu hình backup MySQL với Percona XtraBackup trên Ubuntu 16.04

Database thường lưu trữ một số thông tin có giá trị nhất trong cơ sở hạ tầng của bạn. Do đó, điều quan trọng là phải có các bản backup tin cậy để đề phòng mất dữ liệu trong trường hợp xảy ra sự cố hoặc lỗi phần cứng.

Các công cụ backup Percona XtraBackup cung cấp phương pháp thực hiện backup “nóng” dữ liệu MySQL trong khi hệ thống đang chạy. Họ thực hiện việc này bằng cách sao chép các file dữ liệu ở phạm vi hệ thống file và sau đó thực hiện khôi phục sự cố để đạt được tính nhất quán trong tập dữ liệu.

Trong hướng dẫn này, ta sẽ tạo một hệ thống để tự động backup dữ liệu MySQL trên server Ubuntu 16.04. Ta sẽ sử dụng cron và các công cụ Percona trong một group tập lệnh để tạo các bản backup thường xuyên, an toàn mà ta có thể sử dụng để khôi phục trong trường hợp có sự cố.

Yêu cầu

Để hoàn thành hướng dẫn này, bạn cần một server Ubuntu 16.04 với user sudo không phải root được cấu hình cho các việc quản trị. Bạn có thể làm theo hướng dẫn “ Cài đặt server ban đầu với Ubuntu 16.04” của ta để cài đặt user có các quyền này trên server của bạn.

Khi bạn đã có sẵn user sudo , bạn cần cài đặt MySQL. Có thể sử dụng một trong hai hướng dẫn này, tùy thuộc vào gói bạn muốn sử dụng. Hướng dẫn đầu tiên phù hợp nếu bạn muốn gắn bó với repository Ubuntu chính thức, trong khi hướng dẫn thứ hai phù hợp hơn nếu bạn yêu cầu nhiều tính năng cập nhật hơn:

Sau khi MySQL được cài đặt, hãy đăng nhập vào server của bạn với quyền là user sudo của bạn để tiếp tục.

Cài đặt Percona Xtrabackup Tools

Điều đầu tiên ta cần làm là cài đặt các tiện ích backup Percona thực tế. Dự án duy trì các repository riêng mà ta có thể thêm vào server MySQL của bạn để có quyền truy cập vào các gói.

Để bắt đầu, hãy truy cập trang phát hành Percona cho Ubuntu để tìm các .deb mới nhất để cài đặt repository . Vì ta đang sử dụng Ubuntu 16.04, có tên mã là “Xenial Xerus”, ta nên chọn gói “xenial”. Nhấp chuột phải vào liên kết tương ứng và sao chép địa chỉ.

Lưu ý: Bạn có thể kiểm tra lại tên mã phát hành của server của bạn bất kỳ lúc nào bằng lệnh :

  • lsb_release -c
Output
Codename: xenial

Khi bạn đã sao chép liên kết, hãy chuyển đến /tmp và sau đó download gói cấu hình repository với curl :

  • cd /tmp
  • curl -LO https://repo.percona.com/apt/percona-release_0.1-4.xenial_all.deb

Tiếp theo, sử dụng dpkg để cài đặt gói đã download , gói này sẽ cấu hình repository apt Percona trên hệ thống:

  • sudo dpkg -i percona*

Với repository mới được cấu hình , ta sẽ cập nhật index gói local để kéo xuống thông tin về các gói mới có sẵn. Sau đó ta sẽ cài đặt các công cụ XtraBackup và qpress tiện ích nén từ repository :

  • sudo apt-get update
  • sudo apt-get install percona-xtrabackup-24 qpress

Trong số các tiện ích khác kèm, các xtrabackup , xbstream , và qpress lệnh bây giờ sẽ có sẵn. Các tập lệnh của ta sẽ sử dụng từng thứ này để thực hiện backup và khôi phục dữ liệu.

Cấu hình user backup MySQL và thêm dữ liệu thử nghiệm

Để bắt đầu, hãy bắt đầu một phiên MySQL tương tác với user root MySQL:

  • mysql -u root -p

Bạn sẽ được yêu cầu nhập password quản trị mà bạn đã chọn trong quá trình cài đặt MySQL. Khi bạn đã nhập password , bạn sẽ được đưa vào một phiên MySQL.

Tạo user MySQL với các quyền thích hợp

Điều đầu tiên ta cần làm là tạo một user MySQL mới được cấu hình để xử lý các việc backup . Ta sẽ chỉ cấp cho user này các quyền cần thiết để sao chép dữ liệu một cách an toàn trong khi hệ thống đang chạy.

Để rõ ràng về mục đích của account , ta sẽ gọi là backup user mới. Ta sẽ đặt thông tin đăng nhập của user vào một file an toàn, vì vậy hãy chọn một password phức tạp:

  • CREATE USER 'backup'@'localhost' IDENTIFIED BY 'password';

Tiếp theo, ta cần cấp cho user backup mới các quyền cần thiết để thực hiện tất cả các hành động backup trên hệ thống database . Cấp các quyền cần thiết và áp dụng chúng cho phiên hiện tại bằng lệnh :

  • GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT, CREATE TABLESPACE, PROCESS, SUPER, CREATE, INSERT, SELECT ON *.* TO 'backup'@'localhost';
  • FLUSH PRIVILEGES;

User backup MySQL của ta được cấu hình và có quyền truy cập mà nó yêu cầu.

Tạo dữ liệu thử nghiệm cho các bản backup

Tiếp theo, ta sẽ tạo một số dữ liệu thử nghiệm. Chạy các lệnh sau để tạo database playground với bảng equipment . Ta sẽ bắt đầu bằng cách chèn một bản ghi đại diện cho một slide màu xanh lam:

  • CREATE DATABASE playground;
  • CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));
  • INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");

Phần sau của hướng dẫn này, ta sẽ sử dụng và thay đổi dữ liệu này để kiểm tra khả năng tạo các bản backup đầy đủ và gia tăng.

Trước khi kết thúc phiên MySQL, ta sẽ kiểm tra giá trị của biến datadir . Ta cần biết giá trị này đảm bảo rằng user backup cấp hệ thống của ta có quyền truy cập vào các file dữ liệu MySQL.

Hiển thị giá trị của biến datadir bằng lệnh :

  • SELECT @@datadir;
Output
+-----------------+ | @@datadir | +-----------------+ | /var/lib/mysql/ | +-----------------+ 1 row in set (0.01 sec)

Ghi lại vị trí bạn tìm thấy.

Đây là tất cả những gì ta cần làm trong MySQL vào lúc này. Thoát khỏi shell bằng lệnh :

  • exit

Tiếp theo, ta có thể xem qua một số cấu hình cấp hệ thống.

Cấu hình user backup hệ thống và chỉ định quyền

Bây giờ ta có một user MySQL để thực hiện backup , ta sẽ đảm bảo một user Linux tương ứng tồn tại với các quyền hạn chế tương tự.

Trên Ubuntu 16.04, user backup và group backup tương ứng đã có sẵn. Xác nhận điều này bằng cách kiểm tra các file /etc/passwd/etc/group bằng lệnh sau:

  • grep backup /etc/passwd /etc/group
Output
/etc/passwd:backup:x:34:34:backup:/var/backups:/usr/sbin/nologin /etc/group:backup:x:34:

Dòng đầu tiên từ file /etc/passwd mô tả user backup , trong khi dòng thứ hai từ file /etc/group xác định group backup .

Thư mục /var/lib/mysql nơi lưu giữ dữ liệu MySQL thuộc sở hữu của user và group mysql . Ta có thể thêm user backup vào group mysql để cho phép an toàn truy cập vào các file và folder database . Ta cũng nên thêm user sudo của ta vào group backup để ta có thể truy cập các file ta sẽ backup .

Nhập các lệnh sau để thêm user backup vào group mysql và user sudo của bạn vào group backup :

  • sudo usermod -aG mysql backup
  • sudo usermod -aG backup ${USER}

Nếu ta kiểm tra lại các file /etc/group , bạn sẽ thấy rằng user hiện tại của bạn đã được thêm vào group backup và user backup được thêm vào group mysql :

  • grep backup /etc/group
Output
backup:x:34:sammy mysql:x:116:backup

Group mới không tự động có sẵn trong phiên hiện tại của ta . Để đánh giá lại các group có sẵn cho user sudo của ta , hãy đăng xuất và đăng nhập lại hoặc nhập:

  • exec su - ${USER}

Bạn sẽ được yêu cầu nhập password user sudo của bạn để tiếp tục. Xác nhận phiên hiện tại của bạn hiện có quyền truy cập vào group backup bằng cách kiểm tra lại các group user của ta :

  • id -nG
Output
sammy sudo backup

User sudo của ta bây giờ sẽ có thể tận dụng tư cách thành viên của bạn trong group backup .

Tiếp theo, ta cần làm cho folder /var/lib/mysql và các folder con của nó có thể truy cập được vào group mysql bằng cách thêm quyền thực thi group . Nếu không, user backup sẽ không thể vào các folder đó, mặc dù đó là thành viên của group mysql .

Lưu ý: Nếu giá trị của datadir không phải là /var/lib/mysql khi bạn kiểm tra bên trong MySQL trước đó, hãy thay thế folder bạn đã phát hiện trong các lệnh tiếp theo.

Để cấp cho group mysql quyền truy cập vào các folder dữ liệu MySQL, hãy nhập:

  • sudo find /var/lib/mysql -type d -exec chmod 750 {} \;

User backup của ta hiện có quyền truy cập cần thiết vào folder MySQL.

Tạo tài sản dự phòng

Như vậy, khi có sẵn MySQL và user backup hệ thống, ta có thể bắt đầu cài đặt file cấu hình, khóa mã hóa và các tài sản khác mà ta cần để tạo và bảo mật thành công các bản backup của bạn .

Tạo file cấu hình MySQL với các thông số backup

Bắt đầu bằng cách tạo một file cấu hình MySQL tối thiểu mà tập lệnh backup sẽ sử dụng. Điều này sẽ chứa thông tin đăng nhập MySQL cho user MySQL.

Mở file tại /etc/mysql/backup.cnf trong editor của bạn:

  • sudo nano /etc/mysql/backup.cnf

Bên trong, hãy bắt đầu phần [client] và đặt user backup MySQL và user password mà bạn đã xác định trong MySQL:

/etc/mysql/backup.cnf
[client] user=backup password=password 

Lưu file khi bạn hoàn tất.

Cấp quyền sở hữu file cho user backup và sau đó hạn chế quyền để không user nào khác có thể truy cập file :

  • sudo chown backup /etc/mysql/backup.cnf
  • sudo chmod 600 /etc/mysql/backup.cnf

User backup sẽ có thể truy cập file này để lấy thông tin đăng nhập thích hợp nhưng những user khác sẽ bị hạn chế.

Tạo folder root backup

Tiếp theo, tạo một folder cho nội dung backup . Ta sẽ sử dụng /backups/mysql làm folder cơ sở cho các bản backup của ta :

  • sudo mkdir -p /backups/mysql

Tiếp theo, gán quyền sở hữu folder /backups/mysql cho user backup và quyền sở hữu group cho group mysql :

  • sudo chown backup:mysql /backups/mysql

User backup bây giờ có thể ghi dữ liệu backup vào vị trí này.

Tạo khóa mã hóa để bảo mật file backup

Vì các bản backup chứa tất cả dữ liệu từ chính hệ thống database , điều quan trọng là phải bảo mật chúng đúng cách. Tiện ích xtrabackup có khả năng mã hóa từng file khi nó được backup và lưu trữ. Ta chỉ cần cung cấp cho nó một khóa mã hóa.

Ta có thể tạo một khóa mã hóa trong folder root backup bằng lệnh openssl :

  • printf '%s' "$(openssl rand -base64 24)" | sudo tee /backups/mysql/encryption_key && echo

Điều rất quan trọng là hạn chế quyền truy cập vào file này. , chỉ định quyền sở hữu cho user backup và từ chối quyền truy cập đối với tất cả user khác:

  • sudo chown backup:backup /backups/mysql/encryption_key
  • sudo chmod 600 /backups/mysql/encryption_key

Khóa này sẽ được sử dụng trong quá trình backup và bất kỳ lúc nào bạn cần khôi phục từ bản backup .

Tạo tập lệnh backup và khôi phục

Bây giờ ta có mọi thứ ta cần để thực hiện backup an toàn version MySQL đang chạy.

Để làm cho các bước backup và khôi phục của ta có thể lặp lại, ta sẽ viết kịch bản cho toàn bộ quy trình. Ta sẽ tạo các tập lệnh sau:

  • backup-mysql.sh : Tập lệnh này backup database MySQL, mã hóa và nén các file trong quá trình này. Nó tạo ra các bản backup đầy đủ và gia tăng và tự động sắp xếp nội dung theo ngày. Theo mặc định, tập lệnh duy trì các bản backup có giá trị 3 ngày.
  • extract-mysql.sh : Tập lệnh này extract và giải mã các file backup để tạo các folder với nội dung được backup .
  • prepare-mysql.sh : Tập lệnh này “chuẩn bị” cho các folder backup bằng cách xử lý các file và áp dụng các bản ghi. Mọi bản backup gia tăng đều được áp dụng cho bản backup đầy đủ. Khi tập lệnh chuẩn bị kết thúc, các file đã sẵn sàng để được chuyển trở lại folder dữ liệu.

Bạn có thể xem các tập lệnh trong kho cho hướng dẫn này trên GitHub bất kỳ lúc nào. Nếu bạn không muốn copy paste nội dung bên dưới, bạn có thể download trực tiếp từ GitHub bằng lệnh :

  • cd /tmp
  • curl -LO https://raw.githubusercontent.com/do-community/ubuntu-1604-mysql-backup/master/backup-mysql.sh
  • curl -LO https://raw.githubusercontent.com/do-community/ubuntu-1604-mysql-backup/master/extract-mysql.sh
  • curl -LO https://raw.githubusercontent.com/do-community/ubuntu-1604-mysql-backup/master/prepare-mysql.sh

Hãy nhớ kiểm tra các tập lệnh sau khi download đảm bảo chúng được truy xuất thành công và bạn chấp thuận các hành động mà chúng sẽ thực hiện. Nếu bạn hài lòng, hãy đánh dấu các tập lệnh là có thể thực thi và sau đó di chuyển chúng vào folder /usr/local/bin bằng lệnh :

  • chmod +x /tmp/{backup,extract,prepare}-mysql.sh
  • sudo mv /tmp/{backup,extract,prepare}-mysql.sh /usr/local/bin

Tiếp theo, ta sẽ cài đặt từng script này và thảo luận chi tiết hơn về chúng.

Tạo tập lệnh backup-mysql.sh

Nếu bạn không download tập lệnh backup-mysql.sh từ GitHub, hãy tạo một file mới trong folder /usr/local/bin tên backup-mysql.sh :

  • sudo nano /usr/local/bin/backup-mysql.sh

Copy paste nội dung tập lệnh vào file :

/usr/local/bin/backup-mysql.sh
#!/bin/bash  export LC_ALL=C  days_of_backups=3  # Must be less than 7 backup_owner="backup" parent_dir="/backups/mysql" defaults_file="/etc/mysql/backup.cnf" todays_dir="${parent_dir}/$(date +%a)" log_file="${todays_dir}/backup-progress.log" encryption_key_file="${parent_dir}/encryption_key" now="$(date +%m-%d-%Y_%H-%M-%S)" processors="$(nproc --all)"  # Use this to echo to standard error error () {     printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2     exit 1 }  trap 'error "An unexpected error occurred."' ERR  sanity_check () {     # Check user running the script     if [ "$(id --user --name)" != "$backup_owner" ]; then         error "Script can only be run as the \"$backup_owner\" user"     fi      # Check whether the encryption key file is available     if [ ! -r "${encryption_key_file}" ]; then         error "Cannot read encryption key at ${encryption_key_file}"     fi }  set_options () {     # List the xtrabackup arguments     xtrabackup_args=(         "--defaults-file=${defaults_file}"         "--backup"         "--extra-lsndir=${todays_dir}"         "--compress"         "--stream=xbstream"         "--encrypt=AES256"         "--encrypt-key-file=${encryption_key_file}"         "--parallel=${processors}"         "--compress-threads=${processors}"         "--encrypt-threads=${processors}"         "--slave-info"     )      backup_type="full"      # Add option to read LSN (log sequence number) if a full backup has been     # taken today.     if grep -q -s "to_lsn" "${todays_dir}/xtrabackup_checkpoints"; then         backup_type="incremental"         lsn=$(awk '/to_lsn/ {print $3;}' "${todays_dir}/xtrabackup_checkpoints")         xtrabackup_args+=( "--incremental-lsn=${lsn}" )     fi }  rotate_old () {     # Remove the oldest backup in rotation     day_dir_to_remove="${parent_dir}/$(date --date="${days_of_backups} days ago" +%a)"      if [ -d "${day_dir_to_remove}" ]; then         rm -rf "${day_dir_to_remove}"     fi }  take_backup () {     # Make sure today's backup directory is available and take the actual backup     mkdir -p "${todays_dir}"     find "${todays_dir}" -type f -name "*.incomplete" -delete     xtrabackup "${xtrabackup_args[@]}" --target-dir="${todays_dir}" > "${todays_dir}/${backup_type}-${now}.xbstream.incomplete" 2> "${log_file}"      mv "${todays_dir}/${backup_type}-${now}.xbstream.incomplete" "${todays_dir}/${backup_type}-${now}.xbstream" }  sanity_check && set_options && rotate_old && take_backup  # Check success and print message if tail -1 "${log_file}" | grep -q "completed OK"; then     printf "Backup successful!\n"     printf "Backup created at %s/%s-%s.xbstream\n" "${todays_dir}" "${backup_type}" "${now}" else     error "Backup failure! Check ${log_file} for more information" fi 

Tập lệnh có chức năng sau:

  • Tạo một bản backup đầy đủ được mã hóa, được nén vào lần đầu tiên nó được chạy mỗi ngày.
  • Tạo bản backup gia tăng được mã hóa, nén dựa trên bản backup đầy đủ hàng ngày khi được gọi lại trong cùng ngày.
  • Duy trì các bản backup được sắp xếp theo ngày. Theo mặc định, ba ngày backup được giữ. Điều này có thể được thay đổi bằng cách điều chỉnh tham số days_of_backups trong script.

Khi tập lệnh được chạy, một folder hàng ngày được tạo nơi các file có dấu thời gian đại diện cho các bản backup riêng lẻ sẽ được ghi. Tệp có dấu thời gian đầu tiên sẽ là một bản backup đầy đủ, có tiền tố là full- . Các bản backup tiếp theo trong ngày sẽ là bản backup gia tăng, được biểu thị bằng tiền tố incremental- , đại diện cho những thay đổi kể từ lần backup đầy đủ hoặc gia tăng cuối cùng.

Bản backup sẽ tạo ra một file có tên backup-progress.log trong folder hàng ngày với kết quả từ hoạt động backup mới nhất . Một file có tên xtrabackup_checkpoints chứa metadata backup mới nhất cũng sẽ được tạo ở đó. Tệp này cần thiết để tạo các bản backup tăng dần trong tương lai, vì vậy điều quan trọng là không xóa nó. Một file có tên xtrabackup_info , chứa metadata bổ sung, cũng được tạo nhưng tập lệnh không tham chiếu đến file này.

Khi bạn hoàn tất, hãy lưu file .

Tiếp theo, nếu bạn chưa làm như vậy, hãy làm cho tập lệnh có thể thực thi được bằng lệnh :

  • sudo chmod +x /usr/local/bin/backup-mysql.sh

Bây giờ ta có một lệnh duy nhất có sẵn sẽ bắt đầu backup MySQL.

Tạo tập lệnh extract-mysql.sh

Tiếp theo, ta sẽ tạo script extract-mysql.sh . Điều này sẽ được sử dụng để extract cấu trúc folder dữ liệu MySQL từ các file backup riêng lẻ.

Nếu bạn không download tập lệnh từ repository , hãy tạo và mở một file có tên là extract-mysql.sh trong folder /usr/local/bin :

  • sudo nano /usr/local/bin/extract-mysql.sh

Bên trong, dán tập lệnh sau:

/usr/local/bin/extract-mysql.sh
#!/bin/bash  export LC_ALL=C  backup_owner="backup" encryption_key_file="/backups/mysql/encryption_key" log_file="extract-progress.log" number_of_args="${#}" processors="$(nproc --all)"  # Use this to echo to standard error error () {     printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2     exit 1 }  trap 'error "An unexpected error occurred.  Try checking the \"${log_file}\" file for more information."' ERR  sanity_check () {     # Check user running the script     if [ "${USER}" != "${backup_owner}" ]; then         error "Script can only be run as the \"${backup_owner}\" user"     fi      # Check whether the qpress binary is installed     if ! command -v qpress >/dev/null 2>&1; then         error "Could not find the \"qpress\" command.  Please install it and try again."     fi      # Check whether any arguments were passed     if [ "${number_of_args}" -lt 1 ]; then         error "Script requires at least one \".xbstream\" file as an argument."     fi      # Check whether the encryption key file is available     if [ ! -r "${encryption_key_file}" ]; then         error "Cannot read encryption key at ${encryption_key_file}"     fi }  do_extraction () {     for file in "${@}"; do         base_filename="$(basename "${file%.xbstream}")"         restore_dir="./restore/${base_filename}"          printf "\n\nExtracting file %s\n\n" "${file}"          # Extract the directory structure from the backup file         mkdir --verbose -p "${restore_dir}"         xbstream -x -C "${restore_dir}" < "${file}"          xtrabackup_args=(             "--parallel=${processors}"             "--decrypt=AES256"             "--encrypt-key-file=${encryption_key_file}"             "--decompress"         )          xtrabackup "${xtrabackup_args[@]}" --target-dir="${restore_dir}"         find "${restore_dir}" -name "*.xbcrypt" -exec rm {} \;         find "${restore_dir}" -name "*.qp" -exec rm {} \;          printf "\n\nFinished work on %s\n\n" "${file}"      done > "${log_file}" 2>&1 }  sanity_check && do_extraction "$@"  ok_count="$(grep -c 'completed OK' "${log_file}")"  # Check the number of reported completions.  For each file, there is an # informational "completed OK".  If the processing was successful, an # additional "completed OK" is printed. Together, this means there should be 2 # notices per backup file if the process was successful. if (( $ok_count !=  $# )); then     error "It looks like something went wrong. Please check the \"${log_file}\" file for additional information" else     printf "Extraction complete! Backup directories have been extracted to the \"restore\" directory.\n" fi 

Không giống như tập lệnh backup-mysql.sh , được thiết kế để tự động, tập lệnh này được thiết kế để sử dụng có chủ đích khi bạn định khôi phục từ bản backup . Do đó, tập lệnh mong đợi bạn chuyển các file .xbstream mà bạn muốn extract .

Tập lệnh tạo một folder restore trong folder hiện tại và sau đó tạo các folder riêng lẻ bên trong cho mỗi bản backup được chuyển vào dưới dạng đối số. Nó sẽ xử lý các file .xbstream được cung cấp bằng cách extract cấu trúc folder từ repository , giải mã các file riêng lẻ bên trong, sau đó extract các file được giải mã.

Sau khi quá trình này hoàn tất, folder restore phải chứa các folder cho mỗi bản backup được cung cấp. Điều này cho phép bạn kiểm tra các folder , kiểm tra nội dung của các bản backup và quyết định bản backup nào bạn muốn chuẩn bị và khôi phục.

Lưu file khi bạn hoàn tất. Sau đó, hãy đảm bảo tập lệnh có thể thực thi được bằng lệnh :

  • sudo chmod +x /usr/local/bin/extract-mysql.sh

Tập lệnh này sẽ cho phép ta mở rộng các file backup riêng lẻ vào cấu trúc folder cần thiết để khôi phục.

Tạo tập lệnh read-mysql.sh

Cuối cùng, download hoặc tạo tập lệnh prepare-mysql.sh trong folder /usr/local/bin . Tập lệnh này sẽ áp dụng các bản ghi cho mỗi bản backup để tạo một ảnh chụp nhanh database nhất quán. Nó sẽ áp dụng mọi bản backup gia tăng cho bản backup đầy đủ để kết hợp các thay đổi sau này.

Tạo file tập lệnh trong editor của bạn nếu bạn không download trước đó:

  • sudo nano /usr/local/bin/prepare-mysql.sh

Bên trong, dán các nội dung sau:

/usr/local/bin/prepare-mysql.sh
#!/bin/bash  export LC_ALL=C  shopt -s nullglob incremental_dirs=( ./incremental-*/ ) full_dirs=( ./full-*/ ) shopt -u nullglob  backup_owner="backup" log_file="prepare-progress.log" full_backup_dir="${full_dirs[0]}"  # Use this to echo to standard error error() {     printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2     exit 1 }  trap 'error "An unexpected error occurred.  Try checking the \"${log_file}\" file for more information."' ERR  sanity_check () {     # Check user running the script     if [ "${USER}" != "${backup_owner}" ]; then         error "Script can only be run as the \"${backup_owner}\" user."     fi      # Check whether a single full backup directory are available     if (( ${#full_dirs[@]} != 1 )); then         error "Exactly one full backup directory is required."     fi }  do_backup () {     # Apply the logs to each of the backups     printf "Initial prep of full backup %s\n" "${full_backup_dir}"     xtrabackup --prepare --apply-log-only --target-dir="${full_backup_dir}"      for increment in "${incremental_dirs[@]}"; do         printf "Applying incremental backup %s to %s\n" "${increment}" "${full_backup_dir}"         xtrabackup --prepare --apply-log-only --incremental-dir="${increment}" --target-dir="${full_backup_dir}"     done      printf "Applying final logs to full backup %s\n" "${full_backup_dir}"     xtrabackup --prepare --target-dir="${full_backup_dir}" }  sanity_check && do_backup > "${log_file}" 2>&1  # Check the number of reported completions.  Each time a backup is processed, # an informational "completed OK" and a real version is printed.  At the end of # the process, a final full apply is performed, generating another 2 messages. ok_count="$(grep -c 'completed OK' "${log_file}")"  if (( ${ok_count} == ${#full_dirs[@]} + ${#incremental_dirs[@]} + 1 )); then     cat << EOF Backup looks to be fully prepared.  Please check the "prepare-progress.log" file to verify before continuing.  If everything looks correct, you can apply the restored files.  First, stop MySQL and move or remove the contents of the MySQL data directory:          sudo systemctl stop mysql         sudo mv /var/lib/mysql/ /tmp/  Then, recreate the data directory and  copy the backup files:          sudo mkdir /var/lib/mysql         sudo xtrabackup --copy-back --target-dir=${PWD}/$(basename "${full_backup_dir}")  Afterward the files are copied, adjust the permissions and restart the service:          sudo chown -R mysql:mysql /var/lib/mysql         sudo find /var/lib/mysql -type d -exec chmod 750 {} \\;         sudo systemctl start mysql EOF else     error "It looks like something went wrong.  Check the \"${log_file}\" file for more information." fi 

Tập lệnh tìm kiếm trong folder hiện tại cho các folder bắt đầu bằng full- hoặc incremental- . Nó sử dụng log MySQL để áp dụng các giao dịch đã commit vào bản backup đầy đủ. Sau đó, nó áp dụng bất kỳ bản backup gia tăng nào vào bản backup đầy đủ để cập nhật dữ liệu với thông tin mới hơn, áp dụng lại các giao dịch đã commit .

Khi tất cả các bản backup đã được kết hợp, các giao dịch chưa commit sẽ được khôi phục lại. Đến đây, bản backup full- sẽ đại diện cho một tập hợp dữ liệu nhất quán có thể được chuyển vào folder dữ liệu của MySQL.

Để giảm thiểu nguy cơ mất dữ liệu, tập lệnh dừng việc sao chép các file vào folder dữ liệu. Bằng cách này, user có thể xác minh thủ công nội dung backup và file log được tạo trong quá trình này và quyết định phải làm gì với nội dung hiện tại của folder dữ liệu MySQL. Các lệnh cần thiết để khôi phục hoàn toàn các file được hiển thị khi lệnh thoát.

Lưu file khi bạn hoàn tất. Nếu bạn không làm như vậy trước đó, hãy đánh dấu file là file thực thi được bằng lệnh :

  • sudo chmod +x /usr/local/bin/prepare-mysql.sh

Tập lệnh này là tập lệnh cuối cùng mà ta chạy trước khi chuyển các file backup vào folder dữ liệu của MySQL.

Kiểm tra tập lệnh backup và khôi phục MySQL

Bây giờ các tập lệnh backup và khôi phục đã ở trên server , ta nên kiểm tra chúng.

Thực hiện backup đầy đủ

Bắt đầu bằng cách gọi tập lệnh backup-mysql.sh với user backup :

  • sudo -u backup backup-mysql.sh
Output
Backup successful! Backup created at /backups/mysql/Thu/full-04-20-2017_14-55-17.xbstream

Nếu mọi thứ diễn ra như kế hoạch, tập lệnh sẽ thực thi chính xác, cho biết thành công và xuất ra vị trí của file backup mới. Như kết quả ở trên chỉ ra, một folder hàng ngày ("Thu" trong trường hợp này) đã được tạo để chứa các bản backup trong ngày. Bản thân file backup bắt đầu bằng full- để thể hiện rằng đây là một bản backup đầy đủ.

Hãy chuyển sang folder backup hàng ngày và xem nội dung:

  • cd /backups/mysql/"$(date +%a)"
  • ls
Output
backup-progress.log full-04-20-2017_14-55-17.xbstream xtrabackup_checkpoints xtrabackup_info

Tại đây, ta thấy file backup thực tế ( full-04-20-2017_14-55-17.xbstream trong trường hợp này), log của sự kiện backup-progress.log ( backup-progress.log xtrabackup_checkpoints ), file xtrabackup_checkpoints , bao gồm metadata về nội dung đã backup và file xtrabackup_info , chứa metadata bổ sung.

Nếu ta chỉnh sửa backup-progress.log , ta có thể xác nhận quá trình backup đã hoàn tất thành công.

  • tail backup-progress.log
Output
170420 14:55:19 All tables unlocked 170420 14:55:19 [00] Compressing, encrypting and streaming ib_buffer_pool to <STDOUT> 170420 14:55:19 [00] ...done 170420 14:55:19 Backup created in directory '/backups/mysql/Thu/' 170420 14:55:19 [00] Compressing, encrypting and streaming backup-my.cnf 170420 14:55:19 [00] ...done 170420 14:55:19 [00] Compressing, encrypting and streaming xtrabackup_info 170420 14:55:19 [00] ...done xtrabackup: Transaction log of lsn (2549956) to (2549965) was copied. 170420 14:55:19 completed OK!

Nếu ta xem file xtrabackup_checkpoints , ta có thể xem thông tin về bản backup . Mặc dù file này cung cấp một số thông tin hữu ích cho administrator , nhưng nó chủ yếu được sử dụng cho các công việc backup tiếp theo để họ biết dữ liệu nào đã được xử lý.

Đây là bản sao của một file có trong mỗi repository . Mặc dù bản sao này được overrides lên mỗi bản backup để đại diện cho thông tin mới nhất, mỗi bản root sẽ vẫn có sẵn bên trong repository lưu trữ backup .

  • cat xtrabackup_checkpoints
Output
backup_type = full-backuped from_lsn = 0 to_lsn = 2549956 last_lsn = 2549965 compact = 0 recover_binlog_info = 0

Ví dụ trên cho ta biết rằng một bản backup đầy đủ đã được thực hiện và bản backup bao gồm số thứ tự log (LSN) 0 đến số thứ tự log 2549956. Số last_lsn cho biết một số thao tác đã xảy ra trong quá trình backup .

Thực hiện backup gia tăng

Bây giờ ta đã có bản backup đầy đủ, ta có thể thực hiện các bản backup gia tăng bổ sung. Bản backup tăng dần ghi lại những thay đổi đã được thực hiện kể từ lần backup cuối cùng được thực hiện. Bản backup gia tăng đầu tiên dựa trên bản backup đầy đủ và các bản backup gia tăng tiếp theo dựa trên bản backup gia tăng trước đó.

Ta nên thêm một số dữ liệu vào database của bạn trước khi thực hiện một bản backup khác để có thể biết được bản backup nào đã được áp dụng.

Chèn một bản ghi khác vào bảng equipment của database playground của ta đại diện cho 10 chiếc xích đu màu vàng. Bạn sẽ được yêu cầu nhập password quản trị MySQL trong quá trình này:

  • mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");'

Bây giờ có nhiều dữ liệu hiện tại hơn so với bản backup mới nhất của ta , ta có thể thực hiện một bản backup gia tăng để nắm bắt các thay đổi. Tập lệnh backup-mysql.sh sẽ thực hiện một bản backup gia tăng nếu bản backup đầy đủ cho cùng ngày tồn tại:

  • sudo -u backup backup-mysql.sh
Output
Backup successful! Backup created at /backups/mysql/Thu/incremental-04-20-2017_17-15-03.xbstream

Kiểm tra lại folder backup hàng ngày để tìm repository backup gia tăng:

  • cd /backups/mysql/"$(date +%a)"
  • ls
Output
backup-progress.log incremental-04-20-2017_17-15-03.xbstream xtrabackup_info full-04-20-2017_14-55-17.xbstream xtrabackup_checkpoints

Nội dung của file xtrabackup_checkpoints hiện đề cập đến bản backup tăng dần mới nhất :

  • cat xtrabackup_checkpoints
Output
backup_type = incremental from_lsn = 2549956 to_lsn = 2550159 last_lsn = 2550168 compact = 0 recover_binlog_info = 0

Loại backup được liệt kê là “tăng dần” và thay vì bắt đầu từ LSN 0 như bản backup đầy đủ của ta , nó bắt đầu ở LSN nơi bản backup cuối cùng của ta kết thúc.

Extract các bản backup

Tiếp theo, hãy extract các file backup để tạo folder backup . Do cân nhắc về không gian và bảo mật, điều này thường chỉ được thực hiện khi đã sẵn sàng khôi phục dữ liệu.

Ta có thể extract các bản backup bằng cách chuyển các .xbstream backup .xbstream sang tập lệnh extract-mysql.sh . , điều này phải được chạy bởi user backup :

  • sudo -u backup extract-mysql.sh *.xbstream
Output
Extraction complete! Backup directories have been extracted to the "restore" directory.

Kết quả trên cho biết rằng quá trình đã hoàn tất thành công. Nếu ta kiểm tra lại nội dung của folder backup hàng ngày, thì một file tin extract-progress.log và một folder restore đã được tạo.

Nếu ta chỉnh sửa log extract , ta có thể xác nhận bản backup mới nhất đã được extract thành công. Các thông báo thành công backup khác được hiển thị trước đó trong file .

  • tail extract-progress.log
Output
170420 17:23:32 [01] decrypting and decompressing ./performance_schema/socket_instances.frm.qp.xbcrypt 170420 17:23:32 [01] decrypting and decompressing ./performance_schema/events_waits_summary_by_user_by_event_name.frm.qp.xbcrypt 170420 17:23:32 [01] decrypting and decompressing ./performance_schema/status_by_user.frm.qp.xbcrypt 170420 17:23:32 [01] decrypting and decompressing ./performance_schema/replication_group_members.frm.qp.xbcrypt 170420 17:23:32 [01] decrypting and decompressing ./xtrabackup_logfile.qp.xbcrypt 170420 17:23:33 completed OK! Finished work on incremental-04-20-2017_17-15-03.xbstream

Nếu ta di chuyển vào folder restore , các folder tương ứng với các file backup mà ta đã extract hiện có sẵn:

  • cd restore
  • ls -F
Output
full-04-20-2017_14-55-17/ incremental-04-20-2017_17-15-03/

Các folder backup chứa các file backup thô, nhưng chúng vẫn chưa ở trạng thái mà MySQL có thể sử dụng. Để khắc phục điều đó, ta cần chuẩn bị các file .

Chuẩn bị bản backup cuối cùng

Tiếp theo, ta sẽ chuẩn bị các file backup . Để làm như vậy, bạn phải ở trong folder restore có chứa full- và bất kỳ bản backup incremental- nào. Tập lệnh sẽ áp dụng các thay đổi từ bất kỳ folder incremental- nào vào folder backup full- . Sau đó, nó sẽ áp dụng các bản ghi để tạo ra một tập dữ liệu nhất quán mà MySQL có thể sử dụng.

Nếu vì bất kỳ lý do gì bạn không muốn khôi phục một số thay đổi, thì bây giờ là cơ hội cuối cùng để bạn xóa các folder backup gia tăng đó khỏi folder restore (các file backup gia tăng sẽ vẫn có sẵn trong folder mẹ). Mọi folder incremental- còn lại trong folder hiện tại sẽ được áp dụng cho folder backup full- .

Khi đã sẵn sàng , hãy gọi script prepare-mysql.sh . , hãy đảm bảo bạn đang ở trong folder restore nơi chứa các folder backup riêng lẻ của bạn:

  • sudo -u backup prepare-mysql.sh
Output
Backup looks to be fully prepared. Please check the "prepare-progress.log" file to verify before continuing. If everything looks correct, you can apply the restored files. First, stop MySQL and move or remove the contents of the MySQL data directory: sudo systemctl stop mysql sudo mv /var/lib/mysql/ /tmp/ Then, recreate the data directory and copy the backup files: sudo mkdir /var/lib/mysql sudo xtrabackup --copy-back --target-dir=/backups/mysql/Thu/restore/full-04-20-2017_14-55-17 Afterward the files are copied, adjust the permissions and restart the service: sudo chown -R mysql:mysql /var/lib/mysql sudo find /var/lib/mysql -type d -exec chmod 750 {} \; sudo systemctl start mysql

Kết quả kết quả ở trên cho biết tập lệnh nghĩ rằng bản backup đã được chuẩn bị đầy đủ và bản backup full- hiện đại diện cho một tập dữ liệu hoàn toàn nhất quán. Khi kết quả có trạng thái, bạn nên kiểm tra file prepare-progress.log trình.log để xác nhận không có lỗi nào được báo cáo trong quá trình này.

Tập lệnh không thực sự sao chép các file vào folder dữ liệu của MySQL để bạn có thể xác minh mọi thứ đều chính xác.

Khôi phục dữ liệu backup vào Thư mục dữ liệu MySQL

Nếu bạn hài lòng rằng mọi thứ đều theo thứ tự sau khi xem lại log , bạn có thể làm theo các hướng dẫn được nêu trong kết quả prepare-mysql.sh .

Đầu tiên, dừng quá trình MySQL đang chạy:

  • sudo systemctl stop mysql

Vì dữ liệu backup có thể xung đột với nội dung hiện tại của folder dữ liệu MySQL, ta nên xóa hoặc di chuyển folder /var/lib/mysql . Nếu bạn có dung lượng trên hệ thống file của bạn , tùy chọn tốt nhất là di chuyển nội dung hiện tại sang /tmp hoặc nơi khác trong trường hợp có sự cố:

  • sudo mv /var/lib/mysql/ /tmp

Tạo lại một folder /var/lib/mysql . Ta cần sửa các quyền trong giây lát, vì vậy ta chưa cần phải lo lắng về điều đó:

  • sudo mkdir /var/lib/mysql

Bây giờ, ta có thể sao chép bản backup đầy đủ vào folder dữ liệu MySQL bằng tiện ích xtrabackup . Thay thế đường dẫn đến bản backup đầy đủ đã chuẩn bị của bạn trong lệnh dưới đây:

  • sudo xtrabackup --copy-back --target-dir=/backups/mysql/Thu/restore/full-04-20-2017_14-55-17

Nhật ký đang chạy của các file được sao chép sẽ hiển thị trong suốt quá trình. Khi các file được đặt xong, ta cần sửa lại quyền sở hữu và quyền để user MySQL và group sở hữu và có thể truy cập cấu trúc đã khôi phục:

  • sudo chown -R mysql:mysql /var/lib/mysql
  • sudo find /var/lib/mysql -type d -exec chmod 750 {} \;

Các file đã khôi phục của ta hiện nằm trong folder dữ liệu MySQL.

Khởi động lại MySQL để hoàn tất quá trình:

  • sudo systemctl start mysql

Kiểm tra xem các dữ liệu đã được khôi phục bằng cách xem các nội dung của playground.equipment bảng. , bạn sẽ được yêu cầu nhập password root MySQL để tiếp tục:

  • mysql -u root -p -e 'SELECT * FROM playground.equipment;'
Output
+----+-------+-------+--------+ | id | type | quant | color | +----+-------+-------+--------+ | 1 | slide | 2 | blue | | 2 | swing | 10 | yellow | +----+-------+-------+--------+ 2 rows in set (0.02 sec)

Dữ liệu của ta đã được khôi phục thành công.

Sau khi khôi phục dữ liệu , điều quan trọng là phải quay lại và xóa folder restore . Các bản backup gia tăng trong tương lai không thể được áp dụng cho bản backup đầy đủ khi nó đã được chuẩn bị, vì vậy ta nên xóa nó. Hơn nữa, không nên để các folder backup không được mã hóa trên đĩa vì lý do bảo mật:

  • cd ~
  • sudo rm -rf /backups/mysql/"$(date +%a)"/restore

Lần tới khi ta cần một bản sao sạch của các folder backup , ta có thể extract chúng từ các file backup .

Tạo công việc Cron để chạy backup hàng giờ

Bây giờ ta đã xác minh quá trình backup và khôi phục đang hoạt động trơn tru, ta nên cài đặt cron việc cron để tự động backup thường xuyên.

Ta sẽ tạo một tập lệnh nhỏ trong folder /etc/cron.hourly để tự động chạy tập lệnh backup của ta và ghi lại kết quả. Quy trình cron sẽ tự động chạy sau mỗi giờ:

  • sudo nano /etc/cron.hourly/backup-mysql

Bên trong, ta sẽ gọi tập lệnh backup với tiện ích systemd-cat để kết quả sẽ có sẵn trong log . Ta sẽ đánh dấu chúng bằng mã định danh backup-mysql để ta có thể dễ dàng lọc các log :

/etc/cron.hourly/backup-mysql
#!/bin/bash sudo -u backup systemd-cat --identifier=backup-mysql /usr/local/bin/backup-mysql.sh 

Lưu file khi bạn hoàn tất. Làm cho tập lệnh có thể thực thi bằng lệnh :

  • sudo chmod +x /etc/cron.hourly/backup-mysql

Tập lệnh backup bây giờ sẽ chạy hàng giờ. Bản thân script sẽ thực hiện việc dọn dẹp các bản backup cũ hơn ba ngày trước.

Ta có thể kiểm tra tập lệnh cron bằng cách chạy nó theo cách thủ công:

  • sudo /etc/cron.hourly/backup-mysql

Sau khi hoàn tất, hãy kiểm tra log để tìm thông báo log bằng lệnh :

  • sudo journalctl -t backup-mysql
Output
-- Logs begin at Wed 2017-04-19 18:59:23 UTC, end at Thu 2017-04-20 18:54:49 UTC. -- Apr 20 18:35:07 myserver backup-mysql[2302]: Backup successful! Apr 20 18:35:07 myserver backup-mysql[2302]: Backup created at /backups/mysql/Thu/incremental-04-20-2017_18-35-05.xbstream

Kiểm tra lại sau vài giờ đảm bảo rằng các bản backup bổ sung đang được thực hiện.

Kết luận

Trong hướng dẫn này, ta đã cài đặt các công cụ Percona Xtrabackup để giúp tạo ảnh chụp nhanh trực tiếp dữ liệu MySQL của ta một cách thường xuyên. Ta đã cấu hình MySQL và user backup hệ thống, cài đặt khóa mã hóa để bảo mật các file backup của ta , sau đó cài đặt các tập lệnh để tự động hóa các phần của quy trình backup và khôi phục.

Tập lệnh backup tạo bản backup đầy đủ vào đầu mỗi ngày và backup gia tăng mỗi giờ sau đó, giữ ba ngày backup bất kỳ lúc nào. Các file được mã hóa và khóa mã hóa được dùng kết hợp với các công nghệ backup khác để chuyển dữ liệu ra khỏi trang web nhằm bảo quản an toàn. Việc extract và chuẩn bị các tập lệnh cho phép ta tập hợp các bản backup trong ngày thành một bộ dữ liệu nhất quán được dùng để khôi phục hệ thống.


Tags:

Các tin liên quan

Cách cấu hình sao chép nhóm MySQL trên Ubuntu 16.04
2017-04-13
Cách cài đặt MySQL mới nhất trên Ubuntu 16.04
2017-04-06
Cách cấu hình SSL / TLS cho MySQL trên Ubuntu 16.04
2017-03-20
Cách Import, Export database trong MySQL hoặc MariaDB
2016-12-21
Cách thay đổi thư mục dữ liệu MySQL sang vị trí mới trên CentOS 7
2016-12-19
Cách thay đổi thư mục dữ liệu MySQL sang vị trí mới bằng cách sử dụng liên kết biểu tượng
2016-12-02
Cách cài đặt MySQL trên CentOS 7
2016-12-01
Cách cài đặt MySQL trên Ubuntu 16.04
2016-11-23
Cách kết nối với server MySQL từ xa bằng MySQL Workbench
2016-10-21
Cách cấu hình một cụm Galera với MySQL 5.6 trên Ubuntu 16.04
2016-09-02