MariaDB
 sql >> डेटाबेस >  >> RDS >> MariaDB

गैर-जीटीआईडी ​​​​से जीटीआईडी ​​मारियाडीबी डेटाबेस क्लस्टर में प्रतिकृति मुद्दों को संभालना

हम हाल ही में एक मारियाडीबी प्रतिकृति सेटअप से जुड़े एक दिलचस्प ग्राहक सहायता मामले में भाग गए। हमने इस समस्या पर शोध करने में काफी समय बिताया और सोचा कि इस ब्लॉग पोस्ट में इसे आपके साथ साझा करना उचित होगा।

ग्राहक का पर्यावरण विवरण

समस्या इस प्रकार थी:एक पुराना (पूर्व 10.x) मारियाडीबी सर्वर उपयोग में था और इससे डेटा को हाल ही में मारियाडीबी प्रतिकृति सेटअप में स्थानांतरित करने का प्रयास किया गया था। इसके परिणामस्वरूप नए प्रतिकृति क्लस्टर में दासों के पुनर्निर्माण के लिए मारियाबैकअप का उपयोग करने में समस्याएं आईं। परीक्षणों के उद्देश्य के लिए हमने इस व्यवहार को निम्नलिखित वातावरण में फिर से बनाया:

डेटा को mysqldump का उपयोग करके 5.5 से 10.4 पर माइग्रेट किया गया है:

mysqldump --single-transaction --master-data=2 --events --routines sbtest > /root/dump.sql

इसने हमें मास्टर बाइनरी लॉग निर्देशांक और संगत डंप एकत्र करने की अनुमति दी। नतीजतन, हम मारियाडीबी 10.4 मास्टर नोड का प्रावधान करने और पुराने 5.5 मास्टर और नए 10.4 नोड के बीच प्रतिकृति स्थापित करने में सक्षम थे। यातायात अभी भी 5.5 नोड पर चल रहा था। 10.4 मास्टर जीटीआईडी ​​उत्पन्न कर रहा था क्योंकि उसे डेटा को 10.4 दास को दोहराना था। इससे पहले कि हम विवरण में खुदाई करें, आइए देखें कि मारियाडीबी में जीटीआईडी ​​कैसे काम करता है।

MariaDB और GTID

शुरुआत में, MariaDB Oracle MySQL की तुलना में GTID के एक भिन्न स्वरूप का उपयोग करती है। इसमें डैश द्वारा अलग किए गए तीन नंबर होते हैं:

0 - 1 - 345

पहला एक प्रतिकृति डोमेन है, जो बहु-स्रोत प्रतिकृति को ठीक से संचालित करने की अनुमति देता है। यह हमारे मामले के लिए प्रासंगिक नहीं है क्योंकि सभी नोड एक ही प्रतिकृति डोमेन में हैं। दूसरा नंबर उस नोड का सर्वर आईडी है जिसने GTID जनरेट किया है। तीसरा एक अनुक्रम संख्या है - यह बाइनरी लॉग में संग्रहीत प्रत्येक घटना के साथ एकरस रूप से बढ़ जाती है।

MariaDB किसी दिए गए नोड पर GTID के निष्पादन के बारे में जानकारी संग्रहीत करने के लिए कई चर का उपयोग करता है। हमारे लिए सबसे दिलचस्प हैं:

Gtid_binlog_pos - दस्तावेज़ीकरण के अनुसार, यह चर बाइनरी लॉग में लिखे गए अंतिम ईवेंट समूह का GTID है।

Gtid_slave_pos - दस्तावेज़ीकरण के अनुसार, इस सिस्टम वैरिएबल में सर्वर के स्लेव थ्रेड्स द्वारा डेटाबेस पर लागू किए गए अंतिम लेनदेन का GTID होता है।

