摘要:簡(jiǎn)介項(xiàng)目地址主從環(huán)境下數(shù)據(jù)一致性校驗(yàn)經(jīng)常會(huì)用工具,它的原理及實(shí)施過(guò)程之前寫(xiě)過(guò)一篇文章生產(chǎn)環(huán)境使用檢查數(shù)據(jù)一致性。上面的配置文件可以認(rèn)為是用于控制程序的,這個(gè)配置文件是指定要校驗(yàn)的源庫(kù)和目標(biāo)庫(kù)信息,以及要檢驗(yàn)?zāi)男┍怼?/p>
1. 簡(jiǎn)介
項(xiàng)目地址:https://github.com/seanlook/p...
主從環(huán)境下數(shù)據(jù)一致性校驗(yàn)經(jīng)常會(huì)用 pt-table-checksum 工具,它的原理及實(shí)施過(guò)程之前寫(xiě)過(guò)一篇文章:生產(chǎn)環(huán)境使用 pt-table-checksum 檢查MySQL數(shù)據(jù)一致性。但是DBA工作中還會(huì)有些針對(duì)兩個(gè)表檢查是否一致,而這兩個(gè)表之間并沒(méi)有主從關(guān)系,pt工具是基于binlog把在主庫(kù)進(jìn)行的檢查動(dòng)作,在從庫(kù)重放一遍,此時(shí)就不適用了。
總會(huì)有這樣特殊的需求,比如從阿里云RDS實(shí)例遷移到自建mysql實(shí)例,它的數(shù)據(jù)傳輸服務(wù)實(shí)現(xiàn)方式是基于表的批量數(shù)據(jù)提取,加上binlog訂閱,但強(qiáng)制row模式會(huì)導(dǎo)致pt-table-checksum沒(méi)有權(quán)限把會(huì)話(huà)臨時(shí)改成statement。另一種需求是,整庫(kù)進(jìn)行字符集轉(zhuǎn)換:庫(kù)表定義都是utf8,但應(yīng)用連接使用了默認(rèn)的 latin1,要將連接字符集和表字符集統(tǒng)一起來(lái),只能以latin1導(dǎo)出數(shù)據(jù),再以u(píng)tf8導(dǎo)入,這種情況數(shù)據(jù)一致性校驗(yàn),且不說(shuō)binlog解析程序不支持statement(如canal),新舊庫(kù)本身內(nèi)容不同,pt-table-checksum 算出的校驗(yàn)值也會(huì)不一樣,失效。
所以才萌生了參考 pt-table-checksum 自己寫(xiě)了一個(gè):px-table-checksum 。
2. 實(shí)現(xiàn)方法整體思路是借鑒pt-table-checksum,從源庫(kù)批量(即chunk)取出一塊數(shù)據(jù)如1000行,計(jì)算CRC32值,同樣的語(yǔ)句在目標(biāo)庫(kù)運(yùn)行一遍,結(jié)果都存入另一個(gè)庫(kù),最后檢查對(duì)應(yīng)編號(hào)的chunk crc值是否一致。知道不一致還不行,得能否快速方便的修復(fù)差異,所以繼續(xù)根據(jù)那些不一致的chunk,去目標(biāo)庫(kù)和源庫(kù)找到不一致的行,是缺失,還是多余,還是被修改了,然后生成修復(fù)sql,根據(jù)指示是否自動(dòng)修復(fù)。
那么問(wèn)題就在于:
如何確定批次,也就是下一個(gè)chunk該怎么???
我還沒(méi)想做到pt-table-checksum那樣,可以根據(jù)負(fù)載動(dòng)態(tài)調(diào)整chunk大小,甚至活躍線(xiàn)程數(shù)超過(guò)閥值就暫停檢查,上來(lái)工作量就太大了。目前每次計(jì)算的chunk的行數(shù)是固定的,可以配置1000或2000等。
所以就要用到分頁(yè)查詢(xún),根據(jù)(自增或聯(lián)合)主鍵、唯一索引,每次limit 1000后升序取最后一條,作為下一批的起始。所以要分析表上的鍵情況,組合查詢(xún)條件。目前僅能檢查有主鍵或唯一所以的表。
如何保證源庫(kù)和目標(biāo)庫(kù),運(yùn)行的sql一樣?
之前一版是目標(biāo)庫(kù)和源庫(kù),以多線(xiàn)程各自計(jì)算chunk,入庫(kù),后來(lái)才意識(shí)到嚴(yán)重的bug:比如同樣是取1000行,如果目標(biāo)庫(kù)少數(shù)據(jù),那么下一個(gè)chunk起始就不一樣,比較的結(jié)果簡(jiǎn)直一塌糊涂。
所以必須保證相同編號(hào)的chunk,起點(diǎn)必須相同,所以想到用隊(duì)列,存放在源庫(kù)跑過(guò)的所有校驗(yàn)sql,模擬pt工具在目標(biāo)庫(kù)重放??紤]到要多線(xiàn)程同時(shí)比較多個(gè)表,隊(duì)列可能吃?xún)?nèi)存過(guò)大,于是使用了redis隊(duì)列。
直接在數(shù)據(jù)庫(kù)中計(jì)算crc32,還是取出數(shù)據(jù)在內(nèi)存里計(jì)算?
翻了pt-table-checksum的源碼,它是在數(shù)據(jù)庫(kù)里計(jì)算的。但是第一節(jié)里說(shuō)過(guò),如果目標(biāo)庫(kù)和源庫(kù)要使用不同的字符集才能讀出正確的數(shù)據(jù),只能查詢(xún)出來(lái)之后再比較。所以 px-table-checksum 兩種都支持,只需指定一個(gè)配置項(xiàng)。
同時(shí)檢查多個(gè)表,源庫(kù)sql擠在隊(duì)列,目標(biāo)庫(kù)拿出來(lái)執(zhí)行時(shí)過(guò)了1s,此時(shí)源庫(kù)那條數(shù)據(jù)又被修改了一次同步到了目標(biāo)庫(kù),會(huì)導(dǎo)致計(jì)算結(jié)果不一致,實(shí)則一致,怎么處理
無(wú)法處理,是px-table-checksum相比pt-table-checksum最大的缺陷。
但為了盡可能減少此類(lèi)問(wèn)題(比如主從延遲也可能會(huì)),特意設(shè)計(jì)了多個(gè)redis隊(duì)列,目標(biāo)庫(kù)多個(gè)檢查線(xiàn)程,即比如同時(shí)指定檢查8個(gè)表,源庫(kù)檢查會(huì)有8個(gè)線(xiàn)程對(duì)應(yīng),但可以根據(jù)表的寫(xiě)入情況,配置4個(gè)redis隊(duì)列(目前是隨機(jī)入列),10個(gè)目標(biāo)庫(kù)檢查線(xiàn)程,來(lái)減少不準(zhǔn)確因素。
但站在我的角度往往來(lái)說(shuō),不一致的數(shù)據(jù)會(huì)被記錄下來(lái),如果不多,人工核對(duì)一下;如果較多,就再跑一遍檢查,如果兩次都有同一條數(shù)據(jù)不一致,那就有情況了。
如果檢查期間源表數(shù)據(jù),變化頻繁,有可能檢查的結(jié)果不準(zhǔn)確
也就是上面第4點(diǎn)的問(wèn)題。很明顯,這個(gè)程序每個(gè)檢查的事務(wù)是分開(kāi)的,不像pt工具能?chē)?yán)格保證每條檢查sql的事務(wù)順序。但有不一致的數(shù)據(jù)再排查一下就ok了。實(shí)際在我線(xiàn)上使用過(guò)程中,99.9%是準(zhǔn)確的。
表上必須有主鍵或唯一索引
程序會(huì)檢查,如果沒(méi)有會(huì)退出。
varbinay,blob等二進(jìn)制字段不支持修復(fù)
其實(shí)也不是完全不支持,要看怎么用的。開(kāi)發(fā)如果有把字符先轉(zhuǎn)成字節(jié),再存入mysql,這種就不支持修復(fù)。是有辦法可以處理,那就是從源庫(kù)查時(shí)用 hex()函數(shù),修復(fù)sql里面unhex()寫(xiě)回去。
該python程序基于2.7開(kāi)發(fā),2.6、3.x上沒(méi)有測(cè)試。使用前需要安裝 MySQLdb和hotqueue:
$ sudo pip install MySQL-python hotqueue
要比較的表和選項(xiàng),使用全配置化,即不通過(guò)命令行的方式指定(原諒命令行參數(shù)使用方式會(huì)額外增加代碼量)。
4.1 px-table-checksum.py主程序,運(yùn)行python px-table-checksum.py 執(zhí)行一致性檢查,但一定了解下面的配置文件選項(xiàng)。
4.2 settings_checksum.py配置選項(xiàng)
CHUNK_SIZE: 每次提取的chunk行數(shù)
REDIS_INFO: 指定使用redis隊(duì)列地址
REDIS_QUEUE_CNT: redis隊(duì)列數(shù)量,消費(fèi)者(目標(biāo)庫(kù))有一一對(duì)應(yīng)的線(xiàn)程守著隊(duì)列
REDIS_POOL_CNT: 生產(chǎn)者(源庫(kù))redis客戶(hù)端連接池。這個(gè)設(shè)計(jì)是為了緩解GIL帶來(lái)的問(wèn)題,把入列端與出列端分開(kāi),因?yàn)槿绻矶嗫赡芏虝r(shí)間有大量sql入隊(duì)列,避免hotqueue爭(zhēng)用
CALC_CRC32_DB: True 表示在db里面計(jì)算checksum值,F(xiàn)alse表示取出chunk數(shù)據(jù)在python里面計(jì)算。默認(rèn)給的值是根據(jù)連接字符集定的。
DO_COMPARE: 運(yùn)行模式
0: 只提取數(shù)據(jù)計(jì)算,不比較是否一致??梢栽谥笤谀J?下只比較
1: 計(jì)算,并比較。常用,每次計(jì)算之前會(huì)刪除上一次這個(gè)待檢查表的結(jié)果,比較的結(jié)果只告訴哪些chunk號(hào)不一致。
2: 不計(jì)算,只從t_checkum結(jié)果比較。常用,計(jì)算是消耗數(shù)據(jù)庫(kù)資源的,可以只對(duì)已有的checksum計(jì)算結(jié)果比較不一致的地方。類(lèi)似pt工具的--replicate-check-only選項(xiàng)。
GEN_DATAFIX:
與DO_COMPARE結(jié)合使用,為 True 表示對(duì)不一致的chunk找到具體不一致行,并生成修復(fù)sql;為 False 則什么都不做。
RUN_DATAFIX:
與GEN_DATAFIX結(jié)合使用,為 True 表示對(duì)生成的修復(fù)sql,在目標(biāo)庫(kù)執(zhí)行。需要謹(jǐn)慎,如果哪一次設(shè)置了修復(fù),記得完成后改回False,不然下次檢查另一個(gè)表就出意外了,所以特意對(duì)這個(gè)選項(xiàng)再加了一個(gè)確認(rèn)提示。
DB_CHECKSUM: 一個(gè)字典,指定checksum的結(jié)果存到哪里
配置文件有示例,必須指定 db_name,表會(huì)自動(dòng)創(chuàng)建。
上面的配置文件可以認(rèn)為是用于控制程序的,這個(gè)配置文件是指定要校驗(yàn)的源庫(kù)和目標(biāo)庫(kù)信息,以及要檢驗(yàn)?zāi)男┍怼?/p>
TABLES_CHECK: 字典,指定要檢查哪些表的一致性,db名為key,多個(gè)table名組成列表為value。暫不支持對(duì)整個(gè)db做檢查,同時(shí)比較的表數(shù)量不建議超過(guò)8個(gè)
DB_SOURCE: 字典,指定源庫(kù)的連接信息
DB_SOURCE: 字典,指定目標(biāo)庫(kù)的連接信息
原文鏈接地址:http://seanlook.com/2016/11/2...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/44276.html
摘要:通過(guò)對(duì)一些客戶(hù)的跨云遷移過(guò)程進(jìn)行總結(jié),發(fā)現(xiàn)普遍存在的挑戰(zhàn)有三點(diǎn)數(shù)據(jù)完整性和一致性挑戰(zhàn)。簡(jiǎn)而言之,跨云遷移過(guò)程中的數(shù)據(jù)一致性主要就集中在存量數(shù)據(jù)的遷移如何保證一致。前言隨著互聯(lián)網(wǎng)業(yè)務(wù)發(fā)展對(duì)容災(zāi)以及對(duì)訪(fǎng)問(wèn)加速、多供應(yīng)商成本控制等需求的產(chǎn)生,互聯(lián)網(wǎng)公司的多云部署和跨云遷移逐漸成為剛需,而在此過(guò)程中,最困擾運(yùn)維和研發(fā)人員的就是數(shù)據(jù)的遷移和同步。俗語(yǔ)說(shuō) 上屋搬下屋,搬灑一籮谷 ,在業(yè)務(wù)的遷移過(guò)程中一旦...
摘要:業(yè)務(wù)延遲和錯(cuò)誤量對(duì)比接入數(shù)據(jù)庫(kù)后業(yè)務(wù)邏輯層服務(wù)接口耗時(shí)穩(wěn)定無(wú)抖動(dòng),且沒(méi)有發(fā)生丟棄的情況上圖錯(cuò)誤大多由數(shù)據(jù)訪(fǎng)問(wèn)層服務(wù)隊(duì)列堆積發(fā)生請(qǐng)求丟棄造成。 作者:孫玄,轉(zhuǎn)轉(zhuǎn)公司首席架構(gòu)師;陳東,轉(zhuǎn)轉(zhuǎn)公司資深工程師;冀浩東,轉(zhuǎn)轉(zhuǎn)公司資深 DBA。 公司及業(yè)務(wù)架構(gòu)介紹 轉(zhuǎn)轉(zhuǎn)二手交易網(wǎng) —— 把家里不用的東西賣(mài)了變成錢(qián),一個(gè)幫你賺錢(qián)的網(wǎng)站。由騰訊與 58 集團(tuán)共同投資。為海量用戶(hù)提供一個(gè)有擔(dān)保、便捷的二手...
閱讀 1884·2021-10-12 10:12
閱讀 2632·2021-09-29 09:42
閱讀 2888·2021-09-03 10:28
閱讀 2315·2019-08-30 15:54
閱讀 1219·2019-08-30 15:53
閱讀 1469·2019-08-30 11:26
閱讀 3418·2019-08-30 11:02
閱讀 2202·2019-08-30 11:02