DDL Schema變更之添加列有默認(rèn)值時(shí)處理

對(duì)于NewSQL而言,是有表的概念的,即schema的概念枕磁。NewSQL以單獨(dú)的SQL層接入用戶的SQL請(qǐng)求,進(jìn)行Parse术吝、Logic Plan计济、Physical Plan,之后將對(duì)應(yīng)的計(jì)劃排苍,下推到KV層進(jìn)行執(zhí)行沦寂。

TiDB Architecture

只要有表的存在,就會(huì)有DDL執(zhí)行淘衙,TiDB的在線schema 變更參考了Google F1 Online, Asynchronous Schema Change in F1
關(guān)于這篇論文的討論凑队,我們放在下一篇進(jìn)行分析,將結(jié)合代碼一起討論幔翰。

本篇先只討論單機(jī)情況下,加列并存在默認(rèn)值時(shí)是如何做的西壮,我們以TiDB為例遗增,分析如下場(chǎng)景。

考慮有表t1款青,有2列做修,id int primary key , age int . 并且插入2行數(shù)據(jù):

id age
1 18
2 19

現(xiàn)在要加入一列,叫 marriaged_age int default 26

alter table t1 ADD marriaged_age int default 26 ;

通常抡草,schema信息作為一個(gè)單獨(dú)的Key—Value對(duì)存儲(chǔ)在Kv層饰及,當(dāng)更新這張表的schema信息時(shí),也就是對(duì)這個(gè)key-value的更新康震,我們暫時(shí)不考慮分布式場(chǎng)景燎含。

id age marriaged_age
1 18 empty
2 19 empty

TiDB會(huì)將整行數(shù)據(jù)按照編碼格式編碼成一個(gè)字符串,作為value腿短。key的構(gòu)成格式請(qǐng)參考TiDB的key編碼

對(duì)于存量數(shù)據(jù)屏箍,本身是沒(méi)有這一列的信息的,那么就有兩種做法:

  1. 給存量數(shù)據(jù)的每一行填上這一列的值
  2. 不回填這些值橘忱,當(dāng)根據(jù)新的schema信息去解碼value時(shí)候赴魁,發(fā)現(xiàn)這一列的值是empty,則用schema信息中的default值作為這一列的value钝诚。返回給上層颖御。

TiDB采用第二種方法.

在alter table之后插入的數(shù)據(jù),marriaged_age 這一列無(wú)論是否insert時(shí)候指定凝颇,都會(huì)有一個(gè)對(duì)應(yīng)的值潘拱。

insert into t1 values(3,20);
insert into t1 values(4,22,28);

新插入的數(shù)據(jù)和舊數(shù)據(jù)如下:

id age marriaged_age
1 18 empty
2 19 empty
3 20 26
4 22 28

若這時(shí)疹鳄,對(duì)marriaged_age列的default值再次進(jìn)行修改時(shí):

alter table t1 CHANGE marriaged_age marriaged_age int default 24 ;

此之后插入的數(shù)據(jù)該列的值默認(rèn)值就是24了。

insert into t1 values(5,26);
insert into t1 values(6,27,30);

新插入的數(shù)據(jù)和舊數(shù)據(jù)如下:

id age marriaged_age
1 18 empty
2 19 empty
3 20 26
4 22 28
5 26 24
6 27 30

這時(shí)候泽铛,對(duì)于記錄id為(1尚辑,2)的marriaged_age值,究竟應(yīng)該解析成26盔腔?還是24呢杠茬?

當(dāng)然是26,因?yàn)樵诘谝淮蜠DL變更的時(shí)候(即添加marriaged_age弛随,就相當(dāng)于已經(jīng)對(duì)于存量數(shù)據(jù)做了回填瓢喉,第二次變更只能對(duì)其之后的插入操作造成影響!

TiDB是如何實(shí)現(xiàn)這樣的效果的呢舀透?

TiDB在存Schema信息的時(shí)候栓票,每個(gè)列的屬性中,有一個(gè) OriginalDefaultValue 和 DefaultValue

// model.go中愕够,對(duì)列屬性的描述

// ColumnInfo provides meta data describing of a table column.
type ColumnInfo struct {
    ID                  int64               `json:"id"`
    Name                CIStr               `json:"name"`
    Offset              int                 `json:"offset"`
    OriginDefaultValue  interface{}         `json:"origin_default"`
    DefaultValue        interface{}         `json:"default"`
    DefaultValueBit     []byte              `json:"default_bit"`
    GeneratedExprString string              `json:"generated_expr_string"`
    GeneratedStored     bool                `json:"generated_stored"`
    Dependences         map[string]struct{} `json:"dependences"`
    types.FieldType     `json:"type"`
    State               SchemaState `json:"state"`
    Comment             string      `json:"comment"`
    // Version means the version of the column info.
    // Version = 0: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in system time zone.
    //              That is a bug if multiple TiDB servers in different system time zone.
    // Version = 1: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in UTC time zone.
    //              This will fix bug in version 0. For compatibility with version 0, we add version field in column info struct.
    Version uint64 `json:"version"`
}

當(dāng)value解碼后走贪,存在有的列是empty,那么就采用OriginDefaultValue進(jìn)行填充惑芭。

OriginDefaultValue的存在就是為了保證那些在做DDL變更(這里特指ADD Column)之前的行坠狡,沒(méi)有這列數(shù)據(jù)的value能夠有默認(rèn)值填充。

而DefaultValue就表示的是當(dāng)下這列實(shí)時(shí)的default value值遂跟,以后對(duì)這列的default value 如果再有變更逃沿,那么只需要記錄在DefaultValue這個(gè)變量中就可以了。

感謝磊哥(呂磊)傾情指點(diǎn)

蕭然 2019-07-15 09:56

轉(zhuǎn)載請(qǐng)注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幻锁,一起剝皮案震驚了整個(gè)濱河市凯亮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哄尔,老刑警劉巖假消,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異究飞,居然都是意外死亡置谦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門亿傅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)媒峡,“玉大人,你說(shuō)我怎么就攤上這事葵擎×掳ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)签餐。 經(jīng)常有香客問(wèn)我寓涨,道長(zhǎng),這世上最難降的妖魔是什么氯檐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任戒良,我火速辦了婚禮,結(jié)果婚禮上冠摄,老公的妹妹穿的比我還像新娘糯崎。我一直安慰自己,他們只是感情好河泳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布沃呢。 她就那樣靜靜地躺著,像睡著了一般拆挥。 火紅的嫁衣襯著肌膚如雪薄霜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天纸兔,我揣著相機(jī)與錄音惰瓜,去河邊找鬼。 笑死汉矿,一個(gè)胖子當(dāng)著我的面吹牛鸵熟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播负甸,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼痹届!你這毒婦竟也來(lái)了呻待?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤队腐,失蹤者是張志新(化名)和其女友劉穎蚕捉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柴淘,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迫淹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了为严。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敛熬。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖第股,靈堂內(nèi)的尸體忽然破棺而出应民,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布诲锹,位于F島的核電站繁仁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏归园。R本人自食惡果不足惜黄虱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庸诱。 院中可真熱鬧捻浦,春花似錦、人聲如沸偶翅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)聚谁。三九已至母剥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間形导,已是汗流浹背环疼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朵耕,地道東北人炫隶。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阎曹,于是被迫代替她去往敵國(guó)和親伪阶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349