MySQLシングルテーブルリカバリ方法

10700 ワード

休憩中に電話一本で眠気を完全に吹き飛ばし、「子供靴を開発してupdate SQLを書くときにwhere条件をつけるのを忘れた」とDBAさん一人がこのニュースを聞いたとき、街を罵る衝動があったのではないでしょうか.幸いにも単表に花を書いただけで、どの大神がDBの中でdrop tableで遊んでいるのではありません.単表回復は久しぶりでしたが、手順が頭に残っていて、問題がなければ回復しました.
本題に戻り、単表回復の手順とポイントを記録し、自分にも注意するように注意します.
 
ステップ1:
リストア・マシンとしてパフォーマンスの高いサーバを探し、バックアップ・プールから最近のバックアップをこのリストア・マシンにリカバリします.もちろん、この前提はバックアップがあり、バックアップが利用可能であることです.(何?バックアップをしていないと教えてくれたら、同級生は洗濯して寝て、自由な空気を楽しむ準備をしてもいいでしょう.)
注意:このとき同期を開始しないで、必ず非同期状態を維持してください.
ps:余計なことを言うと、DBAにとって、バックアップは最も重要な一環であり、あるだけでなく、定期的にバックアップが利用可能かどうかをチェックしなければならない.これはDBAの必要素質の一つである.
 
ステップ2:
そのエラーの開発者にエラーのSQL文と時点を連絡し、メインライブラリのbinlogからこのSQLの実行点を見つけます.具体的な操作例は以下の通りです.
###   mysqlbinlog           SQL  

mysqlbinlog mysql-bin.000123 > /data1/000123.sql



###   linux grep    “key word”           SQL     

cat 000123.sql |grep -C 10 'key word' --color



###        SQL,   SQL      ,    SQL      , 2 pos      

# at 20393709

#131205 20:55:08 server id 18984603  end_log_pos 20393779     Query    thread_id=16296016    exec_time=0    error_code=0

SET TIMESTAMP=1386248108/*!*/;

BEGIN

/*!*/;

# at 20393779

#131205 20:55:08 server id 18984603  end_log_pos 20394211     Query    thread_id=16296016    exec_time=0    error_code=0

SET TIMESTAMP=1386248108/*!*/;

update table tablename set names='xxxx';

# at 20394211

#131205 20:55:08 server id 18984603  end_log_pos 20394238     Xid = 92465981

COMMIT/*!*/;

# at 20394238

#131205 20:55:10 server id 18984603  end_log_pos 20394308     Query    thread_id=16296017    exec_time=0    error_code=0

SET TIMESTAMP=1386248110/*!*/;

BEGIN 

 
ステップ3:
ステップ2で得られたpos位置に基づいて同期関係を開始するが、問題SQLより前のpos位置に停止する必要があり、具体的には以下のコマンドを使用する
### pos      SQL begin pos  
slave start until master_log_file='mysql-bin.000123',master_log_pos=20393709;

その後、この問題SQLをスキップして、次のコマンドを使用して次のpos位置に同期changeします.
### pos      SQL commit   pos  
change master to master_log_file='mysql-bin.000123',master_log_pos=20394238;

上の2つの命令から,2番目のステップで得られた2つのpos位置が重要であることが分かった.
 
ステップ4:
メインライブラリに花を書いた表を改名し、その目的は2つあり、その1つは、この表への書き込みを停止すること(もちろんこれは業務に一定の影響を及ぼし、一定期間の書き込み失敗警報が発生し、業務部門と事前に連絡する必要がある)、その2は、いったん失敗を回復すると、少なくとも1つの花を書いた表が存在する.操作を再開する前の状態にすぐに復元できます.
###       

rename table tablename to tablename_bak;

その後、リストアマシンでdump操作を実行します.この操作を実行するには、テーブルに中国語の文字がある場合は、--default-chararter-setパラメータを追加する必要があることに注意してください.
mysqldump -uusername -ppassword -S/tmp/mysql.sock dbname tablename --opt> tablename.sql

最後にこのファイルをプライマリ・ライブラリ・サーバに転送し、最後のリカバリ・オペレーションを完了します.
###       mysql  

source tablename.sql;



###     cmd  

mysql -uusername -ppassword -S/tmp/mysql.sock < tablename.sql

もちろんそんなに面倒ではなく、直接次のコマンドを実行することもできますが、個人的な習慣は歴史操作記録と中間結果を保存する必要があります.私は以上の手順で完成しました.そうすれば、いつでも回復できるテキストファイルを保存することができ、心理的にもっと落ち着いています.
###              ,        

mysql -uusername -ppassword -S /tmp/mysql.sock dbname tablename | mysql -uusername -ppassowrd -hhost -Pport

以上のコマンドでdumpを直接完了してインポートできるようになりましたが、バックアップファイルが生成されないという欠点があります.
 
ステップ5:
基本的なDBAのことはなくなり、開発者に回復したことを伝え、応用テストやデータの正確性の検証を行う必要があります.すべてに問題がなければ、さっきrenameのテーブルdropを削除する必要があります.リカバリ操作全体が成功しても.
drop table if exists tablename_bak;

 
データベース・リカバリはDBAごとに必要なスキルであり、熟練した習得が必要であり、この文章を過ごした学生たちが簡単にリカバリ操作を行うことができることを望んでいる.
ps:この操作は、一万年に一度も使わないほうがいいです.