溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

mysql中pt-osc工具怎么用

發(fā)布時(shí)間:2021-11-06 09:46:56 來源:億速云 閱讀:260 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細(xì)講解有關(guān)mysql中pt-osc工具怎么用,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

使用方法:
pt-online-schema-change h=*,u=* p=**,P=* ,D=enk,t=my1 --alter"add is_sign_1 int(11) unsigned NOT NULL DEFAULT '0'"--drop-old-table [--sleep10]

pt-online-schema-change在線更改表結(jié)構(gòu)的實(shí)現(xiàn)核心有如下幾個(gè)過程:

(注:在跟改過程中涉及到三個(gè)表:原表、tmp_table即作為原表導(dǎo)數(shù)據(jù)的臨時(shí)表,old_table在最后rename 原表的結(jié)果表)


1、
CREATE TABLE `$db`.`$tmp_tbl` LIKE`$db`.`$tbl`" 
新建tmp_table,表結(jié)構(gòu)同原表


2、
在tmp_table上更改表結(jié)構(gòu)為需要的表結(jié)構(gòu)


3、
在原表上建立三個(gè)觸發(fā)器,如下:


(1)CREATETRIGGER mk_osc_del AFTER DELETE ON $table " "FOR EACH ROW " 


"DELETE IGNORE FROM $new_table ""WHERE$new_table.$chunk_column = OLD.$chunk_column";


(2)CREATETRIGGER mk_osc_ins AFTER INSERT ON $table " "FOR EACH ROW "


"REPLACEINTO $new_table ($columns) " 
"VALUES($new_values)";


(3)CREATETRIGGER mk_osc_upd AFTER UPDATE ON $table " "FOR EACH ROW "


"REPLACE INTO $new_table ($columns) ""VALUES ($new_values)";



我們可以看到這三個(gè)觸發(fā)器分別對(duì)應(yīng)于INSERT、UPDATE、DELETE三種操作,


(1)
mk_osc_del,DELETE操作,我們注意到DELETEIGNORE,當(dāng)新有數(shù)據(jù)時(shí),我們才進(jìn)行操作,也就是說,當(dāng)在后續(xù)導(dǎo)入過程中,如果刪除的這個(gè)數(shù)據(jù)還未導(dǎo)入到新表,那么我們可以不在新表執(zhí)行操作,因?yàn)樵谝院蟮膶?dǎo)入過程中,原表中改行數(shù)據(jù)已經(jīng)被刪除,已經(jīng)沒有數(shù)據(jù),那么他也就不會(huì)導(dǎo)入到新表中;


(2)
mk_osc_ins,INSERT操作,所有的INSERT INTO全部轉(zhuǎn)換為REPLACEINTO,為了確保數(shù)據(jù)的一致性,當(dāng)有新數(shù)據(jù)插入到原表時(shí),如果觸發(fā)器還未把原表數(shù)據(jù)未同步到新表,這條數(shù)據(jù)已經(jīng)被導(dǎo)入到新表了,那么我們就可以利用replaceinto進(jìn)行覆蓋,這樣數(shù)據(jù)也是一致的


(3)
mk_osc_upd
UPDATE操作,所有的UPDATE也轉(zhuǎn)換為REPLACEINTO,因?yàn)楫?dāng)跟新的數(shù)據(jù)的行還未同步到新表時(shí),新表是不存在這條記錄的,那么我們就只能插入該條數(shù)據(jù),如果已經(jīng)同步到新表了,那么也可以進(jìn)行覆蓋插入,所有數(shù)據(jù)與原表也是一致的;


我們也能看出上述的精髓也就這這幾條replaceinto操作,正是因?yàn)檫@幾條replaceinto才能保證數(shù)據(jù)的一致性


4、
拷貝原表數(shù)據(jù)到臨時(shí)表中,在腳本中使用如下語句


INSERT IGNORE INTO $to_table ($columns) "
"SELECT $columns FROM $from_table ""WHERE ($chunks->[$chunkno])",我們能看到他是通過一些查詢(基本為主鍵、唯一鍵值)分批把數(shù)據(jù)導(dǎo)入到新的表中,在導(dǎo)入前,我們能通過參數(shù)--chunk-size對(duì)每次導(dǎo)入行數(shù)進(jìn)行控制,已減少對(duì)原表的鎖定時(shí)間,并且在導(dǎo)入時(shí),我們能通過—sleep參數(shù)控制,在每個(gè)chunk導(dǎo)入后與下一次chunk導(dǎo)入開始前sleep一會(huì),sleep時(shí)間越長(zhǎng),對(duì)于磁盤IO的沖擊就越小


5、
Rename 原表到old表中,在把臨時(shí)表Rename為原表,


"RENAME TABLE `$db`.`$tmp_tbl`TO `$db`.`$tbl`"; 在rename過程,其實(shí)我們還是會(huì)導(dǎo)致寫入讀取堵塞的,所以從嚴(yán)格意思上說,我們的OSC也不是對(duì)線上環(huán)境沒有一點(diǎn)影響,但由于rename操作只是一個(gè)修改名字的過程,也只會(huì)修改一些表的信息,基本是瞬間結(jié)束,故對(duì)線上影響不太大


6、
清理以上過程中的不再使用的數(shù)據(jù),如OLD表




以上即為整個(gè)Percona OSC的過程,我們看到精華部分就觸發(fā)器那一塊,不過還有很多細(xì)節(jié)我未介紹,如:外鍵、記錄binlog(默認(rèn)情況是不記錄binlog的)等等,由于環(huán)境的復(fù)雜性,此工具還是有很多風(fēng)險(xiǎn),如以下幾個(gè)方面問題或者需要規(guī)避的一些問題:


1、
此工具不是原子操作,如果某一點(diǎn)失敗,不僅僅會(huì)留下很多中間過程的垃圾文件,而這些文件很難完全清理,并且如果有這些文件存在,那么就不能在次執(zhí)行OSC操作;


2、
在執(zhí)行時(shí),盡量避免有這個(gè)表的批量更新、鎖表、優(yōu)化表的操作,我們能想象的到,如果有鎖表、優(yōu)化表那么OSC是否還能正常執(zhí)行?


3、
如果存在主從結(jié)構(gòu),那么盡量在從庫先執(zhí)行,因?yàn)槿绻谥鲙靾?zhí)行完畢后在到從庫執(zhí)行,我們能想象,主庫字段多同步到從庫,會(huì)不會(huì)有問題呢?


4、
必須是單一列的主鍵或者單一唯一鍵,這樣我們?cè)趇nsert select *from分片時(shí),是不是能更好的處理量呢?


5、
不要有外鍵,盡管腳本經(jīng)過嚴(yán)格測(cè)試,但是是否還有bug,也未知,表的外鍵是不是會(huì)帶來更多的問題呢?


6、
在執(zhí)行之前,我們是不是要對(duì)磁盤容量進(jìn)行評(píng)估呢?因?yàn)镺SC會(huì)使用表的一倍以上空間。

關(guān)于“mysql中pt-osc工具怎么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI