Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

परीक्षण के लिए अपने MySQL उदाहरणों को कैसे विफल या क्रैश करें?

आप एक MySQL डेटाबेस को कई तरीकों से हटा सकते हैं। कुछ स्पष्ट तरीके हैं होस्ट को बंद करना, पावर केबल को बाहर निकालना, या एक अशुद्ध MySQL शटडाउन व्यवहार का अनुकरण करने के लिए SIGKILL के साथ mysqld प्रक्रिया को हार्ड किल करना। लेकिन आपके MySQL सर्वर को जानबूझकर क्रैश करने के कम सूक्ष्म तरीके भी हैं, और फिर देखें कि यह किस प्रकार की श्रृंखला प्रतिक्रिया को ट्रिगर करता है। तुमने ऐसा क्यों करना चाहोगे? विफलता और पुनर्प्राप्ति में कई कोने के मामले हो सकते हैं, और उन्हें समझने से उत्पादन में चीजें होने पर आश्चर्य के तत्व को कम करने में मदद मिल सकती है। आदर्श रूप से, आप एक नियंत्रित वातावरण में विफलताओं का अनुकरण करना चाहते हैं, और फिर डेटाबेस विफलता प्रक्रियाओं को डिज़ाइन और परीक्षण करना चाहते हैं।

MySQL में ऐसे कई क्षेत्र हैं जिनसे हम निपट सकते हैं, इस पर निर्भर करते हुए कि आप इसे कैसे विफल या क्रैश करना चाहते हैं। आप टेबलस्पेस को दूषित कर सकते हैं, MySQL बफ़र्स और कैश को ओवरफ्लो कर सकते हैं, सर्वर को भूखा रखने के लिए संसाधनों को सीमित कर सकते हैं, और अनुमतियों के साथ गड़बड़ भी कर सकते हैं। इस ब्लॉग पोस्ट में, हम आपको लिनक्स वातावरण में MySQL सर्वर को क्रैश करने के कुछ उदाहरण दिखाने जा रहे हैं। उनमें से कुछ उदाहरण के लिए उपयुक्त होंगे। अमेज़ॅन आरडीएस उदाहरण, जहां आपके पास अंतर्निहित होस्ट तक पहुंच नहीं होगी।

मारें, मारें, मारें, मरें, मरें, मरें

एक MySQL सर्वर को विफल करने का सबसे आसान तरीका केवल प्रक्रिया या होस्ट को मारना है, और MySQL को एक सुंदर शटडाउन करने का मौका नहीं देना है। एक mysqld क्रैश का अनुकरण करने के लिए, प्रक्रिया को सिग्नल 4, 6, 7, 8 या 11 भेजें:

$ kill -11 $(pidof mysqld)

MySQL त्रुटि लॉग को देखते समय, आप निम्न पंक्तियाँ देख सकते हैं:

11:06:09 UTC - mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.
..
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...

आप प्रक्रिया को तुरंत समाप्त करने के लिए किल -9 (सिगकिल) का भी उपयोग कर सकते हैं। Linux सिग्नल के बारे में अधिक विवरण यहां पाया जा सकता है। वैकल्पिक रूप से, आप हार्डवेयर पक्ष पर एक मध्यम तरीके का उपयोग कर सकते हैं जैसे कि पावर केबल को खींचना, हार्ड रीसेट बटन को नीचे दबाना या स्टोनीथ पर फेंसिंग डिवाइस का उपयोग करना।

OOM ट्रिगर करना

क्लाउड प्रसाद में लोकप्रिय MySQL जैसे Amazon RDS और Google Cloud SQL के पास उन्हें क्रैश करने का कोई सीधा तरीका नहीं है। सबसे पहले क्योंकि आपको डेटाबेस इंस्टेंस के लिए कोई ओएस-स्तरीय एक्सेस नहीं मिलेगी, और दूसरी बात यह है कि प्रदाता एक मालिकाना पैच वाले MySQL सर्वर का उपयोग करता है। एक तरीका यह है कि कुछ बफ़र्स को ओवरफ्लो किया जाए, और आउट-ऑफ-मेमोरी (OOM) मैनेजर को MySQL प्रोसेस को शुरू करने दें।

आप सॉर्ट बफर आकार को रैम की तुलना में कुछ बड़ा कर सकते हैं, और MySQL सर्वर के विरुद्ध कई MySQL सॉर्ट प्रश्नों को शूट कर सकते हैं। हमारे Amazon RDS इंस्टेंस पर sysbench का उपयोग करके 10 मिलियन पंक्तियों की तालिका बनाते हैं, ताकि हम एक विशाल प्रकार का निर्माण कर सकें:

