1. 程式人生 > >MySQL 不停服務 線上進行100億資料遷移切換

MySQL 不停服務 線上進行100億資料遷移切換

背景:

促銷庫壓力巨大,單例項已經不足以提供寫入效能,雖然有256個分表,但是經常io打滿,總資料量已經達到100億,單例項io已經支撐不住,所以方案是從促銷庫裡面遷移2張壓力大的業務分表到新的16個例項裡面,2張分表的個數大概是256個,剩餘的3000多個表不遷移,任留在原庫,要求是儘量不停服,把影響儘量限制在這遷移的分表的業務上面。

大概思路是,鎖這些遷移的分表,停止這些分表業務,然後把業務遷移到新的16個例項上,在新的例項上功能測試ok,手動kill原庫上因為lock write而阻塞的sql執行緒,然後unlock加的分表鎖。

大概流程是:

1)鎖住256個表的write指令碼準備,停止分表的業務;

(2
)停止資料原庫到16個新例項的資料同步功能; (3)rename新例項的分表,將名字統一改成業務的xxx_2049 ... xxx_2065; (4)啟動分表的業務,配合開發人員觀察業務功能,同時觀察原庫的cpu壓力,如果壓力過高,直接kill因為加鎖而導致的阻塞的sql執行緒; (5)功能ok後,先kill掉加鎖後阻塞的sql執行緒,然後kill加鎖的操作記錄;

指令碼準備:


生成鎖表指令碼locktablessql.sh

#!/bin/bash
for((i=0;i<128;i++))
do
insno=`expr $i % 16`
tbno_add=`expr $i / 16
+ 1025 ` echo "lock tables coupon_$i write;" >>"sql/locktables1.sql" done for((i=0;i<128;i++)) do insno=`expr $i % 16` tbno_add=`expr $i / 16 + 1025 ` echo "lock tables coupon_record_$i write;" >>"sql/locktables1.sql" done


執行鎖表操作指令碼run_locktables.sh

cat sql/locktables1.sql |while read
sql; do mysql -h172.20.xxx.xxx -uroot -pxxxxxx promotion -e "$sql select sleep(10000);" & done


kill阻塞執行緒指令碼kill_online_lock_sql.sh

#!/bin/bash
host=172.20.xxx.xxx
user=root
pwd=xxxx
mysql -h$host -u$user -p$pwd promotion -N -e "select concat('kill ',id,';') from information_schema.processlist where info like ('%coupon_%' ) and time >30" |grep kill > sql/killonline.sql
mysql -h$host -upromotionapi -pxxxxxx promotion < sql/killonline.sql


LOCK方式選擇

用lock tables coupon_record_$i write;不用flush tables coupon_$i with read lock;主要是因為flush table需要清空以前執行的連結,否則會報錯。