आप InnoDB तालिकाओं से विखंडन को कैसे हटाते हैं?


13

मेरे पास एक डेटाबेस है जिसमें तालिकाओं की संख्या है।

मैं तालिकाओं से कुछ रिकॉर्ड हटाना चाहता हूं कि कोई भी रिकॉर्ड 20K या 50K से अधिक नहीं है।

सभी टेबल्स InnoDB हैं। और file_per_tableहै बंद

जब मैं कई तालिकाओं से रिकॉर्ड हटा दूंगा तो तालिकाओं में विखंडन होगा।

क्या विखंडन को हटाने का कोई तरीका है।?

अपडेट 17 अप्रैल को

mysql> select TABLE_NAME, TABLE_SCHEMA, Data_free from information_schema.TABLES where TABLE_SCHEMA NOT IN ('information_schema', 'mysql') and Data_Free >0;
+-----------------+--------------+-----------+
| TABLE_NAME      | TABLE_SCHEMA | Data_free |
+-----------------+--------------+-----------+
| City            | world_innodb |   5242880 |
| City_Copy       | world_innodb |   5242880 |
| Country         | world_innodb |   5242880 |
| CountryLanguage | world_innodb |   5242880 |
| a               | world_innodb |   5242880 |
| t1              | world_innodb |   5242880 |
| t2              | world_innodb |   5242880 |
+-----------------+--------------+-----------+
7 rows in set (0.00 sec)

तो अब मेरा प्रश्न यह है कि मैं कैसे तय करूंगा कि मेरी टेबल खंडित है या नहीं।



1
और एक लेख InnoDB: पेरकोना के ब्लॉग साइट से विखंडन के बाद देखो
ypercube y

जवाबों:


14

मैंने अक्टूबर 2010 में स्टैकऑवरफ्लो में इसे संबोधित किया है

InnoDB बुनियादी ढांचे में सबसे व्यस्त फ़ाइल को ध्यान में रखें: / var / lib / mysql / ibdata1

यह फ़ाइल सामान्य रूप से चार प्रकार की जानकारी रखती है

  • तालिका डेटा
  • टेबल इंडेक्स
  • एमवीसीसी (मल्टीवर्जनिंग कंसीडर कंट्रोल) डेटा
  • टेबल मेटाडेटा (टेबलस्पेस आईडी की सूची)

OPTIMIZE TABLEIbdata1 में संग्रहीत एक 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;

मुझे नहीं लगता है / var / lib / mysql / ibdata1 बहुत व्यस्त है आप की सिफारिश की innodb_file_per_table = 1 विकल्प का उपयोग कर रहे हैं
CrackerJack9

1
@ CrackerJack9 ibdata1 अविश्वसनीय रूप से सुपरबसी है क्योंकि इसमें क्या जाता है: 1) डबल बफ़र जानकारी, 2) सेकेंडरी इंडेक्स के लिए बफर डालें, 3) डेटा डिक्शनरी, 4) रोलबैक सेगमेंट, 5) अंडरटेबल टेबल्स। कृपया इन चीजों के सचित्र प्रतिनिधित्व के लिए goto scribd.com/doc/31337494/XtraDB-InnoDB-internals-in-drawing करें । यहां तक ​​कि InnoDB तालिकाओं के लिए डेटा और इंडेक्स पेजों को हटाने के साथ, ibdata1 अभी भी एक उच्च लेनदेन वाले वातावरण में काफी बढ़ सकता है।
RolandoMySQLDBA

1
@ CrackerJack9 में ibdata1 के आस-पास की अतिरिक्त गतिविधि पर चर्चा करने वाला एक अतिरिक्त पद है: dba.stackexchange.com/a/23367/877
RolandoMySQLDBA

मुझे एहसास नहीं था कि यह अभी भी इतनी भारी इस्तेमाल किया गया था। अत्यधिक सराहनीय!
क्रैकरजैक

@RolandoMySQLDBA क्या आप ढेर में पॉप कर सकते हैं जब आपके पास समय हो?
ypercube y

5

यदि आप बार-बार पंक्तियों को हटाते हैं (या चर-लंबाई डेटा प्रकारों के साथ पंक्तियों को अपडेट करते हैं), तो आप फ़ाइल सिस्टम विखंडन के समान अपनी डेटा फ़ाइल (एस) में बहुत सारे बर्बाद स्थान के साथ समाप्त हो सकते हैं।

यदि आप innodb_file_per_tableविकल्प का उपयोग नहीं कर रहे हैं , तो केवल एक चीज जिसके बारे में आप कर सकते हैं, वह है डेटाबेस का निर्यात और आयात, एक समय-और-डिस्क-गहन प्रक्रिया।

लेकिन यदि आप उपयोग कर रहे हैं innodb_file_per_table, तो आप इस स्थान को पहचान सकते हैं और पुनः प्राप्त कर सकते हैं!

५.१.२१ से पहले, मुक्त स्थान काउंटर तालिका_कॉममेंट कॉलम से info_schema.tables से उपलब्ध है। यहाँ कुछ एसक्यूएल है जिसमें रिक्त स्थान के कम से कम 100M (वास्तव में 97.65M) के साथ तालिकाओं की पहचान की जा सकती है:

तालिका का चयन करें_सेम्मा, table_name, table_comment से जानकारी_schema.tables, जहां से Inn
InnoDB ’और टेबल_comment RLIKE की InnoDB मुक्त: ([0-9] {6,} *);

5.1.21 से शुरू होकर, इसे data_free कॉलम में ले जाया गया (बहुत अधिक उपयुक्त स्थान):

तालिका का चयन करें table_schema, table_name, data_free / 1024/1024 AS_ डेटा_फ्री_एमबी से जानकारी_सहमा.नेट।

आप तालिका के पुनर्निर्माण के द्वारा खोई हुई जगह को पुनः प्राप्त कर सकते हैं। ऐसा करने का सबसे अच्छा तरीका वास्तव में कुछ भी बदले बिना 'परिवर्तन तालिका' का उपयोग करना है:

ALTER TABLE `TableName` ENGINE=InnoDB;

यदि आप एक InnoDB टेबल पर 'ऑप्टिमाइज़ टेबल' चलाते हैं तो MySQL पर्दे के पीछे यही करता है। इसका परिणाम रीड लॉक होगा, लेकिन पूर्ण टेबल लॉक नहीं। कितना समय लगता है यह पूरी तरह से तालिका में डेटा की मात्रा पर निर्भर करता है (लेकिन डेटा फ़ाइल का आकार नहीं)। यदि आपके पास हटाए गए या अपडेट की उच्च मात्रा वाली एक तालिका है, तो आप इस मासिक, या साप्ताहिक रूप से भी चलाना चाह सकते हैं।


एक और बात मैं यह समझने में असमर्थ हूं कि data_free> 100 * 1024 * 1024 का अर्थ क्या है? और जब मैंने परिणाम देखा तो मैं तय नहीं कर पा रहा हूं कि टेबल खंडित है या नहीं .. ?? क्या कोई रास्ता ऐसा है कि मैं? कह सकते हैं कि तालिका खंडित है या खंडित नहीं है?
अब्दुल मनफ

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