成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

內部群炸鍋了,同事又刪庫了...

開發 開發工具 新聞
最近發生了一場生產事故,誤刪了金主爸爸 10 多萬條核心數據,直接導致服務崩潰....

[[412505]]

圖片來自 Pexels

01事件起因

我們的系統中有數據導入的功能,可以把特定的格式的 excel 數據導入到系統中來。

由于客戶電腦的文件比較多,很多文件的名字也比較相近,客戶在導入 excel 時選錯了文件。

這個錯誤的 excel 文件的格式恰好能被系統解析,客戶也沒及時發現導錯了文件,所以就將 6 萬多條沒用的數據導入到了系統中!

[[412506]]

這 6 萬多條數據對系統來說就是無用的數據,不會影響系統的運行,最多也就是占用一點數據庫空間而已。

客戶只需要把正確的 excel 重新導入,就可以繼續完成他的業務了。但是,客戶是一個重度強迫癥患者,他覺得在管理平臺看到這 6 萬多條沒用的數據令他抓狂。

客戶想要把這些數據刪除,我們系統又沒有提供批量刪除功能,只能單個刪除,這無疑是一個巨大的工作量。

客戶就通過客服部門找到了研發團隊,想讓我們研發人員從數據庫中直接刪除。

02刪庫經過

雖然在生產環境直接操作數據庫明顯是違規操作,但客戶的要求又不得不滿足,誰讓人家是爸爸呢。

[[412507]]

由于生產環境的數據和表結構屬于商業機密,我們討論的重點也不在于數據和表結構,而是數據恢復的思路。

所以我在測試環境新建了用戶表,導入了一些測試數據,當作是生產環境進行操作。

研發人員登錄生產數據庫,執行如下 sql,找到了這 6 萬多條錯誤數據:

  1. select * from t_user where age>18 and deptid=100; 

在確認這 6 萬多條數據確實是錯誤導入的數據后就準備開始刪除。由于表里面沒有邏輯刪除字段,所以只能進行物理刪除。

需要刪除的數據已經確定,通常情況下把 sql 中的 select * 替換為 delete 去執行,出錯的機率會小一點。

但是,研發人員并沒有去改原來的 sql,而是重新寫了一個刪除語句并且執行:

  1. delete from t_user where age>18; 

問題就這樣出現了,在新寫的刪除語句中缺少了 deptid=100 的條件。不要問我為什么刪除之前沒有備份,這都是血淚的教訓。

重新查表后發現誤刪了 10 多萬條數據,生產環境中,很多業務都依賴這個表,算是系統的核心表。

雖然是只刪除了 10 萬條數據,但系統的很多功能無法正常使用,其實和刪庫沒啥區別了!

[[412508]]

研發人員發現刪庫后,第一時間報告給了領導(居然沒有第一時間跑路)。

領導當機立斷,要求系統停止運行,給所有客戶發送停服通知,打開所有客服通道,處理客戶投訴和答疑,同時,也安排研發人員進行數據找回,要求盡快搞定。

03數據找回

我們找到刪庫的研發人員詢問他有沒有備份,他的回答是沒有。

我們又去咨詢運維的同事,看看生產環境有沒有開啟數據庫定期自動備份,運維的回答也是沒有。

事情比較難辦了,只能把希望寄托于 mysql 的 binlog 了。

binlog 二進制日志文件,數據庫的 insert、delete、update、create、alter、drop 等寫入操作都會被 binlog 記錄(下文對 binlog 有詳細介紹)。

binlog 記錄日志是需要開啟配置的,希望生產環境的 mysql 數據庫開啟了 binlog 日志,否則只能找專業的磁盤數據恢復的第三方公司了。

登錄生產環境數據庫,查看 binlog 是否開啟:

  1. SHOW VARIABLES LIKE 'LOG_BIN%'

從圖中可以看到 log_bin 是處于 ON 的狀態,說明 binlog 是開啟的。

懸著的心終于放下了一大半,接下來就是想辦法從 binlog 中把數據恢復就行了。

