多需要比較7次,才能完成,而采用二分查 找法,最多只需要比較3次就可W完成。
[0080] 具體到本申請的技術(shù)方案,由于二進(jìn)制日志文件中的記錄是按照執(zhí)行相關(guān)數(shù)據(jù)庫 更改操作的時間順序?qū)懭氲?,而二進(jìn)制日志文件也是按照時間順序逐一生成的(其擴展名 遞增),因此按照時間順序排列的全部二進(jìn)制日志文件中的第一個記錄的時間戳也是按照 時間順序排列的,符合二分查找法要求數(shù)據(jù)序列必須是有序的該一基本要求,因此可W采 用二分法查找本步驟所需的二進(jìn)制日志文件,從而有效提高查找的效率。請參見附圖2,其 為本申請的采用二分法查找其包含的第一個記錄的時間戳不晚于所述預(yù)先指定的時間戳 的最后一個文件的基本流程示意圖,由于二分查找法比較成熟,因此下面僅結(jié)合該附圖對 于在本技術(shù)方案中如何采用二分查找法作簡要說明(為了便于描述,將查找條件"其包含的 第一個記錄的時間戳不晚于所述預(yù)先指定的時間戳"簡化描述為"不晚于tl"):
[0081] 步驟101-1-1;為算法相關(guān)變量賦初值。當(dāng)前有N個二進(jìn)制日志文件,用數(shù)組B代 表,B[0]為第一個文件,B[N-1]為最后一個文件。1代表待查找區(qū)間的起點位置,h代表待 查找區(qū)間的結(jié)束位置,i代表待查找區(qū)間的中間位置。預(yù)先指定的時間戳為tl。
[0082] 步驟101-1-2 ;定位當(dāng)前查找的文件區(qū)間的中間位置,并獲取對應(yīng)文件的第一個 記錄的時間戳t。
[0083] 步驟101-1-3;如果t=tl,則說明找到了所需的記錄(B[i]文件中的第一個記錄), 因此本查找過程結(jié)束。
[0084] 步驟101-1-4;判斷1是否小于等于h,若是說明查找過程尚未結(jié)束,繼續(xù)執(zhí)行后續(xù) 的查找操作。
[0085] 步驟101-1-5;如果t<tl,即:當(dāng)前記錄的時間戳早于tl,但是B[i]文件不一定是 滿足所述"不晚于tl"要求的最后一個文件,因此還需要繼續(xù)在當(dāng)前文件區(qū)間的后半段中查 找,看看是否存在其第一個記錄的時間戳晚于本記錄時間戳、但是早于tl的文件,轉(zhuǎn)到步 驟101-1-6執(zhí)行。
[0086] 步驟101-1-6 ;設(shè)置l=i+l,為在當(dāng)前文件區(qū)間的后半段繼續(xù)查找設(shè)置區(qū)間的起點 位置,轉(zhuǎn)到步驟101-1-2執(zhí)行。
[0087] 步驟101-1-7 ;如果t〉tl,即:當(dāng)前記錄的時間戳晚于tl,B[i]文件不滿足"不晚 于tl"的要求,應(yīng)該在當(dāng)前文件區(qū)間的前半段中繼續(xù)查找,轉(zhuǎn)到步驟101-1-8執(zhí)行。
[0088] 步驟101-1-8 ;設(shè)置h=i-l,為在當(dāng)前文件區(qū)間的前半段繼續(xù)查找設(shè)置區(qū)間的結(jié)束 位置,轉(zhuǎn)到步驟101-1-2執(zhí)行。
[0089] 上述查找過程一直循環(huán)執(zhí)行,該過程在兩種情況下終止;第一種情況,在步驟 101-1-3中判斷出t=tl,則B[i]就是滿足要求的最后一個文件,并且B[i]中的第一個記錄 就是本申請的技術(shù)方案所需查找的記錄,該種情況下可W跳過后續(xù)步驟101-2,直接執(zhí)行步 驟102即可;第二種情況,在步驟101-1-4中判斷出l〉h (起始位置已經(jīng)大于結(jié)束位置),說 明二分查找過程結(jié)束,當(dāng)前B[i]文件就是滿足"不晚于tl"要求的最后一個文件。
[0090] 步驟101-2 ;在所述最后一個文件中查找其時間戳不早于所述預(yù)先指定的時間戳 的第一個記錄。
[0091] 執(zhí)行到本步驟,說明已經(jīng)在所述當(dāng)前MyS化數(shù)據(jù)庫的二進(jìn)制日志文件集合中,找 到了其包含的第一個記錄的時間戳不晚于所述預(yù)先指定的時間戳的最后一個文件,在本步 驟中只需要從所述最后一個文件的第一個記錄開始,遍歷該文件中的所有記錄,找到其時 間戳不早于所述預(yù)先指定的時間戳的第一個記錄。
[0092] 該里需要說明的是,通常情況下,可W在所述最后一個文件中找到其時間戳等于 所述預(yù)先指定的時間戳的第一個記錄,在本步驟中之所W采用了 "不早于"(包括等于和 大于兩種情況)的表述方式,是考慮到具體實施過程中可能發(fā)生的特殊情況:在所述當(dāng)前 MyS化數(shù)據(jù)庫的二進(jìn)制日志文件集合中,無法找到其時間戳與所述預(yù)先指定的時間戳完全 相同的記錄(詳細(xì)說明請參見后文與主備切換相關(guān)的說明)。在該種情況下,為了使本申請 技術(shù)方案依然能夠找到盡可能準(zhǔn)確的起始位點,并保證后續(xù)獲取增量日志的步驟102能夠 順利執(zhí)行,因此在本步驟中采用了查找其時間戳不早于所述預(yù)先指定時間戳的第一個記錄 的方式。
[0093] 例如,在本實施例的一個具體例子中,是該樣實現(xiàn)的;從所述最后一個文件的第一 個記錄開始,如果該記錄的時間戳小于預(yù)先指定的時間戳,則繼續(xù)讀取下一個記錄,并作同 樣的判斷......直到當(dāng)前記錄的時間戳大于或者等于所述預(yù)先指定的時間戳,則該查找 過程結(jié)束,當(dāng)前記錄就是所述最后一個文件中、其時間戳不早于所述預(yù)先指定的時間戳的 第一個記錄。
[0094] 至此,就根據(jù)所述預(yù)先指定的時間戳在所述當(dāng)前MyS化數(shù)據(jù)庫的二進(jìn)制日志文件 集合中找到了對應(yīng)的記錄,那么,就可W根據(jù)已找到的記錄執(zhí)行后續(xù)步驟102實現(xiàn)獲取增 量日志的功能。
[0095] 考慮到在實際應(yīng)用中,需要從MyS化數(shù)據(jù)庫抓取增量二進(jìn)制日志數(shù)據(jù)、W滿足增 量訂閱或消費等相關(guān)業(yè)務(wù)需求的應(yīng)用程序或者系統(tǒng)通常安裝在不同于MyS化數(shù)據(jù)庫所在 服務(wù)器的其他設(shè)備上,在常規(guī)情況下通過網(wǎng)絡(luò)連接從MyS化主數(shù)據(jù)庫抓取增量日志數(shù)據(jù), 在發(fā)生主備切換的場景下,則采用本申請?zhí)峁┑姆椒?,繼續(xù)從備用數(shù)據(jù)庫(即;本申請所述 的當(dāng)前MyS化數(shù)據(jù)庫)抓取增量日志數(shù)據(jù)。在該種情況下,從MyS化主數(shù)據(jù)庫獲取的增量日 志的最后一個記錄的時間戳,即為本步驟所述的預(yù)先指定的時間戳。為了在上述應(yīng)用場景 下實施本申請的技術(shù)方案,則需要在執(zhí)行本步驟101之前執(zhí)行判斷主備切換、記錄時間戳、 建立數(shù)據(jù)連接、獲取二進(jìn)制日志文件列表該四個步驟,請參見附圖3,其為上述處理過程的 實施例流程圖,下面結(jié)合附圖3進(jìn)行進(jìn)一步的說明。為了便于下文的描述,將在抓取增量日 志過程中實現(xiàn)了本申請技術(shù)方案的應(yīng)用程序或者系統(tǒng),統(tǒng)稱為增量日志抓取任務(wù)。
[0096] 步驟100-1;判斷MyS化數(shù)據(jù)庫系統(tǒng)是否執(zhí)行了主備切換操作。
[0097] 增量日志抓取任務(wù)采用與MyS化備用數(shù)據(jù)庫類似的方式,按照MySQL網(wǎng)絡(luò)通信協(xié) 議的要求,將封裝了C0M_BmL0G_DUMP命令的數(shù)據(jù)包發(fā)送給MyS化主數(shù)據(jù)庫,該數(shù)據(jù)包中還 要封裝希望從中獲取增量日志數(shù)據(jù)的二進(jìn)制日志文件的文件名和偏移量,MyS化主數(shù)據(jù)庫 收到該數(shù)據(jù)包后,會將符合要求的增量日志返回給所述增量日志抓取任務(wù)。
[0098] 考慮到MyS化主數(shù)據(jù)庫可能出現(xiàn)故障,為了能夠及時將抓取增量日志的操作切換 到備用數(shù)據(jù)庫上(即:切換后的主數(shù)據(jù)庫),增量日志抓取任務(wù)需要監(jiān)測MyS化數(shù)據(jù)庫系統(tǒng) 是否發(fā)生了主備切換。在本實施例的一個具體例子中,在數(shù)據(jù)庫的元信息庫中用一個特定 的字符串"Grou地ey"表征當(dāng)前的主備數(shù)據(jù)庫,通過檢測該字符串,就可W獲得當(dāng)前主數(shù)據(jù) 庫和備數(shù)據(jù)庫的相關(guān)信息,如果發(fā)現(xiàn)主數(shù)據(jù)庫的IP地址發(fā)生了變化,即可W判定主備數(shù)據(jù) 庫發(fā)生了切換,所述增量日志抓取任務(wù)就需要通過執(zhí)行后續(xù)的步驟,將抓取增量日志的操 作切換到備用數(shù)據(jù)庫上。
[0099] 步驟100-2;記錄從MySQL主數(shù)據(jù)庫獲取的增量日志的最后一個記錄的時間戳,作 為所述預(yù)先指定的時間戳。
[0100] 為了將從MyS化主數(shù)據(jù)庫獲取binlog增量日志的操作切換到MyS化備用數(shù)據(jù)庫 上(即;本申請所述的當(dāng)前MyS化數(shù)據(jù)庫),需要將已經(jīng)從MyS化主數(shù)據(jù)庫獲取的增量日志的 最后一個記錄的時間戳記錄下來,該樣才能執(zhí)行后續(xù)的根據(jù)所述時間戳在備用數(shù)據(jù)庫的二 進(jìn)制日志文件集合中查找起始位點的操作。
[0101] 本步驟中,將已經(jīng)從MyS化主數(shù)據(jù)庫獲取的增量日志的最后一個記錄的時間戳記 錄下來,也就是記錄所述最后一個記錄的頭部的第0-3字節(jié)的時間戳信息,作為后續(xù)在備 用數(shù)據(jù)庫的二進(jìn)制日志文件集合中定位起始位點的依據(jù),從而盡可能保證從備用數(shù)據(jù)庫獲 取的增量日志與從主數(shù)據(jù)庫上獲取的增量日志是連續(xù)的,盡量避免出現(xiàn)數(shù)據(jù)丟失的現(xiàn)象。 本步驟獲取的時間戳,即為本申請所述的預(yù)先指定的時間戳。
[0102] 步驟100-3;與所述當(dāng)前MyS化數(shù)據(jù)庫建立數(shù)據(jù)連接。
[0103] 增量日志抓取任務(wù)遵循MyS化主備數(shù)據(jù)庫之間的交互協(xié)議,與所述當(dāng)前MyS化數(shù) 據(jù)庫(在發(fā)生主備切換后,原來的備用數(shù)據(jù)庫即成為本申請所述的當(dāng)前MyS化數(shù)據(jù)庫)建立 數(shù)據(jù)連接,也就是說增量日志抓取任務(wù)W備用數(shù)據(jù)庫的身份向所述當(dāng)前MyS化數(shù)據(jù)庫請求 增量日志數(shù)據(jù)。
[0104] 本步驟所述的與所述當(dāng)前MyS化數(shù)據(jù)庫建立數(shù)據(jù)連接,采用了相對寬泛的表述方 式,在具體實施中,本步驟不僅包括連接的建立過程,通常還包括了鑒權(quán)等過程,其基本流 程是該樣的;首先需要獲取所述當(dāng)前MyS化數(shù)據(jù)庫所在服務(wù)器的IP地址和所述當(dāng)前MySQL 數(shù)據(jù)庫提供數(shù)據(jù)庫服務(wù)的端口號,然后創(chuàng)建一個socket(套接字)與所述當(dāng)前MyS化數(shù)據(jù)庫 建立數(shù)據(jù)連接,并按照MyS化主備數(shù)據(jù)庫之間的交互協(xié)議執(zhí)行握手和驗證等交互過程,在 該過程中,所述增量日志抓取任務(wù)可能還需要按照MyS化主服務(wù)器的要求提供用戶名、口 令等信息,并且只有通過所述當(dāng)前MyS化數(shù)據(jù)庫的身份驗證,所述數(shù)據(jù)連接才算建立成功。
[0105] 為了完成上述連接建立過程,必須要獲取當(dāng)前MyS化數(shù)據(jù)庫的IP地址和提供數(shù)據(jù) 庫服務(wù)的端口號。在本實施例的一個具體例子中,在數(shù)據(jù)庫的元信息庫中用一個特定的字 符串"Grou地ey"表征當(dāng)前的主備數(shù)據(jù)庫,通過檢測該字符串,就可W獲得當(dāng)前主數(shù)據(jù)庫和 備數(shù)據(jù)庫的相關(guān)信息,在發(fā)生主備切換后,原來的備用數(shù)據(jù)庫成為了當(dāng)前的主數(shù)據(jù)庫(本申 請所述的當(dāng)前MyS化數(shù)據(jù)庫),因此可W從上述字符串中獲取與當(dāng)前MyS化數(shù)據(jù)庫相關(guān)的信 息,并從中提取所述IP地址和所述端口號。在其他實施方式中,可W采用其他獲取方式,例 女口;在不修改MyS化配置文件中的端口設(shè)置的情況下,可W直接使用MyS化默認(rèn)的端口號 3306來建立數(shù)據(jù)連接。