废话就不说了,关于备份与恢复的理论知识参考其它博客。
1、建立测试数据库
2、查看刚创建的测试数据库的日志情况
从中可以看出来,新创建的测试数据库日志文件大小是0.5390625M,有2个分页,其中一个写有数据,另外一个分页还没有写数据。
3、建立测试数据表
GO
--建立测试数据表
CREATE TABLE test
(
id int IDENTITY(1,1) PRIMARY KEY,
content varchar(50)
)
go
4、查看建立测试数据表之后的日志情况
仔细对比该图与上图,细心的读者会发现日志文件大小还是0.5390625M,只是占的日志百分比增大了一点。这说明创建测试表这个事务的大小,还不足以让日志文件去自动增长,故日志总大小没有变。
5、再次向测试表中插入10000条测试数据
--向测试数据表中插入10000条数据
DECLARE @i int
SET @i = 1;
WHILE @i < 10001
BEGIN
INSERT INTO test(content) VALUES (@i);
SET @i = @i + 1;
END
6、查看插入10000条测试数据后的日志情况
细心的读者还是会发现,插入了10000条测试数据,但是日志文件大小还是没有变!这是为什么呢?
这要从上面插入10000条测试数据的语句看起,仔细分析下会发现那一段代码里面执行后实际上是提交了10000个比较小的事务,每个事务都很小,不足以让日志自动增长,而且目前该测试数据库尚未做过一次完整备份,sql server认为,既然你连一次完整备份都还没有做过,我就算把你这10000个事务都全部记录下来,你也没有参照物来重新执行这些事务,我记录它们也就是在白费力气,那干脆我就在日志空间不够的时候,把之前记录的日志空间给覆盖掉了算了!
7、delete掉测试表中的所有数据
--删除掉测试表中的这10000条数据
--因为有10000条数据,故此隐式事务比较大
DELETE FROM test
这次日志信息的情况会怎么样呢?通过上面的阐述,大家已经知道如果数据库还没有做过一次完整备份的话,之前的日志会在日志空间不够的时候被覆盖掉,按照这个理论,日志大小应该还是没有变,对不对呢?看下图:
哇,日志竟然增加到3M多了,而不是之前的0.53M了,看来上面的猜想是错的!那又是为什么呢?
delete from test,这一句,实际上是个比较大的事务,因为它实际上删除了10000条的数据嘛,在记录日志的时候,发现日志空间不够,而该数据库又还没有做过完整备份,那它就去覆盖其它事务的内容,抢了别人的地盘,但是因为它这个事务太大了,把别人的地盘都给抢了,都还放不下它,而且事务又必须遵循完整性的原则,它总不能去抢自己的地盘,去把自己记录的日志信息给覆盖掉了,那该怎么办呢?数据库日志就只有自动的增长了!
8、完整备份测试数据库
经过上面的阐述,相信大家已经知道了完整备份数据库的重要性了,我们这步就把测试数据库做一个完整备份,备份数据库是个很经常的操作,这里就不描述过程了。
9、再次在测试表中插入10000条测试数据
--再次插入10000条数据
DECLARE @i int;
SET @i = 1
WHILE @i < 10001
BEGIN
INSERT INTO test(content) VALUES(10000 + @i)
SET @i = @i + 1
END
之前有过10000条,但是被干掉了,这次又插进10000条,那目前为止测试表中有10000条记录。
这时候的日志信息将会是怎么样的呢?
上面已经论述过,这一段代码实际上会提交10000个比较小的事务,而且目前该数据库已经做过一次完整备份,sql server就没理由不顺序记录这10000个小事务,故数据库日志文件大小应该会增长(除非剩余空间足以容纳这10000个小事务)。对不对呢?看下图:
对不对呢?猜对了,呵呵!
光有完整的数据库备份,还不行,我们还需要经常的备份数据库的日志,下面我们就来备份一次测试数据库的日志。
10、备份数据库日志
很简单,不是吗?注意back type那里选择Transaction Log,而不是备份数据库!而且备份的日志文件的后缀名是trn。
11、模仿一些正常的数据库操作
比如删除掉2000条数据:
--删除掉前2000条数据
DELETE FROM test WHERE id < 12001
删除完之后,也就是模仿正常的数据库操作结束后,我们再备份一次数据库日志。该日志一会用来恢复这些正常的数据库操作。
之前10000条,现在删掉了2000条,那目前还有8000条。
12、又过了一段时间,再次模仿数据库的正常操作
比如,又插入了111条数据:
--再插入111条数据
DECLARE @i int;
SET @i = 1;
WHILE @i< 112
BEGIN
INSERT INTO test(content) VALUES(20000 + @i)
SET @i = @i + 1
END
我们再备份一次数据库日志,该日志一会用来恢复这批正常的数据库操作。
之前的8000条+本次插入的111条,目前有8111条。
13、又过了一段时间,我们不小心做了误删除
比如:不小心把测试表中的300条数据给干掉了!
--再删除掉3000条数据,此操作模拟误删除
DELETE FROM test WHERE id < 12301
怎么办呢?怎么把误删除的数据给找回来呢?
赶快记录下误操作时的时间,比如19:19,接着再做一次数据库日志备份,到此为止我们已经有3个数据库日志备份了。
14、利用完整数据库备份和日志备份恢复数据到某一个点
首先,先用之前完整数据库备份恢复当前数据库(最好把当前的数据库也备份一下)。如下图:
本来恢复数据库这个操作很简单,我不打算截图了,但是,上面有个选项很重要,故我还是截了出来给大家看一下,即上图中的三个单选选项,第一个选项表示恢复了,该数据库就可以用了,用是可以用了,但是我们备份的日志就没法在上面恢复了;第二个选择项表示,恢复完后,该数据库还不能够使用,即还不能连接上去做增删查改之类的操作,必须等相应的日志备份也恢复了,才能够使用。按我们目前的情况,我们选择第二个选择项。
点击ok之后,数据库恢复之后,还不能用,状态如下图所示:
15、使用备份的三个日志恢复之前的数据库事务
操作如下图:
这里的三个选择项同之前的三个选择项,如果是最后一个日志的话,就选择第一项,让数据库可用,如果不是的话,就继续选择第二项。
这里是设置之前备份的数据库日志恢复到哪个时间点。我们之前假设是在19:19的时候误删除数据的,那么这里就可以设置那天19:18。
这里表示是恢复最后一个日志了,选择第一个选项。
16、查看恢复后的数据库
按上面的操作,我们是恢复到了误删除数据前1分钟,我们误删除的时候有8111条数据,那么理论上我们去查看的时候应该也是8111条,是不是呢,我们来看一下:
是8111条记录,我们恢复成功了!