MySQL में ibdata1 फ़ाइल को कैसे सिकोड़ें / शुद्ध करें


561

मैं R में आँकड़ों के प्रदर्शन के लिए "क्विक टूल" के रूप में MySQL का उपयोग कर रहा हूँ, अर्थात, जब मैं R स्क्रिप्ट चलाता हूँ, तो मैं एक नया डेटाबेस (A) बनाता हूँ, एक नया टेबल (B) बनाता हूँ, B में डेटा आयात करता हूँ। मुझे क्या चाहिए पाने के लिए एक क्वेरी सबमिट करें, और फिर मैं बी को गिराता हूं और ए को ड्रॉप करता हूं।

यह मेरे लिए ठीक काम कर रहा है, लेकिन मुझे पता है कि ibdata फ़ाइल का आकार तेजी से बढ़ रहा है, मैंने MySQL में कुछ भी संग्रहीत नहीं किया है, लेकिन ibdata1 फ़ाइल पहले ही 100 एमबी से अधिक हो गई है।

मैं सेटअप के लिए अधिक या कम डिफ़ॉल्ट MySQL सेटिंग का उपयोग कर रहा हूं, क्या मेरे पास निश्चित समय के बाद ibdata1 फ़ाइल को स्वचालित रूप से सिकोड़ / शुद्ध कर सकता है?


जवाबों:


777

यही कारण है कि ibdata1सिकुड़ नहीं है MySQL का एक विशेष रूप से परेशान सुविधा है। ibdata1फ़ाइल वास्तव में जब तक आप सभी डेटाबेस हटाने के लिए, फ़ाइलों को हटा दें और एक डंप को फिर से लोड सिकुड़ नहीं किया जा सकता।

लेकिन आप MySQL को कॉन्फ़िगर कर सकते हैं ताकि प्रत्येक तालिका, जिसमें उसकी अनुक्रमणिका भी शामिल है, एक अलग फ़ाइल के रूप में संग्रहीत है। उस तरह ibdata1से बड़े रूप में विकसित नहीं होगा। बिल करविन की टिप्पणी के अनुसार यह डिफ़ॉल्ट रूप से MySQL के 5.6.6 संस्करण के रूप में सक्षम है।

कुछ समय पहले मैंने ऐसा किया था। हालाँकि, my.cnfइसे सक्षम करने के लिए आपको प्रत्येक तालिका के लिए अलग-अलग फ़ाइलों का उपयोग करने के लिए अपने सर्वर को बदलने की आवश्यकता है :

[mysqld]
innodb_file_per_table=1

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

जैसा कि आप ibdata1वास्तव में फ़ाइल को हटाने के लिए आपसे अंतरिक्ष को पुनः प्राप्त करना चाहते हैं :

  1. क्या एक mysqldumpसभी डेटाबेस, प्रक्रियाओं, ट्रिगर्स आदि के सिवाय mysqlऔर performance_schemaडेटाबेस
  2. उपरोक्त 2 डेटाबेस को छोड़कर सभी डेटाबेस को छोड़ दें
  3. बंद करो mysql
  4. हटाएँ ibdata1और ib_logफ़ाइलें
  5. Mysql शुरू करें
  6. डंप से पुनर्स्थापित करें

जब आप चरण 5 में MySQL शुरू करते हैं ibdata1और ib_logफ़ाइलों को फिर से बनाया जाएगा।

अब आप जाने के लिए फिट हैं। जब आप विश्लेषण के लिए एक नया डेटाबेस बनाते हैं, तो तालिकाओं को अलग-अलग ibd*फ़ाइलों में स्थित किया जाएगा , अंदर नहीं ibdata1। जैसा कि आप आमतौर पर डेटाबेस को जल्द ही छोड़ देते हैं, ibd*फाइलें हटा दी जाएंगी।

http://dev.mysql.com/doc/refman/5.1/en/drop-database.html

आपने शायद इसे देखा है:
http://bugs.mysql.com/bug.php?id=1341

कमांड का उपयोग करके ALTER TABLE <tablename> ENGINE=innodbया OPTIMIZE TABLE <tablename>ibdata1 से डेटा और इंडेक्स पेजों को अलग-अलग फ़ाइलों को निकालने के लिए कर सकते हैं। हालाँकि, ibdata1 तब तक नहीं सिकुड़ेगा जब तक आप ऊपर दिए गए चरणों को नहीं करते।

के संबंध में information_schema, जो न तो आवश्यक है और न ही गिराना संभव है। यह वास्तव में केवल पढ़ने वाले विचारों का एक गुच्छा है, न कि तालिकाओं का। और इनसे जुड़ी कोई फाइल नहीं है, डेटाबेस डायरेक्टरी भी नहीं है। informations_schemaस्मृति db-इंजन का उपयोग किया जाता है और छोड़ दिया और स्टॉप पर पुनर्जीवित कर रहा है / mysqld का पुनरारंभ करें। Https://dev.mysql.com/doc/refman/5.7/en/information-schema.html देखें ।