$ sysbench \
--db-driver=mysql \
--oltp-table-size=10000000 \
--oltp-tables-count=1 \
--threads=1 \
--mysql-host=dbtest.cdw9q2wnb00s.ap-tokyo-1.rds.amazonaws.com \
--mysql-port=3306 \
--mysql-user=rdsroot \
--mysql-password=password \
/usr/share/sysbench/tests/include/oltp_legacy/parallel_prepare.lua \
run

sort_buffer_size बदलें Amazon RDS डैशबोर्ड -> पैरामीटर समूह -> पैरामीटर समूह बनाएं -> समूह का नाम निर्दिष्ट करें -> पैरामीटर संपादित करें -> "sort_buffer_size" चुनें और निर्दिष्ट करें। मान 5368709120 के रूप में।

इंस्टेंस -> इंस्टेंस एक्शन -> संशोधित -> डेटाबेस विकल्प -> डेटाबेस पैरामीटर समूह -> पर जाकर पैरामीटर समूह परिवर्तन लागू करें और हमारे नए बनाए गए पैरामीटर समूह को चुनें। फिर, परिवर्तनों को लागू करने के लिए RDS इंस्टेंस को रीबूट करें।

एक बार हो जाने पर, sort_buffer_size . का नया मान सत्यापित करें :

MySQL [(none)]> select @@sort_buffer_size;
+--------------------+
| @@sort_buffer_size |
+--------------------+
|         5368709120 |
+--------------------+

फिर 48 साधारण प्रश्नों को सक्रिय करें जिनके लिए क्लाइंट से छँटाई की आवश्यकता होती है:

