মাইএসকুয়েলঃ গ্রুপ রেপ্লিকেশন

মাইএসকুয়েল রেপ্লিকেশন এক ডাটাবেসের ডাটা এবং অপারেশন অন্য ডাটাবেসে হুবহু কপি করে। গ্রুপ রেপ্লিকেশন এ একটি ডাটাবেস প্রাইমারি ডাটাবেস সার্ভার হিসাবে থাকে আর অন্য ডাটাবেস সেকেন্ডারি ডাটাবেস সার্ভার হিসাবে থাকে (যদিও মাল্টিপল প্রাইমারী ডাটাবেস সেট করা যায়) । প্রাইমারী ডাটাবেস সার্ভার এ রিড এবং রাইট করা যায়, কিন্তু সেকেন্ডারি ডাটাবেস সার্ভারগুলো রিডঅনলি মুডে থাকে। গ্রুপ রেপ্লিকেশন এ সেকেন্ডারি ডাটাবেস সার্ভারগুলো সবসময় প্রাইমারি ডাটাবেস সার্ভার এর ডাটা সঠিক ভাবে কপি করার কাজ করে যায়। এছাড়া গ্রুপ রেপ্লিকেশন এ প্রাইমারি ডাটাবেস নির্বাচন করে দেওয়ার দরকার পড়ে না, এই কাজ টুকু অটোমেটিক করা হয়ে থাকে। সাধারণত প্রাইমারি ডাটাবেস সার্ভার এ কোন সমস্যা হলে সেকেন্ডারি ডাটাবেস সার্ভারগুলো ডিসাইড করতে পারে (Paxos concensus algorithm দিয়ে) কে নতুন প্রাইমারি ডাটাবেস সার্ভার কাজ করবে।

এই পোস্টে দেখানো হয়েছে কিভাবে একটি “মাইএসকুয়েল গ্রুপ রেপ্লিকেশন” সিস্টেম কনফিগার করতে হয়।

যা যা লাগবেঃ 

  • একাধিক মাইএসকুয়েল ডাটাবেস সার্ভার (রুট এক্সেস সহ)।
  • উবুন্টু অপারেটিং সিস্টেম (যে কোন *নিক্স ভিত্তিক সিস্টেম হলেও চলবে)।

প্রাইমারী ডাটাবেস সার্ভার সেটআপঃ

মাইএসকুয়েল ৫.৭* এর অফিশিয়াল বিল্ডে গ্রুপ রেপ্লিকেশন প্লাগিন ডিফল্ট ভাবে থাকে না, তাই এখানে মাইএসকুয়েল কমিউনিটি বিল্ড ব্যবহার করা হয়েছে। নিচের কমান্ড দিয়ে কমিউনিটি বিল্ড ভার্শন ইন্সটল করুন।

 curl -OL https://dev.mysql.com/get/mysql-apt-config_0.8.3-1_all.deb && sudo dpkg -i mysql-apt-config* && sudo apt-get update && sudo apt-get install mysql-server

ইন্সটল প্রসেস শুরু হবার পর আপনাকে একটি কনফিগারেশন স্ক্রিন দেখানেও হবে, তাতে প্রথমে মাইএসকুয়েল ৫.৭ সিলেক্ট করুন, এরপর সব ওকে চেপে কনফার্ম করুন। বিস্তারিত সেটআপ প্রসেস সম্পর্কে জানতে চাইলে এই পোস্টটি দেখুন।

ডাটাবেসের রুট পাসওয়ার্ড সেট করুন।

uuidgen কমান্ড দিয়ে একটি আইডি জেনারেট করুন, এবং আইডিটি সেভ করে রাখুন এটি আমাদের গ্রুপের UUID হিসাবে ব্যবহার করা হবে।

sudo nano /etc/mysql/my.cnf কমান্ড দিয়ে মাইএসকুয়েল কনফিগ ওপেন করুন। !includedir এর নিচে , নিচের কোড টুকু যুক্ত করুন (সামান্য এডিট করে)।

# সার্ভার এর নাম (এটা দরকারি না)
[mysqld]
# General replication settings
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = ON
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1

# Shared replication group configuration
loose-group_replication_group_name = "গ্রুপ UUID" #এটা জেনারেট করে সেভ করতে বলা হয়েছিলো
loose-group_replication_ip_whitelist = "প্রাইমারী সার্ভারের আইপি, সেকেন্ডারি সার্ভারের আইপি"
loose-group_replication_group_seeds = "প্রাইমারী সার্ভারের আইপি:33061, সেকেন্ডারি সার্ভারের আইপি:33061"

# Host specific replication configuration
server_id = 1 # সার্ভার নাম্বার (১২৩ এই স্টাইলে)
bind-address = "প্রাইমারী সার্ভারের আইপি"
report_host = "প্রাইমারী সার্ভারের আইপি"
loose-group_replication_local_address = " প্রাইমারী সার্ভারের আইপি:33061"

