mysqldump --single-transaction, फिर भी अपडेट क्वेरीज़ बैकअप के लिए इंतजार कर रहे हैं


10

अगर मैं mysqldump --single-transaction का उपयोग करता हूं, तो डॉक्स के अनुसार इसे सुसंगत स्थिति प्राप्त करने के लिए रीड लॉक के साथ फ्लश टेबल करना चाहिए और फिर लेनदेन शुरू करना चाहिए और किसी भी लेखक को इंतजार नहीं करना चाहिए।

हालाँकि, मैंने कल रात को निम्न स्थिति पकड़ी है:

शो पूरी प्रक्रिया सूची से अंश:

उन सैकड़ों ...

   Command: Query
   Time: 291
   State: Waiting for table flush
   Info: insert into db_external_notification.....

फिर यह:

Command: Query
Time: 1204
State: Sending data
Info: SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification`

और बाकी धागे नींद में हैं

किसी को भी पता नहीं है कि इन आवेषण के लिए इंतजार कर रहे हैं? मुझे कोई FLUSH टेबल या DDL या मैनुअल में बताई गई कोई भी चीज दिखाई नहीं दे रही है जिससे प्रश्नों की प्रतीक्षा की जा सके।

पूर्ण mysqldump कमांड

mysqldump --quick --add-drop-table --single-transaction --master-data=2 -uxx -pxx dbname

मुझे लगता है - यहाँ बेमानी है, शायद पहले के समय से बचा हुआ है, यह स्क्रिप्ट बहुत पुरानी है, लेकिन किसी को चोट नहीं पहुंचानी चाहिए


शो फुल प्रोसेसलिस्ट और शो इनोडब स्टेटस (अनाम) का पूरा आउटपुट यहाँ है: pastebin.com/D7WS3QAE
अलेक्जेंडर इवानसेविक

आपकी पूरी कमांड लाइन क्या है mysqldump? विशेष रूप से, आप उपयोग कर रहे हैं --flush-logsया --master-data...? विकल्पों में से संभावित इंटरैक्शन हैं।
माइकल - साइक्लोबोट

पूर्ण mysqldump कमांड जोड़ा, तलाश के लिए धन्यवाद
अलेक्जेंडर इवानिसविक

जवाबों:


6

--एकल-लेन-देन का विकल्प mysqldump ऐसा नहीं करता है FLUSH TABLES WITH READ LOCK;। यह mysqldump को डंप किए जा रहे सभी तालिकाओं के लिए एक दोहराए जाने वाले लेनदेन को सेटअप करने का कारण बनता है।

आपके प्रश्न से, आपने कहा था कि db_external_notificationमेज के लिए mysqldump का चयन उसी तालिका में सैकड़ों INSERT कमांड को पकड़ रहा है। ये क्यों हो रहा है ?

सबसे अधिक संभावना है कि gen_clust_index (जिसे क्लस्टर सूचकांक के रूप में जाना जाता है) पर एक ताला । यह प्रतिमान एक तालिका के लिए सह-अस्तित्व के लिए डेटा और इंडेक्स पेज का कारण बनता है। वे इंडेक्स पेज या तो PRIMARY KEY या ऑटो-जनरेटेड RowID इंडेक्स पर आधारित होते हैं (ऐसी स्थिति में कोई PRIMARY KEY नहीं होती है)।

आपको इसे चलाने में सक्षम होना चाहिए SHOW ENGINE INNODB STATUS\G और gen_clust_index के किसी भी पृष्ठ की तलाश करनी चाहिए जिसमें एक विशेष लॉक हो। एक क्लस्टर सूचकांक के साथ एक तालिका में INSERTs करने के लिए PRIMARY KEY के BTREE को संभालने के लिए एक विशेष लॉक की आवश्यकता होती है, साथ ही auto_increment का क्रमांकन भी होता है।

मैंने इस घटना पर पहले चर्चा की है

अद्यतन 2014-07-21 15:03 EDT

कृपया अपने पास्टबिन की पंक्तियों 614-617 को देखें

mysql tables in use 1, locked 0
MySQL thread id 6155315, OS thread handle 0x85f11b70, query id 367774810 localhost root Sending data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification`
Trx read view will not see trx with id >= 1252538405, sees < 1252538391

ध्यान दें कि रेखा 617 कहती है

Trx read view will not see trx with id >= 1252538405, sees < 1252538391

यह मुझे क्या बताता है? आपके पास कुछ PRIMARY KEY है जिस पर एक auto_increment है id

