問題是這樣產生的,有一個同學問一次性操作(big transaction)對數據庫有什麼不好的地方,當然可以從很多地方來切入,某些BT 對數據庫的操作中的影響。
今天想從另一個方式來切入,看看BT對於數據庫有什麼不好的影響,這次我們從數據庫的存儲方面來切入,這個點一般來說對於BT 來說,鮮有人來從這個點來證明BT對於數據庫的不良的影響。
我們下面做一個 testing, 方法很簡單,你先要生成一個比較大的表,然後借用這張表來證明一些事情。
測試的表
CREATE TABLE `test` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` smallint(6) NOT NULL,
`work_years` smallint(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=162405 DEFAULT CHARSET=utf8 COMMENT='test'
擁有16萬條記錄的表,他佔用了大約12MB的磁盤空間,當然這都不是今天要說的問題
我們下面來做這個實驗
我們新生成一個表和test一樣,名字叫 disk_space ,並且將test 的數據灌入到disk_space中,當然這在一個事務裏面,並且一個10萬條的數據操作在一個事務裏面,不少developers 覺得這並不是一個問題。
然後我們將事務回滾rollback,當然數據庫很聽話,數據已經回滾,從上圖看,我們並沒有任何數據在disk_space表裏面。
那我們翻過來看一下存儲空間,按照原理來說我並不是 insert ---> delete 操作,按照想的,我的磁盤空間也不應該有存儲。
但實際上,disk_space 佔用了和test表一樣的數據存儲空間,並且不再釋放。除非你用其他的方式來讓他“吐出骨頭”。
有人說,那要是我不rollback,我kill 這個事務呢,在commit之前。
我們還是做這個實驗,但我們不rollback,也不commit 我們在操作完畢後,查出他的thread_id ,然後kill 這個session,從下圖看,當前操作的事務session 是 76 .
將這個76 號的session kill 掉
我們再看,磁盤的空間還是會被佔用。上圖已經說明,空間還是會被佔用。
通過上面的過程,可以證明如果運行BT的過程,並且是DML 的操作,則很可能會出現磁盤空間被浪費從系統的層面。
實際上這些空間還是會被重新利用的。
所以從上面的例子,看
儘量將DML 的事務變得小一點,至少這樣有利於減少系統磁盤空間的浪費,尤其在事務失敗,或者回滾的情形下,當然回滾的時間也會縮短,避免產生更多的鎖,影響系統的性能。