Gtid_current_pos - दस्तावेज़ीकरण के अनुसार, इस सिस्टम वैरिएबल में डेटाबेस पर लागू अंतिम लेनदेन का GTID होता है। यदि gtid_binlog_pos में संबंधित GTID का server_id, सर्वर के स्वयं के server_id के बराबर है, और क्रम संख्या gtid_slave_pos में संबंधित GTID से अधिक है, तो gtid_binlog_pos से GTID का उपयोग किया जाएगा। अन्यथा उस डोमेन के लिए gtid_slave_pos से GTID का उपयोग किया जाएगा।

इसलिए, इसे स्पष्ट करने के लिए, gtid_binlog_pos पिछले स्थानीय रूप से निष्पादित घटना के GTID को संग्रहीत करता है। Gtid_slave_pos, स्लेव थ्रेड द्वारा निष्पादित ईवेंट का GTID संग्रहीत करता है और gtid_current_pos या तो gtid_binlog_pos से मान दिखाता है, यदि इसकी अनुक्रम संख्या उच्चतम है और इसमें सर्वर-आईडी या gtid_slave_pos है यदि इसका क्रम उच्चतम है। कृपया इसे अपने दिमाग में रखें।

समस्या का अवलोकन

प्रासंगिक चर की प्रारंभिक स्थिति 10.4 मास्टर पर है:

MariaDB [(none)]> show global variables like '%gtid%';

+-------------------------+----------+

| Variable_name           | Value |

+-------------------------+----------+

| gtid_binlog_pos         | 0-1001-1 |

| gtid_binlog_state       | 0-1001-1 |

| gtid_cleanup_batch_size | 64       |

| gtid_current_pos        | 0-1001-1 |

| gtid_domain_id          | 0 |

| gtid_ignore_duplicates  | ON |

| gtid_pos_auto_engines   | |

| gtid_slave_pos          | 0-1001-1 |

| gtid_strict_mode        | ON |

| wsrep_gtid_domain_id    | 0 |

| wsrep_gtid_mode         | OFF |

+-------------------------+----------+

11 rows in set (0.001 sec)

कृपया gtid_slave_pos पर ध्यान दें, जिसका सैद्धांतिक रूप से कोई मतलब नहीं है - यह उसी नोड से आया है लेकिन स्लेव थ्रेड के माध्यम से। ऐसा तब हो सकता है जब आप पहले मास्टर स्विच करते हैं। हमने ठीक वैसा ही किया - दो 10.4 नोड्स के साथ हमने मास्टर्स को होस्ट से 1001 के सर्वर आईडी के साथ 1002 के सर्वर आईडी के साथ होस्ट करने के लिए और फिर वापस 1001 पर स्विच किया।

बाद में हमने प्रतिकृति को 5.5 से 10.4 तक कॉन्फ़िगर किया और चीजें इस तरह दिखती थीं:

MariaDB [(none)]> show global variables like '%gtid%';

+-------------------------+-------------------------+

| Variable_name           | Value |

+-------------------------+-------------------------+

| gtid_binlog_pos         | 0-55-117029 |

| gtid_binlog_state       | 0-1001-1537,0-55-117029 |

| gtid_cleanup_batch_size | 64                      |

| gtid_current_pos        | 0-1001-1 |

| gtid_domain_id          | 0 |

| gtid_ignore_duplicates  | ON |

| gtid_pos_auto_engines   | |

| gtid_slave_pos          | 0-1001-1 |

| gtid_strict_mode        | ON |

| wsrep_gtid_domain_id    | 0 |

| wsrep_gtid_mode         | OFF |

+-------------------------+-------------------------+

11 rows in set (0.000 sec)

जैसा कि आप देख सकते हैं, मारियाडीबी 5.5 से दोहराए गए ईवेंट, उन सभी को gtid_binlog_pos चर में शामिल किया गया है:55 के सर्वर आईडी वाले सभी ईवेंट। इसके परिणामस्वरूप एक गंभीर समस्या होती है। जैसा कि आपको याद होगा, gtid_binlog_pos में होस्ट पर स्थानीय रूप से निष्पादित ईवेंट शामिल होने चाहिए। यहां इसमें भिन्न सर्वर आईडी वाले किसी अन्य सर्वर से दोहराए गए ईवेंट शामिल हैं।

