重新编译存储过程、触发器,刷新视图

SQL Server中存储过程和触发器一般只会在初次编译时进行优化,之后如果相关的索引或数据库统计发生变化后,已编译的存储过程和触发器不会随之更新优化,可能会导致执行效率低下甚至失效,解决方法:
1、删除重新创建存储过程或触发器,也可以用ALTER方法代替
2、SQL Server提供了sp_recompile用于设置强制编译标识,存储过程或者触发器下次被使用的时候会先重新编译定制优化
3、在创建存储过程的时候使用WITH_RECOMPILE选项,指明不创建优化计划缓存,在每次执行之前都重新编译,但这个会导致存储过程执行数据缓慢;

类似,有时修改完表之后,与之关联视图也有可能不会自动刷新,导致出现一些奇观的问题,例如查询出来的数据列是错位的等,解决方法:
1、删除重新创建视图,也可以用ALTER方法提到
2、SQL Server提供了sp_refreshview方法强制刷新视图

为了自己方便,写了一个自动获取整个数据库中所有数据库实例中用户创建的的存储过程、触发器和视图进行强制刷新的SQL,可将其添加到数据库的JOB中周期执行:

--重新编译存储过程、触发器
use tempdb
go

--create temp table
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[gmcc_recompile_info]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
delete from gmcc_recompile_info
else
create table gmcc_recompile_info
(
dbname varchar(255),
objtype varchar(255),
objowner varchar(255),
objname varchar(255)
)
GO

--get all store procdure info
declare @dbname as varchar(255)

declare xx cursor for
select name from master.dbo.sysdatabases

open xx
fetch next from xx into @dbname
while @@fetch_status = 0
begin

exec('use [' + @dbname + '] insert into tempdb.dbo.gmcc_recompile_info select ''' + @dbname + ''', xtype, sysusers.name, sysobjects.name from sysobjects left join sysusers on sysobjects.uid=sysusers.uid where (xtype=''P'' or xtype=''TR'' or xtype=''V'') and category=0');

fetch next from xx into @dbname
end
close xx
DEALLOCATE xx

--set recompile
declare @objtype as varchar(255)
declare @objowner as varchar(255)
declare @objname as varchar(255)

declare yy cursor for
select dbname, objtype, objowner, objname from tempdb.dbo.gmcc_recompile_info

open yy
fetch next from yy into @dbname, @objtype, @objowner, @objname
while @@fetch_status = 0
begin

if @objtype='P' --storeprocedure
exec('use [' + @dbname + '] exec sp_recompile ''[' + @objowner + '].[' + @objname + ']''')

else if @objtype='TR' --trigger
exec('use [' + @dbname + '] exec sp_recompile ''[' + @objowner + '].[' + @objname + ']''')

else if @objtype='V' --view
exec('use [' + @dbname + '] exec sp_refreshview ''[' + @objowner + '].[' + @objname + ']''')


fetch next from yy into @dbname, @objtype, @objowner, @objname
end

close yy
DEALLOCATE yy


--drop temp table
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[gmcc_recompile_info]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table gmcc_recompile_info
GO


上述SQL存在两个问题尚未解决:
1、由于sp_refreshview刷新视图的及时执行的,如果由于数据库表发生变化,导致某个视图刷新失败的话,整个过程就会停止下来,导致后面的刷新不能进行;
2、不支持数据库名称包含中文的情况

ASP.NET State Service出错

两台WEB服务器,操作系统为Windows2003,IIS 6.0,安装了.NET 2.0,运行的程序相同,相互为负载均衡。

其中一台在进入某个系统功能页面是否会提示错误,提示:

[HttpException : 无法向会话状态服务器发出会话状态请求。请确保已启动 ASP.NET State service,并且客户端和服务器端口是相同的。如果服务器位于远程计算机上,请检查 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection 的值,确保服务器接受远程请求。]


此应用程序是使用了ASPState服务作为会话管理的,在web.config中配置
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
cookieless="false"
timeout="3600"
/>


