MySQL InnoDB तालिका से डेटा पंक्तियों को हटाने के बाद डिस्क स्थान जारी नहीं करता है


140

मेरे पास InnoDB स्टोरेज इंजन का उपयोग करके एक MySQL टेबल है; इसमें लगभग 2M डेटा पंक्तियाँ हैं। जब मैंने तालिका से डेटा पंक्तियों को हटा दिया, तो उसने आवंटित डिस्क स्थान को जारी नहीं किया। न ही optimize tableकमांड चलाने के बाद ibdata1 फ़ाइल का आकार कम हो गया ।

क्या MySQL से डिस्क स्थान को पुनः प्राप्त करने का कोई तरीका है?

मैं एक बुरी स्थिति में हूं; यह एप्लिकेशन लगभग 50 विभिन्न स्थानों पर चल रहा है और अब लगभग सभी पर कम डिस्क स्थान की समस्या दिखाई दे रही है।


ऑप्टिमाइज़ कमांड चलाने के बाद भी, ibdata1 फ़ाइल का आकार कम नहीं हुआ।
सुमित देव

4
मुझे लगता है कि उस टिप्पणी को आपके उत्तर में बेहतर तरीके से संपादित किया जाएगा, और फिर हटा दिया जाएगा
बेन मिलवुड

stackoverflow.com/ संभव की नकल डुप्लिकेट (लेकिन यह एक पहले यहाँ था)
FlipMcF

1
"और न ही ऑप्टिमाइज़ टेबल कमांड को चलाने के बाद ibdata1 फ़ाइल का आकार कम हो गया है" ऐसा इसलिए है क्योंकि आपका innodb_file_per_tableबंद है। अच्छी खबर यह है कि यह विकल्प onMySQL के हाल के संस्करणों में डिफ़ॉल्ट रूप से है।
लेखाकार م

मैं "ऑप्टिमाइज़ टेबल एक्सएक्सएक्स" चलाता हूं और संदेश प्राप्त करता है "टेबल ऑप्टिमाइज़ेशन का समर्थन नहीं करता है, इसके बजाय विश्राम + विश्लेषण करता है।" इसके बाद एक शेल पर "डु-ह / वर / लिब / मस्कल" चल रहा था, मैं देख सकता था कि डेटाबेस सिकुड़ गया था।
user1097111

जवाबों:


137

MySQL ibdata1 के आकार को कम नहीं करता है। कभी। यहां तक ​​कि अगर आप optimize tableहटाए गए रिकॉर्ड से उपयोग किए गए स्थान को मुक्त करने के लिए उपयोग करते हैं, तो यह बाद में इसका पुन: उपयोग करेगा।

एक विकल्प का उपयोग करने के लिए सर्वर को कॉन्फ़िगर करना है innodb_file_per_table, लेकिन इसके लिए बैकअप, ड्रॉप डेटाबेस और पुनर्स्थापना की आवश्यकता होगी। सकारात्मक पक्ष यह है कि तालिका के लिए .ibd फ़ाइल एक के बाद कम हो जाती है optimize table


4
InnoDB फ़ाइल-प्रति-तालिका मोड स्थिति के बारे में MySQL 5.5 डॉक्स "मौजूदा तालिका के लिए [InnoDB फ़ाइल-प्रति-तालिका] सुविधाओं का लाभ उठाने के लिए, आप फ़ाइल-प्रति-तालिका सेटिंग चालू कर सकते हैं और ALTER TABLE t ENGINE=INNODBमौजूदा तालिका पर चल सकते हैं । " इसका अर्थ है कि आप इस सुविधा को चालू कर सकते हैं, मौजूदा सारणी को अलग सारणी कमांड के साथ एक अलग InnoDB फ़ाइल का उपयोग करने के लिए "परिवर्तित" करें, फिर आकार को छोटा करने के लिए तालिका को ऑप्टिमाइज़ करें। हालाँकि, एक बार जब आप कर लेते हैं तो आपको यह पता लगाना होगा कि (विशाल) स्रोत InnoDB फ़ाइल को कैसे हटाया जाए ...
जोश