sudo systemctl restart mysql কমান্ড দিয়ে মাইএসকুয়েল সার্ভিস রিস্টার্ট করুন এবং sudo ufw allow 33061 && sudo ufw allow 3306 কমান্ড দিয়ে উবুন্টু ফায়ারওয়ালে 330613306 পোর্ট আলাউ করুন। mysql -u root -p কমান্ড দিয়ে মাইএসকুয়েল কমান্ডলাইন ইন্টারফেসে প্রবেস করুন। এবার রুট পাসোয়ার্ড দিয়ে অথেন্টিকেট করুন।

নিচের কমান্ডগুলো দিয়ে  SQL_LOG_BIN এর ভ্যালু 0 সেট করুন এরপর রেপ্লিকেশওন এর জন্য একটি ইউজার যুক্ত করুন এবং তাকে রেপ্লিকেশন এর জন্য পারমিশন দিন। এবং শেষে SQL_LOG_BIN এর ভ্যালু 1 সেট করে নিন।

SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1; 

এবার group_replication_recovery চ্যানেলে রেপ্লিকেশন ইউজার এবং পাসোয়ার্ড সেট করতে হবে, এই ইউজার এবং পাসোয়ার্ড গ্রুপের সকল ডাটাবেস সার্ভার রেপ্লিকেশন এর জন্য ব্যবহার করবে।

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='এখানে পাসোয়ার্ড দিন' FOR CHANNEL 'group_replication_recovery';

নিচের কমান্ড দিয়ে রেপ্লিকেশন প্লাগিন ইন্সটল করুন;

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

এবার SHOW PLUGINS; কমান্ড দিয়ে দেখুন প্লাগিনটি ইন্সটল হয়েছে কিনা (group_replication  নামে একটি লাইন দেখতে পাবেন)।

নিচের কমান্ড গুলো দিয়ে রেপ্লিকেশন চালু করুনঃ

SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

এবার SELECT * FROM performance_schema.replication_group_members; কমান্ড দিয়ে দেখুন রেপ্লিকেশন চালু হয়েছে কিনা (MEMBER_STATE  ONLINE দেখাবে)।

এবার এই প্রাইমারি ডাটাবেস সার্ভারে একটি ডাটাবেস তৈরি করুন এবং তাতে কিছু ডাটা যুক্ত করুন (রেপ্লিকেশন টেস্টিং এর জন্য)। 

মনে রাখবেন আপনার ডাটাবেসের ইঞ্জিন টাইপ অবশ্যই InnoDB হতে হবে অন্যথায় রেপ্লিকেশন কাজ করবে না।

সেনেন্ডারী ডাটাবেস সার্ভার সেটআপঃ

আপএবার আসুন সেকেন্ডারী ডাটাবেস সার্ভার কনফিগার করি।

sudo nano /etc/mysql/my.cnf কমান্ড দিয়ে মাইএসকুয়েল কনফিগ ওপেন করুন। !includedir এর নিচে , নিচের কোড টুকু যুক্ত করুন (সামান্য এডিট করে)।

# সার্ভার এর নাম (এটা দরকারি না)
[mysqld]
# General replication settings
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = ON
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1

# Shared replication group configuration
loose-group_replication_group_name = "গ্রুপ UUID" #এটা জেনারেট করে সেভ করতে বলা হয়েছিলো
loose-group_replication_ip_whitelist = "প্রাইমারী সার্ভারের আইপি, সেকেন্ডারি সার্ভারের আইপি"
loose-group_replication_group_seeds = "প্রাইমারী সার্ভারের আইপি:33061, সেকেন্ডারি সার্ভারের আইপি:33061"

# Host specific replication configuration
server_id = 2 # সার্ভার নাম্বার (১২৩ এই স্টাইলে)
bind-address = "সেকেন্ডারি সার্ভারের আইপি"
report_host = "সেকেন্ডারি সার্ভারের আইপি"
loose-group_replication_local_address = "সেকেন্ডারি সার্ভারের আইপি:33061"

sudo systemctl restart mysql কমান্ড দিয়ে মাইএসকুয়েল সার্ভিস রিস্টার্ট করুন এবং sudo ufw allow 33061 && sudo ufw allow 3306 কমান্ড দিয়ে উবুন্টু ফায়ারওয়ালে 330613306 পোর্ট আলাউ করুন। mysql -u root -p কমান্ড দিয়ে মাইএসকুয়েল কমান্ডলাইন ইন্টারফেসে প্রবেস করুন। এবার রুট পাসোয়ার্ড দিয়ে অথেন্টিকেট করুন।

নিচের কমান্ডগুলো দিয়ে  SQL_LOG_BIN এর ভ্যালু 0 সেট করুন এরপর রেপ্লিকেশওন এর জন্য একটি ইউজার যুক্ত করুন এবং তাকে রেপ্লিকেশন এর জন্য পারমিশন দিন। এবং শেষে SQL_LOG_BIN এর ভ্যালু 1 সেট করে নিন।

SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1; 

এবার group_replication_recovery চ্যানেলে রেপ্লিকেশন ইউজার এবং পাসোয়ার্ড সেট করতে হবে, এই ইউজার এবং পাসোয়ার্ড গ্রুপের সকল ডাটাবেস সার্ভার রেপ্লিকেশন এর জন্য ব্যবহার করবে।

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='এখানে পাসোয়ার্ড দিন' FOR CHANNEL 'group_replication_recovery';

নিচের কমান্ড দিয়ে রেপ্লিকেশন প্লাগিন ইন্সটল করুন;

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

এবার SHOW PLUGINS; কমান্ড দিয়ে দেখুন প্লাগিনটি ইন্সটল হয়েছে কিনা (group_replication  নামে একটি লাইন দেখতে পাবেন)।

START GROUP_REPLICATION; কমান্ড দিয়ে রেপ্লিকেশন শুরু করুন (যদিও আমাদের কনফিগারেশন এর কারনে এটা অটোমেটিক হয়ে যাওয়ার কথা)।

SELECT * FROM performance_schema.replication_group_members; কমান্ড দিয়ে দেখুন নতুন একটি ডাটাবেস সার্ভার রেপ্লিকেশন গ্রুপ মেম্বার হিসাবে যুক্ত হয়েছে। এখই পদ্ধতি অনুসারে আপনি আরো ডাটাবেস সার্ভার এই রেপ্লিকেশন গ্রুপে যুক্ত করতে পারবেন।

GTID ডুপ্লিকেট সমস্যার সমাধান

reset master; দিয়ে ডুপ্লিকেট GTID সমস্যার সমাধান করা যায়। reset master; কমান্ড দেওয়ার পর mysql_upgrade দিতে হয়। mysql_upgrade এ যদি রিড অনলি ইরর দেখায় তবে set global read_only = off; দিয়ে রিড অনলি অফ করে mysql_upgrade দিতে হবে, এরপর set global read_only = on; করে দিতে হবে।

MySQL JOIN

MySQL এ দুই বা ততোধিক টেবিলের রো একসাথে যুক্ত করতে JOIN ব্যবহার করা হয়। MySQL এ JOIN মোট ৪ প্রকারের।

INNER JOIN

INNER JOIN কীওয়ার্ড দিয়ে দুই বা ততোধিক টেবিলের রো একসাথে যুক্ত করতে হলে বাম ও ডান কলামের মান সমান হতে হয়।

SQL INNER JOIN সিনট্যাক্স

SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;

অথবা,

SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;

উদাহরনঃ

SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;

LEFT JOIN

LEFT JOIN কীওয়ার্ড দিয়ে দুই বা ততোধিক টেবিলের রো একসাথে যুক্ত করতে হলে বাম কলামের রো এর ডাটার সাথে ডান কলামের রো এর ডাটা তুলনা করা হয় । যেসব স্থানে উভয় কলামের রো এর ডাটা সমান নয় সেসকল ক্ষেত্রে শুধুমাত্র বাম কলামের ডাটা সিলেক্ট করা হয় , আর যেসব স্থানে উভয় কলামের রো এর ডাটা সমান সে ক্ষেত্রে উভয় কলামের রো এর ডাটা সিলেক্ট করা হয়।

SQL LEFT JOIN সিনট্যাক্স


SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

অথবা,

SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;

উদাহরনঃ

SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;

RIGHT JOIN

RIGHT JOIN কীওয়ার্ড দিয়ে দুই বা ততোধিক টেবিলের রো একসাথে যুক্ত করতে হলে বাম কলামের রো এর ডাটার সাথে ডান কলামের রো এর ডাটা তুলনা করা হয় । যেসব স্থানে উভয় কলামের রো এর ডাটা সমান নয় সেসকল ক্ষেত্রে শুধুমাত্র ডান কলামের ডাটা সিলেক্ট করা হয় , আর যেসব স্থানে উভয় কলামের রো এর ডাটা সমান সে ক্ষেত্রে উভয় কলামের রো এর ডাটা সিলেক্ট করা হয়। এটিLEFT JOIN এর বিপরীত।

SQL RIGHT JOIN সিনট্যাক্স

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;

অথবা,

SELECT column_name(s)
FROM table1
RIGHT OUTER JOIN table2
ON table1.column_name=table2.column_name;

উদাহরনঃ

SELECT Orders.OrderID, Employees.FirstName
FROM Orders
RIGHT JOIN Employees
ON Orders.EmployeeID=Employees.EmployeeID
ORDER BY Orders.OrderID;

FULL JOIN

FULL JOIN মুলত LEFT JOIN এবং RIGHT JOIN এর ফলাফল একসাথে যুক্ত করে প্রকাশ করে।

SQL FULL OUTER JOIN সিনট্যাক্স

SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

উদাহরনঃ

SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
FULL OUTER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;