王雪梅,張少波
(南京郵電大學(xué) 計(jì)算機(jī)學(xué)院,江蘇 南京 210003)
在線圖表更新技術(shù)的改進(jìn)與應(yīng)用
王雪梅,張少波
(南京郵電大學(xué) 計(jì)算機(jī)學(xué)院,江蘇 南京 210003)
針對MySQL數(shù)據(jù)庫在進(jìn)行數(shù)據(jù)定義語言(DDL)操作時(shí)因鎖表動作引起長時(shí)間業(yè)務(wù)阻塞的問題,實(shí)現(xiàn)了一種不阻塞讀寫事務(wù)的在線圖表更新(OSC)方法??紤]到電商數(shù)據(jù)庫對讀寫事務(wù)的可用性要求,OSC系統(tǒng)將具有原子性的DDL語句拆分成若干步驟,創(chuàng)建臨時(shí)表分片拷貝全量數(shù)據(jù),并利用觸發(fā)器保證增量數(shù)據(jù)的一致性,在實(shí)現(xiàn)無鎖更改表結(jié)構(gòu)的同時(shí),解決了業(yè)務(wù)長時(shí)間阻塞的問題。另外,針對OSC技術(shù)在應(yīng)用場景中遇到的系列問題,提出了相應(yīng)的改進(jìn)方法,如預(yù)檢測、防并發(fā)執(zhí)行等,并結(jié)合淘寶實(shí)際數(shù)據(jù)庫架構(gòu),提供了復(fù)雜場景下OSC技術(shù)的應(yīng)用分析。
數(shù)據(jù)一致性;影子表;在線圖表更新;觸發(fā)器
互聯(lián)網(wǎng)電商平臺一般以“n個(gè)9”作為指標(biāo),對其業(yè)務(wù)提出高可用性要求;如“5個(gè)9”指一年內(nèi)系統(tǒng)不能正常工作的時(shí)間少于5′15″。但早期的MySQL數(shù)據(jù)庫在執(zhí)行更改表結(jié)構(gòu)的DDL操作時(shí)因?qū)φ麖埍硪腈i表動作,導(dǎo)致較長時(shí)間的業(yè)務(wù)阻塞[1-3]。2010年,為了解決這個(gè)問題,F(xiàn)acebook的數(shù)據(jù)庫技術(shù)團(tuán)隊(duì)首次提出在線圖表更新(online schema change,OSC)[4]解決方案。2011年,阿里巴巴的數(shù)據(jù)庫團(tuán)隊(duì)研發(fā)出了類似OSC技術(shù)的產(chǎn)品MyDDL。同時(shí),MySQL在5.1版本中提供了Fast Index Creation的功能,以InnoDB插件的形式在Optimized Create Index和Drop Index上避免表拷貝行為[5-7]。MySQL的5.6版本引入DDL Online Operate[8],雖然在大部分表更新操作中避免了表拷貝,一定程度上緩解了表鎖定的問題,但由于不能支持全部的DDL操作[9],例如,更改字段類型等,仍然不能徹底消除因日常運(yùn)維的頻繁表結(jié)構(gòu)更改對業(yè)務(wù)可用性的影響。
本文基于Facebook提出的OSC基本思想,實(shí)現(xiàn)了一個(gè)在InnoDB引擎層之上的server層工具,通過將具有原子性的DDL語句拆分成若干原子性操作,創(chuàng)建臨時(shí)表分片拷貝全量數(shù)據(jù),并利用觸發(fā)器保證增量數(shù)據(jù)一致性,因只有極少部分操作會進(jìn)行鎖表從而極大減少了對原表的鎖表時(shí)間。另外,結(jié)合淘寶實(shí)際數(shù)據(jù)庫架構(gòu),針對“讀寫分離架構(gòu)”“單元化架構(gòu)”等復(fù)雜場景下基于OSC的數(shù)據(jù)庫運(yùn)維過程中出現(xiàn)的系列問題,提出了相應(yīng)的優(yōu)化方法,分析了不同場景下OSC技術(shù)的可行性。
為盡量減少鎖表時(shí)間,OSC將原生DDL操作分成15個(gè)原子性步驟,如圖1所示。除了步驟13)
圖1 OSC系統(tǒng)主要流程圖
為了滿足表結(jié)構(gòu)變更需求,OSC系統(tǒng)構(gòu)造影子表(ghost)拷貝原表中的全量數(shù)據(jù),并創(chuàng)建3個(gè)觸發(fā)器(INSERT、UPDATE、DELETE),保證在全量數(shù)據(jù)拷貝過程中對原表新加入數(shù)據(jù)的拷貝,或者在原表上執(zhí)行更改、刪除操作后,實(shí)現(xiàn)影子表與原表數(shù)據(jù)的一致。由于對原表進(jìn)行插入、更新、刪除的操作發(fā)生在全量數(shù)據(jù)拷貝過程中的任意時(shí)刻,因此需要引入輔助表dk(DELETE KEY)用來在整個(gè)全量數(shù)據(jù)拷貝過程結(jié)束后修正原表與影子表不一致數(shù)據(jù)。
圖2為INSERT觸發(fā)器設(shè)計(jì)圖。INSERT觸發(fā)器設(shè)計(jì)如下:
圖2 INSERT觸發(fā)器設(shè)計(jì)圖
在original表全量數(shù)據(jù)拷貝到ghost表中時(shí),當(dāng)有數(shù)據(jù)插入original表時(shí),會通過INSERT觸發(fā)器將數(shù)據(jù)同時(shí)插入到ghost表中,并判斷dk表中是否有該條記錄(DELETE觸發(fā)器可能會將數(shù)據(jù)插入到dk表),若有則從dk表中刪除該記錄。INSERT觸發(fā)器保證了拷貝過程中對增量數(shù)據(jù)的拷貝,每一條在拷貝過程中插入到original表中的數(shù)據(jù)都會通過INSERT觸發(fā)器插入到ghost表。
UPDATE觸發(fā)器將對original表修改的數(shù)據(jù)以“REPLACE INTO”的方式插入ghost表。DELETE觸發(fā)器在刪除ghost表中相應(yīng)數(shù)據(jù)的同時(shí)需要在dk表中插入刪除數(shù)據(jù)主鍵以做標(biāo)記。如果需要刪除的數(shù)據(jù)正在拷貝到ghost表中,并且在delete觸發(fā)器準(zhǔn)備將ghost表中該數(shù)據(jù)刪除的時(shí)刻ghost尚未包含該數(shù)據(jù),但刪除完后數(shù)據(jù)又拷貝到ghost表,此時(shí)會發(fā)現(xiàn)原表中數(shù)據(jù)已被刪除,但ghost表中仍然包含該數(shù)據(jù),從而出現(xiàn)原表與ghost表數(shù)據(jù)不一致的問題。為此,引入輔助表(dk)記錄了DELETE觸發(fā)器的刪除操作,在完成全量拷貝過程后對ghost表進(jìn)行修正。這樣可以有效防止刪除的數(shù)據(jù)仍滯留在ghost表中,從而保證原表數(shù)據(jù)與ghost表數(shù)據(jù)的一致性。
上述問題還存在于全量拷貝過程中。全量數(shù)據(jù)拷貝有可能再次把INSERT觸發(fā)器插入的增量數(shù)據(jù)當(dāng)作全量數(shù)據(jù)進(jìn)行二次拷貝,會出現(xiàn)“ERROR 1062(23000):Duplicate entry”的錯(cuò)誤。因此,全量拷貝需要進(jìn)行“INSERT IGNORE INTO”。INSERT IGNORE INTO與INSERT INTO的區(qū)別就是INSERT IGNORE INTO會忽略數(shù)據(jù)庫中已經(jīng)存在的數(shù)據(jù),如果數(shù)據(jù)庫沒有數(shù)據(jù),就插入新的數(shù)據(jù),如果數(shù)據(jù)庫中有數(shù)據(jù)就跳過這條數(shù)據(jù)。這樣就可以保留數(shù)據(jù)庫中已經(jīng)存在的數(shù)據(jù),達(dá)到在間隙中插入數(shù)據(jù)的目的。
雖然OSC系統(tǒng)一定程度上解決了原生DDL的鎖表問題,但由于OSC本身獨(dú)立于MySQL,在不同場景下運(yùn)行時(shí),如不加限制或優(yōu)化仍然會帶來無法忽視的邏輯錯(cuò)誤,可能會引發(fā)數(shù)據(jù)丟失、數(shù)據(jù)不一致等系列問題。下文著重介紹主備復(fù)用、并發(fā)執(zhí)行等實(shí)際場景中可能出現(xiàn)的問題,并給出相應(yīng)的解決方案。
2.1 主備復(fù)制問題
為了提高容災(zāi)能力,減少系統(tǒng)壓力,電商數(shù)據(jù)庫往往設(shè)計(jì)成主從架構(gòu)。正常情況下,主服務(wù)器端執(zhí)行所有的寫入操作,并將所有寫操作記錄到二進(jìn)制日志文件(binlog)中。為了保證主從服務(wù)器數(shù)據(jù)的一致,從服務(wù)器會定時(shí)從binlog中拷貝日志信息到自身的中繼日志(Relay log)中,并重演Relay log中的所有新發(fā)生的操作或事件。
現(xiàn)在考慮OSC系統(tǒng)在數(shù)據(jù)庫主從架構(gòu)下的應(yīng)用。若在主庫中使用OSC技術(shù),OSC執(zhí)行過程中的每一條語句都將記錄在主庫的binlog文件中,通過上文所述的主從復(fù)制模式,相應(yīng)語句會復(fù)制到從庫中的Relay log中,從庫通過執(zhí)行Relay log操作,實(shí)現(xiàn)主從數(shù)據(jù)庫的數(shù)據(jù)一致性。但是,如果在從庫執(zhí)行OSC系統(tǒng),當(dāng)全量數(shù)據(jù)全部拷貝到影子表中后,交換原表與影子表表名,會出現(xiàn)主庫中表結(jié)構(gòu)與從庫中表結(jié)構(gòu)不一致的情形。當(dāng)有數(shù)據(jù)寫入主表時(shí),再通過主從拷貝機(jī)制往從表插入數(shù)據(jù)就會出現(xiàn)錯(cuò)誤!因此,OSC系統(tǒng)應(yīng)當(dāng)嚴(yán)禁在從庫中執(zhí)行。
為防止因OSC系統(tǒng)在從庫執(zhí)行帶來的數(shù)據(jù)丟失的問題,可以通過將從庫的READ_ONLY變量設(shè)置為ON,禁止SUPER權(quán)限之外的從服務(wù)器線程或用戶執(zhí)行更新操作。非SUPER權(quán)限用戶對READ_ONLY為ON的從庫進(jìn)行數(shù)據(jù)插入、刪除或更改操作時(shí),會出現(xiàn)如下報(bào)錯(cuò):
ERROR 1290(HY000):The MySQL server is running with the--read-only option so it cannot execute this statement.
所以,在OSC系統(tǒng)執(zhí)行之前,需要通過對執(zhí)行庫的READ_ONLY進(jìn)行檢查,以避免OSC系統(tǒng)在從庫上執(zhí)行,從而防止數(shù)據(jù)丟失。
2.2 并發(fā)執(zhí)行
OSC系統(tǒng)不支持同一張表上的并發(fā)執(zhí)行。事實(shí)上在同一張表上并發(fā)執(zhí)行OSC,可能會給整個(gè)數(shù)據(jù)庫帶來災(zāi)難性影響。OSC在執(zhí)行過程中可能會因?yàn)楦鞣N原因中途被迫退出,來不及清理殘留的觸發(fā)器(INSERT、UPDATE、DELETE)、影子表和dk表。為了每次執(zhí)行OSC系統(tǒng)不受這些殘留觸發(fā)器和臨時(shí)表的影響,在OSC系統(tǒng)正式執(zhí)行之前需要對這些觸發(fā)器和臨時(shí)表進(jìn)行清理。但是,當(dāng)在同一張表上并發(fā)執(zhí)行OSC時(shí),如果后執(zhí)行的OSC對先執(zhí)行的OSC的觸發(fā)器和影子表進(jìn)行刪除重建的話,已拷貝進(jìn)影子表的全量數(shù)據(jù)以及增量數(shù)據(jù)會丟失,造成數(shù)據(jù)不一致性問題。
為了防止并發(fā)執(zhí)行OSC系統(tǒng)帶來的不良影響,可以在每次執(zhí)行OSC系統(tǒng)前加上一個(gè)“表名鎖”:
"SELECT GET_LOCK(′{$key}′,{$timeout})AS get_lock";
執(zhí)行OSC的線程會占用“表名鎖”直到整個(gè)OSC系統(tǒng)執(zhí)行完畢。在OSC執(zhí)行過程中,若有其他的OSC系統(tǒng)對該表進(jìn)行操作會因得不到“表名鎖”而出錯(cuò)退出。注意,這里的鎖僅對字符串加鎖,并不影響業(yè)務(wù)讀寫。
2.3 與原生DDL行為不一致問題
如上所述,設(shè)計(jì)OSC系統(tǒng)旨在替代原生DDL,防止因在大表上執(zhí)行DDL操作長時(shí)間阻塞讀寫業(yè)務(wù)。然而,對于某些數(shù)據(jù)表結(jié)構(gòu)的更改操作,往往會出現(xiàn)OSC與原生DDL執(zhí)行結(jié)果不一致的情形。例如,原數(shù)據(jù)表“t1”中包含兩個(gè)字段{ID,name},其中ID設(shè)置為主鍵?!皀ame”列中有若干條數(shù)據(jù)且有部分?jǐn)?shù)據(jù)一致。假設(shè)現(xiàn)在對“t1”表進(jìn)行如下原生DDL操作:
Mysql>ALTER TABLE T1 ADD UNIQUE KEY UK(name)
由于該操作試圖對擁有重復(fù)性的列加唯一索引,系統(tǒng)會報(bào)告“1062”錯(cuò)誤:
ERROR 1062(23000):Duplicate entry′0′for key′UK′
如果應(yīng)用OSC執(zhí)行該功能,OSC首先會根據(jù)原表表結(jié)構(gòu)更改需求創(chuàng)建影子表,將原表數(shù)據(jù)通過insert ignore into拷貝到影子表中。如果原表的“name”列中出現(xiàn)重復(fù)項(xiàng),向影子表進(jìn)行拷貝時(shí)會因?yàn)槲ㄒ凰饕募s束造成數(shù)據(jù)丟失。
事實(shí)上,OSC系統(tǒng)與原生DDL的行為不一致問題很難通過程序的邏輯判斷來檢測出來,這時(shí)有必要引入前置檢查,即在原表中取少部分樣本數(shù)據(jù),分別進(jìn)行原生DDL操作與OSC操作,檢查兩種行為的一致性,若兩種行為一致則通過,否則放棄OSC操作。
統(tǒng)計(jì)學(xué)中對樣本有如下要求:1)總體內(nèi)所有觀察單位必須是同質(zhì)的;2)在抽取樣本的過程中,必須遵守隨機(jī)化原則,并且達(dá)到足夠的數(shù)量。事實(shí)上,若在大表中執(zhí)行select count(*)操作需要對全表進(jìn)行掃描,造成長時(shí)間阻塞,脫離了OSC系統(tǒng)的初衷。另外,前置檢查的主要目的是檢測OSC與原生DDL的一致性,需要抽取原表中可能會造成OSC與原生DDL不一致行為的數(shù)據(jù)樣本,無須通過隨機(jī)抽樣覆蓋原表中的不同數(shù)據(jù)種類。經(jīng)驗(yàn)表明,大部分造成OSC與原生DDL行為不一致性的數(shù)據(jù)出現(xiàn)于表的開頭與結(jié)尾即邊緣數(shù)據(jù)??紤]到數(shù)據(jù)多樣性,在數(shù)據(jù)表中間部分也應(yīng)抽取少量樣本。樣本提取的具體做法是:在數(shù)據(jù)表中的前、中、后各取3 000條數(shù)據(jù)表項(xiàng)作為樣本,根據(jù)主鍵排序limit 3 000來獲得頭與尾的數(shù)據(jù)(通過主鍵索引并不會影響效率)。中間部分的數(shù)據(jù)由于無法獲得數(shù)據(jù)總量,只能對數(shù)據(jù)量進(jìn)行估算;若是數(shù)據(jù)型主鍵(多主鍵情況下只考慮最左主鍵),則對最小值和最大值取平均數(shù)作為中間數(shù)據(jù)起始點(diǎn);對于非數(shù)據(jù)項(xiàng)數(shù)據(jù),如日期型、字符串型,可以忽略中間樣本。獲得中間數(shù)據(jù)起始點(diǎn)后,通過主鍵排序以及l(fā)imit n,m語句可獲得中間部分?jǐn)?shù)據(jù)。但這樣會對整個(gè)表通過索引進(jìn)行半表掃描,通過where限定可以有效提高效率。
獲得最小主鍵:select key_name from original_ table order by key_name limit1;
獲得最大主鍵:select key_name from original_ table order by key_name desc limit 1;
獲得估算中間值:middle_num=(min_ num+max_num)/2;
獲得中間數(shù)據(jù):
insert into test_table
select*from original_table
order by key_name
limit middle_num,3000
where key_name>middle_name;
一般情況下,通過引入前置檢查確實(shí)可以避免OSC與原生DDL行為在執(zhí)行表結(jié)構(gòu)更新操作上的不一致性,但在某些極端情況下仍然存在不一致情形,比如,如果在進(jìn)行預(yù)檢查時(shí)表中無數(shù)據(jù),而檢查后對表中插入若干數(shù)據(jù)(加唯一索引列存在重復(fù)項(xiàng)),此時(shí)執(zhí)行OSC仍會出現(xiàn)上述問題,并且該問題難以通過編程解決。
2.4 多版本行為的一致性
MySQL不同版本之間存在差異,如果不對這些差異進(jìn)行處理,OSC系統(tǒng)在不同版本的MySQL執(zhí)行下會有行為不一致問題。
以MySQL 5.1.50為例,#Bug 56226導(dǎo)致My-ISAM引擎在alter table后binlog文件出錯(cuò)。官方描述”After ALTER TABLE without column size change,binlog gets corrupted since the tablemap is unexpectedly set to 0 in subsequent updates.The problem can be avoided by flushing table after ALTER TABLE command.The problem happens on MyISAM table only.”例如在test庫的t1表中進(jìn)行alter table操作,binlog日志記錄如下:
|binlog.000001|1329|Table_map|1|1371|table_id:0(test.t1)
|binlog.000001|1371|Update_rows|1|1419|table_id:0 flags:STMT_END_F
此時(shí),table_id被意外地設(shè)置為0,這對數(shù)據(jù)恢復(fù)、主從備份都有較大的影響。
為了在不同版本下的MySQL都能良好地運(yùn)行OSC系統(tǒng),需要針對不同的版本做出相應(yīng)的調(diào)整。主要有以下兩個(gè)方面:
對于MySQL 5.1.50之前的版本,在ALTER TABLE之后對表進(jìn)行FLUSH操作;在MySQL 5.6版本以后,由于內(nèi)置DDL Online operate,一些DDL操作運(yùn)用原生DDL較之OSC系統(tǒng)更具可靠性;所以,可以對DDL語句進(jìn)行智能判斷,若DDL Online operate操作能夠在不鎖表的情況下完成DDL操作,則選擇原生DDL進(jìn)行,否則繼續(xù)選擇OSC系統(tǒng)。
OSC通過將一條DDL語句分解為若干原子性步驟,有效緩解了原生DDL操作鎖表帶來的業(yè)務(wù)阻塞問題,可以應(yīng)用在具有容災(zāi)需求的一些復(fù)雜應(yīng)用場景中。下面將分析OSC在讀寫分離的主從架構(gòu)[11-12]和單元化架構(gòu)[13-14]下的應(yīng)用。
3.1 讀寫分離的主從架構(gòu)
簡單的讀寫分離主從架構(gòu)由一個(gè)中心服務(wù)器(主庫)和若干個(gè)單元服務(wù)器(從庫)組成,中心服務(wù)器主要負(fù)責(zé)寫操作,單元服務(wù)器負(fù)責(zé)讀操作,主從服務(wù)器都保存全部數(shù)據(jù)量。由于主從數(shù)據(jù)庫中的數(shù)據(jù)都是相同的,而從庫端無寫入操作。因此,觸發(fā)器的創(chuàng)建無須復(fù)制到從庫端,除了觸發(fā)器之外,所有其他DDL操作均需復(fù)制到從庫端,ghost表和dk表的數(shù)據(jù)也復(fù)制到從庫端。具體來說,在從庫端,無須執(zhí)行圖1中的第8)~第10)步驟。執(zhí)行主庫對ghost表、dk表的DDL語句就能保證從庫端ghost表、dk表與主庫端一致,在完成圖1的步驟14)后即可保證主從端數(shù)據(jù)一致性。所以,在配置復(fù)制任務(wù)時(shí),只需通過在從庫端執(zhí)行臨時(shí)表的創(chuàng)建,并且過濾掉從庫端觸發(fā)器相關(guān)的DDL操作即可。
圖3 讀寫分離的簡單主從架構(gòu)下從庫OSC系統(tǒng)
3.2 單元化架構(gòu)
單元化架構(gòu)是從并行計(jì)算領(lǐng)域發(fā)展而來。在分布式服務(wù)設(shè)計(jì)領(lǐng)域,一個(gè)單元(cell)就是滿足某個(gè)分區(qū)所有業(yè)務(wù)操作的自包含的安裝。而一個(gè)分區(qū)(shard),則是整體數(shù)據(jù)集的一個(gè)子集,如果你用尾號來劃分用戶,那同樣尾號的那部分用戶就可以認(rèn)為是一個(gè)分區(qū)。單元化就是將一個(gè)服務(wù)設(shè)計(jì)改造讓其符合單元特征的過程。
為了解決單機(jī)瓶頸問題,淘寶數(shù)據(jù)庫從最初的單機(jī)MySQL升級形成IOE架構(gòu)。近幾年,不斷擴(kuò)展的業(yè)務(wù)規(guī)模和用戶規(guī)模對數(shù)據(jù)庫的并發(fā)性、可用性和擴(kuò)展性等方面提出了更高的要求,阿里引入sharding的思想,將數(shù)據(jù)庫分布到多個(gè)物理節(jié)點(diǎn),讓多節(jié)點(diǎn)并發(fā)處理不同的寫請求。并且考慮到容災(zāi)需要,阿里內(nèi)部基于MySQL已建設(shè)完成了單元化架構(gòu)。
單元化式架構(gòu)由一個(gè)中心和若干單元組成,與簡單的讀寫分離架構(gòu)不同,單元化式架構(gòu)的中心、單元均能承擔(dān)讀寫業(yè)務(wù),中心保存100數(shù)據(jù)量,單元保存部分?jǐn)?shù)據(jù)量。在單元化式架構(gòu)中,DDL操作可以在中心,也可以在某個(gè)單元;每個(gè)單元保存部分?jǐn)?shù)據(jù),并且它們保存的數(shù)據(jù)不完全一樣。
由于單元化式架構(gòu)下各個(gè)單元保存數(shù)據(jù)的差異性,導(dǎo)致系列問題:1)圖1步驟11)中全量遷移的數(shù)據(jù),可能包括目的端不需要的數(shù)據(jù);2)步驟8)~步驟10)中由觸發(fā)器產(chǎn)生的增量數(shù)據(jù),可能并不是目的端需要的數(shù)據(jù);3)步驟8)~步驟12)中目的端也許有源端沒有的數(shù)據(jù),沒有正確地被遷移到ghost表中,刪除的primary key也沒有正確地被記錄到dk表;4)在步驟13)中,由于目的端的數(shù)據(jù)和源端數(shù)據(jù)不一樣,則不一樣的那一部分隨著rename操作而丟失。
總之,如果按照上面的OSC復(fù)制方案,目的端的表數(shù)據(jù)最終會變得和源端一模一樣。導(dǎo)致數(shù)據(jù)不一樣的主要是步驟8)~步驟12),因此這些步驟需要重構(gòu)。
步驟8)~步驟12)主要完成全量數(shù)據(jù)、增量數(shù)據(jù)的拷貝工作,ghost表和dk表數(shù)據(jù)不能像讀寫分離結(jié)構(gòu)下直接從源端復(fù)制過來,要直接從目的端生成,需要在配置復(fù)制任務(wù)時(shí)加入數(shù)據(jù)同步黑名單中,即在源端的ghost表與dk表的DDL操作不復(fù)制到目的端。由于增量數(shù)據(jù)部分主要由步驟8)~步驟10)這3步所建的3個(gè)trigger產(chǎn)生的,所以只需要在目的端同步這3個(gè)trigger的創(chuàng)建操作,目的端就可以直接產(chǎn)生自己的增量數(shù)據(jù)到ghost表和dk表。
步驟11)主要是搬遷原表的全量數(shù)據(jù)到ghost表,我們需要將這個(gè)搬遷邏輯在目的端按照源端一樣的邏輯規(guī)則搬遷,但不是直接復(fù)制源端的數(shù)據(jù),因此需要復(fù)制源端全量遷移的算法在目的端執(zhí)行。這個(gè)算法是OSC實(shí)現(xiàn)的,因此有如下兩種方法可以實(shí)現(xiàn)算法的搬遷:
1)將OSC的全量遷移算法代碼集成到復(fù)制數(shù)據(jù)的中間件中,這樣在目的端就可以按照這個(gè)邏輯來實(shí)現(xiàn)數(shù)據(jù)全量遷移;
2)將OSC的全量遷移算法代碼從源端往目的端復(fù)制,一個(gè)可行的方法是,將算法以MySQL的存儲過程來實(shí)現(xiàn),然后OSC以創(chuàng)建存儲過程的形式將算法復(fù)制到目的端。
OSC技術(shù)是解決企業(yè)數(shù)據(jù)庫日常運(yùn)維過程中鎖表之痛的實(shí)用工具,在OSC技術(shù)之前,企業(yè)在運(yùn)維數(shù)據(jù)庫過程中如果要對表結(jié)構(gòu)有變更需求,一般只能選擇在業(yè)務(wù)低峰期去變更或在主備架構(gòu)下分次變更,這對運(yùn)維工作帶來了極大的不便。雖然MySQL官方也一直致力于解決此類問題,相繼推出Fast Index Creation和DDL Online Operate功能,但仍然不能徹底解決全部的DDL鎖表問題。OSC系統(tǒng)依舊是未來一段時(shí)間內(nèi)解決DDL操作鎖表問題的不可或缺的手段。
雖然OSC技術(shù)思想簡單,但在實(shí)際運(yùn)用過程中由于業(yè)務(wù)場景的復(fù)雜性,以及表變更需求的多樣化,往往會出現(xiàn)一系列問題,如OSC變更與原生DDL變更行為不一致。本文針對OSC在實(shí)際應(yīng)用過程中遇到的系列問題,提出了相應(yīng)的改進(jìn)方法,并對兩種典型的復(fù)雜應(yīng)用場景下OSC系統(tǒng)的應(yīng)用進(jìn)行分析。
[1]AXMARK D,LARSSON A,WIDENIUSM,et al.MySQL 5.0 reference manual[M].first edition.Sweden:MySQLAB,2006,56-200.
[2]AXMARK D,LARSSON A,WIDENIUS M,et al. MySQL internals manual[M].Sweden:MySQLAB,2006.32-135.
[3]Paul DuBois.MySQL技術(shù)內(nèi)幕[M].楊曉云,王建橋,楊濤,譯.4版.北京:人民郵電出版社,2011.
[4]NOACH Shlomi.Online schema change[Z/OL].America:Facebook,2010.https://code.google.com/p/openarkkit/.
[5]MySQL 5.5 Reference Manual.InnoDB Fast Index Creation[EB/OL].[2016-02-12].http://dev.mysql.com/doc/refman/5.5/en/innodb-create-index.htm l,2015.
[6]姜承堯.MySQL技術(shù)內(nèi)幕:InnoDB存儲引擎[M].北京:機(jī)械工業(yè)出版社,2011.
[7]陳小輝,文佳,鄧杰英.MySQL的體系結(jié)構(gòu)及InnoDB表引擎的配置[J].福建電腦,2009,25(7):162-162.
[8]MySQL 5.6 Reference Manual.DDLOnline Operate[EB/OL].[2016-02-12].http://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.htm l,2015.
[9]MySQL 5.6 Reference Manual.Limitations of online DDL[EB/OL].[2016-02-12].http://dev.mysql.com/doc/refman/5.6/en/innodb-create-indexlimitations.htm l,2015.
[10]MySQL 5.6 Overview of Online DDL[EB/OL].[2016-02-12].http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.htm l,2015.
[11]沙光華,陳泳,張長江.讀寫分離技術(shù)在運(yùn)營支撐系統(tǒng)中的應(yīng)用[J].計(jì)算機(jī)工程與應(yīng)用,2015,51(12):107-110.
[12]劉小俊,徐正全,潘少明.一種讀寫分離的分布式元數(shù)據(jù)管理方法——以“數(shù)字城市”應(yīng)用為例[J].武漢大學(xué)學(xué)報(bào)(信息科學(xué)版),2013,38(10):1248-1252.
[13]華竹軒,王桂榮,徐楠,等.支持海量數(shù)據(jù)的分布式數(shù)據(jù)庫架構(gòu)設(shè)計(jì)與驗(yàn)證[J].河南科學(xué),2014(9):1719-1725.
[14]梁宇鵬.單元化架構(gòu),為什么要用以及我們?nèi)绾巫龅剑跡B/OL].[2016-02-12].http://www.infoq.com/cn/articles/how-weibo-do-unit-architecture,2014.
表1 實(shí)際與計(jì)算對比
圖6 實(shí)際效果圖
本文開發(fā)的智能輔助飲食系統(tǒng)可以幫助無臂殘疾人進(jìn)行自主飲食。本系統(tǒng)對二值化圖像進(jìn)行數(shù)字圖像處理,由算法可進(jìn)行嘴部定位,精度較高,全程通過語音進(jìn)行交互,減少了系統(tǒng)的使用難度。該系統(tǒng)具有自動添水和溫度異常警告功能。另外本系統(tǒng)還具有良好的可拓展性,可以在未來進(jìn)行功能的添加和結(jié)構(gòu)的改進(jìn)。
參考文獻(xiàn)
[1]潘松.黃繼業(yè).陳龍.EDA技術(shù)與Verilog HDL[M].北京:清華大學(xué)出版社,2010.
[2]李朝青.單片機(jī)原理及接口技術(shù)[M].北京:北京航空航天大學(xué)出版社,2005.
[3]王曉明.電動機(jī)的單片機(jī)控制[M].北京:北京航空航天大學(xué)出版社,2011.
[4]朱文佳.戚飛虎.快速人臉檢測與特征定位[J].中國圖像圖形學(xué)報(bào),2005,10(11):1454-1457.
[5]王軍南.叢爽.基于視覺定位的二自由度機(jī)械臂控制系統(tǒng)[J].機(jī)械與電子,2008(2):49-52.
[6]張培仁.楊興明.機(jī)器人系統(tǒng)設(shè)計(jì)與算法[M].安徽;中國科學(xué)技術(shù)大學(xué)出版社,2008.
[7]薛丹丹.基于眼和嘴定位的人臉歸一化算法研究[J].電子測試,2012(9);53-57.
[8]徐光輝.程東旭.黃如.基于FPGA的嵌入式開發(fā)與應(yīng)用[M].北京:電子工業(yè)出版社,2006.
[9]江國強(qiáng).SOPC技術(shù)與應(yīng)用[M].北京:機(jī)械工業(yè)出版社,2006.
[10]彭澄廉.挑戰(zhàn)SoC——基于Nios的SOPC設(shè)計(jì)與實(shí)[M].北京:清華大學(xué)出版社,2004.
The Improvement and Application of Online Schema Change
WANG Xuemei,ZHANG Shaobo
(College of Computer Science,Nanjing University of Posts and Telecommunications,Nanjing 210003,China)
To solve the business blocking problem caused by DDL operation in MySQL database,an online schema change(OSC)method is implemented with non-blocking operation in reading and writing transactions.Considering the availability requirement of the electronic commerce database on the read and write transaction,OSC system divides atomic DDL statements into several successive steps,creates a temporary ghost table to make a copy of all data from the original table fragment by fragment,and adopts triggers to ensure data consistency incrementally,so as to realize schema change with non-lock and solve the problem of business long time blocking.In addition,aiming at solving the problems of the OSC system encountered in practical applications,a series of solutions are presented,such as pre-detection,concurrency execution prevention etc.Moreover,combined with the Taobao's database architecture,the analysis on the OSC's application in complex business scenarios is provided.
data consistency;ghost table;online schema change;trigger
TP311.1
A
10.3969/j.issn.1672-4550.2016.06.019
2016-03-03;修改時(shí)間:2016-03-16
江蘇省研究生創(chuàng)新計(jì)劃(CXZZ13_0476);南京郵電大學(xué)校級科研基金(NY215169)。
王雪梅(1978-),女,碩士,講師,主要從事現(xiàn)代通信網(wǎng)絡(luò)、信息處理技術(shù)的研究工作。和步驟14)對原表進(jìn)行了可忽略的輕量級鎖表操作,其余操作規(guī)避了對原表的鎖表行為,從而達(dá)到避免阻塞業(yè)務(wù)讀寫的目的。與MySQL5.6的新特性DDL Online Operate相比,OSC不依賴于某個(gè)具體的存儲引擎,具有更為廣泛的適用性;例如,DDL Online Operate無法完成對表進(jìn)行存儲引擎的更改以及列類型的變化,但OSC系統(tǒng)卻可以做到。詳細(xì)的Summary of Online Status for DDL Operations,見MySQL5.6官方文檔14.10.1 Overview of Online DDL[10],該表記錄了DDL Online Operate的適用范圍。
實(shí)驗(yàn)科學(xué)與技術(shù)2016年6期