常规都会认为是ASPState服务没开,但是其他页面都工作正常,检查服务也是启动了的,重启IIS、ASPState、服务器均无法解决。检查系统日志由如下出错信息:
事件类型: 错误
事件来源: ASP.NET 2.0.50727.0
事件种类: 无
事件 ID: 1074
日期: 2008-2-27
事件: 18:36:41
用户: N/A
计算机: XXXX
描述:
An error occurred in while processing a request in state server. Major callstack: ProcessCompletion-->ProcessReading-->Tracker::Read. Error code: 0x80072747



看起来是连接成功了ASPState服务的,但是服务出错,搜索错误代码0x80072747,提示:
WSAENOBUFS (0x80072747)
No buffer space available.
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.


貌似内存管理的问题,Google出来的信息非常有限,有4-5个有相同问题,但是均没有答案。完全没有头绪了。想了很久,折腾了很久,突然想到boot.ini中开启了/3GB开关:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /fastdetect /3GB


将/3GB开关去掉,重启,恢复~~!怀疑是ASPState在大内存管理下有BUG造成。

天才呀,这个都能想到,其实还是运气好。下班,咔咔。

FTP的客户端和服务器端都处在防火墙(NAT)后面如何通信?

首先来介绍一些基础知识:
1、一般我们说的连接FTP服务器的哪个端口,是指的FTP服务器的指令端口,其实数据的传送还需要其他端口辅助;为了简单,我们将其成为指令端口和数据端口;

2、FTP数据传输分两种模式,主动模式和被动模式;



下图中FTP客户端是A,服务器端是B,网络上直通:



主动模式:
A通过一个随机端口连接B的指令端口(默认为21,well-konwn port),有数据需要传输的时候,A通过PORT命令告知B自己开启了另外一个随机数据端口,此时B从数据端口(默认为20)主动发起连接到A,完成数据传输
例如:PORT 211,1,2,3,17,24,意思是A开通了211.1.2.3的4376端口等待B来链接

被动模式:
A通过一个随机端口连接B的指令端口,有数据需要传输的时候,B通过227命令告知A自己开了另外一个随机数据端口,此时A也开启另外一个随机数据端口连接B,B是被动等待连接
例如:227 Entering Passive Mode (211,1,2,3,31,166),意思是B开通了211.1.2.3的8102端口等待A来链接

上述随机端口一般是大于1024的端口



明白了主动和被动的原理之后,再来看看如果A、B都在防火墙后面,与公网通信都依靠NAT实现,要如何才能完成整个通信和数据传输过程;通常如果不做特殊设置,一般表现为可以登录,但是不能传输数据或者列目录信息,出现超时等错误




主动模式:
1、对于B侧防火墙,需要开通公网地址到内网FTP服务器地址指令端口的映射,一般是21;因为数据端口20是B主动发起,可通过NAT机制完成,因此不需要开通端口映射;
2、对于A侧防火墙,需要开通公网地址到内网FTP客户端大于1024的数据端口映射,或者把这个客户端地址设置为防火墙的DMZ,即全部公网地址的请求都转发到此客户端

被动模式:
1、对于B侧防火墙,需要开通公网地址到内网FTP服务器地址指令端口的映射和大于1024的数据端口映射
2、对于A,无特殊要求



看了上面的要求都很复杂,特别是大于1024的数据端口映射全开,在很多管理下面都是不允许的,只能按需开放,这里就需要利用FTP服务器端的特殊功能来解决,这里以ServU为例,其他的软件就要看是否有类似功能了。



这里介绍的方法只能采用被动模式:
1、对于B侧防火墙,需要开通公网地址到内网FTP服务器地址指令端口的映射和大于1024的一个或者一段数据端口映射,例如8101-8102

2、对于A,无特殊要求

3、对于ServU软件,需要做一下两个配置:
3.1、设置被动端口范围,这个是解决被动端口需要开放端口太多的问题

3.2、设置防火墙对应映射的公网IP,这个是解决由于服务器端放置在防火墙内部,一般是一个私网地址,在发送227指令的时候会将私网地址填进去,这样对于客户端来说是无法连接到的
这个配置不做有一些FTP客户端和IE浏览器无法传输数据,不过我发现FlashFXP似乎“智能”一些,设不设没影响



