Mysql誤刪資料解決方案及kill語句原理

2022-09-24 20:42:09 字數 2793 閱讀 9877

mysql誤刪資料

對於誤刪行

對於誤刪庫/表

需要使用全量備份,加增量日誌程式設計客棧的方式。要求線上有定期的全量備份嗎,並且實時備份binlog。

假如有人中午12點誤刪了乙個庫,恢復資料的流程如下:

取最近一次全量備份,假設這個庫是一天一備,上次備份是當天0點;

用備份恢復出乙個臨時庫;

從日誌備份里面,取出凌晨0點之後的日誌

把這些日誌,除了誤刪除資料程式設計客棧的語句外,全部應用到臨時庫。

注意:為了加速資料恢復,如果這個臨時庫上有多個資料庫,你可以在使用mysqlbinlog命令時,加上乙個–database引數,用來指定誤刪表所在的庫。這樣,就避免了在恢復資料時還要應用其他庫日誌的情況。

在應用日誌的時候,需要跳過12點誤操作的那個語句的binlog:

加速恢復的方法:備份恢復出臨時例項之後,將這個臨時例項設定成線上備庫的從庫,

乙個系統不可能備份無限的日誌,你還需要根據成本和磁碟空間資源,設定乙個日誌保留

的天數。如果你的dba團隊告訴你,可以保證把某個實例恢復到半個月內的任意時間點,這就表示備份系統保留的日誌時間就至少是半個月。

雖然「發生這種事,大家都不想的」,但是萬一出現了誤刪事件,能夠快速恢復資料,將損失

降到最小,也應該不用跑路了。而如果臨時再手忙腳亂地手動操作,最後又誤操作了,對業務造成了二次傷害,那就說不過去了。

延遲復製備庫

對於rm刪除資料

只要不是惡意地把整個集群刪除,而只是刪掉了其中某乙個節點的資料的話,ha系統就會開始工作,選出乙個新的主庫,從而保證整個集群的正常工作。這時anzmp,你要做的就是在這個節點上把資料恢復回來,再接入整個集群。

當然了,現在不止是dba有自動化系統,sa(系統管理員)也有自動化系統,所以也許乙個批量下線機器的操作,會讓你整個mysql集群的所有節點都全軍覆沒。應對這種情況,我的建議只能是說盡量把你的備份跨機房,或者最好是跨城市儲存。kill sql語句

session b是直接終止掉執行緒,什麼都不管就直接退出嗎?顯然,這是不行的。

當對乙個表做增刪改查操作時,會在表上加mdl讀鎖。所以,session b雖然處於blocked狀態,但還是拿著乙個mdl讀鎖的。如果執行緒被kill的時候,就直接終止,那之後這個mdl讀鎖就沒機會被釋放了。

kill並不是馬上停止的意思,而是告訴執行執行緒說,這條語句已經不需要繼續執行了,可以開始「執行停止的邏輯了」。

實際上,當執行kill query thread_id_b,mysql裡處理kill命令的執行緒做了以下事情:

因為像圖1的我們例子里面,session b處於鎖等待狀態,如果只是把session b的執行緒狀態設定

thd::kill_query,執行緒b並不知道這個狀態變化,還是會繼續等待。發乙個訊號的目的,就

是讓session b退出等待,來處理這個thd::kill_query狀態。

以上包含了三層意思:

乙個kill不掉的例子

執行set global innodb_thread_concurrency=2,將innodb的併發執行緒上限數設定為2;然後,執行下面的序列:

可以看到:

sesssion c執行的時候被堵住了;

但是session d執行的kill query c命令卻沒什麼效果,

直到session e執行了kill connection命令,才斷開了session c的連線,提示「lost connection to mysql server during query」,

但是這時候,如果在session e中執行show processlist,你就能看到下面這個圖:

id=12這個執行緒的commnad列顯示的是killed。也就是說,客戶端雖然斷開了連線,但實際上服務端上這條語句還在執行過程中。

在這個例子里,12號執行緒的等待邏輯是這樣的:每10毫秒判斷一下是否可以進入innodb執

行,如果不行,就呼叫nanosleep函式進入sleep狀態。

也就是說,雖然12號執行緒的狀態已經被設定成了kill_query,但是在這個等待進入innodb的迴圈過程中,並沒有去判斷執行緒的狀態,因此根本不會進入終止邏輯階段。

而當session e執行kill connection 命令時,是這麼做的,

那為什麼執行show processlist的時候,會看到command列顯示為kil程式設計客棧led呢?其實,這就是因為在執行show processlist的時候,有乙個特別的邏輯:

如果乙個執行緒的狀態是kill_connection,就把command列顯示成killed。

所以其實,即使是客戶端退出了,這個執行緒的狀態仍然是在等待中。只有等到滿足進入innodb的條件後,session c的查詢語句繼續執行,然後才有可能判斷到執行緒狀態已經變成了kill_query或者kill_connection,再進入終止邏輯階段。

kill無效的第一類情況,即:執行緒沒有執行到判斷執行緒狀態的邏輯。可能也會由於io壓力過大程式設計客棧,讀寫io的函式一直無法返回,導致不能及時判斷執行緒的狀態。

ctrl+c,mysql實際上也是啟動了乙個連線程序傳送了kill query命令。

關於客戶端連線慢的誤解

如果庫裡面的表很多,連線就會很慢。比如有乙個庫有上萬個表,使用預設引數連線的時候,mysql會提供乙個本地庫名和表名補全的功能:

第三步是耗時比較長的操作,也就是我們感知到慢不是連線滿,也不是服務端慢,而是客戶端慢。如果在這個連線中加上 -a,就可以取消自動補全功能,很快返回。

自動補全的效果就是,在輸入庫名或者表名的時候,將輸入字首,可以使用tab自動補全或者顯示提示。實際如果自動補全用的不多,可以每次使用都加-a。

本文標題: mysql誤刪資料解決方案及kill語句原理

本文位址:

Mysql誤刪資料解決方案及kill語句原理

mysql誤刪資料 使用delete語句誤刪資料行 使用drop table或者truncate table誤刪資料表 使用drop database語句誤刪資料庫 使用rm誤刪mysql整個例項 對於誤刪行 使用flashback工具閃回,把資料恢復回來。原理是修改binlog的內容,拿回原庫重放...

mysql 解決方案 Mysql解決方案

mysql解決方案 一 centos7安裝mysql5.7 wget rpm uvh mysql80 community release el7 3.noarch.rpm yum repolist all grep mysql 發現預設mysql8.0是預設安裝的,然而我們要安裝的是mysql5.7...

誤刪Path後完美解決方案

每台計算機安裝程式不同,環境變數path會有不同,若誤刪了環境變數path,可以如下完美解決.win r 輸入regedit開啟登錄檔 開始 執行裡輸入regedit 找到 hkey local machine system controlset002 control session manager...