1. 直接添加字段
ALTER TABLE my_table ADD name VARCHAR(64) DEFAULT '' COMMENT '名字' ;
方法適合十幾萬的數據量,可以直接進行加字段操作,但是,線上的一張表如果數據量很大,執行加字段操作就會鎖表,這個過程可能需要很長時間甚至導致服務崩潰,那么這樣操作就有風險。
2. 臨時表方式
① 創建一個臨時的新表,首先復制舊表的結構(包含索引);
create table my_table_copy like my_table;
② 給新表加上新增的字段,注意,此時新表是空表,加字段很快;
③ 復制舊表數據到新表;
insert into my_table_copy(id,age) select id,age from my_table;
④ 刪除舊表,重命名新表的名字為舊表的名字
不過這里需要注意,執行第三步的時候,可能這個過程也需要時間,這個時候有新的數據進來,所以原來的表如果有字段記錄了數據的寫入時間就最好了,可以找到執行這一步操作之后的數據,並重復導入到新表,直到數據差異很小。不過還是會可能損失極少量的數據。
所以,如果表的數據特別大,同時又要保證數據完整,最好停機操作。
3. 使用pt-online-schema-change
3.1 介紹
pt-online-schema-change是percona公司開發的一個工具,在percona-toolkit包里面可以找到這個功能,它可以在線修改表結構
3.2 原理
- 首先它會新建一張一模一樣的表,表名一般是
_為前綴_new后綴,例如原表為t_user臨時表就是_t_user_new - 然后在這個新表執行更改字段操作
- 然后在原表上加三個觸發器,
DELETE/UPDATE/INSERT,將原表中要執行的語句也在新表中執行 - 最后將原表的數據拷貝到新表中,然后替換掉原表
SQL語句:
ALTER TABLE tmp_task_user ADD support tinyint(1) unsigned NOT NULL DEFAULT '1';
工具命令:
sh pt.sh tmp_task_user "ADD COLUMN support tinyint(1) unsigned NOT NULL DEFAULT '1'"
好處:
- 降低主從延時的風險
- 可以限速、限資源,避免操作時MySQL負載過高
建議:
- 在業務低峰期做,將影響降到最低
- 刪除索引后再修改表結構,效率將大大提升
安裝步驟參考:
