MySQL修改表結(jié)構(gòu)時(shí)的拷貝問題
MySQL修改表結(jié)構(gòu)時(shí)難免會出現(xiàn)問題,而MySQL修改表結(jié)構(gòu)時(shí)拷貝的時(shí)間嚴(yán)重影響了MySQL修改表結(jié)構(gòu)的操作,下面就對該問題進(jìn)行分析。
mysql數(shù)據(jù)庫里,對一個(gè)已創(chuàng)建的表進(jìn)行DDL操作,比如說添加一個(gè)字段。在做測試時(shí),發(fā)現(xiàn)ddl操作的時(shí)間特別的長。oracle里,通常情況下只是修改數(shù)據(jù)字典就可以了,操作時(shí)間非常的短,阻塞DML的時(shí)間也比較短。mysql數(shù)據(jù)庫對表進(jìn)行ddl操作跟oracle數(shù)據(jù)庫有很大的不同,它先要把原表拷貝一份到臨時(shí)表,這期間不阻塞select,阻塞所有的更改操作(update,delete,insert),對臨時(shí)表ddl操作完成,刪除原表,重命名臨時(shí)表。
如果一張比較大的表進(jìn)行ddl變更,比如說40G,那拷貝的時(shí)間讓人無法忍受,并且阻塞所有的DML操作,讓業(yè)務(wù)無法繼續(xù)。
以下是測試過程:
- [coolcode]
- mysql> desc t1;
- +————–+————-+——+—–+———+——-+
- | Field | Type | Null | Key | Default | Extra |
- +————–+————-+——+—–+———+——-+
- | id | int(11) | YES | MUL | NULL | |
- | nick | varchar(32) | YES | | NULL | |
- | email | varchar(32) | YES | | NULL | |
- | gmt_create | datetime | YES | | NULL | |
- | gmt_modified | datetime | YES | | NULL | |
- +————–+————-+——+—–+———+——-+
- mysql> select count(*) from t1;
- +———-+
- | count(*) |
- +———-+
- | 2228017 |
- +———-+
- 1 row in set (1.78 sec)
- [/coolcode]
- 現(xiàn)在對它進(jìn)行表結(jié)構(gòu)變更,增加一列:
- [coolcode]
- mysql> alter table t1 add(tel varchar(20));
- Query OK, 2304923 rows affected (41.03 sec)
- Records: 2304923 Duplicates: 0 Warnings: 0
- [/coolcode]
- 在上述表結(jié)構(gòu)變更過程中,啟動另外一個(gè)會話,進(jìn)行select查詢操作和一個(gè)更新操作:
- [coolcode]
- mysql> select count(*) from t1;
- +———-+
- | count(*) |
- +———-+
- | 2304923 |
- +———-+
- 1 row in set (2.10 sec)
- mysql> select * from t1 limit 10;
- +——+——-+——————+———————+———————+
- | id | nick | email | gmt_create | gmt_modified |
- +——+——-+——————+———————+———————+
- | 0 | nick0 | nick0@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 1 | nick1 | nick1@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 2 | nick2 | nick2@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 3 | nick3 | nick3@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 4 | nick4 | nick4@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 5 | nick5 | nick5@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 6 | nick6 | nick6@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 7 | nick7 | nick7@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 8 | nick8 | nick8@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- | 9 | nick9 | nick9@taobao.com | 2008-03-14 00:00:00 | 2008-03-14 00:00:00 |
- +——+——-+——————+———————+———————+
- 10 rows in set (0.00 sec)
- mysql> update t1 set nick=’test_nick’ where id=1;
- Query OK, 4 rows affected (43.89 sec) –這里是阻塞的時(shí)間
- Rows matched: 4 Changed: 4 Warnings: 0
- [/coolcode]
通過以上實(shí)驗(yàn)可以看出,對表進(jìn)行ddl操作時(shí),mysql并不阻塞select查詢,但會嚴(yán)重阻塞dml操作。另外,如果你要對表進(jìn)行ddl操作,由于有一個(gè)拷貝操作,你要計(jì)算好你的可用空間夠不夠?如果你的系統(tǒng)經(jīng)常要進(jìn)行MySQL修改表結(jié)構(gòu),那么你將不得不要考慮此問題!
【編輯推薦】