idमेज के लिए आपका अधिकतम db_external_notificationउस समय से कम था 1252538391जब mysqldump लॉन्च किया गया था। जब आप से घटाते 1252538391हैं1252538405 , तो इसका मतलब है कि 14 या अधिक INSERT कमांड का प्रयास किया गया है। आंतरिक रूप से, इसे कम से कम 14 बार इस तालिका के स्वत: एकीकरण को स्थानांतरित करने की आवश्यकता होगी। फिर भी, इस idअंतर को प्रबंधित करने के कारण लॉग बफ़र में कुछ भी प्रतिबद्ध या यहां तक ​​कि धक्का नहीं दिया जा सकता है ।

अब, अपने पेस्टबिन से प्रक्रिया सूची को देखें। जब तक मैंने गर्भपात नहीं किया, मैंने 38 डीबी कनेक्शनों को एक INSERT (19 से पहले mysqldump प्रक्रिया (प्रक्रिया आईडी 6155315), 19 बाद) देखा। मुझे यकीन है कि Auto_increment गैप के प्रबंधन के कारण 14 या अधिक कनेक्शन फ्रीज़ हो गए हैं।


मैं लंबे समय से देख रहा था और कोई विशेष ताले नहीं पा रहा था। मैंने pastebin.com/D7WS3QAE में पूर्ण शो इनरोड स्टेटस चिपकाया है , मेरे लिए किसी भी चीज़ पर एक्सक्लूसिव लॉक जैसा कुछ नहीं दिखता है
अलेक्जेंडर इवानिसेविक

स्पष्टीकरण के लिए धन्यवाद। मैं सोच रहा हूं कि वे केवल-पढ़ने के लिए लेन-देन का उपयोग क्यों नहीं करते क्योंकि यह स्पष्ट है कि बैकअप कभी नहीं लिखेंगे, लेकिन मैं अनुमान लगा रहा हूं कि वे अपने उद्यम बैकअप के लिए उस सुविधा को रख रहे हैं।
अलेक्जेंडर इवानिसैविक

10

का --single-transactionविकल्प बैकअप कार्य शुरू करने से पहले mysqldump करता है लेकिन केवल कुछ शर्तों के तहत। उन शर्तों में से एक है जब आप भी निर्दिष्ट करते हैंFLUSH TABLES WITH READ LOCK--master-data विकल्प ।

स्रोत कोड में, mysql-5.6.19/client/mysqldump.cपंक्ति 5797 से:

if ((opt_lock_all_tables || opt_master_data ||
     (opt_single_transaction && flush_logs)) &&
    do_flush_tables_read_lock(mysql))
  goto err;

दोहराए जाने वाले लेन-देन को शुरू करने से पहले, सटीक बिनलॉग निर्देशांक पर एक ठोस लॉक प्राप्त करने के लिए, झूठ --master-data विकल्प इस लॉक को प्राप्त करने के लिए ट्रिगर करता है और फिर एक बार बिनलॉग निर्देशांक प्राप्त होने के बाद जारी किया जाता है।

वास्तव में, mysqldumpएक FLUSH TABLESद्वारा पीछा किया जाता हैFLUSH TABLES WITH READ LOCK क्योंकि दोनों काम करने की अनुमति देता है पढ़ने ताला मामलों में जहां प्रारंभिक फ्लश कुछ समय लगता है में तेजी से प्राप्त किया जा करने के लिए।

...तथापि...

जैसे ही उसने बिनलॉग निर्देशांक प्राप्त किया है, mysqldumpएक UNLOCK TABLESबयान जारी करता है, इसलिए आपके द्वारा शुरू किए गए फ्लश के परिणामस्वरूप कुछ भी अवरुद्ध नहीं होना चाहिए। Waiting for table flushलेन-देन के परिणामस्वरूप न तो कोई सूत्र होना चाहिएmysqldump

जब आप Waiting for table flushराज्य में एक थ्रेड देखते हैं , तो इसका मतलब यह होना चाहिए कि FLUSH TABLES [WITH READ LOCK]स्टेटमेंट जारी किया गया था और क्वेरी शुरू होने पर अभी भी चल रहा था - इसलिए क्वेरी को टेबल फ्लश के लिए इंतजार करना होगा, इससे पहले कि यह निष्पादित हो सके। आपके द्वारा पोस्ट की गई प्रक्रिया सूची के मामले में, mysqldumpयह उसी तालिका से पढ़ रहा है, और क्वेरी कुछ समय से चल रही है, फिर भी अवरुद्ध क्वेरीज़ को लंबे समय तक अवरुद्ध नहीं किया गया है।

यह सब बताता है कि कुछ और हुआ है।