जब आप 10.4 स्लेव को फिर से बनाना चाहते हैं, तो इससे चीजें मुश्किल हो जाती हैं, ऐसा क्यों है। मारियाबैकअप, एक्स्ट्राबैकअप की तरह ही सरल तरीके से काम करता है। यह फिर से लॉग स्कैन करते समय और आने वाले किसी भी लेनदेन को संग्रहीत करते समय मारियाडीबी सर्वर से फाइलों की प्रतिलिपि बनाता है। जब फ़ाइलों की प्रतिलिपि बनाई गई है, मारियाबैकअप या तो फ्लश टेबल के साथ रीड लॉक या बैकअप लॉक का उपयोग करके डेटाबेस को फ्रीज कर देगा, मारियाडीबी संस्करण और बैकअप लॉक की उपलब्धता के आधार पर। फिर यह नवीनतम निष्पादित GTID को पढ़ता है और इसे बैकअप के साथ संग्रहीत करता है। फिर लॉक जारी किया जाता है और बैकअप पूरा हो जाता है। बैकअप में संग्रहीत GTID को नोड पर नवीनतम निष्पादित GTID के रूप में उपयोग किया जाना चाहिए। दासों के पुनर्निर्माण के मामले में इसे gtid_slave_pos के रूप में रखा जाएगा और फिर GTID प्रतिकृति शुरू करने के लिए उपयोग किया जाएगा। यह GTID gtid_current_pos से लिया गया है, जो सही मायने में समझ में आता है - आखिरकार यह "डेटाबेस पर लागू अंतिम लेनदेन का GTID" है। तीव्र पाठक पहले से ही समस्या देख सकते हैं। आइए वेरिएबल का आउटपुट दिखाते हैं जब 10.4 5.5 मास्टर से दोहराता है:

MariaDB [(none)]> show global variables like '%gtid%';

+-------------------------+-------------------------+

| Variable_name           | Value |

+-------------------------+-------------------------+

| gtid_binlog_pos         | 0-55-117029 |

| gtid_binlog_state       | 0-1001-1537,0-55-117029 |

| gtid_cleanup_batch_size | 64                      |

| gtid_current_pos        | 0-1001-1 |

| gtid_domain_id          | 0 |

| gtid_ignore_duplicates  | ON |

| gtid_pos_auto_engines   | |

| gtid_slave_pos          | 0-1001-1 |

| gtid_strict_mode        | ON |

| wsrep_gtid_domain_id    | 0 |

| wsrep_gtid_mode         | OFF |

+-------------------------+-------------------------+

11 rows in set (0.000 sec)

Gtid_current_pos 0-1001-1 पर सेट है। यह निश्चित रूप से सही समय नहीं है, यह gtid_slave_pos से लिया गया है, जबकि हमारे पास लेनदेन का एक समूह है जो उसके बाद 5.5 से आया है। समस्या यह है कि उन लेन-देन को gtid_binlog_pos के रूप में संग्रहीत किया जाता है। दूसरी ओर gtid_current_pos की गणना इस तरह से की जाती है कि gtid_current_pos के रूप में उपयोग करने से पहले gitd_binlog_pos में GTID के लिए स्थानीय सर्वर आईडी की आवश्यकता होती है। हमारे मामले में उनके पास 5.5 नोड की सर्वर आईडी है, इसलिए उन्हें 10.4 मास्टर पर निष्पादित घटनाओं के रूप में ठीक से नहीं माना जाएगा। बैकअप पुनर्स्थापना के बाद, यदि आप बैकअप में संग्रहीत GTID स्थिति के अनुसार दास को सेट करते हैं, तो यह 5.5 से आने वाली सभी घटनाओं को फिर से लागू कर देगा। यह, जाहिर है, प्रतिकृति को तोड़ देगा।

