यह सब इस तथ्य के साथ शुरू हुआ कि एक बिंदु पर कर्नेल ने मायस्कल्ड डेमन को nailed किया और mysql_safe ने स्वचालित रूप से इसे फिर से शुरू किया और सब कुछ ठीक हो जाएगा, लेकिन डेटाबेस में केवल टेबल का उपयोग MyISAM द्वारा किया गया था। अंत में, मुझे myisamcheck का उपयोग करना पड़ा लेकिन यह एक पूरी तरह से अलग कहानी है। इंडेक्स की जांच और फिक्सिंग की प्रक्रिया में, एक तालिका का सामना करना पड़ा और बैकअप से बहाल करने का निर्णय लिया गया, यह अच्छा है कि उन्हें दिन में एक बार किया जाता है।
स्रोत डेटा:
- हमारे पास बोर्ड पर MySQL के साथ एक डेटाबेस सर्वर है;
- किसी भी चीज़ के लॉग (सांख्यिकी) की क्षतिग्रस्त तालिका जो लगातार भरी जा रही है और उदाहरण के लिए, थोड़ी देर के लिए उपयोग नहीं की जा सकती है
- दैनिक बैकअप;
- पिछले दैनिक (पूर्ण) बैकअप से बाइनरी लॉग।
उद्देश्य:
- ऑपरेशन के लिए सर्वर उपलब्ध होना चाहिए;
- नया डेटा तालिका में गिरना चाहिए;
- डेटा अखंडता को पुनर्स्थापित करें।
अपेक्षित परिणाम:
क्षतिग्रस्त तालिका में डेटा तरबूज डेटाबेस को रोकने के बिना बहाल किया जाता है;
तालिका में वर्तमान सहित सभी डेटा शामिल हैं।
लीजेंड:
- DB-SRV - एक डेटाबेस के साथ उत्तर;
- ACME_DB - वह डेटाबेस जिसमें "खोई" तालिका;
- ACME_DB_RECOVERY - पुनर्प्राप्ति, तालिका या डेटाबेस के लिए डेटाबेस;
- ACME_DB_INCREMENTAL - बाइनरी लॉग से पुनर्प्राप्ति के लिए डेटाबेस;
- FAIL_TABLE - क्षतिग्रस्त तालिका को बहाल किया जाए;
- ACME_DB.FAIL_TABLE.BACKUPDATE.sql - अंतिम पूर्ण बैकअप से क्षतिग्रस्त तालिका के डंप के साथ फ़ाइल।
इस तरह के बगीचे पर गर्व क्यों था। और सभी डेटाबेस के आकार और संसाधनों की कमी के कारण, वर्तमान में एक सारणीबद्ध डंप का उपयोग किया जा रहा है, इसलिए बैकअप के समय डेटा अखंडता का कोई सवाल ही नहीं है।
अस्वीकरण के बजाय:
- तालिका के क्रैश होने पर डेटा रिकवरी के लिए एक और रणनीति शुरू करने के उद्देश्य से लेख लिखा गया है। सभी ASIS का उपयोग दृढ़ता से हतोत्साहित किया जाता है। ठीक है, आप अपने डेटा के लिए होने वाली हर चीज के लिए खुद जिम्मेदार हैं :)
कार्य योजना (वसूली):
हम क्षतिग्रस्त तालिका की एक प्रति बनाते हैं ताकि वर्तमान डेटा को जोड़ना है
mysql > CREATE TABLE FAIL_TABLE_NEW LIKE FAIL_TABLE;
यदि AUTO_INCREMENT फ़ील्ड वाली तालिका है, तो हम काउंटर पर भी परिवर्तन करते हैं। हम किसी भी राशि से काउंटर मूल्य बढ़ाते हैं, उदाहरण के लिए, FAIL_TABLE तालिका में वर्तमान मूल्य से 1000।
mysql> ALTER TABLE FAIL_TABLE_NEW AUTO_INCREMENT = मूल्य;
mysql > RENAME FAIL_TABLE TO FAIL_TABLE_OLD, FAIL_TABLE_NEW TO FAIL_TABLE;
हम सहायक डेटाबेस ACME_DB_RECOVERY और ACME_DB_INCREMENTAL बनाते हैं
mysql > CREATE DATABASE ACME_DB_RECOVERY;
mysql > CREATE DATABASE ACME_DB_INCREMENTAL;
पागल के लिए :) प्रत्येक सहायक आधार के लिए एक उपयोगकर्ता बनाना संभव है।
mysql > CREATE USER 'recovery'@'localhost' IDENTIFIED BY 'mypass';
mysql > CREATE USER 'increment'@'localhost' IDENTIFIED BY 'mypass';
mysql > GRANTSELECT,INSERT,UPDATE,DELETE,LOCK TABLES,SUPER,INDEX,CREATE ON ACME_DB_RECOVERY TO 'recovery'@'localhost';
mysql > GRANT SELECT,INSERT,UPDATE,DELETE,LOCK TABLES,SUPER,INDEX,CREATE ON ACME_DB_INCREMENTAL TO 'increment'@'localhost';
mysql > FLUSH PRIVILEGES;
पूर्ण बैकअप से क्षतिग्रस्त तालिका पुनर्प्राप्त करें
$ mysql -u recovery -p -h DB-SRV ACME_DB_RECOVERY < ACME_DB.FAIL_TABLE.BACKUPDATE.sql
इसके बाद, सर्वर डेटादिर पर जाएं और फॉर्म server_hostname-bin.004324 की फाइलें ढूंढें
हमें एक उपयुक्त बिनलॉग मिलता है, जो बैकअप से तालिका में डेटा से पहले शुरू होता है और भ्रष्टाचार के साथ डेटा के साथ बायनॉगॉग होता है। आप देख सकते हैं कि mysqlbinlog -d ACME_DB कमांड के साथ बाइनरी लॉग में क्या है।
बिनलॉग से उबरने के लिए, आपको पूर्ण तालिका संरचना ACME_DB बनाने की आवश्यकता है
$ mysqldump --no-data -u ACME_USER -p ACME_DB -h DB-SRV | mysql -h DB-SRV -u increment -p ACME_DB_INCREMENTAL
और उनके द्वारा बनाए गए क्रम में बाइनरी लॉग से डेटा दर्ज करें।
$ mysqlbinlog -d ACME_DB < > | mysql -u increment -p ACME_DB_INCREMENTAL
अगला, हमें डंप और बाइनरी लॉग से डेटा कनेक्ट करने की आवश्यकता है।
हम बैकअप से तालिका में अंतिम डेटा निर्धारित करते हैं, इस "क्षण" से हम बाइनरी लॉग्स से पुनर्प्राप्त तालिका से डेटा और अस्थायी तालिका से पहला डेटा जोड़ेंगे। उदाहरण के लिए, इन प्रश्नों के साथ:
mysql > USE ACME_DB;
mysql > SELECT MIN(id) FROM FAIL_TABLE; # FIRST_ID
mysql > SELECT MIN(date) FROM FAIL_TABLE; # FISRT_DATE
mysql> USE ACME_DB_RECOVERY;
mysql > SELECT MAX(id) FROM FAIL_TABLE; # LAST_ID
mysql > SELECT MAX(date) FROM FAIL_TABLE; # LAST_DATE
mysql > INSERT INTO FAIL_TABLE (SELECT * FROM ACME_DB_INCREMENTAL.FAIL_TABLE WHERE ID > LAST_ID AND ID < FIRST_ID);
#
mysql > INSERT INTO FAIL_TABLE (SELECT * FROM ACME_DB_INCREMENTAL.FAIL_TABLE WHERE DATE >= LAST_DATE AND DATE < FIRST_DATE);
इसलिए, डेटा को गिरावट के क्षण तक बहाल किया गया था, अब यह थोड़ा डेटा ट्रांसफर है, उदाहरण AUTO_INCREMENT फ़ील्ड वाली तालिका के लिए होगा, यदि नहीं, तो आप काउंटर सेट करने के साथ जगह को छोड़ सकते हैं।
हम ACME_DB.FAIL_TABLE तालिका में वर्तमान काउंटर को देखते हैं, ACME_RECOVERY.FAIL_TABLE तालिका में ACME_RECOVERY.FAIL_TABLE तालिका को थोड़ा और सेट करते हैं, यह सब निर्भर करता है कि आपने कितने रिकॉर्ड डेटाबेस में डाले हैं, कई हजार पर्याप्त होना चाहिए
mysql > USE ACME_RECOVERY;
mysql > ALTER TABLE FAIL_TABLE AUTO_INCREMENT = value;
mysql > USE ACME_DB;
mysql > RENAME TABLE FAIL_TABLE TO FAIL_TABLE_SMALL, ACME_RECOVERY.FAIL_TABLE TO ACME_DB.FAIL_TABLE;
mysql > INSERT INTO FAIL_TABLE (SELECT * FROM FAIL_TABLE_SMALL);
सभी अस्थायी डेटा हटाएं
mysql > DROP DATABASE ACME_DB_INCREMENTAL;
mysql > DROP DATABASE ACME_DB_RECOVERY;
अद्यतन:
zhirafovod ने सुझाव दिया कि एक डेटाबेस दूसरों के परिवर्तनों पर डेटा प्राप्त कर सकता है, उदाहरण के लिए, ACME2.TABLE को अपडेट करें ...
परिवर्तनों से बचने के लिए, आपको निश्चित रूप से नए डेटाबेस और विशेष रूप से उनके लिए बनाए गए उपयोगकर्ताओं के लिए विशेषाधिकार निर्धारित करना चाहिए।