जब MySQL सर्वर में डिस्क स्थान समाप्त हो जाता है, तो आपको अपने एप्लिकेशन में निम्न में से एक त्रुटि दिखाई देगी (साथ ही MySQL त्रुटि लॉग में):
ERROR 3 (HY000) at line 1: Error writing file '/tmp/AY0Wn7vA' (Errcode: 28 - No space left on device)
बाइनरी लॉग के लिए त्रुटि संदेश ऐसा दिखता है:
[ERROR] [MY-000035] [Server] Disk is full writing './binlog.000019' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.
रिले लॉग के लिए त्रुटि संदेश ऐसा दिखता है:
[ERROR] [MY-000035] [Server] Disk is full writing './relay-bin.000007' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.
धीमी क्वेरी लॉग के लिए आपको इस तरह एक त्रुटि संदेश दिखाई देगा:
[ERROR] [MY-011263] [Server] Could not use /var/log/mysql/mysql-slow.log for logging (error 28 - No space left on device). Turning logging off for the server process. To turn it on again: fix the cause, then either restart the query logging by using "SET GLOBAL SLOW_QUERY_LOG=ON" or restart the MySQL server.
InnoDB के लिए ऐसा दिखता है:
[ERROR] [MY-012144] [InnoDB] posix_fallocate(): Failed to preallocate data for file ./#innodb_temp/temp_8.ibt, desired size 16384 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/8.0/en/operating-system-error-codes.html
[Warning] [MY-012638] [InnoDB] Retry attempts for writing partial data failed.
[ERROR] [MY-012639] [InnoDB] Write to file ./#innodb_temp/temp_8.ibt failed at offset 81920, 16384 bytes should have been written, only 0 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
[ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'
[Warning] [MY-012145] [InnoDB] Error while writing 16384 zeroes to ./#
वे सभी एक ही त्रुटि कोड संख्या की रिपोर्ट कर रहे हैं जो कि 28 है। वैकल्पिक रूप से, हम त्रुटि कोड का उपयोग वास्तविक त्रुटि को देखने के लिए पेरर कमांड के साथ कर सकते हैं:
$ perror 28
OS error code 28: No space left on device
उपरोक्त का सीधा सा मतलब है कि MySQL सर्वर डिस्क स्थान से बाहर है, और इस बिंदु पर अधिकांश समय MySQL बंद या रुका हुआ है। इस ब्लॉग पोस्ट में, हम Linux-आधारित वातावरण में चल रहे MySQL के लिए इस समस्या को हल करने के तरीकों पर गौर करने जा रहे हैं।
समस्या निवारण
सबसे पहले, हमें यह निर्धारित करना होगा कि कौन सा डिस्क विभाजन भरा हुआ है। MySQL को किसी भिन्न डिस्क या विभाजन पर डेटा संग्रहीत करने के लिए कॉन्फ़िगर किया जा सकता है। शुरू करने के लिए त्रुटि में बताए गए पथ को देखें। इस उदाहरण में, हमारी निर्देशिका डिफ़ॉल्ट स्थान पर स्थित है, /var/lib/mysql जो / विभाजन के अंतर्गत है। हम df कमांड का उपयोग कर सकते हैं और डेटा को संग्रहीत करने वाले विभाजन को प्राप्त करने के लिए डेटादिर को पूरा पथ निर्दिष्ट कर सकते हैं:
$ df -h /var/lib/mysql
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 40G 40G 20K 100% /
उपरोक्त का मतलब है कि हमें रूट पार्टीशन में कुछ जगह खाली करनी होगी।
अस्थायी समाधान
अस्थायी समाधान कुछ डिस्क स्थान को खाली करना है ताकि MySQL डिस्क पर लिख सके और संचालन को फिर से शुरू कर सके। अगर हमें इस तरह की समस्या का सामना करना पड़ता है, तो हम इन चीज़ों से संबंधित हैं:
- अनावश्यक फ़ाइलों को निकालना
- बाइनरी लॉग का शुद्धिकरण
- पुरानी टेबल को छोड़ना, या एक बहुत बड़ी टेबल का पुनर्निर्माण करना
अनावश्यक फ़ाइलें हटाएं
यदि MySQL सर्वर डाउन या अनुत्तरदायी है, या आपके पास कोई बाइनरी लॉग सक्षम नहीं है, तो यह आमतौर पर पहला कदम है। उदाहरण के लिए, /var/log/ के अंतर्गत फ़ाइलें आमतौर पर अनावश्यक फ़ाइलों को देखने के लिए पहली जगह होती हैं:
$ cd /var/log
$ find . -type f -size +5M -exec du -sh {} +
8.1M ./audit/audit.log.6
8.1M ./audit/audit.log.5
8.1M ./audit/audit.log.4
8.1M ./audit/audit.log.3
8.1M ./audit/audit.log.2
8.1M ./audit/audit.log.1
11M ./audit/audit.log
8.5M ./secure-20190429
8.0M ./wtmp
उपरोक्त उदाहरण दिखाता है कि 5MB से बड़ी फ़ाइलों को कैसे पुनर्प्राप्त किया जाए। हम रोटेट की गई लॉग फ़ाइलों को सुरक्षित रूप से हटा सकते हैं जो आमतौर पर {filename}.{number} स्वरूप में होती हैं, उदाहरण के लिए ऑडिट.लॉग.1 से ऑडिट.लॉग.6 तक। सर्वर में संग्रहीत किसी भी बड़े पुराने बैकअप के बारे में भी यही बात कही जा सकती है। यदि आपने Percona Xtrabackup या MariaDB बैकअप के माध्यम से एक बहाली की थी, तो xtrabackup_ के साथ उपसर्ग वाली सभी फ़ाइलों को MySQL डेटादिर से हटाया जा सकता है, क्योंकि वे अब बहाली के लिए आवश्यक नहीं हैं। xtrabackup_logfile आमतौर पर सबसे बड़ी फ़ाइल होती है क्योंकि इसमें सभी लेन-देन निष्पादित होते हैं जबकि xtrabackup प्रक्रिया डेटादिर को गंतव्य तक कॉपी करती है। निम्न उदाहरण MySQL डेटादिर में सभी संबंधित फाइलों को दिखाता है:
$ ls -lah /var/lib/mysql | grep xtrabackup_
-rw-r-----. 1 mysql root 286 Feb 4 11:30 xtrabackup_binlog_info
-rw-r--r--. 1 mysql root 24 Feb 4 11:31 xtrabackup_binlog_pos_innodb
-rw-r-----. 1 mysql root 83 Feb 4 11:31 xtrabackup_checkpoints
-rw-r-----. 1 mysql root 808 Feb 4 11:30 xtrabackup_info
-rw-r-----. 1 mysql root 179M Feb 4 11:31 xtrabackup_logfile
-rw-r--r--. 1 mysql root 1 Feb 4 11:31 xtrabackup_master_key_id
-rw-r-----. 1 mysql root 248 Feb 4 11:31 xtrabackup_tablespaces
इसलिए, उल्लिखित फ़ाइलों को हटाया जाना सुरक्षित है। कम से कम 10% अधिक खाली स्थान होने पर MySQL सेवा प्रारंभ करें।
बाइनरी लॉग को शुद्ध करें
यदि MySQL सर्वर अभी भी उत्तरदायी है और इसमें बाइनरी लॉग सक्षम है, उदाहरण के लिए, प्रतिकृति या पॉइंट-इन-टाइम पुनर्प्राप्ति के लिए, हम PURGE स्टेटमेंट का उपयोग करके और प्रदान करके पुरानी बाइनरी लॉग फ़ाइलों को शुद्ध कर सकते हैं मध्यान्तर। इस उदाहरण में, हम 3 दिन पहले सभी बाइनरी लॉग हटा रहे हैं:
mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);
mysql> SHOW BINARY LOGS;
MySQL प्रतिकृति के लिए, उन सभी लॉग को हटाना सुरक्षित है जिन्हें दोहराया गया है और दासों पर लागू किया गया है। सर्वर पर Relay_Master_Log_File मान की जाँच करें:
mysql> SHOW SLAVE STATUS\G
...
Relay_Master_Log_File: binlog.000008
...
और पुरानी लॉग फ़ाइलों को हटा दें, उदाहरण के लिए binlog.000007 और पुराने। यह सुनिश्चित करने के लिए कि उसके पास पर्याप्त संसाधन हैं, MySQL सर्वर को पुनरारंभ करना अच्छा अभ्यास है। हम बाइनरी लॉग रोटेशन को एक्सपायर_लॉग्स_डे वेरिएबल (
फिर, [mysqld] अनुभाग के अंतर्गत MySQL कॉन्फ़िगरेशन फ़ाइल में निम्न पंक्ति जोड़ें:
MySQL 8.0 में, इसके बजाय binlog_expire_logs_seconds का उपयोग करें, जहां डिफ़ॉल्ट मान 2592000 सेकंड (30 दिन) है। इस उदाहरण में, हम इसे घटाकर केवल 3 दिन (60 सेकंड x 60 मिनट x 24 घंटे x 3 दिन) कर देते हैं:
SET PERSIST सुनिश्चित करेगा कि कॉन्फ़िगरेशन अगले पुनरारंभ में लोड हो गया है। इस कमांड द्वारा सेट किया गया कॉन्फ़िगरेशन /var/lib/mysql/mysqld-auto.cnf. ध्यान दें कि DELETE ऑपरेशन डिस्क स्थान खाली नहीं करेगा जब तक कि ऑप्टिमाइज़ टेबल को बाद में निष्पादित नहीं किया जाता है। इस प्रकार, यदि आपने कई पंक्तियों को हटा दिया है, और आप एक विशाल DELETE ऑपरेशन के बाद OS पर वापस खाली स्थान वापस करना चाहते हैं, OPTIMIZE TABLE चलाएँ, या इसे फिर से बनाएँ। उदाहरण के लिए:
हम ALTER स्टेटमेंट का उपयोग करके टेबल को फिर से बनाने के लिए भी बाध्य कर सकते हैं:
ध्यान दें कि उपरोक्त डीडीएल ऑपरेशन ऑनलाइन डीडीएल के माध्यम से किया जाता है, जिसका अर्थ है कि MySQL समवर्ती डीएमएल संचालन की अनुमति देता है जबकि पुनर्निर्माण जारी है। डीफ़्रेग्मेंटेशन ऑपरेशन करने का दूसरा तरीका है mysqldump का उपयोग टेबल को टेक्स्ट फ़ाइल में डंप करने के लिए, टेबल को ड्रॉप करने के लिए और इसे डंप फ़ाइल से पुनः लोड करने के लिए। अंततः, हम अप्रयुक्त तालिका को हटाने के लिए DROP TABLE का उपयोग कर सकते हैं या तालिका में सभी पंक्तियों को साफ़ करने के लिए TRUNCATE TABLE, जिसके परिणामस्वरूप स्थान वापस OS पर वापस आ जाता है। स्थायी समाधान निश्चित रूप से संबंधित डिस्क या विभाजन में अधिक स्थान जोड़ना है, या सर्वर में अनावश्यक फ़ाइलों को रखने के लिए एक छोटा अवधारण नियम लागू करना है। यदि आप एक स्केलेबल फ़ाइल स्टोरेज सिस्टम के शीर्ष पर चल रहे हैं, तो आपको बहुत अधिक परेशानी के बिना या MySQL सेवा में न्यूनतम व्यवधान और डाउनटाइम के बिना संसाधन को बढ़ाने में सक्षम होना चाहिए। अपने भंडारण को कैसे आयाम दें और MySQL और MariaDB क्षमता नियोजन को समझने के बारे में अधिक जानने के लिए, इस ब्लॉग पोस्ट को देखें।
डिस्क से संबंधित डेटाबेस समस्याएं MySQL डेटाबेस प्रशासकों और RDBMS के साथ काम करने वाले डेवलपर्स से संबंधित सबसे प्रचलित मुद्दों में से एक हैं - हालाँकि, जबकि वे मुद्दे प्रचलित हो सकते हैं, उन्हें हल करने के कई तरीके भी हैं - और उन्हें अच्छे के लिए हल करें। इस तरह की समस्या से निपटने के तरीके हमेशा सीधे नहीं हो सकते हैं, हालांकि, क्लस्टरकंट्रोल जैसे टूल द्वारा प्रदान किए गए थोड़े से प्रयास और सहायता से इन सभी को हल किया जा सकता है।
ClusterControl की सक्रिय निगरानी क्षमताओं के साथ, डेटाबेस से संबंधित मुद्दों को आपकी चिंता कम से कम होनी चाहिए:डिस्क स्थान के 80% तक पहुंचने पर आपको एक चेतावनी के रूप में एक सूचना मिलेगी, और एक महत्वपूर्ण चेतावनी के रूप में एक अधिसूचना यदि आपकी डिस्क का उपयोग 90% या अधिक तक पहुँच जाता है। हमें उम्मीद है कि इस ब्लॉग पोस्ट ने आपको MySQL डिस्क स्थान के उपयोग से संबंधित कम से कम कुछ मुद्दों को हल करने, ClusterControl के अपने उपयोग का आनंद लेने में मदद की है, और हम आपको अगले ब्लॉग में देखेंगे।mysql> SET GLOBAL expire_logs_days = 3;
expire_logs_days=3
mysql> SET GLOBAL binlog_expire_logs_seconds = (60*60*24*3);
mysql> SET PERSIST binlog_expire_logs_seconds = (60*60*24*3);
पुरानी तालिकाएँ छोड़ें / तालिकाओं का पुनर्निर्माण करें
mysql> DELETE tbl_name WHERE id < 100000; -- remove 100K rows
mysql> OPTIMIZE TABLE tbl_name;
mysql> ALTER TABLE tbl_name FORCE;
mysql> ALTER TABLE tbl_name; -- a.k.a "null" rebuild
डिस्क स्थान की समस्याओं का स्थायी समाधान
सारांश