समाधान

इस समस्या का समाधान कई अतिरिक्त कदम उठाना है:

  1. प्रतिकृति को 5.5 से 10.4 तक रोकें। 10.4 मास्टर पर स्टॉप स्लेव चलाएं
  2. किसी भी लेन-देन को 10.4 पर निष्पादित करें - यदि मौजूद नहीं है तो स्कीमा बनाएं बगफिक्स - यह GTID स्थिति को इस तरह बदल देगा:
MariaDB [(none)]> show global variables like '%gtid%';

+-------------------------+---------------------------+

| Variable_name           | Value   |

+-------------------------+---------------------------+

| gtid_binlog_pos         | 0-1001-117122   |

| gtid_binlog_state       | 0-55-117121,0-1001-117122 |

| gtid_cleanup_batch_size | 64                        |

| gtid_current_pos        | 0-1001-117122   |

| gtid_domain_id          | 0   |

| gtid_ignore_duplicates  | ON   |

| gtid_pos_auto_engines   |   |

| gtid_slave_pos          | 0-1001-1   |

| gtid_strict_mode        | ON   |

| wsrep_gtid_domain_id    | 0   |

| wsrep_gtid_mode         | OFF   |

+-------------------------+---------------------------+

11 rows in set (0.001 sec)

नवीनतम GITD को स्थानीय रूप से निष्पादित किया गया था, इसलिए इसे gtid_binlog_pos के रूप में संग्रहीत किया गया था। चूंकि इसमें स्थानीय सर्वर आईडी है, इसलिए इसे gtid_current_pos के रूप में चुना गया है। अब, आप एक बैकअप ले सकते हैं और इसका उपयोग 10.4 मास्टर से दासों के पुनर्निर्माण के लिए कर सकते हैं। एक बार यह हो जाने के बाद, दास धागा फिर से शुरू करें।

MariaDB इस बात से अवगत है कि इस प्रकार की बग मौजूद है, हमें मिली प्रासंगिक बग रिपोर्ट में से एक यह है: https://jira.mariadb.org/browse/MDEV-10279 दुर्भाग्य से, अब तक कोई समाधान नहीं किया गया है . हमने जो पाया वह यह है कि यह समस्या मारियाडीबी को 5.5 तक प्रभावित करती है। गैर-जीटीआईडी ​​​​इवेंट जो मारियाडीबी 10.0 से आते हैं, उन्हें सही ढंग से 10.4 पर स्लेव थ्रेड से आने के रूप में गिना जाता है और gtid_slave_pos को ठीक से अपडेट किया जाता है। मारियाडीबी 5.5 काफी पुराना है (भले ही यह अभी भी समर्थित है) इसलिए आप अभी भी इस पर चल रहे सेटअप देख सकते हैं और 5.5 से अधिक हाल के जीटीआईडी-सक्षम मारियाडीबी संस्करणों में माइग्रेट करने का प्रयास कर सकते हैं। क्या बुरा है, हमें मिली बग रिपोर्ट के अनुसार, यह गैर-मारियाडीबी से आने वाली प्रतिकृति को भी प्रभावित करता है (टिप्पणियों में से एक में पेरकोना सर्वर 5.6 पर दिखाई देने वाली समस्या का उल्लेख है) सर्वर मारियाडीबी में।

वैसे भी, हम आशा करते हैं कि आपको यह ब्लॉग पोस्ट उपयोगी लगी होगी और आशा है कि आप हमारे द्वारा अभी-अभी बताई गई समस्या का सामना नहीं करेंगे।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मारियाडीबी में एक सीमा के भीतर एक यादृच्छिक पूर्णांक कैसे उत्पन्न करें

  2. कैसे CONVERT () मारियाडीबी में काम करता है

  3. मारियाडीबी JSON_OBJECTAGG () समझाया गया

  4. मारियाडीबी में LEFT () कैसे काम करता है

  5. कैसे UNHEX () मारियाडीबी में काम करता है