日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员自救指南:一不小心删库删表怎么办?

發布時間:2025/3/16 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员自救指南:一不小心删库删表怎么办? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 作者丨林曉斌

策劃丨小智

寫在前面

雖然我們之前遇到的大多數的數據被刪,都是運維同學或者 DBA 背鍋的。但實際上,只要有數據操作權限的同學,都有可能踩到誤刪數據這條線。

今天我們就來聊聊誤刪數據前后,我們可以做些什么,減少誤刪數據的風險,和由誤刪數據帶來的損失。

以 MySQL 為例,為了找到解決誤刪數據的更高效的方法,我們需要先對和 MySQL 相關的誤刪數據,做下分類:

  • 使用 delete 語句誤刪數據行;

  • 使用 drop table 或者 truncate table 語句誤刪數據表;

  • 使用 drop database 語句誤刪數據庫;

  • 使用 rm 命令誤刪整個 MySQL 實例。

  • 誤刪行如果是使用 delete 語句誤刪了數據行,可以用 Flashback 工具通過閃回把數據恢復回來。

    Flashback 恢復數據的原理,是修改 binlog 的內容,拿回原庫重放。而能夠使用這個方案的前提是,需要確保 binlog_format=row 和 binlog_row_image=FULL。

    具體恢復數據時,對單個事務做如下處理:

  • 對于 insert 語句,對應的 binlog event 類型是 Write_rows event,把它改成 Delete_rows event 即可;

  • 同理,對于 delete 語句,也是將 Delete_rows event 改為 Write_rows event;

  • 而如果是 Update_rows 的話,binlog 里面記錄了數據行修改前和修改后的值,對調這兩行的位置即可。

  • 如果誤操作不是一個,而是多個,會怎么樣呢?比如下面三個事務:

    (A)delete ...(B)insert ...(C)update?...

    現在要把數據庫恢復回這三個事務操作之前的狀態,用 Flashback 工具解析 binlog 后,寫回主庫的命令是:

    (reverse C)update ...(reverse B)delete ...(reverse?A)insert?...

    也就是說,如果誤刪數據涉及到了多個事務的話,需要將事務的順序調過來再執行。

    需要說明的是,我不建議你直接在主庫上執行這些操作。

    恢復數據比較安全的做法,是恢復出一個備份,或者找一個從庫作為臨時庫,在這個臨時庫上執行這些操作,然后再將確認過的臨時庫的數據,恢復回主庫。

    為什么要這么做呢?

    這是因為,一個在執行線上邏輯的主庫,數據狀態的變更往往是有關聯的。可能由于發現數據問題的時間晚了一點兒,就導致已經在之前誤操作的基礎上,業務代碼邏輯又繼續修改了其他數據。所以,如果這時候單獨恢復這幾行數據,而又未經確認的話,就可能會出現對數據的二次破壞。

    當然,我們不止要說誤刪數據的事后處理辦法,更重要是要做到事前預防。我有以下兩個建議:

  • 把 sql_safe_updates 參數設置為 on。這樣一來,如果我們忘記在 delete 或者 update 語句中寫 where 條件,或者 where 條件里面沒有包含索引字段的話,這條語句的執行就會報錯。

  • 代碼上線前,必須經過 SQL 審計。

  • 你可能會說,設置了 sql_safe_updates=on,如果我真的要把一個小表的數據全部刪掉,應該怎么辦呢?

    如果你確定這個刪除操作沒問題的話,可以在 delete 語句中加上 where 條件,比如 where id>=0。

    但是,delete 全表是很慢的,需要生成回滾日志、寫 redo、寫 binlog。所以,從性能角度考慮,你應該優先考慮使用 truncate table 或者 drop table 命令。

    使用 delete 命令刪除的數據,你還可以用 Flashback 來恢復。而使用 truncate /drop table 和 drop database 命令刪除的數據,就沒辦法通過 Flashback 來恢復了。為什么呢?

    這是因為,即使我們配置了 binlog_format=row,執行這三個命令時,記錄的 binlog 還是 statement 格式。binlog 里面就只有一個 truncate/drop 語句,這些信息是恢復不出數據的。

    那么,如果我們真的是使用這幾條命令誤刪數據了,又該怎么辦呢?

    ??

    誤刪庫 / 表

    這種情況下,要想恢復數據,就需要使用全量備份,加增量日志的方式了。這個方案要求線上有定期的全量備份,并且實時備份 binlog。

    在這兩個條件都具備的情況下,假如有人中午 12 點誤刪了一個庫,恢復數據的流程如下:

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

  • 用備份恢復出一個臨時庫;

  • 從日志備份里面,取出凌晨 0 點之后的日志;

  • 把這些日志,除了誤刪除數據的語句外,全部應用到臨時庫。

  • 這個流程的示意圖如下所示:

    圖 1 數據恢復流程 -mysqlbinlog 方法

    關于這個過程,我需要和你說明如下幾點:

  • 為了加速數據恢復,如果這個臨時庫上有多個數據庫,你可以在使用 mysqlbinlog 命令時,加上一個 --database 參數,用來指定誤刪表所在的庫。這樣,就避免了在恢復數據時還要應用其他庫日志的情況。

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

    如果原實例沒有使用 GTID 模式,只能在應用到包含 12 點的 binlog 文件的時候,先用 --stop-position 參數執行到誤操作之前的日志,然后再用 --start-position 從誤操作之后的日志繼續執行;

    如果實例使用了 GTID 模式,就方便多了。假設誤操作命令的 GTID 是 gtid1,那么只需要執行 set gtid_next=gtid1;begin;commit; 先把這個 GTID 加到臨時實例的 GTID 集合,之后按順序執行 binlog 的時候,就會自動跳過誤操作的語句。

  • 不過,即使這樣,使用 mysqlbinlog 方法恢復數據還是不夠快,主要原因有兩個:

  • 如果是誤刪表,最好就是只恢復出這張表,也就是只重放這張表的操作,但是 mysqlbinlog 工具并不能指定只解析一個表的日志;

  • 用 mysqlbinlog 解析出日志應用,應用日志的過程就只能是單線程。我們在第 26 篇文章中介紹的那些并行復制的方法,在這里都用不上。

  • 一種加速的方法是,在用備份恢復出臨時實例之后,將這個臨時實例設置成線上備庫的從庫,這樣:

  • 在 start slave 之前,先通過執行 change replication filter replicate_do_table = (tbl_name) 命令,就可以讓臨時庫只同步誤操作的表;

  • 這樣做也可以用上并行復制技術,來加速整個數據恢復過程。

  • 這個過程的示意圖如下所示:

    圖 2 數據恢復流程 -master-slave 方法

    可以看到,圖中 binlog 備份系統到線上備庫有一條虛線,是指如果由于時間太久,備庫上已經刪除了臨時實例需要的 binlog 的話,我們可以從 binlog 備份系統中找到需要的 binlog,再放回備庫中。

    假設,我們發現當前臨時實例需要的 binlog 是從 master.000005 開始的,但是在備庫上執行 show binlogs 顯示的最小的 binlog 文件是 master.000007,意味著少了兩個 binlog 文件。這時,我們就需要去 binlog 備份系統中找到這兩個文件。

    把之前刪掉的 binlog 放回備庫的操作步驟,是這樣的:

  • 從備份系統下載 master.000005 和 master.000006 這兩個文件,放到備庫的日志目錄下;

  • 打開日志目錄下的 master.index 文件,在文件開頭加入兩行,內容分別是 “./master.000005”和“./master.000006”;

  • 重啟備庫,目的是要讓備庫重新識別這兩個日志文件;

  • 現在這個備庫上就有了臨時庫需要的所有 binlog 了,建立主備關系,就可以正常同步了。

  • 不論是把 mysqlbinlog 工具解析出的 binlog 文件應用到臨時庫,還是把臨時庫接到備庫上,這兩個方案的共同點是:誤刪庫或者表后,恢復數據的思路主要就是通過備份,再加上應用 binlog 的方式。

    也就是說,這兩個方案都要求備份系統定期備份全量日志,而且需要確保 binlog 在被從本地刪除之前已經做了備份。

    但是,一個系統不可能備份無限的日志,你還需要根據成本和磁盤空間資源,設定一個日志保留的天數。如果你的 DBA 團隊告訴你,可以保證把某個實例恢復到半個月內的任意時間點,這就表示備份系統保留的日志時間就至少是半個月。

    另外,我建議你不論使用上述哪種方式,都要把這個數據恢復功能做成自動化工具,并且經常拿出來演練。為什么這么說呢?

    這里的原因,主要包括兩個方面:

  • 雖然“發生這種事,大家都不想的”,但是萬一出現了誤刪事件,能夠快速恢復數據,將損失降到最小,也應該不用跑路了。

  • 而如果臨時再手忙腳亂地手動操作,最后又誤操作了,對業務造成了二次傷害,那就說不過去了。

  • 延遲復制備庫

    雖然我們可以通過利用并行復制來加速恢復數據的過程,但是這個方案仍然存在“恢復時間不可控”的問題。

    如果一個庫的備份特別大,或者誤操作的時間距離上一個全量備份的時間較長,比如一周一備的實例,在備份之后的第 6 天發生誤操作,那就需要恢復 6 天的日志,這個恢復時間可能是要按天來計算的。

    那么,我們有什么方法可以縮短恢復數據需要的時間呢?

    如果有非常核心的業務,不允許太長的恢復時間,我們可以考慮搭建延遲復制的備庫。這個功能是 MySQL 5.6 版本引入的。

    一般的主備復制結構存在的問題是,如果主庫上有個表被誤刪了,這個命令很快也會被發給所有從庫,進而導致所有從庫的數據表也都一起被誤刪了。

    延遲復制的備庫是一種特殊的備庫,通過 CHANGE MASTER TO MASTER_DELAY = N 命令,可以指定這個備庫持續保持跟主庫有 N 秒的延遲。

    比如你把 N 設置為 3600,這就代表了如果主庫上有數據被誤刪了,并且在 1 小時內發現了這個誤操作命令,這個命令就還沒有在這個延遲復制的備庫執行。這時候到這個備庫上執行 stop slave,再通過之前介紹的方法,跳過誤操作命令,就可以恢復出需要的數據。

    這樣的話,你就隨時可以得到一個,只需要最多再追 1 小時,就可以恢復出數據的臨時實例,也就縮短了整個數據恢復需要的時間。

    預防誤刪庫 / 表的方法

    雖然常在河邊走,很難不濕鞋,但終究還是可以找到一些方法來避免的。所以這里,我也會給你一些減少誤刪操作風險的建議。

    第一條建議是,賬號分離。這樣做的目的是,避免寫錯命令。比如:

    • 我們只給業務開發同學 DML 權限,而不給 truncate/drop 權限。而如果業務開發人員有 DDL 需求的話,也可以通過開發管理系統得到支持。

    • 即使是 DBA 團隊成員,日常也都規定只使用只讀賬號,必要的時候才使用有更新權限的賬號。

    第二條建議是,制定操作規范。這樣做的目的,是避免寫錯要刪除的表名。比如:

    • 在刪除數據表之前,必須先對表做改名操作。然后,觀察一段時間,確保對業務無影響以后再刪除這張表。

    • 改表名的時候,要求給表名加固定的后綴(比如加 _to_be_deleted),然后刪除表的動作必須通過管理系統執行。并且,管理系刪除表的時候,只能刪除固定后綴的表。

    rm 刪除數據

    其實,對于一個有高可用機制的 MySQL 集群來說,最不怕的就是 rm 刪除數據了。只要不是惡意地把整個集群刪除,而只是刪掉了其中某一個節點的數據的話,HA 系統就會開始工作,選出一個新的主庫,從而保證整個集群的正常工作。

    這時,你要做的就是在這個節點上把數據恢復回來,再接入整個集群。

    當然了,現在不止是 DBA 有自動化系統,SA(系統管理員)也有自動化系統,所以也許一個批量下線機器的操作,會讓你整個 MySQL 集群的所有節點都全軍覆沒。

    應對這種情況,我的建議只能是說盡量把你的備份跨機房,或者最好是跨城市保存。

    作者介紹:

    林曉彬,網名丁奇,前阿里資深技術專家,極客時間 MySQL 實戰 45 講專欄作者。

    有道無術,術可成;有術無道,止于術

    歡迎大家關注Java之道公眾號

    好文章,我在看??

    總結

    以上是生活随笔為你收集整理的程序员自救指南:一不小心删库删表怎么办?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久久久久久久久网 | 亚洲欧美日韩在线一区 | www.狠狠| 国产成人精品影视 | 扶她futa粗大做到怀孕 | 国产夫妇交换聚会群4p | 性欧美熟妇videofreesex | 亚洲精品88 | 亚洲欧洲成人 | 午夜免费片 | 一级特黄录像免费看 | 蜜桃一区二区 | 奇米888一区二区三区 | 中文字幕一区2区3区 | 国产又粗又猛又爽 | 国产女同视频 | 另类天堂av| 一二三不卡 | 精品国产中文字幕 | 日韩欧美在线视频观看 | 欧美不卡三区 | 久久久精品一区二区涩爱 | 中文字幕亚洲一区二区三区五十路 | 亚洲破处视频 | 天堂中文在线最新 | 一级做a爱视频 | 中文字幕丰满人伦在线 | 97国产精品视频人人做人人爱 | 亚洲一卡二卡在线 | 亚洲麻豆一区二区三区 | 手机免费av| av激情在线 | 免费观看一级黄色片 | 久草视频在线资源 | 熟女肥臀白浆大屁股一区二区 | 亚洲天堂中文字幕在线观看 | 久久精品久久久久 | 超碰caopor| 国产伦精品一区二区三区免费 | 全黄一级裸片视频 | 色呦呦中文字幕 | 伊人久久爱 | jizzjizz视频 | 亚洲精品午夜 | 青青青手机在线视频 | 国产农村妇女精品一区二区 | 超碰97国产精品人人cao | 欧美精品一区二区性色a+v | 亚洲永久免费 | 亚洲精品福利网站 | 99夜色 | 免费观看一区二区三区毛片 | 91快色 | 日韩一区二区a片免费观看 伊人网综合在线 | 超碰在线网址 | av网站免费大全 | 韩国裸体网站 | 极品美女被c | 肥老熟妇伦子伦456视频 | 奇米四色在线视频 | 五月天婷婷视频 | 成人午夜精品无码区 | zzjj国产精品一区二区 | 91大神精品在线 | 综合av一区| 男人日女人免费视频 | 欧美中文字幕在线 | 7m精品福利视频导航 | 秋霞网一区二区 | 国产成人在线播放视频 | 巨骚综合 | 日日夜夜噜 | 日韩第六页 | 亚洲图片综合区 | 欧美黑人一区二区三区 | 韩国三级hd两男一女 | 色天天色综合 | 青青超碰 | 无码精品在线观看 | 无码人妻精品一区二区三区不卡 | 国产精品电影一区二区 | 二三区视频 | www日本黄色| 在办公室被c到呻吟的动态图 | 精品区一区二区 | 国产日韩在线免费观看 | 在线不卡二区 | 亚洲天堂福利视频 | 草碰在线 | 夜间福利在线观看 | 国产999精品 | 美国黄色av | 国产精品国产精品国产专区蜜臀ah | 国产探花视频在线观看 | 一级肉体全黄裸片 | 99午夜视频 | 午夜亚洲aⅴ无码高潮片苍井空 | 国产网红女主播精品视频 | 一区二区三区黄色 |