मैंने अक्टूबर 2010 में स्टैकऑवरफ्लो में इसे संबोधित किया है ।
InnoDB बुनियादी ढांचे में सबसे व्यस्त फ़ाइल को ध्यान में रखें: / var / lib / mysql / ibdata1
यह फ़ाइल सामान्य रूप से चार प्रकार की जानकारी रखती है
- तालिका डेटा
- टेबल इंडेक्स
- एमवीसीसी (मल्टीवर्जनिंग कंसीडर कंट्रोल) डेटा
- टेबल मेटाडेटा (टेबलस्पेस आईडी की सूची)
OPTIMIZE TABLE
Ibdata1 में संग्रहीत एक InnoDB टेबल के खिलाफ दौड़ना दो काम करता है:
- तालिका का डेटा बनाता है और ibdata1 के अंदर सन्निहित अनुक्रमित करता है, इस प्रकार तेजी से उपयोग होता है
- यह ibdata1 को विकसित करता है क्योंकि सन्निहित डेटा और सूचकांक पृष्ठों को ibdata1 से जोड़ा जाता है
जब आप ibdata1 से टेबल डेटा और टेबल इंडेक्स को अलग कर सकते हैं और स्वतंत्र रूप से innodb_file_per_table का उपयोग करके उन्हें प्रबंधित कर सकते हैं , तो ibdata1 में डिस्कस्पेस के पूरे बड़े अंतर को केवल अस्वीकार नहीं किया जाएगा और पुनः प्राप्त नहीं किया जा सकता है। आपको अधिक करना चाहिए।
Ibdata1 को एक बार और सभी के लिए सिकोड़ने के लिए आपको निम्नलिखित कार्य करने होंगे:
1) MySQLDump सभी डेटाबेस को SQL टेक्स्ट फ़ाइल (इसे /root/SQLData.sql पर कॉल करें)
2) सभी डेटाबेस (mysql स्कीमा को छोड़कर)
3) शटडाउन mysql
4) निम्नलिखित पंक्तियों को /etc/my.cnf में जोड़ें
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
सिडेनोट: जो भी आपका सेट innodb_buffer_pool_size के लिए है, सुनिश्चित करें कि innodb_log_file_size 25% innodb_buffer_pool_size है।
5) ibdata1, ib_logfile0 और ib_logfile1 हटाएं
इस बिंदु पर, केवल / var / lib / mysql में mysql स्कीमा होना चाहिए
6) mysql को पुनरारंभ करें
यह ibdata1 को 10 या 18MB (MySQL के onthe संस्करण के आधार पर), ib_logfile0 और ib_logfile1 प्रत्येक 1G पर पुनः बनाएगा।
7) mysql में Reload /root/SQLData.sql
ibdata1 बढ़ेगा लेकिन इसमें केवल टेबल मेटाडेटा होगा। वास्तव में, यह वर्षों में बहुत धीरे-धीरे बढ़ेगा। यदि आपके पास निम्न में से एक या अधिक है तो एकमात्र तरीका ibdata1 वृद्धि है:
- DDL का एक बहुत (
CREATE TABLE
, DROP TABLE
, ALTER TABLE
)
- बहुत सारा लेन-देन
- प्रति लेनदेन करने के लिए बहुत सारे बदलाव
प्रत्येक InnoDB तालिका ibdata1 के बाहर मौजूद होगी
मान लीजिए कि आपके पास mydb.mytable नाम की एक InnoDB तालिका है। यदि आप / var / lib / mysql / mydb में जाते हैं, तो आपको तालिका का प्रतिनिधित्व करने वाली दो फाइलें दिखाई देंगी
- mytable.frm (संग्रहण इंजन हैडर)
- mytable.ibd (mydb.mytable के लिए टेबल डेटा और टेबल इंडेक्स का घर)
ibdata1 में अब कभी भी InnoDB डेटा और इंडेक्स नहीं होंगे।
/Etc/my.cnf में innodb_file_per_table विकल्प के साथ, आप चला सकते हैं OPTIMIZE TABLE mydb.mytable;
और फ़ाइल /var/lib/mysql/mydb/mytable.ibd वास्तव में सिकुड़ जाएगी।
मैंने अपने करियर में कई बार MySQL DBA के रूप में ऐसा किया है
वास्तव में, मैंने पहली बार ऐसा किया था, मैंने 500MB में एक 50GB ibdata1 फ़ाइल को ढहा दिया।
कोशिश करो। यदि आपके पास इस पर और प्रश्न हैं, तो मुझे ईमेल करें। मुझ पर विश्वास करो। यह छोटी अवधि में और लंबी दौड़ में काम करेगा !!!
UPDATE 2012-04-19 09:23 EDT
उपरोक्त चरणों को चलाने के बाद, आप यह कैसे निर्धारित कर सकते हैं कि तालिकाओं को डीफ़्रैग्मेन्ट करने की आवश्यकता क्या है? यह पता लगाना संभव है, लेकिन आपके पास इसकी स्क्रिप्ट होगी।
यहाँ एक उदाहरण है: मान लीजिए कि आपके पास तालिका है mydb.mytable
। Innodb_file_per_table सक्षम होने के साथ, आपके पास फ़ाइल /var/lib/mysql/mydb/mytable.ibd
आपको दो नंबर प्राप्त करने होंगे
OS से FILESIZE: आप इस तरह से OS से फाइल का पता लगा सकते हैं
ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print $5}'
INFORMATION_SCHEMA से FILESIZE: आप इस तरह की सूचनाओं से जानकारी प्राप्त कर सकते हैं:
SELECT (data_length+index_length) tblsize FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';
बस OS मान से INFORMATION_SCHEMA मान घटाएं और INFORMATION_SCHEMA मान द्वारा अंतर विभाजित करें।
वहाँ से आप तय करेंगे कि उस तालिका को डीफ़्रैग करने के लिए कितना प्रतिशत आवश्यक है। बेशक, आप इसे निम्न आदेशों में से एक का उपयोग करके डीफ़्रैग्मेंट करते हैं:
OPTIMIZE TABLE mydb.mytable;
या
ALTER TABLE mydb.mytable ENGINE=InnoDB;