16
@JordanMagnuson जानकारी_schema छोड़ने के लिए परेशान मत करो। यह वास्तव में केवल पढ़ने वाले विचारों का एक गुच्छा है, न कि तालिकाओं का। और इनसे जुड़ी कोई फाइल नहीं है। डेटाबेस के लिए एक निर्देशिका भी नहीं है। Informations_schema मेमोरी db-engine का उपयोग कर रही है और इसे बंद कर दिया गया है और mysqld के स्टॉप / रिस्टार्ट पर पुनर्जीवित हो गया है। Dev.mysql.com/doc/refman/5.5/en/information-schema.html देखें । Performance_schema के बारे में मैंने स्वयं उस स्कीमा का उपयोग नहीं किया है।
जॉन पी।

4
मुझे नहीं पता कि यह हाल की बात है लेकिन एक बार innodb_file_per_table विकल्प सक्षम हो जाने के बाद आप "ALTER TABLE <tablename> Engine = InnoDB" (भले ही यह पहले से ही InnoDB है) चला सकते हैं और यह तालिका को अपनी व्यक्तिगत फ़ाइल में ले जाएगा। । डेटाबेस और ऐसे ड्रॉप करने की आवश्यकता नहीं है।
सी.आर.

3
+1 FWIW, MySQL 5.6 innodb_file_per_tableडिफ़ॉल्ट रूप से सक्षम करता है।
बिल कारविन

3
हां, ibdata1 अन्य फ़ाइलों के साथ मौजूद होने की उम्मीद है। Ibdata1 फ़ाइल अभी भी टेबल, पूर्ववत लॉग और बफ़र्स के बारे में मेटाडेटा रखेगी।
जॉन पी

1
मैंने अपने सर्वर में ibdata1 फ़ाइल के कारण अंतरिक्ष से बाहर चला दिया है, इसलिए मैं डेटाबेस भी डंप नहीं कर सकता। क्या यह केवल / var / lib / mysql ("mysql", "ibdata1", "ib_logfile0" और "ib_logfile1") को छोड़कर फ़ाइलों को स्थानांतरित करने के लिए समान होगा और फिर चरणों का पालन करें? देखें stackoverflow.com/questions/2482491/…
सोफीवॉर्स

47

जॉन पी के जवाब में जोड़ना ,

एक Linux सिस्टम के लिए, चरण 1-6 को इन कमांडों के साथ पूरा किया जा सकता है:

  1. mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
  2. DROP DATABASE [database_name];
  3. sudo /etc/init.d/mysqld stop
  4. sudo rm /var/lib/mysql/ibdata1
    sudo rm /var/lib/mysql/ib_logfile (और किसी अन्य ib_logfile का नाम हटाएं ib_logfile0, जिसका नाम हो सकता है , ib_logfile1आदि ...)
  5. sudo /etc/init.d/mysqld start
  6. create database [database_name];
  7. mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

चेतावनी: यदि आप इस mysql उदाहरण पर अन्य डेटाबेस रखते हैं, तो ये निर्देश आपको अन्य डेटाबेस खो देंगे। सुनिश्चित करें कि आपके द्वारा रखे जाने वाले सभी डेटाबेस को कवर करने के लिए चरण 1,2 और 6,7 को संशोधित किया गया है।


6
आपको हर डेटाबेस के लिए 1,2 और 6 को दोहराना होगा, जिसमें InnoDB टेबल है।
लोर्न

4
आपको # 5 और # 6 के बीच कुछ और चरणों की आवश्यकता है। आपको डेटाबेस को फिर से बनाना होगा और अनुमतियों को फिर से असाइन करना होगा। इसलिए mysql क्लाइंट कमांड प्रॉम्प्ट से create database database_name;और फिरgrant all privileges on database_name.* to 'username'@'localhost' identified by 'password';
फ्रेड

1
@ ऐसा करने पर मुझे विशेषाधिकारों को देने की आवश्यकता नहीं है। संभवतः क्योंकि मैंने डेटाबेस को उसी नाम से बनाया था?
crampicco

2
एक Password:संकेत पर पासवर्ड टाइप करने के लिए (जो एक सुरक्षित अभ्यास है), बस -pबिना किसी वास्तविक पासवर्ड के डाल दिया जाए ।
ADTC

जब तक आप mysqldump को ऐसा करने के लिए नहीं कहते हैं तब तक ट्रिगर, घटनाओं और दिनचर्या / कार्यों को डंप नहीं किया जाता है। यदि आपके किसी भी डेटाबेस में - thetriggers, --events और --routines जोड़ें। इसके अलावा, बस सभी डेटाबेस को एक-एक करके एक के बजाय एक-एक करके डंप करें।
फ्रीक