4、对于客户端软件,要设置为强制使用被动模式,以FlashFXP为例:





System.Web.HttpException: 服务器太忙

Windows 2003 Enterprise Server自带IIS 6.0,上面有多个站点,其中一个是企业门户,访问量较大,由于门户需要连接很多数据库和WebService接口获取需要展示的数据,有时在这些数据源出现缓慢的时候,也会导致门户站点报告“System.Web.HttpException: 服务器太忙”错误。

从发生错误的情况判断应该是服务器的处理队列达到限制,因此抛出异常。

之前曾经调整过对应Framework版本的machine.config文件,主要涉及processModel节的maxWorkerThreadsmaxIoThreadsminWorkerThreads,情况有所好转,但是一直未能根除,感觉只是提升了WEB服务器自身的处理极限,但当外部数据源缓慢的时候,需要处理的事务依然会排长队,超出队列长度,进而报错。

最近看到篇介绍machine.config配置的文章:《ASP.NET 设置架构参考》,很详细,这才发现,原来已经距离答案很近,只是没留意,请注意学习processModel章节。

首先在machine.config中是可以配置整个WEB服务器的请求队列长度(processModelrequestQueueLimit,默认5000)和单个站点默认的请求队列长度(httpRuntimeappRequestQueueLimit,默认100);考虑到其他站点访问量没有这么大,并且整个WEB服务器的请求队列长度5000也应该足够,那我们需要的就是单独修改该站点的队列长度;鉴于httpRuntime节是可以在对应站点下的web.config中配置的,所以我们只需要改动这个站点的web.config即可,增加一行配置,指定队列长度为1000(未修改之前是对应Framework版本下的machine.config中httpRuntime节appRequestQueueLimit决定默认值的),问题有明显改善,今天在一度极端缓慢的情况下,也没有观察到服务器太忙的错误重现。

<system.web>
...
<httpRuntime appRequestQueueLimit="1000"/>
...
</system.web>


附:
1、怎么知道我的站点是用的哪个版本的Microsoft.NET Framework:IIS中对应站点鼠标右键>属性


2、machine.config文件在哪里:一般<WINDOWS安装目录>\Microsoft.NET\Framework\对应版本号\CONFIG\

3、网上看到另外一种说法是修改对应站点归属应用程序池的“请求队列限制”来解决相同问题,我之前单独修改试过,观察不到效果;不过我想可以双管齐下,现在也是这么做的;这个的默认值是4000


4、怎么知道某个站点用的哪个应用程序池:IIS中对应站点鼠标右键>属性

IBM x3650 RAID/DASD报错

一台IBM x3650服务器死机,看面板RAID告警,重启之后RAID告警消失,改为DASD告警,启动自检出现“Following Arrays have missing required members and cannot be configured Array#0-RAID-5”提示,磁盘阵列配置丢失,无法启动。

报800,2个工作日之后工程师上门先是换RAID卡,之后进入RAID配置界面发现检测不到硬盘,怀疑磁盘背板损坏,又等将近10个工作日,背板备件到货更换后故障消失,但是阵列已经无法回复,数据全部丢失。

据说近期热销的3650也是维修白热化中,问题最多的就是集中在磁盘系统。

手机QQ2007

这个应该算是一个火星消息,最近有了最新的手机QQ2007 Beta2,但是暂时只能诺基亚、摩托罗拉、索爱的一些手机能用,我的O2 Atom只能去找Beta1的多普达838的版本替代,其实就是WM(WindowsMobile) 5.0的版本,安装之后一旦登陆就出现“正在拨号”的字样,等待一段时间之后就会提示超时,郁闷,google了半天,只有人提问,就没人一个能用的答案,而且这个问题在一些SmartPhone和PPC的手机上都有出现。

最后还是自己折腾出来了,登陆看看,比起之前版本有了很大变化,电脑上的QQ实时通信功能都能包括,好友、分组、群(群资料、群成员),不过群下面的组还是看不到;希望很快可以看到正式版的PPC版本。下载去这里:http://mobile.qq.com/