$ for i in {1..48}; do (mysql -urdsroot -ppassword -h dbtest.cdw9q2wnb00s.ap-tokyo-1.rds.amazonaws.com -e 'SELECT * FROM sbtest.sbtest1 ORDER BY c DESC >/dev/null &); done

यदि आप उपरोक्त को एक मानक होस्ट पर चलाते हैं, तो आप देखेंगे कि MySQL सर्वर समाप्त हो जाएगा और आप निम्न पंक्तियों को OS के syslog या dmesg में प्रकट होते हुए देख सकते हैं:

[164199.868060] Out of memory: Kill process 47060 (mysqld) score 847 or sacrifice child
[164199.868109] Killed process 47060 (mysqld) total-vm:265264964kB, anon-rss:3257400kB, file-rss:0kB

सिस्टमड के साथ, MySQL या MariaDB स्वचालित रूप से पुनरारंभ हो जाएगा, इसलिए Amazon RDS करता है। आप देख सकते हैं कि हमारे आरडीएस इंस्टेंस के लिए अपटाइम को वापस 0 (mysqladmin स्थिति के तहत) पर रीसेट कर दिया जाएगा, और 'नवीनतम पुनर्स्थापना समय' मान (आरडीएस डैशबोर्ड के तहत) को उस क्षण तक अपडेट किया जाएगा जब वह नीचे चला गया।

डेटा को दूषित करना

InnoDB के पास ibdata1 नाम की फ़ाइल के अंदर डेटा डिक्शनरी, बफ़र्स और रोलबैक सेगमेंट को स्टोर करने के लिए अपना सिस्टम टेबलस्पेस है। यदि आप innodb_file_per_table (MySQL 5.6.6+ में डिफ़ॉल्ट रूप से सक्षम) कॉन्फ़िगर नहीं करते हैं, तो यह साझा टेबलस्पेस को भी संग्रहीत करता है। हम बस इस फ़ाइल को शून्य कर सकते हैं, mysqld को क्रैश करने के लिए एक राइट ऑपरेशन और फ्लश टेबल भेज सकते हैं:

# empty ibdata1
$ cat /dev/null > /var/lib/mysql/ibdata1
# send a write
$ mysql -uroot -p -e 'CREATE TABLE sbtest.test (id INT)'
# flush tables
$ mysql -uroot -p -e 'FLUSH TABLES WITH READ LOCK; UNLOCK TABLES'

लिखने के बाद, त्रुटि लॉग में, आप देखेंगे:

2017-11-15T06:01:59.345316Z 0 [ERROR] InnoDB: Tried to read 16384 bytes at offset 98304, but was only able to read 0
2017-11-15T06:01:59.345332Z 0 [ERROR] InnoDB: File (unknown): 'read' returned OS error 0. Cannot continue operation
2017-11-15T06:01:59.345343Z 0 [ERROR] InnoDB: Cannot continue operation.

इस बिंदु पर, mysql हैंग हो जाएगा क्योंकि यह कोई ऑपरेशन नहीं कर सकता है, और फ्लशिंग के बाद, आपको "mysqld को सिग्नल 11" लाइनें मिलेंगी और mysqld बंद हो जाएगा। साफ करने के लिए, आपको दूषित ibdata1, साथ ही ib_logfile* को हटाना होगा क्योंकि रीडो लॉग फ़ाइलों का उपयोग एक नए सिस्टम टेबलस्पेस के साथ नहीं किया जा सकता है जो कि अगले पुनरारंभ पर mysqld द्वारा उत्पन्न किया जाएगा। डेटा हानि अपेक्षित है।

MyISAM तालिकाओं के लिए, हम MySQL डेटादिर के अंतर्गत .MYD (MyISAM डेटा फ़ाइल) और .MYI (MyISAM अनुक्रमणिका) के साथ गड़बड़ कर सकते हैं। उदाहरण के लिए, निम्न कमांड फ़ाइल के अंदर स्ट्रिंग "F" की किसी भी घटना को "9" से बदल देता है:

$ replace F 9 -- /var/lib/mysql/sbtest/sbtest1.MYD

फिर, लक्ष्य तालिका में कुछ लेखन (जैसे, sysbench का उपयोग करके) भेजें और फ्लशिंग करें:

mysql> FLUSH TABLE sbtest.sbtest1;

निम्नलिखित MySQL त्रुटि लॉग में दिखाई देना चाहिए:

2017-11-15T06:56:15.021564Z 448 [ERROR] /usr/sbin/mysqld: Incorrect key file for table './sbtest/sbtest1.MYI'; try to repair it
2017-11-15T06:56:15.021572Z 448 [ERROR] Got an error from thread_id=448, /export/home/pb2/build/sb_0-24964902-1505318733.42/rpm/BUILD/mysql-5.7.20/mysql-5.7.20/storage/myisam/mi_update.c:227

MyISAM तालिका को क्रैश के रूप में चिह्नित किया जाएगा और इसे फिर से सुलभ बनाने के लिए REPAIR TABLE स्टेटमेंट चलाना आवश्यक है।

संसाधन सीमित करना

हम अपनी mysqld प्रक्रिया के लिए ऑपरेटिंग सिस्टम संसाधन सीमा भी लागू कर सकते हैं, उदाहरण के लिए ओपन फाइल डिस्क्रिप्टर की संख्या। open_file_limit चर (डिफ़ॉल्ट 5000 है) का उपयोग करने से mysqld को setrlimit() कमांड का उपयोग करके फ़ाइल डिस्क्रिप्टर आरक्षित करने की अनुमति मिलती है। आप इस वेरिएबल को अपेक्षाकृत छोटा सेट कर सकते हैं (बस mysqld को शुरू करने के लिए पर्याप्त है) और फिर सीमा तक पहुंचने तक MySQL सर्वर को कई प्रश्न भेजें।

यदि mysqld एक सिस्टमड सर्वर में चल रहा है, तो हम इसे /usr/lib/systemd/system/mysqld.service पर स्थित सिस्टमड यूनिट फ़ाइल में सेट कर सकते हैं, और निम्न मान को कुछ कम में बदल सकते हैं (systemd डिफ़ॉल्ट 6000 है):

# Sets open_files_limit
LimitNOFILE = 30

सिस्टमड में परिवर्तन लागू करें और MySQL सर्वर को पुनरारंभ करें:

$ systemctl daemon-reload
$ systemctl restart mysqld

फिर, नए कनेक्शन/क्वेरी भेजना शुरू करें जो अलग-अलग डेटाबेस और टेबल में गिने जाते हैं ताकि mysqld को कई फाइलें खोलनी पड़े। आपको निम्न त्रुटि दिखाई देगी:

2017-11-16T04:43:26.179295Z 4 [ERROR] InnoDB: Operating system error number 24 in a file operation.
2017-11-16T04:43:26.179342Z 4 [ERROR] InnoDB: Error number 24 means 'Too many open files'
2017-11-16T04:43:26.179354Z 4 [Note] InnoDB: Some operating system error numbers are described at http://dev.mysql.com/doc/refman/5.7/en/operating-system-error-codes.html
2017-11-16T04:43:26.179363Z 4 [ERROR] InnoDB: File ./sbtest/sbtest9.ibd: 'open' returned OS error 124. Cannot continue operation
2017-11-16T04:43:26.179371Z 4 [ERROR] InnoDB: Cannot continue operation.
2017-11-16T04:43:26.372605Z 0 [Note] InnoDB: FTS optimize thread exiting.
2017-11-16T04:45:06.816056Z 4 [Warning] InnoDB: 3 threads created by InnoDB had not exited at shutdown!

इस बिंदु पर, जब सीमा समाप्त हो जाती है, तो MySQL फ्रीज हो जाएगा और यह कोई भी ऑपरेशन नहीं कर पाएगा। कनेक्ट करने का प्रयास करते समय, आपको कुछ समय बाद निम्नलिखित दिखाई देंगे:

$ mysql -uroot -p
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 104

अनुमतियों के साथ खिलवाड़

mysqld प्रक्रिया "mysql" उपयोगकर्ता द्वारा चलती है, जिसका अर्थ है कि सभी फाइलें और निर्देशिका जिन्हें इसे एक्सेस करने की आवश्यकता है, वे MySQL उपयोगकर्ता/समूह के स्वामित्व में हैं। अनुमति और स्वामित्व के साथ खिलवाड़ करके, हम MySQL सर्वर को बेकार बना सकते हैं:

$ chown root:root /var/lib/mysql
$ chmod 600 /var/lib/mysql

सर्वर पर कुछ लोड उत्पन्न करें और फिर MySQL सर्वर से कनेक्ट करें और सभी तालिकाओं को डिस्क पर फ्लश करें:

mysql> FLUSH TABLES WITH READ LOCK; UNLOCK TABLES;

इस समय, mysqld अभी भी चल रहा है, लेकिन यह एक तरह से बेकार है। आप इसे एक mysql क्लाइंट के माध्यम से एक्सेस कर सकते हैं लेकिन आप कोई ऑपरेशन नहीं कर सकते:

mysql> SHOW DATABASES;
ERROR 1018 (HY000): Can't read dir of '.' (errno: 13 - Permission denied)

गड़बड़ी को साफ करने के लिए, सही अनुमतियां सेट करें:

$ chown mysql:mysql /var/lib/mysql
$ chmod 750 /var/lib/mysql
$ systemctl restart mysqld

इसे लॉक करें

फ्लश टेबल विथ रीड लॉक (FTWRL) कई स्थितियों में विनाशकारी हो सकता है। उदाहरण के लिए, गैलेरा क्लस्टर में जहां सभी नोड्स लिखने को संसाधित करने में सक्षम हैं, आप इस कथन का उपयोग किसी एक नोड के भीतर से क्लस्टर को लॉक करने के लिए कर सकते हैं। यह कथन लॉक जारी होने तक फ्लशिंग के दौरान mysqld द्वारा संसाधित किए जाने वाले अन्य प्रश्नों को रोकता है, जो बैकअप प्रक्रियाओं (MyISAM तालिकाओं) और फ़ाइल सिस्टम स्नैपशॉट के लिए बहुत आसान है।

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

mysql> FLUSH TABLES WITH READ LOCK;
mysql> exit

फिर mysqld को max_connections . तक पहुंचने तक नई क्वेरीज़ का एक गुच्छा भेजें मूल्य। जाहिर है, आप एक बार आउट होने के बाद पिछले सत्र की तरह वापस नहीं आ सकते। तो लॉक असीमित रूप से चल रहा होगा और लॉक को रिलीज़ करने का एकमात्र तरीका किसी अन्य सुपर विशेषाधिकार उपयोगकर्ता (दूसरे सत्र का उपयोग करके) क्वेरी को मारना है। या mysqld प्रक्रिया को स्वयं बंद कर दें, या हार्ड रीबूट करें।

अस्वीकरण

यह ब्लॉग MySQL के साथ विफलता परिदृश्यों को अनुकरण करने के लिए sysadmins और DBA के विकल्प देने के लिए लिखा गया है। इन्हें अपने प्रोडक्शन सर्वर पर न आजमाएं :-)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. प्रमाणीकरण प्लगइन 'caching_sha2_password' समर्थित नहीं है

  2. MySQL PHP असंगति

  3. एक क्वेरी के साथ कई पंक्तियाँ सम्मिलित करें MySQL

  4. अपडेट क्वेरी के लिए स्टेटमेंट कैसे तैयार करें?

  5. बाउंड पैरामीटर का कई बार उपयोग करें