MySQL非主從環境下資料一致性校驗及修復程序
1. 簡介
專案位址:https://github.com/seanlook/p...
主從環境下資料一致性校驗經常會用pt-table-checksum 工具,它的原理及實作過程之前寫過一篇文章:生產環境使用pt-table-checksum 檢查MySQL資料一致性。但是DBA工作中還會有些針對兩個表檢查是否一致,而這兩個表之間並沒有主從關係,pt工具是基於binlog把在主庫進行的檢查動作,在從庫重放一遍,此時就不適用了。
總是會有這樣特殊的需求,例如從阿里雲RDS實例遷移到自建mysql實例,它的資料傳輸服務實作方式是基於表的批次資料擷取,加上binlog訂閱,但強制row模式會導致pt -table-checksum沒有權限把會話暫時改成statement。另一種需求是,整庫進行字符集轉換:庫表定義都是utf8,但應用連接使用了默認的latin1,要將連接字符集和表字符集統一起來,只能以latin1導出數據,再以utf8導入,這種情況資料一致性校驗,不說binlog解析程序不支援statement(如canal),新舊庫本身內容不同,pt-table-checksum 算出的校驗值也會不一樣,失效。
所以才萌生了參考 pt-table-checksum 自己寫了一個:px-table-checksum 。
2. 實作方法
整體思路是藉用pt-table-checksum,從源庫批量(即chunk)取出一塊資料如1000行,計算CRC32值,同樣的語句在目標庫運行一遍,結果都存入另一個庫,最後檢查對應編號的chunk crc值是否一致。知道不一致還不行,得能否快速方便的修復差異,所以繼續根據那些不一致的chunk,去目標庫和源庫找到不一致的行,是缺失,還是多餘,還是被修改了,然後生成修復sql,根據指示是否自動修復。
那麼問題就在於:
如何決定批次,也就是下一個chunk該怎麼取?我還沒想做到pt-table-checksum那樣,可以根據負載動態調整chunk大小,甚至活躍線程數超過閥值就暫停檢查,上來工作量就太大了。目前每次計算的chunk的行數是固定的,可以配置1000或2000等。
所以就要用到分頁查詢,根據(自增或聯合)主鍵、唯一索引,每次limit 1000後升序取最後一條,作為下一批的起始。所以要分析表上的鍵情況,組合查詢條件。目前只能檢查有主鍵或唯一所以的表。
如何保證來源函式庫和目標函式庫,運作的sql一樣?之前一版是目標庫和來源庫,以多線程各自計算chunk,入庫,後來才意識到嚴重的bug:比如同樣是取1000行,如果目標庫少數據,那麼下一個chunk起始就不一樣,比較的結果簡直一塌糊塗。
所以必須保證相同編號的chunk,起點必須相同,所以想到用隊列,存放在源庫跑過的所有校驗sql,模擬pt工具在目標庫重播。考慮到要多執行緒同時比較多個表,佇列可能吃記憶體過大,於是使用了redis佇列。
直接在資料庫中計算crc32,還是取出資料在記憶體裡計算?翻了pt-table-checksum的源碼,它是在資料庫裡計算的。但第一節裡說過,如果目標庫和來源庫要使用不同的字元集才能讀出正確的數據,只能查詢出來之後再比較。所以 px-table-checksum 兩者都支持,只需指定一個配置項。
同時檢查多個表,源庫sql擠在隊列,目標庫拿出來執行時過了1s,此時源庫那條數據又被修改了一次同步到了目標庫,會導致計算結果不一致,實則一致,怎麼處理無法處理,是px-table-checksum相比pt-table-checksum最大的缺陷。
但為了盡可能減少此類問題(例如主從延遲也可能會),特意設計了多個redis隊列,目標庫多個檢查線程,即例如同時指定檢查8個表,源庫檢查會有8個線程對應,但可以根據表的寫入情況,配置4個redis隊列(目前是隨機入列),10個目標庫檢查線程,來減少不準確因素。但站在我的角度往往來說,不一致的數據會被記錄下來,如果不多,人工核對一下;如果較多,就再跑一遍檢查,如果兩次都有同一數據不一致,那就有情況了。
3. 限制
如果檢查期間源表數據,變化頻繁,有可能檢查的結果不準確也就是上面第4點的問題。很明顯,這個程序每個檢查的事務是分開的,不像pt工具能嚴格保證每個檢查sql的事務順序。但有不一致的數據再檢查一下就ok了。實際在我線上使用過程中,99.9%是準確的。
表上必須有主鍵或唯一索引程式會檢查,如果沒有會退出。
varbinay,blob等二進位字段不支援修復
其實也不是完全不支持,要看怎麼用的。開發如果有把字元先轉成字節,再存入mysql,這種就不支援修復。是有辦法可以處理,就是從來源庫查時用 hex()函數,修復sql裡面unhex()寫回去。
4. 使用說明
該python程式基於2.7開發,2.6、3.x上沒有測試。使用前需要安裝 MySQLdb和hotqueue:
$ sudo pip install MySQL-python hotqueue
要比較的表格和選項,使用全配置化,即不透過命令列的方式指定(原諒額外命令列參數使用方式會增加代碼量)。
4.1 px-table-checksum.py
主程序,執行python px-table-checksum.py 執行一致性檢查,但一定了解下面的設定檔選項。
4.2 settings_checksum.py
設定選項
CHUNK_SIZE: 每次擷取的chunk行數
REDIS_INFO: 指定使用NTredis(佇列位址
REDIS_QUED3IS_INFO: 指定使用NTredis(每個佇列地址)守著佇列
REDIS_POOL_CNT: 生產者(來源庫)redis客戶端連線池。這個設計是為了緩解GIL帶來的問題,把入列端與出列端分開,因為如果表多可能短時間有大量sql入隊列,避免hotqueue爭用
CALC_CRC32_DB: True 表示在db裡面計算checksum值,False表示取出chunk資料在python裡面計算。預設給的值是根據連接字元集定的。
DO_COMPARE: 運作模式
0: 只擷取資料計算,不比較是否一致。可以在之後在模式2下只比較
1: 計算,並比較。常用,每次計算前會刪除上一次這個待檢查表的結果,比較的結果只告訴哪些chunk號不一致。
2: 不計算,只從t_checkum結果比較。常用,計算是消耗資料庫資源的,可以只對已有的checksum計算結果比較不一致的地方。類似pt工具的--replicate-check-only選項。
GEN_DATAFIX:
與DO_COMPARE結合使用,為 True 表示對不一致的chunk找到具體不一致行,並產生修復sql;為 False 則什麼都不做。
RUN_DATAFIX:
與GEN_DATAFIX結合使用,為 True 表示對產生的修復sql,在目標庫執行。需要謹慎,如果哪一次設定了修復,記得完成後改回False,不然下次檢查另一個表就出意外了,所以特意對這個選項再加了一個確認提示。
DB_CHECKSUM: 一個字典,指定checksum的結果存到哪裡
設定檔有範例,必須指定 db_name,表會自動建立。
4.3 settings_cs_tables.py
上面的設定檔可以認為是用於控製程式的,這個設定檔是指定要校驗的來源函式庫和目標函式庫信息,以及要檢驗哪些資料表。
TABLES_CHECK: 字典,指定要檢查哪些表的一致性,db名為key,多個table名組成列表為value。暫不支援對整個db做檢查,同時比較的表格數量不建議超過8個
DB_SOURCE: 字典,指定來源庫的連接資訊
DB_SOURCE: 字典,指定目標庫的連接資訊

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

在使用Thelia開發電商網站時,我遇到了一個棘手的問題:MySQL模式設置不當,導致某些功能無法正常運行。經過一番探索,我找到了一個名為TheliaMySQLModesChecker的模塊,它能夠自動修復Thelia所需的MySQL模式,徹底解決了我的困擾。

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。
