การจำลองแบบ MySQL Master-Slave บนเครื่องเดียวกัน
เผยแพร่แล้ว: 2022-03-11การจำลองแบบ MySQL เป็นกระบวนการที่ช่วยให้สามารถคัดลอกข้อมูลจากเซิร์ฟเวอร์ฐานข้อมูล MySQL (ต้นแบบ) หนึ่งเครื่องไปยังเซิร์ฟเวอร์ฐานข้อมูล MySQL (ทาส) ได้โดยอัตโนมัติ โดยปกติจะใช้เพื่อกระจายการเข้าถึงการอ่านบนเซิร์ฟเวอร์หลายเครื่องเพื่อความสามารถในการปรับขนาด แม้ว่าจะสามารถใช้เพื่อวัตถุประสงค์อื่น เช่น เพื่อเฟลโอเวอร์ หรือการวิเคราะห์ข้อมูลบนทาสเพื่อไม่ให้โอเวอร์โหลดมาสเตอร์
เนื่องจากการจำลองแบบมาสเตอร์-สเลฟเป็นการจำลองแบบทางเดียว (จากมาสเตอร์ไปยังสเลฟ) เฉพาะฐานข้อมูลหลักเท่านั้นที่ใช้สำหรับการดำเนินการเขียน ในขณะที่การดำเนินการอ่านอาจแพร่กระจายในฐานข้อมูลสเลฟหลายฐานข้อมูล สิ่งนี้หมายความว่าหากใช้การจำลองแบบ master-slave เป็นโซลูชันการขยายขนาด คุณจะต้องกำหนดแหล่งข้อมูลอย่างน้อยสองแหล่ง แหล่งหนึ่งสำหรับการดำเนินการเขียน และแหล่งที่สองสำหรับการดำเนินการอ่าน
นักพัฒนา MySQL มักจะทำงานบนเครื่องเพียงเครื่องเดียวและมักจะมีสภาพแวดล้อมการพัฒนาทั้งหมดบนเครื่องนั้นด้วยตรรกะที่ว่าพวกเขาไม่ได้ขึ้นอยู่กับเครือข่ายหรือการเชื่อมต่ออินเทอร์เน็ต หากจำเป็นต้องมีการจำลองแบบ master-slave เนื่องจากจำเป็นต้องทดสอบการจำลองแบบในสภาพแวดล้อมการพัฒนาก่อนที่จะปรับใช้การเปลี่ยนแปลงที่อื่น พวกเขาจะต้องสร้างในเครื่องเดียวกัน แม้ว่าการตั้งค่าอินสแตนซ์ MySQL ตัวเดียวจะค่อนข้างง่าย แต่เราจำเป็นต้องใช้ความพยายามเป็นพิเศษในการตั้งค่าวินาที จากนั้นจึงทำการจำลองแบบมาสเตอร์-สเลฟ
สำหรับบทช่วยสอนทีละขั้นตอนนี้ ฉันเลือก Ubuntu Linux เป็นระบบปฏิบัติการโฮสต์ และคำสั่งที่ให้มานั้นมีไว้สำหรับระบบปฏิบัติการนั้น หากคุณต้องการตั้งค่าการจำลองแบบ master-slave ของ MySQL บนระบบปฏิบัติการอื่น คุณจะต้องทำการปรับเปลี่ยนคำสั่งเฉพาะ อย่างไรก็ตาม หลักการทั่วไปของการตั้งค่าการจำลองแบบ master-slave ของ MySQL บนเครื่องเดียวกันนั้นเหมือนกันสำหรับระบบปฏิบัติการทั้งหมด
การติดตั้งอินสแตนซ์ MySQL ตัวแรก
หากคุณมีฐานข้อมูล MySQL หนึ่งอินสแตนซ์ติดตั้งอยู่ในเครื่องแล้ว คุณสามารถข้ามขั้นตอนนี้ได้
วิธีที่ง่ายที่สุดในการติดตั้ง MySQL บน Ubuntu คือการเรียกใช้คำสั่งต่อไปนี้จากพรอมต์เทอร์มินัล:
sudo apt-get install mysql-server
ระหว่างขั้นตอนการติดตั้ง คุณจะได้รับแจ้งให้ตั้งรหัสผ่านสำหรับผู้ใช้ root
ของ MySQL
การตั้งค่า mysqld_multi
เพื่อจัดการอินสแตนซ์ MySQL สองอินสแตนซ์บนเครื่องเดียวกันอย่างมีประสิทธิภาพ เราจำเป็นต้องใช้ mysqld_multi
ขั้นตอนแรกในการตั้งค่า mysqld_multi
คือการสร้างกลุ่ม [mysqld]
สองกลุ่มแยกกันในไฟล์ my.cnf
ที่มีอยู่ ตำแหน่งเริ่มต้นของไฟล์ my.cnf
บน Ubuntu คือ /etc/mysql/
ดังนั้น เปิดไฟล์ my.cnf
ด้วยโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ แล้วเปลี่ยนชื่อกลุ่ม [mysqld]
ที่มีอยู่เป็น [mysqld1]
กลุ่มที่เปลี่ยนชื่อนี้จะใช้สำหรับการกำหนดค่าของอินสแตนซ์ MySQL ตัวแรกและจะได้รับการกำหนดค่าเป็นอินสแตนซ์หลักด้วย เช่นเดียวกับการจำลองแบบ master-slave ของ MySQL แต่ละอินสแตนซ์ต้องมี server-id
เฉพาะของตัวเอง ให้เพิ่มบรรทัดต่อไปนี้ในกลุ่ม [mysqld1]
:
server-id = 1
เนื่องจากเราต้องการกลุ่ม [mysqld]
แยกต่างหากสำหรับอินสแตนซ์ MySQL ตัวที่สอง ให้คัดลอกกลุ่ม [mysqld1]
ด้วยการกำหนดค่าปัจจุบันทั้งหมด และวางลงด้านล่างในไฟล์ my.cnf
เดียวกัน ตอนนี้ เปลี่ยนชื่อกลุ่มที่คัดลอกเป็น [mysqld2]
และทำการเปลี่ยนแปลงต่อไปนี้ในการกำหนดค่าสำหรับทาส:
server-id = 2 port = 3307 socket = /var/run/mysqld/mysqld_slave.sock pid-file = /var/run/mysqld/mysqld_slave.pid datadir = /var/lib/mysql_slave log_error = /var/log/mysql_slave/error_slave.log relay-log = /var/log/mysql_slave/relay-bin relay-log-index = /var/log/mysql_slave/relay-bin.index master-info-file = /var/log/mysql_slave/master.info relay-log-info-file = /var/log/mysql_slave/relay-log.info read_only = 1
ในการตั้งค่าอินสแตนซ์ MySQL ตัวที่สองเป็นทาส ให้ตั้งค่า server-id
เป็น 2 เนื่องจากต้องแตกต่างจาก server-id ของมาสเตอร์
เนื่องจากทั้งสองอินสแตนซ์จะทำงานบนเครื่องเดียวกัน ให้ตั้งค่า port
สำหรับอินสแตนซ์ที่สองเป็น 3307
เนื่องจากจะต้องแตกต่างจากพอร์ตที่ใช้สำหรับอินสแตนซ์แรก ซึ่งโดยค่าเริ่มต้นคือ 3306
เพื่อให้อินสแตนซ์ที่สองนี้ใช้ไบนารี MySQL เดียวกันได้ เราจำเป็นต้องตั้งค่าที่แตกต่างกันสำหรับ socket
, pid-file
, datadir
และ log_error
เรายังจำเป็นต้องเปิดใช้ relay-log
เพื่อที่จะใช้อินสแตนซ์ที่สองเป็นทาส (พารามิเตอร์ relay-log
, relay-log-index
รีเลย์ และ relay-log-info-file
) รวมถึงการตั้งค่า master-info-file
สุดท้าย เพื่อให้อินสแตนซ์ทาสเป็นแบบอ่านอย่างเดียว พารามิเตอร์ read_only
ถูกตั้งค่าเป็น 1
คุณควรระมัดระวังกับตัวเลือกนี้ เนื่องจากไม่ได้ป้องกันการเปลี่ยนแปลงในสเลฟอย่างสมบูรณ์ แม้เมื่อตั้งค่า read_only
เป็น 1
การอัปเดตจะได้รับอนุญาตจากผู้ใช้ที่มีสิทธิ์ SUPER
เท่านั้น MySQL เพิ่งเปิดตัวพารามิเตอร์ใหม่ super_read_only
เพื่อป้องกันไม่ให้ผู้ใช้ SUPER
ทำการเปลี่ยนแปลง ตัวเลือกนี้มีอยู่ในเวอร์ชัน 5.7.8
นอกเหนือจากกลุ่ม [mysqld1]
และ [mysqld2]
เรายังต้องเพิ่มกลุ่มใหม่ [mysqld_multi]
ลงในไฟล์ my.cnf
:
[mysqld_multi] mysqld = /usr/bin/mysqld_safe mysqladmin = /usr/bin/mysqladmin user = multi_admin password = multipass
เมื่อเราติดตั้งอินสแตนซ์ MySQL ตัวที่สอง และเราเริ่มต้นทั้งคู่ เราจะให้สิทธิ์ที่เหมาะสมแก่ผู้ใช้ multi_admin
เพื่อให้สามารถปิดอินสแตนซ์ MySQL ได้
สร้างโฟลเดอร์ใหม่สำหรับอินสแตนซ์ MySQL ตัวที่สอง
ในขั้นตอนก่อนหน้านี้ เราได้เตรียมไฟล์การกำหนดค่าสำหรับอินสแตนซ์ MySQL ที่สอง ในไฟล์การกำหนดค่านั้นจะใช้โฟลเดอร์ใหม่สองโฟลเดอร์ ควรใช้คำสั่ง Linux ต่อไปนี้เพื่อสร้างโฟลเดอร์ที่มีสิทธิ์ที่เหมาะสม:
mkdir -p /var/lib/mysql_slave chmod --reference /var/lib/mysql /var/lib/mysql_slave chown --reference /var/lib/mysql /var/lib/mysql_slave mkdir -p /var/log/mysql_slave chmod --reference /var/log/mysql /var/log/mysql_slave chown --reference /var/log/mysql /var/log/mysql_slave
การตั้งค่าความปลอดภัยเพิ่มเติมใน AppArmor
ในสภาพแวดล้อม Linux บางระบบ จำเป็นต้องมีการตั้งค่าความปลอดภัยของ AppArmor เพื่อเรียกใช้อินสแตนซ์ MySQL ตัวที่สอง อย่างน้อยก็จำเป็นสำหรับ Ubuntu
ในการตั้งค่า AppArmor อย่างถูกต้อง ให้แก้ไขไฟล์ /etc/apparmor.d/usr.sbin.mysqld
ด้วยโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ ให้เพิ่มบรรทัดต่อไปนี้:
/var/lib/mysql_slave/ r, /var/lib/mysql_slave/** rwk, /var/log/mysql_slave/ r, /var/log/mysql_slave/* rw, /var/run/mysqld/mysqld_slave.pid rw, /var/run/mysqld/mysqld_slave.sock w, /run/mysqld/mysqld_slave.pid rw, /run/mysqld/mysqld_slave.sock w,
หลังจากที่คุณบันทึกไฟล์แล้ว ให้รีบูตเครื่องเพื่อให้การเปลี่ยนแปลงเหล่านี้มีผล
การติดตั้งอินสแตนซ์ MySQL ที่สอง
อาจมีการปฏิบัติตามแนวทางต่างๆ หลายวิธีในการติดตั้งอินสแตนซ์ MySQL ตัวที่สอง แนวทางที่นำเสนอในบทช่วยสอนนี้ใช้ไบนารี MySQL เดียวกันกับวิธีแรก โดยมีไฟล์ข้อมูลแยกต่างหากที่จำเป็นสำหรับการติดตั้งครั้งที่สอง
เนื่องจากเราได้เตรียมไฟล์การกำหนดค่าและโฟลเดอร์ที่จำเป็นและการเปลี่ยนแปลงด้านความปลอดภัยในขั้นตอนก่อนหน้านี้แล้ว ขั้นตอนการติดตั้งขั้นสุดท้ายของอินสแตนซ์ MySQL ที่สองคือการเริ่มต้นของไดเร็กทอรีข้อมูล MySQL

ดำเนินการคำสั่งต่อไปนี้เพื่อเริ่มต้นไดเร็กทอรีข้อมูล MySQL ใหม่:
mysql_install_db --user=mysql --datadir=/var/lib/mysql_slave
เมื่อเริ่มต้นไดเร็กทอรีข้อมูล MySQL แล้ว คุณสามารถเริ่มอินสแตนซ์ MySQL ทั้งสองได้โดยใช้บริการ mysqld_multi
:
mysqld_multi start
ตั้งรหัสผ่าน root
ทสำหรับอินสแตนซ์ MySQL ตัวที่สองโดยใช้ mysqladmin
กับโฮสต์และพอร์ตที่เหมาะสม โปรดทราบว่าหากไม่ได้ระบุโฮสต์และพอร์ต mysqladmin
จะเชื่อมต่อกับอินสแตนซ์ MySQL ตัวแรกตามค่าเริ่มต้น:
mysqladmin --host=127.0.0.1 --port=3307 -u root password rootpwd
ในตัวอย่างข้างต้น ฉันตั้งรหัสผ่านเป็น “rootpwd” แต่แนะนำให้ใช้รหัสผ่านที่ปลอดภัยกว่า
การกำหนดค่าเพิ่มเติมของ mysqld_multi
ในตอนท้ายของส่วน "การตั้งค่า mysqld_multi" ฉันเขียนว่าเราจะให้สิทธิ์ที่เหมาะสมแก่ผู้ใช้ multi_admin
ในภายหลัง ดังนั้นตอนนี้ก็ถึงเวลาแล้ว เราจำเป็นต้องให้สิทธิ์ที่เหมาะสมแก่ผู้ใช้รายนี้ในทั้งสองกรณี ดังนั้นเรามาเชื่อมต่อกับอินสแตนซ์แรกกันก่อน:
mysql --host=127.0.0.1 --port=3306 -uroot -p
เมื่อเข้าสู่ระบบแล้ว ให้ดำเนินการสองคำสั่งต่อไปนี้:
mysql> GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass'; mysql> FLUSH PRIVILEGES;
ออกจากไคลเอนต์ MySQL และเชื่อมต่อกับอินสแตนซ์ที่สอง:
mysql --host=127.0.0.1 --port=3307 -uroot -p
เมื่อเข้าสู่ระบบแล้ว ให้รันคำสั่งสองคำสั่งเดียวกันกับด้านบน:
mysql> GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass'; mysql> FLUSH PRIVILEGES;
ออกจากไคลเอนต์ MySQL
เริ่มอินสแตนซ์ MySQL ทั้งสองโดยอัตโนมัติเมื่อ Boot
ขั้นตอนสุดท้ายของการตั้งค่า mysqld_multi
คือการติดตั้งสคริปต์บูตอัตโนมัติใน init.d
ในการทำเช่นนั้น ให้สร้างไฟล์ใหม่ที่ชื่อ mysqld_multi
ใน /etc/init.d
และให้สิทธิ์ที่เหมาะสม:
cd /etc/init.d touch mysqld_multi chmod +x /etc/init.d/mysqld_multi
เปิดไฟล์ใหม่นี้ด้วยโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ แล้วคัดลอกสคริปต์ต่อไปนี้:
#!/bin/sh ### BEGIN INIT INFO # Provides: scriptname # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO bindir=/usr/bin if test -x $bindir/mysqld_multi then mysqld_multi="$bindir/mysqld_multi"; else echo "Can't execute $bindir/mysqld_multi"; exit; fi case "$1" in 'start' ) "$mysqld_multi" start $2 ;; 'stop' ) "$mysqld_multi" stop $2 ;; 'report' ) "$mysqld_multi" report $2 ;; 'restart' ) "$mysqld_multi" stop $2 "$mysqld_multi" start $2 ;; *) echo "Usage: $0 {start|stop|report|restart}" >&2 ;; esac
เพิ่มบริการ mysqld_multi
ให้กับระดับการทำงานเริ่ม runlevels
ด้วยคำสั่งต่อไปนี้:
update-rc.d mysqld_multi defaults
รีบูตเครื่องของคุณและตรวจสอบว่าอินสแตนซ์ MySQL ทั้งสองกำลังทำงานโดยใช้คำสั่งต่อไปนี้:
mysqld_multi report
ตั้งค่าการจำลองแบบ Master-slave
ตอนนี้ เมื่อเรามีอินสแตนซ์ MySQL สองอินสแตนซ์ที่ทำงานบนเครื่องเดียวกัน เราจะตั้งค่าอินสแตนซ์แรกเป็นมาสเตอร์ และอินสแตนซ์ที่สองเป็นทาส
ส่วนหนึ่งของการกำหนดค่าได้ดำเนินการไปแล้วในบท “การตั้งค่า mysqld_multi” การเปลี่ยนแปลงเพียงอย่างเดียวที่เหลืออยู่ในไฟล์ my.cnf
คือการตั้งค่าการบันทึกไบนารีบนต้นแบบ ในการดำเนินการนี้ ให้แก้ไขไฟล์ my.cnf
ด้วยการเปลี่ยนแปลงและเพิ่มเติมต่อไปนี้ในกลุ่ม [mysqld1]
:
log_bin = /var/log/mysql/mysql-bin.log innodb_flush_log_at_trx_commit = 1 sync_binlog = 1 binlog-format = ROW
รีสตาร์ทอินสแตนซ์ MySQL หลักเพื่อให้การเปลี่ยนแปลงเหล่านี้มีผล:
mysqld_multi stop 1 mysqld_multi start 1
เพื่อให้ทาสเชื่อมต่อกับต้นแบบด้วยสิทธิ์การจำลองแบบที่ถูกต้อง ผู้ใช้ใหม่ควรจะถูกสร้างขึ้นบนต้นแบบ เชื่อมต่อกับอินสแตนซ์หลักโดยใช้ไคลเอนต์ MySQL กับโฮสต์และพอร์ตที่เหมาะสม:
mysql -uroot -p --host=127.0.0.1 --port=3306
สร้างผู้ใช้ใหม่สำหรับการจำลองแบบ:
mysql> CREATE USER 'replication'@'%' IDENTIFIED BY 'replication'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
ออกจากไคลเอนต์ MySQL
ดำเนินการคำสั่งต่อไปนี้เพื่อสร้างดัมพ์ของข้อมูลหลัก:
mysqldump -uroot -p --host=127.0.0.1 --port=3306 --all-databases --master-data=2 > replicationdump.sql
ที่นี่เราใช้ตัวเลือก --master-data=2
เพื่อให้ความคิดเห็นที่มีคำสั่ง CHANGE MASTER
ภายในไฟล์สำรอง ความคิดเห็นนั้นระบุพิกัดการจำลองในขณะที่ทำการสำรองข้อมูล และเราจะต้องมีพิกัดเหล่านั้นในภายหลังสำหรับการอัปเดตข้อมูลหลักในอินสแตนซ์สเลฟ นี่คือตัวอย่างของความคิดเห็นนั้น:
-- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=349;
นำเข้าดัมพ์ที่คุณสร้างในขั้นตอนก่อนหน้าไปยังอินสแตนซ์สเลฟ:
mysql -uroot -p --host=127.0.0.1 --port=3307 < replicationdump.sql
สุดท้าย เพื่อให้อินสแตนซ์ของสเลฟเชื่อมต่อกับอินสแตนซ์หลัก ข้อมูลหลักบนสเลฟจะต้องได้รับการอัปเดตด้วยพารามิเตอร์การเชื่อมต่อที่เหมาะสม
เชื่อมต่อกับอินสแตนซ์ทาสโดยใช้ไคลเอนต์ MySQL กับโฮสต์และพอร์ตที่เหมาะสม:
mysql -uroot -p --host=127.0.0.1 --port=3307
ดำเนินการคำสั่งต่อไปนี้เพื่ออัปเดตข้อมูลหลัก (ใช้พิกัดการจำลองแบบจากไฟล์ดัมพ์ replicationdump.sql
ตามที่อธิบายไว้ข้างต้น):
mysql> CHANGE MASTER TO -> MASTER_HOST='127.0.0.1', -> MASTER_USER='replication', -> MASTER_PASSWORD='replication', -> MASTER_LOG_FILE='mysql-bin.000001', -> MASTER_LOG_POS=349;
ดำเนินการคำสั่งต่อไปนี้เพื่อเริ่มต้นทาส:
mysql> START SLAVE;
ดำเนินการคำสั่งต่อไปนี้เพื่อตรวจสอบว่าการจำลองแบบเปิดและทำงานอยู่:
mysql> SHOW SLAVE STATUS \G
ยินดีด้วย. ตั้งค่าการจำลองแบบ master-slave ของ MySQL ในเครื่องเดียวกันเรียบร้อยแล้ว
สรุป
การมีการจำลองแบบ master-slave ที่กำหนดค่าไว้ในสภาพแวดล้อมการพัฒนาของคุณนั้นมีประโยชน์ถ้าคุณต้องการสำหรับโซลูชันการขยายขนาดในสภาพแวดล้อมการผลิต ด้วยวิธีนี้ คุณจะมีแหล่งข้อมูลแยกต่างหากที่กำหนดค่าไว้สำหรับการดำเนินการเขียนและอ่าน เพื่อให้คุณสามารถทดสอบภายในเครื่องว่าทุกอย่างทำงานตามที่คาดไว้ก่อนที่จะปรับใช้ต่อไป
นอกจากนี้ คุณอาจต้องการกำหนดค่าอินสแตนซ์ของทาสหลายตัวในเครื่องเดียวกันเพื่อทดสอบตัวโหลดบาลานซ์ที่กระจายการดำเนินการอ่านไปยังทาสหลายตัว ในกรณีนั้น คุณสามารถใช้คู่มือฉบับเดียวกันนี้เพื่อตั้งค่าอินสแตนซ์ทาสอื่น ๆ ได้โดยการทำซ้ำขั้นตอนเดียวกันทั้งหมด