9
मुझे लगता है कि यह तकनीकी रूप से प्रश्न का उत्तर देता है, लेकिन मैं उम्मीद करूंगा कि इस विषय को खोजने वाले अधिकांश लोग अंतरिक्ष को सिकोड़ने / पुनः प्राप्त करने के लिए वास्तविक प्रक्रिया की तलाश कर रहे हैं, जो यह उत्तर प्रदान नहीं करता है।
मनची

@Manachi यह प्रक्रिया "सर्वर को innodb_file_per_table", "बैकअप" सर्वर का उपयोग करने के लिए कॉन्फ़िगर करती है, "डेटाबेस को गिराएं", mysql को रोकें, हटाएं। सर्वर को शुरू करें और डेटाबेस (एस) को पुनर्स्थापित करें। MySQL 5.5+ के साथ आप जोश के द्वारा कही गई बातों का उपयोग कर सकते हैं, और सभी तालिकाओं को बदलने के बाद, सर्वर को रोक दें, विशाल .ibd को हटा दें और इसे फिर से शुरू करें।
लियोनेल मार्टिन्स

39

बस खुद को ही समस्या थी।

क्या होता है, कि अगर आप डेटाबेस को छोड़ देते हैं, तो भी innodb डिस्क स्थान को रिलीज़ नहीं करेगा। मुझे निर्यात करना था, mysql को रोकना, फ़ाइलों को मैन्युअल रूप से हटाना, mysql को शुरू करना, डेटाबेस और उपयोगकर्ता बनाना और फिर आयात करना। भगवान का शुक्र है कि मेरे पास केवल 200MB मूल्य की पंक्तियाँ थीं, लेकिन इसने 250GB की मासूम फ़ाइल को बख्श दिया।

डिजाइन द्वारा विफल।


10
हाँ, यह निश्चित रूप से विफल है।
त्रुक्त्र

1
MySql 5.5 में एक ही मुद्दा है: मैंने 28 जीबी टेबल के डिस्क उपयोग को कम करने के लिए "ऑप्टिमाइज़ टेबल" चलाया। ऑपरेशन ने संभवतः मूल एक का एक अनुकूलित क्लोन बनाने की कोशिश की, और ऐसा करने से विभाजन पर सभी जगह का उपयोग हुआ। अब "ऑप्टिमाइज़ टेबल" फेल हो गया और मैंने पूरा डीबी गिरा देने के बाद भी पार्टीशन पर कोई जगह नहीं छोड़ी ... बहुत निराशाजनक।
तुलसीकोड

1
और 4+ साल बाद मैं MySQL के साथ एक ही समस्या में चला गया। MS SQL समान है: dba.stackexchange.com/questions/47310/…
Csaba Toth

24

यदि आप innodb_file_per_table का उपयोग नहीं करते हैं , तो डिस्क स्थान को पुनः प्राप्त करना संभव है, लेकिन काफी थकाऊ है, और डाउनटाइम की एक महत्वपूर्ण राशि की आवश्यकता होती है।

कैसे करने के लिए बहुत गहराई है - लेकिन मैं नीचे प्रासंगिक हिस्सा चिपकाया।

अपने डंप में अपने स्कीमा की एक प्रति भी रखना सुनिश्चित करें।

वर्तमान में, आप सिस्टम टेबलस्पेस से डेटा फ़ाइल नहीं निकाल सकते। सिस्टम तालिकाओं के आकार को कम करने के लिए, इस प्रक्रिया का उपयोग करें:

अपने सभी InnoDB तालिकाओं को डंप करने के लिए mysqldump का उपयोग करें।

सर्वर बंद करो।

Ibdata और ib_log फ़ाइलों सहित सभी मौजूदा टेबलस्पेस फ़ाइलों को हटा दें। यदि आप जानकारी की एक बैकअप प्रतिलिपि रखना चाहते हैं, तो अपने कंप्यूटर की स्थापना में फ़ाइलों को हटाने से पहले सभी ib * फ़ाइलों को किसी अन्य स्थान पर कॉपी करें।