34

जब आप निर्दोष तालिकाओं को हटाते हैं, तो MySQL ibdata फ़ाइल के अंदर स्थान खाली नहीं करता है, इसीलिए यह बढ़ता रहता है। ये फाइलें शायद ही कभी सिकुड़ती हैं।

मौजूदा ibdata फ़ाइल को कैसे सिकोड़ें:

http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html

आप इसे स्क्रिप्ट कर सकते हैं और समय की निश्चित अवधि के बाद चलाने के लिए स्क्रिप्ट शेड्यूल कर सकते हैं, लेकिन ऊपर वर्णित सेटअप के लिए ऐसा लगता है कि कई टेबलस्पेस एक आसान समाधान है।

यदि आप कॉन्फ़िगरेशन विकल्प का उपयोग करते हैं innodb_file_per_table, तो आप कई टेबलस्पेस बनाते हैं। यानी, MySQL एक साझा फ़ाइल के बजाय प्रत्येक तालिका के लिए अलग-अलग फ़ाइल बनाता है। ये अलग-अलग फ़ाइलें डेटाबेस की निर्देशिका में संग्रहीत होती हैं, और जब आप इस डेटाबेस को हटाते हैं, तो वे हटा दिए जाते हैं। यह आपके मामले में ibdata फ़ाइलों को सिकोड़ने / शुद्ध करने की आवश्यकता को दूर करना चाहिए।

कई टेबलस्पेस के बारे में अधिक जानकारी:

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html


पहला लिंक टूटा, निकटतम मिलान मुझे मिल सकता है: dev.mysql.com/doc/refman/5.5/en/…
BlackICE

14

यदि आप अपने MySQL तालिकाओं के लिए (कुछ) InnoDB संग्रहण इंजन का उपयोग करते हैं, तो आप शायद पहले से ही इसके डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ समस्या में आ गए हैं। जैसा कि आपने अपने MySQL के डेटा डायरेक्टरी (Debian / Ubuntu - / var / lib / mysql में) पर गौर किया होगा, जिसमें 'ibdata1' नामक एक फाइल निहित है। यह MySQL उदाहरण के लगभग सभी InnoDB डेटा (यह लेन-देन लॉग नहीं है) रखती है और काफी बड़ा हो सकता है। डिफ़ॉल्ट रूप से इस फ़ाइल का प्रारंभिक आकार 10Mb है और यह स्वचालित रूप से फैली हुई है। दुर्भाग्य से, डिजाइन द्वारा InnoDB डेटा फ़ाइलों को छोटा नहीं किया जा सकता है। यही कारण है कि DELETE, TRUNCATEs, DROPs, आदि फ़ाइल द्वारा उपयोग किए गए स्थान को पुनः प्राप्त नहीं करेंगे।

मुझे लगता है कि आप वहां अच्छी व्याख्या और समाधान पा सकते हैं:

http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/


11

झटपट स्वीकार किए गए उत्तर की प्रक्रिया को जल्द से जल्द स्क्रिप्ट में लिख दें:

#!/usr/bin/env bash
DATABASES="$(mysql -e 'show databases \G' | grep "^Database" | grep -v '^Database: mysql$\|^Database: binlog$\|^Database: performance_schema\|^Database: information_schema' | sed 's/^Database: //g')"
mysqldump --databases $DATABASES -r alldatabases.sql && echo "$DATABASES" | while read -r DB; do
    mysql -e "drop database \`$DB\`"
done && \
    /etc/init.d/mysql stop && \
    find /var/lib/mysql -maxdepth 1 -type f \( -name 'ibdata1' -or -name 'ib_logfile*' \) -delete && \
    /etc/init.d/mysql start && \
    mysql < alldatabases.sql && \
    rm -f alldatabases.sql

के रूप में सहेजें purge_binlogs.shऔर के रूप में चलाएँ root

इससे बाहर रखा गया mysql, information_schema, performance_schema(और binlogनिर्देशिका)।

मान लें कि आपके पास व्यवस्थापक क्रेडेंशियल हैं /root/.my.cnfऔर आपका डेटाबेस डिफ़ॉल्ट /var/lib/mysqlनिर्देशिका में रहता है ।

इस स्क्रिप्ट को चलाने के बाद आप बाइनरी लॉग भी शुद्ध कर सकते हैं:

PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;