आंतरिक रूप से काम करने के तरीके के साथ बग # 44884 में लंबे समय से जारी एक समस्या है FLUSH TABLESमुझे आश्चर्य नहीं होगा अगर मुद्दा अभी भी बना रहे, मुझे आश्चर्य होगा कि अगर यह मुद्दा कभी भी "ठीक" हो जाता है, क्योंकि यह हल करने के लिए एक बहुत ही जटिल मुद्दा है - वास्तव में एक उच्च संगामिति वातावरण में ठीक करना असंभव है - और किसी भी प्रयास में इसे ठीक करने से कुछ और टूटने, या नया, अलग, और अभी भी अवांछनीय व्यवहार करने का एक महत्वपूर्ण जोखिम होता है।

ऐसा लगता है कि जो आप देख रहे हैं उसके लिए यह स्पष्टीकरण होगा।

विशेष रूप से:

  • यदि आपके पास एक टेबल के खिलाफ लंबे समय से चल रही क्वेरी है, और समस्या है FLUSH TABLES, तो FLUSH TABLESलंबे समय तक चलने वाले क्वेरी के पूरा होने तक ब्लॉक हो जाएगा।

  • इसके अलावा, FLUSH TABLESजारी होने के बाद शुरू होने वाला कोई भी प्रश्न FLUSH TABLESपूरा होने तक अवरुद्ध हो जाएगा ।

  • इसके अलावा, यदि आप FLUSH TABLESक्वेरी को मारते हैं, तो अवरुद्ध होने वाली क्वेरी अभी भी मूल लंबे समय से चल रहे क्वेरी पर ब्लॉक होगी , जो क्वेरी को अवरुद्ध कर रही थी FLUSH TABLES, क्योंकि भले ही मारे गए FLUSH TABLESक्वेरी समाप्त नहीं हुई थी, वह तालिका (एक, या अधिक, लंबे समय से चल रहे क्वेरी के साथ शामिल) अभी भी फ्लश होने की प्रक्रिया में है, और यह कि लंबित फ्लश जल्द ही होने वाला है, जो लंबे समय से चल रहे क्वेरी को पूरा करता है - लेकिन पहले नहीं।

यहां संभावित निष्कर्ष यह है कि एक अन्य प्रक्रिया - शायद एक अन्य mysqldump, या एक बीमार-सलाह क्वेरी, या एक खराब-लिखित निगरानी प्रक्रिया एक तालिका को फ्लश करने की कोशिश की।

उस प्रश्न को बाद में एक अज्ञात तंत्र द्वारा मार दिया गया या समाप्त कर दिया गया, लेकिन इसके बाद के प्रभाव तक तक सीमित रहे mysqldump प्रश्न में तालिका से पढ़ने समाप्त हो गए।

आप इस स्थिति को दोहरा सकते हैं, FLUSH TABLESजबकि लंबे समय से चल रही क्वेरी प्रक्रिया में है। फिर एक और क्वेरी शुरू करें, जो ब्लॉक हो जाएगी। फिर FLUSH TABLESक्वेरी को मारें , जो नवीनतम क्वेरी को अनब्लॉक नहीं करेगी। फिर पहले क्वेरी को मारें, या इसे खत्म होने दें, और अंतिम क्वेरी सफलतापूर्वक चलेगी।


बाद में, यह असंबंधित है:

Trx read view will not see trx with id >= 1252538405, sees < 1252538391

यह सामान्य है, क्योंकि mysqldump --single-transactionएक मुद्दा है START TRANSACTION WITH CONSISTENT SNAPSHOT, जो इसे डंपिंग डेटा से बचाता है जो कि बदल गया था जबकि डंप प्रगति में था। इसके बिना, शुरुआत में प्राप्त बिनलॉग निर्देशांक निरर्थक होगा, क्योंकि यह --single-transactionवह नहीं होगा जो यह होने का दावा करता है। यह किसी भी तरह से इस Waiting for table flushमुद्दे से संबंधित नहीं होना चाहिए , क्योंकि यह लेनदेन स्पष्ट रूप से कोई ताले नहीं रखता है।


यह उत्तर वास्तव में सही है।
बोबन पी।

2

मैंने एक सुविधा अनुरोध प्रस्तुत किया: https://support.oracle.com/epmos/faces/BugDisplay?id=27103902

मैंने 5.6.37 के खिलाफ एक पैच भी लिखा है जो कि --सिंघल-ट्रांजेक्शन - मास्टर-डेटा संयोजन के साथ -सिंघल-ट्रांजेक्शन - स्लेव-डेटा के समान विधि का उपयोग करता है, जो बिना वारंटी के साथ उपलब्ध कराया जाता है। अपने जोखिम पार इस्तेमाल करें।