InnoDB तालिकाओं के लिए किसी भी .frm फ़ाइलों को निकालें।

एक नया टेबलस्पेस कॉन्फ़िगर करें।

सर्वर को पुनरारंभ करें।

डंप फ़ाइलों को आयात करें।


चरणों को शामिल करने के लिए धन्यवाद - AFAICT 'कैसे' लिंक इस जानकारी अब और शामिल नहीं है
एलैंड

3

दस साल बाद और मुझे भी यही समस्या थी। मैंने इसे निम्नलिखित तरीके से हल किया:

  • मैं अनुकूलित सभी डेटाबेस बने रहे।
  • मैंने अपने कंप्यूटर और MySQL को सेवाओं पर फिर से शुरू किया (Windows + r -> services.msc)

बस इतना ही :)


1

अंतरिक्ष पुनः प्राप्त करने की समस्या को हल करने का दूसरा तरीका है, तालिका के भीतर कई विभाजन बनाएँ - रेंज आधारित, मूल्य आधारित विभाजन और अंतरिक्ष को पुनः प्राप्त करने के लिए विभाजन को छोड़ / विभाजित करें, जो विशेष विभाजन में संग्रहीत पूरे डेटा द्वारा उपयोग किए गए स्थान को छोड़ देगा।

जब आप अपनी तालिका के लिए विभाजन की शुरुआत करते हैं, तो तालिका स्कीमा में कुछ परिवर्तन करने की आवश्यकता होगी जैसे - विशिष्ट कुंजी, अनुक्रमणिका में विभाजन को शामिल करना आदि।


0

साल भर पहले मुझे mysql5.7 वर्जन और ibdata1 पर 150 Gb का कब्जा था। इसलिए मैंने पूर्ववत सारणी जोड़ी

मायस्कल्डपम्प बैकअप लें
mysql सर्विस बंद करें
डेटा से सभी डेटा को निकालें dir
करें वर्तमान में मौजूदा तालिका में नीचे जोड़ें।

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

Mysql सर्विस
स्टोर mysqldump बैकअप शुरू करें

समस्या का समाधान हुआ !!


-1

MySQL Inodb इंजन के लिए तालिका से डेटा हटाने के बाद डिस्कस्पेस को पुनः प्राप्त करने के कई तरीके हैं

यदि आप शुरू से ही innodb_file_per_table का उपयोग नहीं करते हैं, तो सभी डेटा को डंप करते हुए, सभी फ़ाइल को हटा दें, डेटाबेस को फिर से बनाएं और डेटा को फिर से आयात करें (ऊपर FlipMcF के उत्तर की जांच करें)

यदि आप innodb_file_per_table का उपयोग कर रहे हैं, तो आप प्रयास कर सकते हैं

  1. यदि आप सभी डेटा को हटा सकते हैं ट्रंकट कमांड डेटा को हटा देगा और आपके लिए डिस्कस्पेस पुनः प्राप्त करेगा।
  2. ऑल्टर टेबल कमांड ड्रॉप करेगा और टेबल को फिर से बनाएगा ताकि वह डिस्कस्पेस को पुनः प्राप्त कर सके। इसलिए डेटा हटाने के बाद, परिवर्तन तालिका को चलाएं जो हार्डक रिलीज को बदलने के लिए कुछ भी नहीं बदलती है (यानी: टेबल TBL_A में charset uf8 है, डेटा को हटाने के बाद बदल दें TBL_A charset utf8 -> यह कमांड आपकी मेज से कुछ भी नहीं बदलता है लेकिन mysql को आपकी तालिका को फिर से बनाता है और पुनः प्राप्त करता है। डिस्क में जगह
  3. TBL_A की तरह TBL_B बनाएं। वह चुनिंदा डेटा डालें जिसे आप TBL_A से TBL_B में रखना चाहते हैं। TBL_A छोड़ें, और TBL_A को TBL_A नाम दें। यह तरीका बहुत प्रभावी है यदि TBL_A और डेटा जिसे हटाने की आवश्यकता है वह बड़ा है (MySQL innodb में कमांड हटाएं बहुत बुरा है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.