फिर भी यकीन नहीं हो रहा है, लेकिन आज एक समान प्रक्रिया के दौरान मेरी कुछ InnoDB टेबल्स दूषित हो गई थीं, इसलिए alldatabases.sqlयदि सभी टेबल स्वस्थ हैं , तो मैं डबल चेकिंग से पहले नहीं हटाऊंगा। कुछ सुधारों के लिए: innodb_fast_shutdown=0शटडाउन से पहले सेट करें , autocommit=0SQL फ़ाइल आयात करने से पहले सेट करें, SQL फ़ाइल आयात COMMITकरने के autocommit=1बाद निष्पादित करें और सेट करें, mysqlcheck --all-databasesबैकअप हटाने से पहले उपयोग करें ।
विक्टर

6

यदि आपका लक्ष्य MySQL मुक्त स्थान की निगरानी करना है और आप अपनी ibdata फ़ाइल को सिकोड़ने के लिए MySQL को रोक नहीं सकते हैं, तो इसे टेबल स्टेटस कमांड के माध्यम से प्राप्त करें। उदाहरण:

MySQL> 5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'

MySQL <5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'

फिर इस मूल्य को अपनी ibdata फ़ाइल से तुलना करें:

du -b ibdata1

स्रोत: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html


4

ऊपर mysql- सर्वर व्यंजनों के एक नए संस्करण में "mysql" डेटाबेस को क्रश करेगा। पुराने संस्करण में यह काम करता है। नए कुछ तालिकाओं में तालिका प्रकार INNODB पर स्विच किया जाता है, और ऐसा करने से आप उन्हें नुकसान पहुंचाएंगे। सबसे आसान तरीका है:

  • आप सभी डेटाबेस को डंप करें
  • mysql- सर्वर की स्थापना रद्द करें,
  • my.cnf में बने रहें:
    [mysqld]
    innodb_file_per_table=1
  • सभी को / var / lib / mysql में मिटा दें
  • mysql-server इंस्टॉल करें
  • उपयोगकर्ताओं और डेटाबेस को पुनर्स्थापित करें

1

जैसा कि पहले ही नोट किया गया है कि आप ibdata1 को सिकोड़ नहीं सकते (ऐसा करने के लिए आपको डंप और पुनर्निर्माण करने की आवश्यकता है), लेकिन अक्सर कोई वास्तविक आवश्यकता भी नहीं होती है।

ऑटोबेक्स्टेंड (शायद सबसे सामान्य आकार की सेटिंग) का उपयोग करके ibdata1 स्टोरेज का प्रचार करता है, हर बार बढ़ने पर यह लगभग भर जाता है। यह तेजी से लिखता है क्योंकि अंतरिक्ष पहले से ही आवंटित है।

जब आप डेटा हटाते हैं तो यह सिकुड़ता नहीं है लेकिन फ़ाइल के अंदर का स्थान अप्रयुक्त के रूप में चिह्नित किया जाता है। अब जब आप नया डेटा डालेंगे तो यह फ़ाइल को आगे बढ़ने से पहले फ़ाइल में खाली जगह का पुनः उपयोग करेगा।

यदि आपको वास्तव में उस डेटा की आवश्यकता है तो यह केवल बढ़ना जारी रखेगा। जब तक आपको वास्तव में किसी अन्य एप्लिकेशन के लिए स्थान की आवश्यकता न हो, तब तक इसे सिकोड़ने का कोई कारण नहीं है।


66
मुझे लगता है कि आप अंतरिक्ष को खाली करने की आवश्यकता के बारे में थोड़ा बहुत खारिज कर रहे हैं।
आकर्षित किया

2
मैं एक 60Gig ठोस राज्य विभाजन है। मैं अंतरिक्ष से तेजी से बाहर निकलता हूं, क्योंकि मैं 4 + गिग डेटाबेस के साथ काम करता हूं। मैं mysql को जल्द ही एक और विभाजन में ले जाना चाहता हूं, लेकिन यह सवाल है और यह उत्तर मुझे इस बीच मदद करेगा
NullVoxPopuli

3
इस उत्तर के लिए धन्यवाद, यह बहुत उपयोगी है। मैंने विरासत डेटा से कुछ तालिकाओं को साफ कर दिया है ... यह जानना अच्छा है कि डिस्क पर आकार जल्द ही किसी भी समय फिर से नहीं बढ़ेगा।
ब्रैड

1
मेरे पास 500G ibdata1 फ़ाइल है - लेकिन इसमें संग्रहीत डेटा का लगभग सभी अब प्रति-डेटाबेस फ़ाइलों में संग्रहीत है। मुझे अंतरिक्ष के इस महाविस्फोट वाले कचरे को सिकोड़ने की बहुत आवश्यकता है!
फ्रैंकस्टर

2
पूरी बकवास! एक फाइल जो फूली रहती है उसे ट्रिम करने की आवश्यकता है चाहे आप अंतरिक्ष से बाहर चल रहे हों या नहीं । मैं इसे ए कहूंगा storage leak
एडीटीसी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.