tungsten API 同步日誌清除Binlog失敗的BUG解決

 在簡單修改tungsten API實現日誌解析完成後,切換到下一個日誌前,會進行此日誌清除操作。此操作的目的是防止RelayLog同步mysql master日誌過多,引起磁盤空間佔用過多的問題。此操作在BinlogPosition reset方法中增加了clearFile相關操作。

        實現應用時發現一個問題:第一個解析的Binlog日誌刪除不了,以及中間偶爾會有一個binlog日誌清除不了。(對於未清除的日誌file會有記錄,在下次清除file時會嘗試再次刪除,在操作過程中,如果我們的binlog日誌足夠多,重試多次後,第一個binlog有時是能刪除成功的)

        通過以上分析,猜測第一個Binlog 日誌應該存在一種特殊邏輯,導致file在刪除前,在內存中還保留着文件句柄,而且猜測會在JVM中遺留一段時間,當發生GC時,此句柄能被正常回收。

        與是在調試MysqlExtractor解析源碼中發現,在processEvent方法中,當打開的InputStream流非空,且Binlog Position爲0時,會openFile一個新的文件,對於此打開新的file邏輯本身是沒有問題的,但是其處理代碼是:

        有可能InputStream 非空,

        但是其在未關閉前就直接:fIS = new FileInputStream(file)//

        對於此類問題在文件處理中是不可取的,如果原先文件未關閉,此文件句柄還會在JVM中佔用空間,且導致此file不能被其它應用清除。(直到GC)

       (而我們使用過程中第一個Binlog處理的position正是從0開始! 由於是API調用並未考慮對於從日誌的中間開始解析,以及解析過程中保存此類狀態)

       以上BUG解決實際是對file流操作的問題,在以上操作前,加上流非空,關閉流的判斷後,file能正常刪除了。


       最近兩片小記都是對於mysql binlog處理過程中基於tungsten API同步過程中調試遇到的一些典型比較深刻的BUG,在此小記一下。

      (最近項目是處理mysql binlog發現特定SQL的變化 ,爲另一個系統做數據一致性而開發。算是一個小的嘗試,現在開發已經接近尾聲,實時性以及可行性都可取,下週開始將會把數據庫實時修改考慮更新到redis緩存中去,(系統第一階段是通過自己實現基於redis的分佈式緩存),但是存在於一定侷限性,且跟應用本身DAO耦合比較大。接下來會陸續記錄開發過程中相關調研以及相關問題記錄,有時間也會把第一隊段,基於redis的分佈式緩存架構簡單記錄於此,用於日後查看。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章