ว่าด้วยเรื่องการ Replication ของ MySQL เพื่อทำการ replicate ข้อมูลในฐานข้อมูล (database) จากเครื่องหลัก (Master) ไปยังเครื่องสำรอง (Slave) ได้
หลังจากที่คอนฟิก Replication ถูกต้องเรียบร้อย เมื่อมีการเปลี่ยนแปลงข้อมูลในฐานข้อมูลบนเครื่องหลัก (Master) ไม่ว่าจะเป็นการ INSERT, UPDATE, DELETE หรือ แก้ไข table การเปลี่ยนแปลงนี้จะถูกส่งต่อ (replicate) ไปยังเครื่องสำรอง (Slave) โดยอัตโนมัติ
การคอนฟิก Replication ส่วนใหญ่จะเป็นการ ทำเพือกระจายโหลดการทำงาน จากเครื่องหลัก ด้านการ Select ข้อมูล ไปยังเครื่อง Slave เพราะโดยธรรมชสติของการใช้งานแล้วเรามักจะใช้งานด้านการ Select มากกว่าการ INSERT, UPDATE, DELETE อยู่แล้ว ซึ่งในจุด นี้ ต้องเขียนให้ตัวซอฟแวร์สามารถรับรู้รองรับการแยกการ Select เครื่องด้วยน่ะครับ
1 ข้อควรจำใส่ใจ อย่างมาก Slave ต้องไม่มีการไปเขียนค่า INSERT, UPDATE, DELETE น่ะครับไม่งั้นข้อมูลจะเพี้ยนไม่ตรงกับเครื่องหลักเลยทีเดียว
2 ข้อควรจำสอง Replication เป็นการ ดึงข้อมูลจากตัวหลังตลอดเวลาให้ ตัว Slave มันมีข้อมูลเหมื่อนตัวแรก ไม่ใช้การแบล๊คอัพข้อมูลน่ะครับเกิดไปทำการที่ db ตัวหลักเสียหายเช่นไปลบ Slave ก็ ตามไปเหมื่อนกัน
ระบบทดสอบ
ตัวอย่างในบทความนี้ จะทดสอบบนเครื่องสองเครื่องที่ติดตั้ง CentOS 6.9 และ MySQL 5.1.73 ที่ติดตั้งผ่าน Yum ตามปกติ
เครื่อง Master
- ip: 192.168.1.1
- hostname: dba-mas
เครื่อง Slave
- ip: 192.168.1.2
- hostname: dba-slv
หมายเหตุ
yum install mysql-server ทั้งสองเครื่องให้เรียบร้อยน่ะครับถ้าเริ่มทำระบบใหม่ ๆ
ทั้งสองเครื่องต้อง ไม่ข้อมูล เท่า ๆ และ เหมื่อน ๆ กัน
ถ้า จะเพิ่ม slave หลังจาก ที่ระบบเดิมมีอยู่แล้ว ให้ mysqldump ข้อมูล จาก master มา slave ให้ข้อมูล ทั้งสองเครื่องตรงกันเป๊ะ ๆ ตรงนี้แนะนำว่าให้ปิดการบริการ master ระหว่างการทำงานไปน่ะ sync เสร็จค่อยเปิด
เครื่อง MASTER — สร้าง USER สำหรับ REPLICATION
เริ่มต้น ต้องสร้าง user ของ MySQL บนเครื่อง Master เพื่ออนุญาตสิทธิในการทำ ‘REPLICATION’ จากเครื่อง Slave คือสร้างสิทะ์ ให้เข้าไปอ่านได้นั่นแหละ หลักการคือมันจะวิ่งไปอ่านมาแล้วทำการ insert เข้าตัวมันเอง
ตัวอย่างการสร้าง user ชื่อ ‘repl’ และรหัส ‘repl1234’เพื่อให้สิทธิการทำ REPLICATION จากเครื่องที่มี ip 192.168.1.2
[root@dba-mas ~]# mysql -u root -pmysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.2' IDENTIFIED BY 'repl1234';
เครื่อง MASTER — คอนฟิก REPLICATION MASTER
บนเครื่อง Master ปิดเซอร์วิส MySQL แล้วแก้ไขไฟล์ /etc/my.cnf เพื่อเปิดคุณสมบัติ binary log (log-bin) และเซ็ต server-id
[root@dba-mas ~]# service mysql stop
Shutting down MySQL.. [ OK ]
ตัวอย่างไฟล์คอนฟิก /etc/my.cnf เพื่อคอนฟิกเป็น Replication Master
[root@dba-mas ~]# cat /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
ใช้คำสั่ง service เพื่อรันเซอร์วิส MySQL
[root@dba-mas ~]# service mysql start
Starting MySQL. [ OK ]
เครื่อง MASTER — ตรวจสอบสถานะของ MASTER BINARY LOG
บนเครื่อง Master ใช้คำสั่ง SHOW MASTER STATUS ตรวจสอบสถานะของ Master Binary Log
เราจะใช้ค่า ‘File’ และ ‘Position’ เพื่อระบุบนเครื่อง Slave
[root@dba-mas ~]# mysql -u root -pmysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 224 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
เครื่อง SLAVE — คอนฟิก REPLICATION SLAVE
บนเครื่อง Slave ปิดเซอร์วิส MySQL เพื่อแก้ไขคอนฟิกไฟล์ /etc/my.cnf
[root@dba-slv ~]# service mysql stop
Shutting down MySQL.. [ OK ]
เบื้องต้นบนเครื่อง Slave คอนฟิกแค่ ‘server-id’ ที่มีค่าแตกต่างจากเครื่อง Master
ถ้าทำ slave หลาย ๆ เครื่อง ก็เรียงเลข server-i d ไปครับอย่าให้เลขชนกันเป็นพอ
[root@dba-slv ~]# cat /etc/my.cnf
[mysqld]
server-id=2
รันเซอร์วิส MySQL บนเครื่อง Slave
[root@dba-slv ~]# service mysql start
Starting MySQL. [ OK ]
ใช้คำสั่ง CHANGE MASTER เพื่อระบุ ip ของ Master ชื่อ user, password ที่ใช้เพื่อการทำ Replication และต้องระบุค่า log_file (File) และ log_pos (Position) ที่ได้จากผลลัพธ์ในการรันคำสั่ง SHOW MASTER STATUS บนเครื่อง Master
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.1',
MASTER_USER='repl',
MASTER_PASSWORD='repl1234',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=224;
Query OK, 0 rows affected (0.03 sec)
รันคำสั่ง START SLAVE เพื่อเริ่มต้นการทำ Replicate ข้อมูลจาก เครื่อง Master
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
ตรวจสอบสถานะ Replication บนเครื่อง Slave
mysql> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 244
Relay_Log_File: dba-slv-relay-bin.000004
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 244
Relay_Log_Space: 411
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
1 row in set (0.00 sec)
หากคอนฟิกถูกต้อง ค่า ‘Slave_IO_State’ จะแสดงเป็น ‘Waiting for master to send event’
ทดสอบการ REPLICATION
ทดสอบสร้าง database บนเครื่อง Master
[root@dba-mas ~]# mysql -u root -p mysql> CREATE DATABASE test1; Query OK, 1 row affected (0.01 sec)mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test1 | +--------------------+ 3 rows in set (0.00 sec)
ข้อมูลการสร้าง database จะถูกส่งต่อ (replicate) ไปยังเครื่อง Slave โดยอัตโนมัติ
[root@dba-slv ~]# mysql -u root -p
Enter password:
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test1 |
+--------------------+
3 rows in set (0.00 sec)
สร้าง table และทดสอบการ INSERT ข้อมูล
[root@dba-mas ~]# mysql -u root -p mysql> use test; mysql> CREATE TABLE books (id INTEGER, name VARCHAR(255)); mysql> INSERT INTO books VALUES (1, 'data1'); mysql> INSERT INTO books VALUES (2, 'data2');mysql> SELECT * FROM books; +------+-----------------+ | id | name | +------+-----------------+ | 1 | data1 | | 2 | data2 | +------+-----------------+ 2 rows in set (0.00 sec)
การเปลี่ยนแปลงบนเครื่อง Master จะถูก replicate ไปยังเครื่อง Slave โดยอัตโนมัติ
[root@dba-slv ~]# mysql -u root -p
mysql> use test;
mysql> SELECT * FROM books;
+------+-----------------+
| id | name |
+------+-----------------+
| 1 | data1 |
| 2 | data2 |
+------+-----------------+
2 rows in set (0.00 sec)