データ復旧redis

この記事の著者は、従業員Stepan Karamyshevに属します。

彼にはまだ招待状がないので、私は彼のために投稿しています。

彼に代わってさらにナレーション。



このテキストは天才のふりをするものではなく、そこに記載されている方法は万能薬でも特効薬でもありません。 以下で説明する事故の際に実施された調査の結果、ロシア語または英語(またはドイツ語ではないようですが)で同様の情報を提供する単一のソースは見つかりませんでした。 注意:情報は「現状のまま」提供されるため、思慮深い調査なしで使用すると致命的になる可能性があります。



red'kuの祖父

民話



画像







ケースは異なります。 時々、最も信頼性の高いシステムでさえ失敗することがあります。 それで、今回、恐怖と苦々しさで私のコマンドセンターの椅子に沈んで、Skypeチャットで100以上のメッセージを見つけました。 ストーリーの対角線を読むと、クライアントのredisが腫れて意識を失い、OOMキラーの助けを借りて殺されたことがわかりました。 当然、追加専用ファイルは適切に延期できませんでした。 魔法のredis-check-aof --fixは、ファイルの修正を喜んで報告し、同時に8ギガバイトのファイルを900メガバイトにトリミングすることを提案しました。



-ああ、恐怖! -顧客に叫んだ。

-フィアスコ! -顧客に叫んだ。

-$#%\![_ ***#%\! -顧客に叫んだ。





aof-filesでは、誰も知らない場合、連続して実行されるredisコマンドがあります。



幸いなことに、このファイルは実行前にコピーされていました-「バトルで」修正。 並行して、ファイルを修正せずに放置しないという管理上の決定が下されました。



ファイルでデーモンをロードする最初の試みは、「HQETコマンドが見つかりません」を示しました。 その後、心のゲームが始まりました。 ヤスリは再び罪から埋葬された後、厳しい生体解剖を受けた。 まず、http://redis.io/commandsページが開かれました。ここでは、可能なすべてのredis制御コマンドが利用可能です。



画像



最初のレベル。 痛いです。




yum install -y hexedit <-put hexedit

hexedit <aofファイル> <-hexeditファイルを開きます

<-アスキーモードに移動

</> <-検索に移動

HQET-> <-目的のコマンドを探して編集

<ctrl-X> <-hexeditを終了



コマンドの最初の波(HQET、HSAT、ZASD)を修正した後、redis-check-aofがファイルで再設定されました。 実行結果は



画像



レベル2。 ウルトラバイオレンス。




ファイルは次の点に注意する必要がありました。



0x308a7042: Expected prefix '\r\n', got: '0f0a'
      
      







hexedit <aofファイル> <-hexeditファイルを開きます

<-住所に行く

<0f0aを0d0aに修正> <-思い出してください、0d0aはこれが16進数の\ r \ nです。



それはさらに簡単に思えたが、次のredis-check-aofの実行について話し始めた



画像



レベル3。 悪夢!




 0x       308a7046: Expected prefix '*', got: '$'
      
      







大根ソースがダウンロードされ、redis-check-aofが拡張ロギングで再構築されました。 私の場合、より正確な識別のために、問題の箇所に文字シーケンスを印刷した後、次のようなものを取得することを好みました。



 '34' 'D' 'A' '0'
      
      







これは、buf [0]だけでなく、その後の数文字、またはbufのみをログに記録することによって行われます。

さらに、hexeditでは、上記の例の行は「34 0D 0A 00」、つまり 2つの先行ゼロ文字。



さらに、問題のある場所の前にASCIIを注意深く読む必要があります。

上記の例を見ると、ASCIIでは次のように表示されます。



 HSET..$16..{u204237826932}g..$3..150..$1..1..*6..$4..HSET..$16..{u204237826932}g..$3 ..139..$1..1..*4..$4..
      
      







さらに、redisのソース、特に次の部分を慎重に調査しました。



     if (buf[0] != '*') goto fmterr;       argc = atoi(buf+1);       if (argc < 1) goto fmterr;       argv = zmalloc(sizeof(robj*)*argc);       for (j = 0; j < argc; j++) {           if (fgets(buf,sizeof(buf),fp) == NULL) goto readerr;           if (buf[0] != '$') goto fmterr;           len = strtol(buf+1,NULL,10);           argsds = sdsnewlen(NULL,len);           if (len && fread(argsds,len,1,fp) == 0) goto fmterr;           argv[j] = createObject(REDIS_STRING,argsds);           if (fread(buf,2,1,fp) == 0) goto fmterr; /* discard CRLF */    }
      
      







ある時点で、上記の行が理解できるようになりました。



 HSET..$16..{u204237826932}g..$3..150..$1..1..*6..$4..HSET..$16..{u204237826932}g..$3 ..139..$1..1..*4..$4..
      
      







次のように修正された場合、チェックによって通常通りに食べられます



 HSET..$16..{u204237826932}g..$3..150..$1..1..*4..$4..HSET..$16..{u204237826932}g..$3 ..139..$1..1..*4..$4..
      
      







怠zyな場合、違いは2番目のHSETの前に6を4に置き換えることです。これにより、上記のコードの引数の行の長さが変わり、goto fmterrセクションを通過して静かに進むことができます。



その結果、ファイルは手動でアップロードされ、redisが起動され、クライアントは安心し、プロジェクトは仕事に戻り、評判はわずかに枯渇し、ファイルのバックアップは再構成され、再確認されました。 念のため、2回。



All Articles