我们知道在SqlServer实例启动过程中数据库会进行还原(Redo,Undo)然后打开提供服务,但我们知道tempdb是不提供重做机制的(Redo)那tempdb是如何还原的呢?如果tempdb损坏我们该怎么办,这里我将通过实例给大家介绍.
有时tempdb因为一些原因会变得非常巨大,一些DBA的解决方式就是重启数据库实例,的确重启后tempdb就会恢复到初始设置大小,理由很简单tempdb会重新创建.
Tempdb的创建过程.
1在model库打开后进行tempdb创建(可以日志中看到model总是在tempdb之前打开)
2从model库中拷贝extent(s)到tempdb主文件并根据master库中的meta data信息创建tempdb主数据文件(Mdf)
3 根据master中定义tempdb的主文件大小填充主文件
4 根据master中定义的主日志文件大小创建日志文件
5 创建,附加其他文件
注:如果tempdb不能创建,则实例shutdown
这里我们做个测试在model库中简单的创建一个表然后重启实例
code
use model create table t1(id int)
重启实例后我们可以发现tempdb中也存在表t1 如图1-1,其实就是tempdb启动时主文件要从model中拷贝扩展区(extent).我们甚至可以分析相应的数据页,可以看到相应的数据页tempdb与model是完全一致的.感兴趣的朋友可以自行尝试.
图1-1
问题来了,我们可以看到tempdb是先通过master确定文件位置,大小的,如果启动过程中从master库中获得位置的磁盘损坏或者不存在,那么tempdb将无法创建,实例也就无法启动,这将是一个实例级问题,影响严重.
此时我们可以使用trace flag 3608在只还原master的情形下启动实例,并进行相应调整,然后重新启动数据库.
注意:tf3608启动数据库时是个极其特殊的情形,这时我们最好使用最小配置启动(/f),以避免对数据库造成其他的意外操作(损坏)
最小配置启动 /f
a.单用户模式
b.无法检查点(checkpoint)
c.不支持远程访问及预读
d.禁止启动执行Proc
模拟故障
1 将tempdb文件修改到其他盘符
2 重新启动时disable相应盘符,则sql server无法启动 如图1-2
Code
Alter Database tempdb Modify File (Name = ‘tempdev‘, FileName = ‘E:\tempdb.mdf‘) Alter Database tempdb Modify File (Name = ‘templog‘, FileName = ‘E:\templog.ldf‘)
图1-2
这种情况下数据库实例是无法正常启动的我们可以用先前提到的tf3608在只还原master的情形下最小化配置/f启动,然后做相应修改.
注意:最小化配置启动由于是单用户模式,启动前我们应该关闭与实例相关的进程.(如sqlagent) 否则将用户将无法访问实例
处理步骤
1 Code(Dos下),或是配置管理器中配置启动参数
Net start mssqlserver /t3608 /f
2用sqlcmd以管理员链接方式进入实例执行相关调整,具体信息如图1-3
sqlcmd -A -S localhost -q"Alter Database tempdb Modify File (Name = ‘tempdev‘, FileName = ‘D:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\tempdb.mdf‘);" sqlcmd -A -S localhost -q"Alter Database tempdb Modify File (Name = ‘templog‘, FileName = ‘D:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\templog.ldf‘,);"
3调整完毕后重新启动数据库
图1-3
这样我们就在特定情形中完成了对tempdb的调整.
关于tempdb日志
我们都知道日志文件是不能进行及时初始化的.所以最好预先设定其大小,避免导致其因为文件增长造成的tempdb性能瓶颈.
结语
现实中由于tempdb的特定角色导致其很可能成为性能瓶颈,有些应用者基于性能考量将tempdb放入特定磁盘上如SSD,由于tempdb的工作特点,导致其复写率可能非常高,这样基于SSD的擦写特点造成其寿命较短,这样就造成了库损坏问题,这类问题需要是可以防范的,但如果被动响应,我们仍可采用相关手段处理.