ما هو التكرار ولماذا هو مطلوب
في حد ذاته ، يشير النسخ المتماثل إلى عملية مزامنة نسخ متعددة من كائن. في حالتنا ، مثل هذا الكائن هو خادم قاعدة البيانات ، والبيانات نفسها ذات قيمة أكبر. إذا كان لدينا خادمان أو أكثر ، وحافظنا بأي طريقة ممكنة على مجموعة متزامنة من البيانات عليها ، فقد قمنا بتنفيذ نسخ النظام. حتى الخيار اليدوي c
mysqldump -> mysql load
هو أيضًا نسخ متماثل.
يجب أن يكون مفهوماً أن نسخ البيانات بحد ذاته ليس له قيمة ، وهو مجرد أداة لحل المهام التالية:
- تحسين أداء قراءة البيانات. بمساعدة النسخ المتماثل ، سنتمكن من الاحتفاظ بعدة نسخ من الخادم ، وتوزيع الحمل بينها.
- . , . , .
- . , , , .
- . , ( , ), , .
- . , , .
- . .
MySQL
تتضمن عملية النسخ المتماثل للنشر تغييرات البيانات من الخادم الرئيسي (يشار اليها عادة باسم سيد، سيد )، إلى واحد أو أكثر من خوادم العبيد (الرقيق، الرقيق ). هناك أيضًا تكوينات أكثر تعقيدًا ، لا سيما مع العديد من الخوادم الرئيسية ، ولكن لكل تغيير على خادم رئيسي معين ، تصبح العناصر الرئيسية المتبقية عبيدًا بشكل مشروط ، وتستهلك هذه التغييرات.
بشكل عام ، يتكون نسخ MySQL من ثلاث خطوات:
- يكتب الخادم الرئيسي تغييرات البيانات في السجل. يسمى هذا السجل بالسجل الثنائي ، وتسمى التغييرات بأحداث السجل الثنائي .
- ينسخ العبد التغييرات التي تم إجراؤها على السجل الثنائي إلى سجل خاص به ، يسمى سجل الترحيل .
- يقوم العبد بإعادة التغييرات من سجل الترحيل ، وتطبيقها على بياناته الخاصة.
أنواع النسخ المتماثل
هناك طريقتان مختلفتان جوهريًا للنسخ المتماثل: الأمر - بأمر - وصف تلو الصف . في حالة النسخ المتماثل للأمر عن طريق الأمر ، يتم تسجيل طلبات تغيير البيانات (INSERT ، UPDATE ، DELETE) في السجل الرئيسي ، ويقوم العبيد بإعادة إنتاج نفس الأوامر تمامًا. باستخدام النسخ المتماثل صفًا تلو الآخر ، سيغير السجل الصفوف الموجودة في الجداول مباشرةً ، وسيتم بعد ذلك تطبيق نفس التغييرات الفعلية على التابع.
نظرًا لعدم وجود حل سحري ، فإن كل طريقة من هذه الطرق لها مزاياها وعيوبها. يعد النسخ المتماثل عن طريق الأمر أسهل في التنفيذ والفهم ، ويقلل من الحمل على الجهاز الرئيسي وعلى الشبكة. ومع ذلك ، يمكن أن يؤدي النسخ المتماثل لكل أمر إلى تأثيرات غير متوقعة عند استخدام وظائف غير حتمية مثل NOW () و RAND () وما إلى ذلك. يمكن أن تكون هناك أيضًا مشاكل ناجمة عن البيانات غير المتزامنة بين السيد والعبد. يؤدي النسخ المتماثل صفًا تلو الآخر إلى نتائج أكثر قابلية للتنبؤ ، حيث يتم التقاط تغييرات البيانات الفعلية وإعادة إنتاجها. ومع ذلك ، يمكن أن تؤدي هذه الطريقة إلى زيادة الحمل على الخادم الرئيسي بشكل كبير ، والذي يجب أن يسجل كل تغيير في السجل ، وعلى الشبكة التي تنتشر من خلالها هذه التغييرات.
تدعم MySQL كلاً من طريقتي النسخ ، وتغير الافتراضي (يمكننا القول أنه موصى به) اعتمادًا على الإصدار. تستخدم الإصدارات الحديثة مثل MySQL 8 النسخ المتماثل المستند إلى الصفوف افتراضيًا.
المبدأ الثاني لتقسيم طرق النسخ المتماثل هو عدد الخوادم الرئيسية... يعني وجود خادم رئيسي واحد أنه فقط يقبل تغييرات البيانات ، وهو نوع من المعايير التي يتم من خلالها نشر التغييرات بالفعل للعديد من العبيد. في حالة النسخ المتماثل الرئيسي ، نحصل على بعض الأرباح والمشكلات. تتمثل إحدى المزايا ، على سبيل المثال ، في أنه يمكننا منح العملاء البعيدين من نفس سيدني وهلسنكي فرصة بنفس السرعة لكتابة تغييراتهم في قاعدة البيانات. هذا يؤدي إلى العيب الرئيسي ، إذا قام كلا العميلين بتغيير نفس البيانات في وقت واحد ، والتي تعتبر تغييراتها نهائية ، وتعاملتها ملتزمة ، ومعاملتها تم التراجع عنها.
أيضًا ، من الجدير بالذكر أن وجود نسخة رئيسية رئيسية لا يمكن أن تزيد من أداء كتابة البيانات في النظام. لنتخيل أن سيدنا الوحيد يمكنه معالجة ما يصل إلى 1000 طلب في المرة الواحدة. من خلال إضافة نسخة رئيسية ثانية مكررة إليها ، لن نتمكن من معالجة 1000 طلب على كل منها ، لأنه بالإضافة إلى معالجة طلباتهم ، سيتعين عليهم تطبيق التغييرات التي تم إجراؤها على الرئيسي الثاني. هذا ، في حالة النسخ المتماثل للأمر بأمر ، سيجعل إجمالي الحمل المحتمل على أضعفها ، ومع النسخ المتماثل صفًا تلو الآخر ، لا يمكن التنبؤ بالتأثير تمامًا ، يمكن أن يكون إيجابيًا أو سلبيًا ، اعتمادًا على ظروف محددة.
مثال على بناء نسخة متماثلة بسيطة في MySQL
حان الوقت الآن لإنشاء تكوين نسخ متماثل بسيط في MySQL. لهذا سوف نستخدم صور Docker و MySQL من dockerhub ، بالإضافة إلى قاعدة البيانات العالمية .
بادئ ذي بدء ، سنقوم بإطلاق حاويتين ، إحداهما سنقوم بتهيئتها لاحقًا لتكون رئيسية ، والأخرى كعبيد. دعونا نتواصل معهم حتى يتمكنوا من التحدث مع بعضهم البعض.
docker run -d --name samplereplication-master -e MYSQL_ALLOW_EMPTY_PASSWORD=true -v ~/path/to/world/dump:/docker-entrypoint-initdb.d mysql:8.0
docker run -d --name samplereplication-slave -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:8.0
docker network create samplereplication
docker network connect samplereplication samplereplication-master
docker network connect samplereplication samplereplication-slave
تم تحديد اتصال وحدة التخزين مع world.sql dump للحاوية الرئيسية لمحاكاة وجود قاعدة أولية عليها. عند إنشاء حاوية ، سيقوم mysql بتنزيل وتنفيذ برامج SQL النصية الموجودة في دليل docker-entrypoint-initdb.d.
للعمل مع ملفات التكوين ، نحتاج إلى محرر نصوص. يمكن استخدام أي واحد مناسب ، وأنا أفضل vim.
docker exec samplereplication-master apt-get update && docker exec samplereplication-master apt-get install -y vim
docker exec samplereplication-slave apt-get update && docker exec samplereplication-slave apt-get install -y vim
بادئ ذي بدء ، سننشئ حسابًا على الماستر ليتم استخدامه للنسخ المتماثل:
docker exec -it samplereplication-master mysql
mysql> CREATE USER 'replication'@'%';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
بعد ذلك ، دعنا نغير ملفات التكوين للخادم الرئيسي:
docker exec -it samplereplication-master bash
~ vi /etc/mysql/my.cnf
يجب إضافة المعلمات التالية إلى ملف my.cnf في قسم [mysqld]:
server_id = 1 # log_bin = mysql-bin #
عند تمكين / تعطيل السجل الثنائي ، يلزم إعادة تشغيل الخادم. في حالة Docker ، يتم إعادة تحميل الحاوية.
docker restart samplereplication-master
تأكد من تمكين السجل الثنائي. قد تختلف القيم المحددة مثل اسم الملف وموضعه.
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 156 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
لبدء نسخ البيانات ، من الضروري "سحب" العبد إلى حالة السيد. للقيام بذلك ، تحتاج إلى حظر المعالج نفسه مؤقتًا لعمل لقطة من البيانات الفعلية.
mysql> FLUSH TABLES WITH READ LOCK;
بعد ذلك ، سنستخدم mysqldump لتصدير البيانات من قاعدة البيانات. بالطبع ، في هذا المثال ، يمكنك استخدام نفس world.sql ، لكن دعنا نقترب من سيناريو أكثر واقعية.
docker exec samplereplication-master mysqldump world > /path/to/dump/on/host/world.sql
بعد ذلك ، من الضروري تنفيذ الأمر SHOW MASTER STATUS مرة أخرى ، وتذكر أو تدوين قيم الملف والموضع. هذه هي ما يسمى بإحداثيات السجل الثنائي. ومنهم سنشير كذلك إلى بدء العبد. الآن يمكننا فتح السيد مرة أخرى:
mysql> UNLOCK TABLES;
تم تكوين البرنامج الرئيسي وجاهز للنسخ المتماثل إلى خوادم أخرى. دعنا ننتقل إلى العبد الآن. بادئ ذي بدء ، قم بتحميل التفريغ من السيد فيه.
docker cp /path/to/dump/on/host/world.sql samplereplication-slave:/tmp/world.sql
docker exec -it samplereplication-slave mysql
mysql> CREATE DATABASE `world`;
docker exec -it samplereplication-slave bash
~ mysql world < /tmp/world.sql
وبعد ذلك سنقوم بتغيير تكوين الرقيق بإضافة معلمات:
log_bin = mysql-bin # server_id = 2 # relay-log = /var/lib/mysql/mysql-relay-bin # relay-log-index = /var/lib/mysql/mysql-relay-bin.index # read_only = 1 # “ ”
بعد ذلك ، أعد تحميل العبد:
docker restart samplereplication-slave
والآن نحتاج إلى إخبار العبد بالخادم الذي سيكون سيده ، وأين نبدأ في تكرار البيانات. بدلاً من MASTER_LOG_FILE و MASTER_LOG_POS ، يجب استبدال القيم التي تم الحصول عليها من SHOW MASTER STATUS على الماستر. يشار إلى هذه المعلمات بشكل جماعي باسم إحداثيات السجل الثنائي.
mysql> CHANGE MASTER TO MASTER_HOST='samplereplication-master', MASTER_USER='replication', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=156;
لنبدأ في إعادة تشغيل سجل الترحيل ، والتحقق من حالة النسخ المتماثل:
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
حالة الرقيق
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: samplereplication-master Master_User: replication Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 156 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 324 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: 156 Relay_Log_Space: 533 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: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: c341beb7-3a33-11eb-9440-0242ac110002 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: Master_public_key_path: Get_master_public_key: 0 Network_Namespace: 1 row in set, 1 warning (0.00 sec)
إذا سارت الأمور على ما يرام ، يجب أن تبدو حالتك متشابهة. المعلمات الرئيسية هنا:
- Slave_IO_State - في الواقع ، حالة النسخ المتماثل.
- Read_Master_Log_Pos هو آخر موضع تمت قراءته من السجل الرئيسي.
- Relay_Master_Log_File - ملف السجل الرئيسي الحالي.
- Seconds_Behind_Master - يتخلف العبد عن السيد ، بالثواني.
- Last_IO_Error ، Last_SQL_Error - أخطاء النسخ المتماثل ، إن وجدت.
دعنا نحاول تغيير البيانات الموجودة على المعلم:
docker exec -it samplereplication-master mysql
mysql> USE world;
mysql> INSERT INTO city (Name, CountryCode, District, Population) VALUES ('Test-Replication', 'ALB', 'Test', 42);
وتحققوا من ظهورهم على العبد.
docker exec -it samplereplication-slave mysql
mysql> USE world;
mysql> SELECT * FROM city ORDER BY ID DESC LIMIT 1;
+------+------------------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------------+-------------+----------+------------+
| 4081 | Test-Replication | ALB | Test | 42 |
+------+------------------+-------------+----------+------------+
1 row in set (0.00 sec)
ممتاز! السجل الذي تم إدخاله مرئي أيضًا على العبد. تهانينا ، لقد أنشأت الآن أول نسخة متماثلة لـ MySQL!
خاتمة
آمل أن أتمكن في إطار هذه المقالة من إعطاء فهم أساسي لعمليات النسخ ، والتعرف على استخدام هذه الأداة ، ومحاولة تنفيذ مثال بسيط للنسخ بشكل مستقل في MySQL. موضوع النسخ المتماثل وتطبيقه العملي واسع للغاية ، وإذا كنت مهتمًا بهذا الموضوع ، يمكنني أن أوصي بالمصادر التالية للدراسة:
- تقرير "كيف يعمل MySQL Replication" بقلم أندريه أكسينوف (سفنكس)
- كتاب MySQL to the Maximum. التحسين ، النسخ المتماثل ، النسخ الاحتياطي "- بارون شوارتز ، بيتر زايتسيف ، فاديم تكاتشينكو
- "Highload" - هنا يمكنك العثور على وصفات محددة لنسخ البيانات
آمل أن تكون هذه المقالة مفيدة ونرحب بتعليقاتك وتعليقاتك!