การ backup และทำ replication database โดยไม่ต้องปิด server by

31
May
1

โดยปกติแล้ว การ backup database เรามักจะใช้คำสั่ง mysqldump กันใช่ไหมครับ แต่คำสั่งนี้มีข้อเสียที่ร้ายแรงอย่างหนึ่งคือตารางที่ backup ทุกตารางจะต้องถูก Lock จนกว่าจะทำการ backup เสร็จ ทำให้ผู้ใช้ไม่สามารถให้บริการเว็บไซต์ของเราในระหว่าง backup ได้ ส่งผลให้ต้องมีการปิด maintenance ระหว่าง backup หรือถูกบังคับให้ทำ Replication แบ่งสองเครื่องทั้งที่เราเองก็มีทรัพยากรจำกัด เนื้อที่จำกัด ไม่สามารถทำ Replication กับทุกๆ ฐานข้อมูลได้ วันนี้ผมมีวิธีช่วย backup ดีๆ ง่ายๆ มาแนะนำคือเราจะใช้ Xtrabackup ซึ่งเป็นชุดซอฟต์แวร์ของ Percona Server นั่นเอง

ก่อนอื่นต้องอธิบายก่อนว่า Percona Server คือ MySQL เวอร์ชั่นปรับปรุงนั่นเอง โดยทางทีมพัฒนาได้นำเอา InnoDB Engine ไปพัฒนาและปรับปรุงประสิทธิภาพหลายๆ อย่าง และใส่ฟีเจอร์เด็ดๆ เพิ่มเข้ามามากมายจนสุดท้ายออกมาเป็น Percona Server ซึ่งเจ้านี่มีความเข้ากันได้กับ InnoDB Engine ตัวเดิมของ MySQL 100% ครับ ใช้แทน MySQL ได้ทุกประการ รวมไปถึง Tools ต่างๆ ที่เคยใช้กับ MySQL ได้ก็จะใช้กับ Percona Server ได้เช่นกัน (แม้จะเป็น MyISAM ก็สามารถใช้งานได้ปกติไม่มีปัญหาใดๆ ครับ แค่ performance จะยังคงเหมือน MySQL ไม่ได้ถูกปรับปรุงขึ้นตามด้วย)

ส่วน Tools ที่เราจะใช้สำหรับ Backup จริงๆ ชื่อ XtraBackup ครับ ซึ่งเป็นทีมพัฒนาทีมเดียวกับ Percona Server (และ Percona Data Recovery Tool for InnoDB จากบทความที่แล้วด้วยเช่นกัน) เจ้าตัว Xtrabackup นี้จริงๆ ใช้งานกับ mysql ธรรมดาที่ไม่ใช่ Percona Server ก็ได้แต่จะมีความสามารถบางอย่างที่ทำไม่ได้หากไม่ได้ใช้ Percona Server ครับ เช่น การ Backup/Restore ฐานข้อมูลเฉพาะตารางบางตารางที่เราต้องการ (เพื่อประหยัดเวลา/cpu ของ server) เป็นต้น ซึ่ง Tools ตัวนี้จะช่วย Backup แบบไม่ต้องปิด server (ไม่ต้อง Lock Table ระหว่างทำการ backup) ได้เฉพาะตารางที่ใช้งานฐานข้อมูลชนิด InnoDB เท่านั้น (จริงๆ MyISAM ก็ใช้ Tools ตัวนี้ช่วย backup ได้ครับ แค่จะยังติด lock อยู่เหมือนเดิม) นอกจากนี้หากเราใช้งานฐานข้อมูลบน VPS หรือ Cloud ที่ให้พื้นที่ใช้งานน้อยๆ ยังสามารถ Backup เป็นแบบ Incremental หรือส่งไฟล์ Backup เป็น stream ไปเข้า server ตัวอื่นที่มีพื้นที่เยอะกว่าได้อีกด้วย! (Amazing ไหมละ!) ซึ่งการ Backup โดยที่ Server ยังคงให้บริการได้ปกติแบบนี้เราจะเรียกว่า Hot Backup ครับ ส่วนการ Backup ที่จำเป็นต้องปิด Server ระหว่าง Backup เราจะเรียกว่า Cold Backup เอาละหลังจากติดตั้งเสร็จแล้ว (และต้องมี account root ของ OS ด้วยนะครับ) ลองมาดูวิธีใช้งานกันดีกว่าครับ (ทุกขั้นต้อนต้องทำขณะเป็น root ครับ)