--- mysql-5.6.37/client/mysqldump.c.bak 2017-11-14 12:24:41.846647514 -0600
+++ mysql-5.6.37/client/mysqldump.c 2017-11-14 14:17:51.187050091 -0600
@@ -4900,10 +4900,10 @@
   return 0;
 }

+/*
 static int do_stop_slave_sql(MYSQL *mysql_con)
 {
   MYSQL_RES *slave;
-  /* We need to check if the slave sql is running in the first place */
   if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
     return(1);
   else
@@ -4911,23 +4911,21 @@
     MYSQL_ROW row= mysql_fetch_row(slave);
     if (row && row[11])
     {
-      /* if SLAVE SQL is not running, we don't stop it */
       if (!strcmp(row[11],"No"))
       {
         mysql_free_result(slave);
-        /* Silently assume that they don't have the slave running */
         return(0);
       }
     }
   }
   mysql_free_result(slave);

-  /* now, stop slave if running */
   if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
     return(1);

   return(0);
 }
+*/

 static int add_stop_slave(void)
 {
@@ -5841,10 +5839,12 @@
   if (!path)
     write_header(md_result_file, *argv);

+  /*
   if (opt_slave_data && do_stop_slave_sql(mysql))
     goto err;
+  */

-  if ((opt_lock_all_tables || opt_master_data ||
+  if ((opt_lock_all_tables || opt_master_data || opt_slave_data ||
        (opt_single_transaction && flush_logs)) &&
       do_flush_tables_read_lock(mysql))
     goto err;
@@ -5853,7 +5853,7 @@
     Flush logs before starting transaction since
     this causes implicit commit starting mysql-5.5.
   */
-  if (opt_lock_all_tables || opt_master_data ||
+  if (opt_lock_all_tables || opt_master_data || opt_slave_data ||
       (opt_single_transaction && flush_logs) ||
       opt_delete_master_logs)
   {
 static int add_stop_slave(void)
 {
@@ -5841,10 +5839,12 @@
   if (!path)
     write_header(md_result_file, *argv);

+  /*
   if (opt_slave_data && do_stop_slave_sql(mysql))
     goto err;
+  */

-  if ((opt_lock_all_tables || opt_master_data ||
+  if ((opt_lock_all_tables || opt_master_data || opt_slave_data ||
        (opt_single_transaction && flush_logs)) &&
       do_flush_tables_read_lock(mysql))
     goto err;
@@ -5853,7 +5853,7 @@
     Flush logs before starting transaction since
     this causes implicit commit starting mysql-5.5.
   */
-  if (opt_lock_all_tables || opt_master_data ||
+  if (opt_lock_all_tables || opt_master_data || opt_slave_data ||
       (opt_single_transaction && flush_logs) ||
       opt_delete_master_logs)
   {

मैंने FK रिश्तों के साथ बहुत सारे निष्णात गुरुओं का उपयोग करते हुए दास के साथ निम्नलिखित प्रक्रिया के साथ इसका परीक्षण किया।

  1. दास ए।
  2. ~ 15 मिनट प्रतीक्षा करें।
  3. विकल्प B- दास-लेन-देन और डम्प-दास = 2 के साथ डीबी 1 को डंप करें
  4. चरण 3 से डंप में निर्देशांक तक गुलाम ए शुरू करें।
  5. गुलाम ए से ड्रॉप डीबी 1 और 2।
  6. गुलाम A पर खाली DB 1 और 2 बनाएँ।
  7. डंप स्टेप 3 से स्लेव ए में लोड करें।
  8. एक ही विकल्प के साथ दास बी से डंप डीबी 2। DB 2 में FK के संबंध DB 1 से हैं।
  9. DB 2 के लिए replicate_ignore_db और दास A पर Skip_slave_start जोड़ें।
  10. गुलाम ए।
  11. दास ए पर चरण 8 में डंप से निर्देशांक तक दास शुरू करें।
  12. डंप स्टेप 8 से स्लेव ए में लोड करें।
  13. दास A से replicate_ignore_db और Skip_slave_start विकल्प निकालें।
  14. गुलाम ए।
  15. रुको ~ 1 सप्ताह।
  16. डेटा अखंडता को सत्यापित करने के लिए pt-checkum का उपयोग करें।

ओरेकल की पैच सबमिटल प्रक्रिया बल्कि गहन है इसलिए मैं इस मार्ग पर गया। मैं Percona और / या MariaDB के साथ इसे एकीकृत करने के लिए प्रयास कर सकता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.