1. 程式人生 > >從刪表到跑路

從刪表到跑路

shel query type 後來 allow 既然 重建 serve 繼續

之前有人一直說從刪庫到跑路,一直覺得是個笑話,今天真是的體驗了一把,果然一點都不好笑 總結: 對數據表在執行不明白原理的命令之前一定要備份好數據表,不要隨意終止你不清楚底層原理的命令,因為很可能就會造成表的損壞,比如optimize命令 事情是這樣的,最近在整理一個幾億的數據表,因為數據表太大,在執行插入等操作的時候變得非常慢,而我自告奮勇的主要要優化這個表,結果差點把數據全部清了。 之前自己建了一個新表,沒有多大的數據量,因為在刪除表之後,需要把磁盤空間釋放一下, 比如在自己建的表操作 技術分享圖片

技術分享圖片 知識點之一:執行delete刪除的時候,mysql並沒有把數據文件刪除,而是將數據文件的標識位刪除,沒有整理文件,因此不會徹底釋放空間,被刪除的數據將會保存在一個連接清單中,當有數據寫入mysqsl利用這些已刪除的空間再寫入,刪除操作會帶來一些數據碎片,正是這些碎片在占用硬盤空間,官方文檔上寫的是innodb引擎的可以利用操作系統來幫忙回收這些碎片,myisam的標沒有辦法自己回首。 官方推薦使用命令是optimize table 表名 . 之後再看數據 技術分享圖片

技術分享圖片 因為這個是新表,空間也沒有很大,沒有人用,所以在執行optimize命令的時候很快 但是!執行線上的表就有問題 後來了解到這個表有人在實時的往裏寫數據,而且存儲引擎還是myisam,而且這個表存放的數據上億 表數據: 技術分享圖片

技術分享圖片 然後我執行了刪除其中的一個月份數據,看到的空閑空間是 技術分享圖片

技術分享圖片 最後刪除其中一部分備份過的數據後,空閑的空間是: 技術分享圖片 技術分享圖片

執行了 optimize命令的過程,看進程 技術分享圖片 技術分享圖片

如果在這個過程中不小心終止了進程,就會出現 Table ‘./庫名/表名‘ is marked as crashed and last (automatic?) repair failed提示!!! 執行了check table 表名後: 技術分享圖片

技術分享圖片 是這個提示!!大概意思就是表壞了 一谷歌全是讓你修復表的 哎 然後我就著急 執行了repair table 表名,然後就等了十幾分鐘就開始報超時,對 就是Lost connection to MySQL server during query 因為我這個上億的表數據實在太大了,空間根本就不夠, 然後開始查原因 一個是mysql允許的最大數據包設置,就是sql操作的時間過長,或者傳送的數據太大,這樣可以修改max_allowed_packet配置參數 另一個執行show global variables like ‘%timeout‘; 看一下wait_timeout、interactive_timeout參數把它改大我設置的都是28800也就是八小時,後來執行修復的命令在八小時內弄完了謝天謝地 後來兩次執行的repair命令都自動超時斷開,但是show processlist後看到這個進程還在,因為無知,kill掉這個進程之後再看數據表,幾億的數據只剩一條。。。一條數據。。。後來我們就琢磨是不是kill的原因,最後用最後一條數據做了實驗,果然。。。。 具體引用大神的解釋: 技術分享圖片

技術分享圖片 後來考慮到我有17G的數據,然後就把參數myisam_max_sort_file_size設置了18G,這個參數的意思是mysql重建索引時所允許的最大臨時文件的大小還有參數myisam_sort_buffer_size表示myisam表發生變化時重新排序所需的索引緩沖 設置完以上參數後 執行mysqlcheck -hdatabasehost -uuser -ppassword database table -c //檢查這個損壞的表 返回 技術分享圖片

技術分享圖片 非常清楚的顯示了表現在的問題 執行 mysqlcheck -hhost -uuser -ppassword database table -r 之後 經歷了漫長的等待之後返回的結果就是: 技術分享圖片

技術分享圖片 哎 總算數據都回來了 我們其實還做了plan B 就是從從庫中把表導出,也確實導出來了,35個G。。。正準備怎麽替換的時候執行完成了, 最後鄭重的感謝大熱天幫忙的兄弟,總之 感謝身邊的人 讓我還能安穩的活著 本來 以為 這是我在公司的最後一天的。。。。 總結:備份 備份!還有不清楚的命令千萬不要去設置 既然修復表好了之後,工作還得繼續,後續做的方案就是不能直接執行優化表,因為一不知道具體時間多長時候會影響別的端使用 第一次使用的方案是,新建一張一摸一樣的表,但是不加索引,然後把這種表導入到新表,用insert。。 select 很快因為沒有索引,導入完之後再加索引,第一個索引很快,第二個就超時了。。。fail 第二次使用的方案就是直接建一張帶索引的新表,然後使用shell腳本把數據導入,花費六個多小時吧,最後檢查兩張表數據是否一致並且使用left join 或者抽查數據是否一致,這些工作都做完之後就準備修改表名 因為使用alter table 表名 rename to 新表名,這樣執行其實是很快的 ,但是也得確保這個時候用的人很少,而且還要看進程有沒有鎖表的查詢之類的,如果沒有,就可以執行了 非常快 不用一秒,完成。 這樣整體任務完成 現在可以用老表做實驗,看看優化表操作可以用多久,最後發現優化10G的空間用了49分鐘 技術分享圖片

技術分享圖片 那這樣的話推測一百多兆的空間應該是很快的,感覺自己要學習的東西太多,加油。。。

從刪表到跑路