问题是这样产生的,有一个同学问一次性操作(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 的事务变得小一点,至少这样有利于减少系统磁盘空间的浪费,尤其在事务失败,或者回滚的情形下,当然回滚的时间也会缩短,避免产生更多的锁,影响系统的性能。