ขั้นตอนการ Backup

  1. innobackupex –user=DBUSER –password=DBUSERPASS –no-lock –defaults-file=/path/to/my.cnf /path/to/BACKUP-DIR/
    แก้ dbuser/dbuserpass ให้เรียบร้อย และ path นี้เป็น dir สำหรับเก็บ backup ที่ได้ออกมา รอจนปรากฎคำว่า “innobackupex: completed OK!” ที่บรรทัดสุดท้าย แสดงว่าสำเร็จ (ถ้าโปรแกรมฟ้องว่าหา datadir ไม่พบให้ไปแก้ my.cnf เติม datadir เข้าไปครับ ทั่วไป default จะอยู่ที่ /var/lib/mysql แต่ถ้ามี datadir แล้วยังฟ้อง แสดงว่าหาไฟล์ my.cnf ไม่เจอ ตรวจสอบไฟล์ my.cnf ให้ดีว่า path ที่ระบุถูกต้องหรือไม่)
  2. innobackupex –apply-log /path/to/BACKUP-DIR/xxx
    โดยที่ xxx คือ dir ที่โปรแกรมสร้างขึ้นซึ่งมักจะเป็นชื่อวันที่ + เวลาที่ backup รอจนปรากฎคำว่า “innobackupex: completed OK!” ที่บรรทัดสุดท้าย แสดงว่าสำเร็จ (ถ้าโปรแกรมฟ้องว่า ibbackup เลือก binary ไม่ถูก ให้เติม option –ibbackup ตามด้วยชื่อในหน้านี้โดยเลือกให้ถูกต้องตามที่เขียนไว้ครับ)

ขั้นตอนการ Restore

  1. เมื่อต้องการ Restore Backup ที่เก็บไว้ ให้สั่ง “service mysql stop” ลบข้อมูลใน datadir ทิ้งให้ว่างเปล่า (หรือจะแค่เปลี่ยนชื่อ ป้องกันความผิดพลาดก็ได้ครับ) แล้วสั่ง
    innobackupex –copy-back –default-file=/path/to/my.cnf  /path/to/BACKUP-DIR/xxx
    รอจนปรากฎคำว่า “innobackupex: completed OK!” ที่บรรทัดสุดท้าย แสดงว่าสำเร็จ ถ้าขึ้นว่า “Original data directory ‘./’ is not empty! at /opt/local/bin/innobackupex” แสดงว่าหาไฟล์ my.cnf ไม่เจอ
  2. chown -R mysql:mysql /var/lib/mysql
    เพื่อเปลี่ยน permission จาก root (user ที่เราใช้อยู่) เป็น mysql แล้วสั่ง “service mysql start” เป็นอันเสร็จ ง่ายไหมล่ะครับ หุหุ

ขั้นตอนการทำ Replication