從上圖中也可以看到 log_bin_basename 是 /var/lib/mysql/bin-log,說明 binlog 是存放在 mysql 所在的服務器的 /var/lib/mysql 目錄下,文件是以 bin-log 開頭,比如:bin-log.000001。

登錄 mysql 所在的服務器,進入到 binlog 所在的目錄:

  1. cd /var/lib/mysql 

查看 binlog 日志文件:

binlog 日志文件是滾動生成的,從圖中看到現在已經有 4 個文件了。

通常情況下,生產環境的 binlog 會有成百上千個,這時候就需要確認我們需要的數據是在第幾個 binlog 中了,下文也會講怎么確定我們需要的是第幾個。

因為我們刪庫是剛剛發生的事情,所以我們需要的數據大概率是在第 4 個文件中。

直接去查看第 4 個 binlog 文件,看到的全都是亂碼,就像下面這樣,這是因為 binlog 文件是二進制的。

我們需要借助 mysql 官方提供的 mysqlbinlog 命令去才能正確解析 binlog 文件。

用 mysqlbinlog 命令可以打開 binlog 文件,但是一個 binlog 文件的大小可能有幾百兆,要從幾百兆日志中找到我們需要的日志,還是比較麻煩的。

還好 mysqlbinlog 命令提供一些參數選項可以讓我們對 binlog 文件進行篩選,最常用的參數就是時間參數。(下文也會對 mysqlbinlog 的詳細用法進行說明)

經過和刪庫的研發人員確定,刪庫的時間大概是 10:40,那我們就以這個時間點為參考,找前后 5 分鐘的日志:

  1. mysqlbinlog -v --start-datetime='2021-06-10 10:35:00' --stop-datetime='2021-06-10 10:45:00' bin-log.000004 | grep t_user 

從圖中可以看到,這個時間點的日志確實包含我們刪除數據的日志。

接下來我們就需要把這些日志整理一下,然后想辦法恢復到數據庫就可以了。

首先,把我們需要的日志單獨保存到 tmp.log 文件中,方便下載到本地:

  1. mysqlbinlog -v --start-datetime='2021-06-10 10:35:00' --stop-datetime='2021-06-10 10:45:00' bin-log.000004 > tmp.log 

把 tmp.log 下載到本地,用文本編輯工具打開看一下,可以看到一堆偽 sql:

在上圖的偽 sql 中:

  • @1 表示第一個字段
  • @2 表示第二個字段
  • 其他的以此類推

日志中包含的 sql 是一些偽 sql,并不能直接在數據庫執行,我們需要想辦法把這些偽 sql 處理成可在數據庫執行的真正的 sql。

我們使用的文本編輯工具的批量替換功能,就像下面這樣:

最終處理好的 sql 就像是這樣:

把處理好的 sql 在測試數據庫驗證一下沒問題后直接在生產庫執行。sql 執行完以后,被誤刪除的數據就恢復回來了。

我們和刪庫的研發一起,把客戶要求刪除的 6 萬多條數據重新給刪除,算是完成了客戶的要求。

至此,刪庫事件就暫時告一段落。不要問刪庫的研發受到了什么處分,問就是什么處分都沒有。

04幾點建議

刪庫跑路真的不只是一句玩笑話,如果真的不小心刪庫了而又無法找回數據的話,不僅僅是簡單的罰款、扣績效就完事了,甚至有可能會面臨牢獄之災。

對于公司來說,一個不小心的刪庫操作,就有可能把公司刪沒了。畢竟刪庫造成的數據損失、經濟損失不是所有公司都有能力承擔的。

所以,生產環境的數據安全一定是重中之重。根據我多年的刪庫經歷,也總結了一些經驗分享給你們,希望對你們有所幫助。

①研發人員不能直連生產庫

生產庫一般由 DBA 或者運維來維護,研發人員很少有需要登錄生產數據庫查看數據的需求,就算數據真的有問題,一般情況下 DBA 或運維人員也能解決。

