很久没有执行过Backup database的语句了,想想上次客户那里执行backup还是去年10月份的事情。当时发现SQL Server 2008中的backup compression是一个很不错的功能,可以省去购买Lite Speed的成本了(虽然那个东西也不贵),不但能够提升备份的速度还可以减少备份文件的尺寸,节约空间就是节约成本(节约的成本要是能够把50%分给个人就好了)。今天讲课时突然想到,如果压缩遇到其他的SQL特性会如何。
备份压缩要是遇到表压缩空间和速度观察了一下,没有太对变化,当然不可能用户对所有的表都压缩(我测试的数据库只有1个表,选择了行压缩和页压缩)。
use bk01
go
create table t0
(id int identity(1,1), d datetime2)
go
use bk02
go
create table t1
(id int identity(1,1), d datetime2)
go
declare @i int=100000
while(@i>0)
begin
insert bk02.dbo.t1 values(SYSDATETIME())
insert bk01.dbo.t0 values(SYSDATETIME())
set @i-=1
end
backup database bk02 to disk='e:\bk02_notablecompression_nobackupcompression.bak'
backup database bk02 to disk='e:\bk02_notablecompression_backupcompression.bak' with compression
backup database bk01 to disk='e:\bk01_tablecompression_nobackupcompression.bak'
backup database bk01 to disk='e:\bk01_tablecompression_backupcompression.bak' with compression
运行结果是
tablecompression_backupcompression 811KB
tablecompression_nobackupcompression 3162KB
notablecompression_backupcompression 640KB
notablecompression_nobackupcompression 3731KB
表压缩对于减少备份压缩没有太多帮助。
如果备份压缩遇到TDE,感觉备份文件的大小没有什么变化,这个应该和文件的内容有关系。例如文本文件和视频文件的压缩比会差很多,文本文家加密后的压缩比就与视频文件的比较类似了。TDE是在存储文件的内容上进行的加密,原来SQL Server的文件都是明文的,存在可以压缩的规律,但是加密后数据没有什么规律,这样备份压缩就起不到太大作用,而且还会带来额外的CPU开销。
TDE和备份压缩建议不要一起使用。
这几天项目中遇到了一些棘手的问题,除了过程的苦恼外,又是环境,晕呀。。。
我们的程序需要在运行时迁移用户配置文件,这个操作可以有很多方法来实现,最安全的方式是使用USMT来做,但是这个方案不太可行,需要占用大量的磁盘空间用来复制配置文件中的所有文件。次选方案是使用Moveuser.exe来实现,这个方案也相对安全,但是需要使用额外的程序来支持。最后的方案就是更改用户注册表,在HKML\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\{sid}\ProfileImagePath记录着用户的配置文件路径,只需要为新的用户创建相应的键值并复制路径即可,这个方法非常快捷,但是前提是,新用户具有本地管理员权限,否则新的用户无法读取用户配置文件。
在用户的生产环境中发现他们有一部分机器中的用户配置文件夹的管理员权限被删除了,在程序操作前必须先验证Administrators组是否对于配置文件夹有权限。使用FSO来处理基本上很难,因为当前运行的用户肯定有权限,需要模拟Administrators组的用户(还要先建立一个账号在Administrators组中,否则无法知道Administrator的密码),然后判断是否可以读写文件来判断,这种方法不但复杂而且也不完全可用,毕竟NTFS权限不止有Write\Read\Delete。
VB code
Dim objWMIFileSecSetting
Set objWMIFileSecSetting = GetObject("winmgmts:Win32_LogicalFileSecuritySetting.path='C:\\Testapp\\PermissionCheckTest\\TestFolder2'")
Dim intRetVal As Integer
Dim wmiSecurityDescriptor
intRetVal = objWMIFileSecSetting.GetSecurityDescriptor(wmiSecurityDescriptor)
If Err.Number = 0 Then
Dim wmiAce
For Each wmiAce In wmiSecurityDescriptor.DACL
MsgBox "Access Mask: " & wmiAce.AccessMask
MsgBox "Trustee Name: " & wmiAce.Trustee.Name
Next
Else
MsgBox Err.Number & " " & Err.Description
End If
在WMI中提供了Win32_LogicalFileSecuritySetting这个类可以用来获取对于文件或文件夹权限的安全描述,在DACL中定义了ACE(访问控制项),可以通过读取访问控制项中的Trustee.Name来获取用户名称,AccessMask用于获取用户的访问控制掩码,这样我们就可以很方便的检查用户的NTFS权限。
参考资源:
Win32_LogicalFileSecuritySetting
Win32_SecurityDescriptor
Win32_ACE
我这个人的技术领域搞的比较多,SE\DEV\DBA都能做做,时间长了发现见的东西多了,Desgin Solution反而成了最喜欢做的事情。
最近在一个项目中很郁闷,技术上到没什么太多的问题,关键是环境,用户的生产环境和测试环境差很多,网络状况更是非常的复杂,导致客户也无法正确的评估工作量和项目的金额,这个项目没怎么挣到钱,但是经验获取了不少。
国内的SE就是SE,一点code都不懂,DEV就是DEV,一点Server的东西都不懂,这个项目就是一个典型的SE+DEV的项目。用户功能其实很简单就是将计算机加入域,并且迁移用户配置文件。这种工作以前都是通过写脚本执行的,当然脚本的功能还是稍微弱了一点,而且UI上不是非常的理想。没办法了,只能使用VB6来做(当你了解的.net以后让你用vb6写程序是一件很痛苦的事情),毕竟不保证每个客户端都有.net framework。程序主要就是调用ADSI和+WMI来实现用户验证、OU判断、计算机名称判断、更改注册表之类的功能,但是这些功能中很多都是需要和AD进行交互。
WMI估计很多人都使用过,可以使用WMI来操作本地或远程的计算机,执行操作或查询信息,里面的CIM模型也都是通用的,只不过MS基于CIM模型实现了自己的一些Win32 CLASS,可以管理NT4以后的计算机,当然9x的也可以,但是要安装WMI Core组件。
ADSI就是一个接口,根据不同的Provider来访问不同的系统信息,例如LDAP\WinNT\IIS等,当然不同接口也有一些区别。访问AD可以使用WinNT和LDAP。WinNT使用的是SAM数据库的方式,一种在Windows NT时代的Secruity Account Management数据库,平面没有层次的可以通过Domain\Name,class,例如contoso\bob,user,来定位一个用户,书写简单。LDAP也已访问AD,但是使用DN来定位对象,例如CN=bob,OU=UserAccounts,DC=Contoso,DC=com,书写比较麻烦。使用WinNT Provider无法制定DC,因为在NT时代,只能访问PDC来修改数据,但是LDAP可以制定特定的DC,因为AD中DC都可以对数据进行修改(Win2008 中的 RODC不可以).
可能很多人还不了解AD(Active Directory),你可以理解为LDAP DB +DS Service,基本上我们的程序只需要实现对于LDAP数据库进行查询和修改就可以了。在测试环境中我们使用VPC来模拟DC和Workstation,程序运行的非常顺利,1周左右程序基本上成型了。我们就去客户现场进行测试,出现了很多诡异的问题,有一些网络问题,我们通过程序进行了一些修改,还有一些就是AD的问题。因为MS在设计AD的时候抛弃了NT时PDC(主域控制器,可以进行读写)和BDC(只读备份域控制器)的概念,提出了多主复制的理念,这样就可能出现访问域控制器的时候根据网络的不同使用的是不同的域控制器,例如,WIFI连接的时候使用DC1,LAN连接使用DC2。因为程序中我们需要实现对于计算机的命名(企业中对于名称有特定的规范),根据用户信息判断计算机名称和计算机账号所在OU,这样必须将计算机唯一的标识UUID写入计算机账号的属性中(netbootGUID)。在WMI中JoinDomain函数可以自动创建计算机账号,但是无法制定在某个DC中创建,同时我们要对创建的计算机账号写入信息,就会出现在DC1上创建计算机账号,但是在DC2中查询不到该计算机账号的情况(DC同步需要时间),这个情况在我们自己的测试环境中是测试不到的,因为无法模拟客户的网络和服务器环境。还好我们选择了在指定的DC上创建计算机账号并修改netbootGUID,然后调用JoinDomain是选择不创建计算机账号的方式可以将这个问题跳过。
总结下来,SE最好能够写代码,否则这种问题让DEV处理基本上是无解的,但是现实的情况是SE基本上开发能力很差,所以我才有了市场。
另外,测试一定要模拟真实的生产环境,如果没有,那就必须要考虑在生产环境里测试,否则程序写好了也不能运行。