อันนี้เป็นของแถมครับ โดยปกติแล้วเราจะทำ Replication กันเราจะต้อง Backup ข้อมูลจากเครื่อง Master และสั่ง Lock Table ไม่ให้มีการเปลี่ยนแปลงข้อมูลได้จนกว่าจะ Setup Replication เสร็จ แต่นี่ไม่ต้องครับ ตัว Master ยังคงให้บริการได้ปกติและเราสามารถเพิ่มจำนวน Slave กี่ตัวก็ได้ในขณะนั้นตามต้องการ โดยให้ทำตามขั้นตอน Backup จนจบขั้นตอนที่ 2 แล้วต่อด้วยขั้นตอนด้านล่างต่อครับ

  1. หลังได้ไฟล์ Backup ชื่อ xxx (เป็นเวลา backup) แล้วสั่ง
    tar -zcvf db.tar.gz xxx
    ให้เรียบร้อย โดย xxx คือ dir ที่เก็บ backup ของเราเอาไว้ (ที่ชื่อเป็นวัน-เวลา backup นั่นแหละครับ) เพื่อเตรียมโยนไปยัง server อีกตัวที่ต้องการจะทำ Slave ครับ
  2. โยนไฟล์ db.tar.gz ที่บีบอัดไว้ไปยังเครื่อง Slave ด้วย rsync, scp ตามแต่สะดวกครับ หรือใครไม่ได้ลงไว้ ก็ใช้ tools มาตรฐานเลยครับ ssh ด้วยคำสั่ง
    ssh USER@SLAVE_IP cat < “/path/to/db.sql.gz” “>” “/path/to/save”
    ก็แก้ไข USER, SLAVE_IP, path ตัวแรก (เครื่องที่มี backup ไว้), path ที่ต้องการจะส่งไปให้ (เครื่อง slave) ให้ถูกต้องแล้วส่งไฟล์ได้เลยครับ
  3. โยนไฟล์ my.cnf จากเครื่อง Master ไปยังเครื่อง Slave ด้วยคำสั่งเดียวกันกับข้อ 2 ครับ
  4. mysql -uroot -p เข้าในเครื่อง Master ไปสร้าง user สำหรับเครื่อง Slave ดังนี้ครับ
    GRANT REPLICATION SLAVE ON *.*  TO ‘repl’@'$slaveip’ IDENTIFIED BY ‘$slavepass’;
    repl คือ user mysql ส่วน $slaveip, $slavepass ก็ตามชื่อเลยครับ
  5. login เข้าเครื่อง Slave แล้ว untar ด้วย
    tar -zxvf db.tar.gz
    ที่ตำแหน่งที่เราเก็บไฟล์ไว้ตามคำสั่งในข้อ 2
  6. service mysql stop ที่เครื่อง slave
  7. copy dir xxx ที่ได้จากการแกะ tar ไปที่ datadir ของเครื่อง Slave ทับไปเลย (หรือจะ mv เปลี่ยนชื่อ datadir เดิมเก็บไว้ก่อนก็ได้เช่นเดิมครับ)
  8. แก้ไฟล์ my.cnf ที่เครื่อง slave โดยบรรทัด server-id แก้เป็น
    server-id=2
  9. ถ้าใช้ ubuntu หรือ debian ให้แก้ไฟล์ /etc/mysql/debian.cnf ซึ่งจะมี user debian-sys-maint อยู่ในนั้นด้วยครับ โดยแก้ password ให้เป็น password เดียวกับเครื่อง Master ไม่อย่างนั้น startup script “service mysql stop/start/restart” จะพังครับ
  10. chown -R mysql:mysql datadir
    โดย datadir แก้เป็นตำแหน่งที่เก็บข้อมูล database ตามต้องการครับ (default คือ /var/lib/mysql)
  11. เปิดไฟล์ xtrabackup_binlog_info ที่อยู่ใน datadir ที่เราพึ่ง copy มาจะพบเลขลักษณะประมาณนี้
    TheMaster-bin.000001 481
    ของคุณจะเป็นเลขอื่นที่ไม่ซ้ำกันกับผมแน่ๆ ครับ เป็นเลขตำแหน่ง log สุดท้ายของ database ที่เราต้องการจะ replicate นั่นเอง
  12. mysql -uroot -p
    เข้า mysql เครื่อง Slave ครับแล้วพิมพ์

    CHANGE MASTER TO
    MASTER_HOST='$masterip',
    MASTER_USER='repl',
    MASTER_PASSWORD='$slavepass',
    MASTER_LOG_FILE='TheMaster-bin.000001',
    MASTER_LOG_POS=481;
    START SLAVE;
    แก้ข้อมูลให้ถูกต้องโดยตามข้อมูลที่สร้างที่ผ่านมา
  13. ลองสั่ง SHOW SLAVE STATUS \G โดยยังไม่ออกจาก MySQL Console หากพบบรรทัดเหล่านี้แสดงว่าสำเร็จแล้ว
             ...
             Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
             ...

เป็นไงบ้าง เจ๋งใช่ไหมละครับ ลองเก็บไปใช้กันดูนะครับ :)

Enjoy this article?

Consider subscribing to our RSS feed!

1 ความเห็น

  1. varawut
    18:27 on December 27th, 2013

    จะลองนำไปทดสอบครับ ขอบคุณครับ

ใส่ความเห็น

RSS feed for comments on this post