如果一個系統需要研發人員頻繁的登錄數據庫去維護數據,這時就該考慮在系統中增加一個管理功能來使用,而不是頻繁登錄數據庫。

所以,研發就不應該具有生產庫的登錄權限。如果偶爾的需要登錄生產庫查看數據,可以找 DBA 開一個臨時賬號。

②登錄生產庫使用只讀賬號

大部分人使用數據庫都會使用連接工具,比如 Navicat、SQLyog 等。

每個人的電腦上,大概率也只有一個連接工具。開發庫、測試庫、生產庫都在同一個連接工具中打開,有時只是想在開發庫中修改一條數據,卻不小心修改了生產庫。

而 MySQL 的事務是自動提交的,在連接工具中,正在修改的當前行失去光標后就會自動提交事務,極其容易操作失誤。

所以,如果確實的需要登錄生產庫,盡量使用具有只讀權限的賬號登錄。

③關閉 autocomit、多人復核

如果確實需要在生產庫進行數據的增加、修改或刪除,在執行 sql 之前最好先關閉事務的自動提交。

在需要登錄生產庫修改數據的情況下,想必問題也比較復雜,一條 sql 語句應該是完成不了,可能需要寫 N 多個 sql 才能完成數據的修改。

這么多的 sql,很有可能在執行的時候會選錯。有時你只是想執行一個 select 語句,結果發現執行的是 delete。

更坑爹的是,大部分的數據庫連接工具有執行當前選中內容的功能。有時候你只想執行當前選中的內容,結果發現執行的是全部內容。

如果關閉了自動提交,就算出現上面的情況,也還有機會挽回。

比如下面這樣:

  1. -- 關閉事務自動提交 
  2. set @@autocommit=0; 
  3.  
  4.  
  5. -- 查看需要刪除的數據,共65600條 
  6. select * from t_user where age>18 and deptid=100; 
  7. -- 刪除 
  8. delete from t_user where age>18; 
  9.  
  10.  
  11. -- 發現有問題,回滾 
  12. select * from t_user where age>18 and deptid=100; 
  13. rollback ; 
  14.  
  15. -- 確認沒問題,提交 
  16. -- commit; 

另外,在 commit 之前需要至少再找一個同事進行確認。所謂當局者迷,自己有時可能處于一個錯誤的思路上,就想當然的認為結果沒問題,這時就需要一個旁觀者來指點迷津。

兩個人都確認沒問題之后再提交,出錯的機率也會小很多。

④修改數據之前先備份

備份、備份、備份,重要的事情說三遍!!!備份雖然會麻煩一點,但它是保證數據準確性最有效的手段,況且,掌握一些技巧后,備份也不是很麻煩的事情。

比如,我們刪除數據之前可以先這樣備份:

  1. -- 創建一個和原表一樣的備份表(包含索引) 
  2. create table t_user_bak like t_user; 
  3.  
  4. -- 拷貝數據到備份表 
  5. INSERT into t_user_bak select * from t_user; 
  6.  
  7. -- 確認數據拷貝完成 
  8. select * from t_user_bak; 

這樣備份的數據,就算原表數據誤刪了,甚至都不用恢復數據,只需要把備份表的名字改成原表的名字直接使用就可以了。

在生產庫修改數據之前,一定要記得備份,一旦數據修改出錯,這是成本最低并且最有效的恢復途徑。

⑤設置數據庫定期備份

生產環境,運維人員一定要設置數據庫定期備份。研發人員也有義務提醒運維同事編寫自動備份腳本,因為生產庫一旦出現問題需要恢復數據,沒有定期備份的話,麻煩的不只是運維人員,研發人員也要跟著麻煩。

備份周期可以根據業務需要來決定。如果業務對數據要求的實時性比較高,備份周期相對短一點,恢復數據時可以最大程度的避免數據丟失;反之,備份周期可以長一點,節省磁盤空間。