调整方法供大家参考:
1、首先你的PPC手机使用cmwap可以正常上网浏览

2、设 置 > 连接 > 连接 > 高级 > “选择自动使用的网络” > 选择网络 > 修改为你可以正常WAP浏览的连接,我的名称是“CM WAP Settings”


3、点击“编辑”,选中GPRS模式的连接方法,我的是“CM WAP”
如何判断是GPRS方法连接的呢?点击编辑,调制解调器应该是“蜂巢电话线路(GPRS)”

数据库出错

刚才上来发现进入bo-blog出错,提示:
Bo-Blog Database System Tips: MySQL Query Error

Time: 2007-7-20 3:47pm
Script:

SQL: SELECT COUNT(blogid) FROM `***blogs` WHERE `property`<>'2' AND `property`<>'3'
Error: Table './wjinfo-bo-blog/***blogs' is marked as crashed and should be repaired
Errno.: 145



进入phpmyadmin后发现对应的***blogs只能看到结构,不能看到数据。尝试mysqldump备份数据库提示:
mysqldump: Got error: 145: Table './wjinfo-bo-blog/boblog_blogs' is marked as crashed and should be repaired when using LOCK TABLES


最后找到MySQL对应表的MYI数据文件,执行myisamchk -c -r boblog_blogs.MYI
- recovering (with sort) MyISAM-table 'boblog_blogs.MYI'
Data records: 359
- Fixing index 1
- Fixing index 2
- Fixing index 3
- Fixing index 4


再次进入发现数据恢复。

F5 - iRules备忘

使加入负载均衡Pool服务器同网段的其他服务器可访问负载均衡资源,也适用于一些部署在负载均衡环境中的应用需要访问自身的接口:
class local_server {
服务器网段/掩码
...
}

when CLIENT_ACCEPTED {
if {[matchclass [IP::remote_addr] equals $::local_server]} {
snat <同网段IP,可以复用负载均衡虚拟IP>
}
else {
}
}

登陆加入负载均衡Pool的服务器,保证访问负载均衡虚拟IP时,一定是负载均衡到本机,方便在有问题的时候,检查是哪一台服务器有问题:
class iap_web_server {
服务器1 IP
服务器2 IP
...
}

when HTTP_REQUEST {
if {[matchclass [IP::client_addr] equals $::iap_web_server]} {
node [IP::client_addr]
}
}


一些资源:
http://www.f5.com.cn/bbs/
http://www.sinogrid.com/cisybbs/

如何在Pocket PC程序的线程内修改用户界面控件的属性

用上O2 Atom之后,就开始研究Windows Mobile 5.0的开发。

今天用.NET Compact Framework 2.0做了一个小东西,为了追求界面的响应感受,使用了线程,线程内部操作界面控件的属性,例如Button.Enabled和Lable.Text。发现在PC上运行正常,但是一旦放到PPC上就出错,找了半天发现是一旦在线程内部修改界面控件的属性就会导致出错。

纳闷,无解,于是google之,发现MSDN中有不错的PPC开发资源,这个问题也得以解决,原来是操作的方法有错,应该使用delegate方法并配合this.Invoke才能保证线程安全操作,具体可查阅http://www.microsoft.com/china/msdn/librar...2.mspx?mfr=true中的“练习 4:更新线程内的用户界面控件 ”,而且文中还有所讲的源代码下载,甚是不错。

无法访问网络位置

我的笔记本年前突然出现了不能使用共享文件的问题,具体表现为访问其他计算机的共享文件报错,提示“无法访问网络位置”。

一直很忙,今天下午得空来看了看,发现系统日志有以下错误:
事件类型: 错误
事件来源: NetBT
事件种类: 无
事件 ID: 4311
描述:
由于驱动程序设备无法创建,初始化操作失败。


发现ipconfig /all看到的Node Type是Unkonwn,而不是一般的Hybrid

怀疑是之前卸载了Norton或者其他什么东西出的问题,最后焦点集中到注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters,发现TransportBindName的值是空字符串,找了另一台正常的机器对比,填写上“\Device\”(不包含引号),重启后访问正常。