mysql修改表结构大表_在线修改MySQL大表的表结构
由于某個臨時需求,需要給在線MySQL的某個超過千萬的表增加一個字段。此表在設(shè)計之時完全按照需求實現(xiàn),并沒有多余的保留字段。
我們知道在MySQL中如果要執(zhí)行ALTER TABLE操作,MySQL會通過制作原來表的一個臨時副本來工作。對于表結(jié)構(gòu)的修改在副本上施行,然后將新表替換原始表,此時會產(chǎn)生鎖表,用戶可以從原始表讀取數(shù)據(jù),而用戶的更新和寫入操作都會被lock,待新表準備好后寫入新表。
這對于在線的數(shù)據(jù)量較大的表來說是絕對無法容忍的,并且由于這種在線操作時間會很長,此時如果show processlist,會發(fā)現(xiàn)有若干的MySQL進程處于lock狀態(tài),當這種進程太多超過單臺服務(wù)器允許的MySQL進程數(shù),其它進程可能會被拒絕連接。
有哪些方案可以處理這個問題呢?
方案1、直接ALTER TABLE
這個方案只能說這僅僅是一種方案,在某些非實時在線或數(shù)據(jù)量較小時有較好的表現(xiàn)。
方案2、模擬數(shù)據(jù)庫修改表結(jié)構(gòu)的操作,在非數(shù)據(jù)庫層實現(xiàn)整個過程。
實現(xiàn)業(yè)務(wù)中對于數(shù)據(jù)的讀寫分離
創(chuàng)建一個已經(jīng)按需求修改好結(jié)構(gòu)的新表
修改業(yè)務(wù)邏輯,將讀操作指向舊表,將寫操作指向新表。如果讀舊表沒有,再讀新表,并將舊的數(shù)據(jù)寫入到新表,當然這一步寫入操作我們可以不用,我們可以在后臺做一個定時任務(wù)將舊數(shù)據(jù)同步到新表。
這種方案有一個較大的缺點,需要業(yè)務(wù)邏輯層配合實現(xiàn)數(shù)據(jù)的遷移,對于業(yè)務(wù)邏輯有修改,并且如果有多臺機器的話,需要一臺一臺的修改,較費時間,但是對于MySQL的兩種主要存儲引擎都適用。
按需求創(chuàng)建新表
針對原始表創(chuàng)建觸發(fā)器
對于原始表的更新操作都會被觸發(fā)器更新到新表中
把原始表中的數(shù)據(jù)復(fù)制到新表中
將新表替換舊表
fb的osc方案從數(shù)據(jù)庫層解決了方案2的問題,但是它僅支持InnoDB存儲引擎。
方案4、換一個思路,保留字段。
假設(shè)一切可以從頭再來,我們也許可以加多一些冗余字段,各個類型都加一些,備用。只是,回不去了!
方案5、再換一個思路,增加擴展表。
我們不在原有的表的基礎(chǔ)上修改了,以增加擴展表的方式,將新字段的數(shù)據(jù)寫入到擴展表中,修改業(yè)務(wù)邏輯,這些字段從新表中讀取。
志強同學說這是典型的維表結(jié)構(gòu)設(shè)計。
暫時解決了問題,如果這些字段后續(xù)使用頻率高的話,可能會有對后期維護或業(yè)務(wù)有一定的影響。
后記
基于現(xiàn)有的需求,只是需要記錄新的字段,所以采用了擴展表的方案。
轉(zhuǎn)載【http://www.phppan.com/2012/05/online-schema-change/】
問題描述
由于某個臨時需求,需要給在線MySQL的某個超過千萬的表增加一個字段。此表在設(shè)計之時完全按照需求實現(xiàn),并沒有多余的保留字段。
我們知道在MySQL中如果要執(zhí)行ALTER TABLE操作,MySQL會通過制作原來表的一個臨時副本來工作。對于表結(jié)構(gòu)的修改在副本上施行,然后將新表替換原始表,此時會產(chǎn)生鎖表,用戶可以從原始表讀取數(shù)據(jù),而用戶的更新和寫入操作都會被lock,待新表準備好后寫入新表。
這對于在線的數(shù)據(jù)量較大的表來說是絕對無法容忍的,并且由于這種在線操作時間會很長,此時如果show processlist,會發(fā)現(xiàn)有若干的MySQL進程處于lock狀態(tài),當這種進程太多超過單臺服務(wù)器允許的MySQL進程數(shù),其它進程可能會被拒絕連接。
有哪些方案可以處理這個問題呢?
方案1、直接ALTER TABLE
這個方案只能說這僅僅是一種方案,在某些非實時在線或數(shù)據(jù)量較小時有較好的表現(xiàn)。
方案2、模擬數(shù)據(jù)庫修改表結(jié)構(gòu)的操作,在非數(shù)據(jù)庫層實現(xiàn)整個過程。
實現(xiàn)業(yè)務(wù)中對于數(shù)據(jù)的讀寫分離
創(chuàng)建一個已經(jīng)按需求修改好結(jié)構(gòu)的新表
修改業(yè)務(wù)邏輯,將讀操作指向舊表,將寫操作指向新表。如果讀舊表沒有,再讀新表,并將舊的數(shù)據(jù)寫入到新表,當然這一步寫入操作我們可以不用,我們可以在后臺做一個定時任務(wù)將舊數(shù)據(jù)同步到新表。
這種方案有一個較大的缺點,需要業(yè)務(wù)邏輯層配合實現(xiàn)數(shù)據(jù)的遷移,對于業(yè)務(wù)邏輯有修改,并且如果有多臺機器的話,需要一臺一臺的修改,較費時間,但是對于MySQL的兩種主要存儲引擎都適用。
按需求創(chuàng)建新表
針對原始表創(chuàng)建觸發(fā)器
對于原始表的更新操作都會被觸發(fā)器更新到新表中
把原始表中的數(shù)據(jù)復(fù)制到新表中
將新表替換舊表
fb的osc方案從數(shù)據(jù)庫層解決了方案2的問題,但是它僅支持InnoDB存儲引擎。
方案4、換一個思路,保留字段。
假設(shè)一切可以從頭再來,我們也許可以加多一些冗余字段,各個類型都加一些,備用。只是,回不去了!
方案5、再換一個思路,增加擴展表。
我們不在原有的表的基礎(chǔ)上修改了,以增加擴展表的方式,將新字段的數(shù)據(jù)寫入到擴展表中,修改業(yè)務(wù)邏輯,這些字段從新表中讀取。
志強同學說這是典型的維表結(jié)構(gòu)設(shè)計。
暫時解決了問題,如果這些字段后續(xù)使用頻率高的話,可能會有對后期維護或業(yè)務(wù)有一定的影響。
后記
基于現(xiàn)有的需求,只是需要記錄新的字段,所以采用了擴展表的方案。
總結(jié)
以上是生活随笔為你收集整理的mysql修改表结构大表_在线修改MySQL大表的表结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 001_Mysql错误积累0
- 下一篇: unity json mysql_uni