如果有必要,可以定期把備份文件拷貝到異地服務器,避免由于一些不可抗力因素導致的當前服務器磁盤損壞,如地震、臺風等。

五、binglog 日志

binlog 即 Binary Log,它是二進制文件,用來記錄數據庫寫操作的日志。

數據庫的 insert、delete、update、create、alter、drop 等寫入操作都會被 binlog 記錄。

因此,數據庫的主從數據同步通常也是基于 binlog 完成的,本文只對 binlog 做一些簡單介紹,后期會單獨寫一篇文章講基于 binlog 的主從數據同步。

binlog 日志需要配置開啟,可以通過腳本查看 binlog 是否開啟:

  1. SHOW VARIABLES LIKE 'LOG_BIN%'

如果 log_bin 參數顯示的是 OFF 說明 binlog 是關閉狀態,需要手動開啟。

開啟 binlog 需要修改數據庫的 my.cnf 配置文件,my.cnf 文件通常在服務器的 /etc 目錄下。

  1. # 啟用binlog并設置binlog日志的存儲目錄 
  2. log_bin = /var/lib/mysql/bin-log 
  3. # 設置binlog索引存儲目錄 
  4. log_bin_index = /var/lib/mysql/mysql-bin.index 
  5. # 30天之前的日志自動刪除 
  6. expire_logs_days = 30 
  7. # 設置binlog日志模式,共有3種模式:STATMENT、ROW、MIXED 
  8.  binlog_format = row 

binlog 的日志有三種格式,分別是 STATEMENT、ROW、MIXED。

在 mysql 5.7.7 版本之前默認使用的是 STATEMENT,之后的版本默認使用的是 ROW。

①ROW 格式

ROW 格式下,binlog 記錄的是每一條數據被修改的詳細細節。

比如,執行 delete 語句,刪除的數據有多少條,binlog 中就記錄有多少條偽 sql:

  1. delete from t_user where age>18; 

那么 row 格式的日志的缺點就很明顯,在發生批量操作時,日志文件中會記錄大量的偽 sql,占用較多的磁盤空間。

尤其是當進行 alter 操作時,每條數據都發生變化,日志文件中就會有每一條的數據的日志。此時,如果表中的數據量很大的話,日志文件也會非常大。

在 mysql 5.6 版本之后,針對 ROW 格式的日志,新增了 binlog_row_image 參數。

當 binlog_row_image 設置為 minimal 時,日志中只會記錄發生改變的列,而不是全部的列,這在一定程度上能減少 binlog 日志的大小。

雖然記錄每行數據的變化會造成日志文件過大,但這也是它的優點所在。

因為它記錄了每條數據修改細節,所以在一些極端情況下也不會出現數據錯亂的問題。在做數據恢復或主從同步時能很好的保證數據的真實性和一致性。

②STATEMENT 格式

STATEMENT 格式下,日志中記錄的是真正的 sql 語句,就像是這樣:

日志中的 sql 是直接可以拿到數據庫運行的,STATEMENT 格式的日志的優缺點和 ROW 格式的正好相反,它記錄的是 sql 語句和執行語句時的上下文環境,而不是每一條數據。

所以它的日志文件會比 ROW 格式的日志文件小一些,由于記錄的只是 sql 語句和上下文的環境,STATEMENT 格式的日志在進行主從數據同步時會有一些不可預估的情況出現,導致數據錯亂。

比如 sleep()、last_insert_id() 等函數會出現問題。

③MIXED 格式

MIXED 格式是 STATEMENT 和 ROW 的結合,mysql 會根據具體執行的 sql 語句,來選擇合適的日志格式進行記錄。

MIXED 格式下,在執行普通的 sql 語句時會選 STATEMENT 來記錄日志,在遇到復雜的語句或函數操作時會選擇 ROW 來記錄日志。

06mysqlbinlog 命令

mysql 數據庫的 binlog 文件是二進制的,基本看不懂,使用數據庫自帶的 mysqlbinlog 命令可以把二進制文件轉換成能看懂的十進制文件。

由于數據庫的 binlog 文件可能會很大,查看起來會很麻煩,所以 mysqlbinlog 命令也提供了一些參數可以用來篩選日志。

mysqlbinlog 語法:

  • options:可選參數
  • log-files:文件名稱
  1. mysqlbinlog [options] log-files 

options 的常用值:

  • -d:根據數據庫的名稱篩選日志
  • -o:跳過前 N 行日志
  • -r,--result-fil:把日志輸出到指定文件
  • --start-datetime:讀取指定時間之后的日志,時間格式:yyyy-MM-dd HH:mm:ss
  • --stop-datetime:讀取指定時間之前的日志,時間格式:yyyy-MM-dd HH:mm:ss
  • --start-position:從指定位置開始讀取日志
  • --stop-position:讀取到指定位置停止
  • --base64-output:在 row 格式下,顯示偽 sql 語句
  • -v,--verbose:顯示偽 sql 語句,-vv 可以為 sql 語句添加備注

常用寫法如下:

查看 fusion 數據庫的日志:

  1. mysqlbinlog -d=fusion bin-log.000001 

查看某個時間段內的日志:

  1. mysqlbinlog  --start-datetime='2021-06-09 19:30:00' --stop-datetime='2021-06-09 19:50:00' bin-log.000001 

恢復數據,事件的開始位置是 4300,結束位置是 10345:

  1. mysqlbinlog --start-position 4300 --stop-position 10345 bin-log.000001 | mysql -uroot -p123456 fusion 

作者:王小伍

編輯:陶家龍

出處:轉載自公眾號赫連小伍

 

責任編輯:武曉燕 來源: 赫連小伍
相關推薦

2019-01-17 09:14:34

2022-04-29 10:27:58

數據庫刪庫MySQL

2014-07-23 10:19:02

小米4

2021-11-05 11:10:13

MyBatisSQL查詢

2021-09-09 18:12:22

內存分段式網絡

2023-07-18 19:11:21

配置信令系統

2021-09-22 10:15:52

裁員選擇公司個人發展

2024-07-30 08:46:56

2023-10-30 22:23:12

Cacherkube版本

2022-12-07 07:35:20

B站裁員隱情

2023-03-10 08:24:27

OOMdump線程

2022-10-17 10:13:58

谷歌云游戲

2020-03-31 16:02:23

戴爾

2020-10-16 09:09:56

代碼業務模型

2023-11-08 17:15:57

2017-12-28 10:44:08

JavaScript瀏覽器網頁

2021-12-13 01:49:34

漏洞Log4j代碼

2022-11-18 07:34:12

Docker項目目錄

2020-07-30 07:47:32

互聯網

2020-10-27 10:50:04

軟件教父網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成av在线| 午夜影院在线观看 | 国产91色在线 | 亚洲 | 91人人看| 四虎影院一区二区 | 亚洲精品专区 | 一级毛片在线视频 | 天天摸天天干 | 久久久久亚洲 | 中文字幕精品视频 | 91精品国产91久久久久久最新 | 91久久精品日日躁夜夜躁国产 | 日韩精品在线播放 | 国产精品呻吟久久av凹凸 | 中文字幕一区二区三区在线观看 | 欧美精品一区二区三区在线 | 九九久久精品 | www国产成人免费观看视频,深夜成人网 | 日韩理论电影在线观看 | 免费黄色日本 | 美日韩免费视频 | 91在线观看视频 | 韩日一区二区 | 国产精品成人国产乱一区 | 亚洲永久免费 | 日韩国产黄色片 | 午夜成人免费视频 | 韩日精品视频 | 综合色影院 | 羞羞的视频网站 | 成人在线国产 | 国产美女一区 | 欧美美女被c | a级在线免费观看 | 看av网| 在线婷婷| 成人一区二区三区 | 亚洲视频在线一区 | 天天操网 | 精品国产一区二区三区性色 | 中文字幕亚洲一区二区va在线 |