随笔 - 249  文章 - 1  评论 - 53 
  置顶随笔
摘要: 我们没有离开我们只是在另一个世界守望着我们的故乡在浩瀚而美丽的夜空中点点繁星犹如闪耀的烟花是我们永远不灭的生命的渔火我们没有离开我们只是悄悄的沉睡在故乡的土地上等待有一天我们会幻化成丛林里的精灵为生存在这片土地的人们放歌我们没有离开我们期待着这里再次开满鲜花再次稻香遍野我们没有离开我们依然相信终有一天太阳的光辉会照耀我们的灵魂为这个世界点缀闪闪光芒我们没有离开在梦里我们还会再次相见手拉手追寻儿时的...阅读全文
posted @ 2008-05-25 10:16 大斌锅 阅读(188) 评论(15) 编辑
  2012年1月18日
经常有开发同事反映如下情况:我有一条语句或者一个JOB昨天跑半个小时就完成了,今天怎么跑了两个小时还没有完成?

是不是数据库出现问题了?

    数据库语句运行时间异常,其实是一个比较复杂的情况,因为数据是不断变动的,今天好好的一条语句,有可能明天运行就

不在预计的时间内了,这个场景是没办法完全重溯的,即便有当时的备份数据,但是当时的服务器压力是没有办法知道和营造

的;但是好在现在不是要调查昨天语句跑时间异常的原因,而是要找到现在语句运行异常的原因,现在的情况还正在进行着呢,

所以我们可以根据语句目前的情况,初步来排查一下;

    其实要考虑的问题比较多:

    1. 索引是否正常(索引是否损坏、有没有人删除索引等);

    2. 统计信息是否过时;

    3. 语句执行计划是否发生偏移(和索引、统计信息以及数据量都有关系);

    4. 语句是否有bug;

    5. 是否发生的阻塞;

    6. 系统资源是否遇到瓶颈;

    .........

    这么多的情况都考虑的话我们很难下手,一般解决这个问题我们都需要采用比较快的方式来做排查,以下方法主要针对5和6两

个方面进行,因为这两个方面是最常见的情况。

我们来简单模拟一下排查过程:

1. 创建测试表和数据

USE [master]
GO

/****** Object: Table [dbo].[a] Script Date: 01/17/2012 16:46:34 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[a](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](100) NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


insert into a values('aa'),('bb'),('cc')

2. 制造阻塞:开两个session,分别运行下面的语句

--Session 1
use master
go
begin tran
update A set name='abc' where id=2

--rollback


--Session 2
select * from a

因为Session1 的Update语句没有能够提交,所以此时Session2 过程会被阻塞


3. 分析排查:

  我们首先需要查询下此时数据库中是否存在阻塞:

--Blocked
select * from sys.sysprocesses with(nolock) where blocked<>0


 我们看到了阻塞的记录,53阻塞了56,被阻塞的资源是:dbid 1 file 1 page 307;

 接下来我们需要知道阻塞和被阻塞的是什么语句,有两种方式:

 a. dbcc inputbuffer

 b. sys.dm_exec_sql_text

 方法一与方法二相比:

   优点:方法一能显示非活动session的语句,方法二只能查活动的session(通过sp_who2 active 能显示是否活动);

   缺点:方法一只能一个一个查询,方法二可以多个一起查询;

方法一:

--No1:
dbcc inputbuffer(53)
go
dbcc inputbuffer(56)

方法二:

--No2:
SELECT
S.session_id, R.blocking_session_id,
S.host_name, S.login_name,
databaseName=DB_NAME(R.database_id),R.command, R.status,
current_execute_sql = SUBSTRING(T.text,
R.statement_start_offset / 2 + 1,
CASE
WHEN statement_end_offset = -1 THEN LEN(T.text)
ELSE (R.statement_end_offset - statement_start_offset) / 2+1
END),
S.program_name,
S.status,
S.cpu_time, memory_usage_kb = S.memory_usage * 8, S.reads, S.writes,
S.transaction_isolation_level,
C.connect_time, C.last_read, C.last_write,
C.net_transport, C.client_net_address, C.client_tcp_port, C.local_tcp_port,
R.start_time,
R.wait_time, R.wait_type, R.last_wait_type, R.wait_resource,
R.open_transaction_count, R.transaction_id

FROM sys.dm_exec_sessions S
LEFT JOIN sys.dm_exec_connections C
ON S.session_id = C.session_id
LEFT JOIN sys.dm_exec_requests R
ON S.session_id = R.session_id
AND C.connection_id = R.connection_id
OUTER APPLY sys.dm_exec_sql_text(R.sql_handle) T
WHERE S.is_user_process = 1 -- 如果不限制此条件,则查询所有进程(系统和用户进程)
and s.session_id in(53,56)

我们看到方法一两条语句都能查出来,而方法二只能查出一个语句;

到这里,我们已经能判断语句运行慢的原因是被阻塞了,我们再来查查阻塞的原因是什么,可以通过以下语句查看:

select request_session_id,resource_type,db_name(resource_database_id) as DBName,resource_description,
request_mode,request_type,request_status from sys.dm_tran_locks where request_session_id in(56,53)
order by request_session_id

可以看到,56处于WAIT状态,它在等待获取1:307:1 上的一个共享锁,但是1:307:1上被53的一个排他锁占据了(GRANT代表

已获得资源,正在运行),因此56必须等待53上的排他锁释放后才能继续运行;于是我们转而调查53排他锁没有释放的原因;可能是

53需要的其他资源被其他进程占有了,在等待其他进程释放锁;也可能是因为Update语句更新的数据量过多,需要的时间比较长,不

能够及时的释放锁;还有就是我们现在的情况,没有提交事物了(语句中可以直接看到);阻塞的排查方法都是类似的。

 

如果语句并没有被其他语句blocked呢? 那我们需要再进一步查找的原因就是Wait了,前面已经有wait的相关查询,下面我们来查下

更具体的信息:

-- wait & lock
select lo.request_session_id as [Session],
DB_NAME(lo.resource_database_id) as Dbname,
lo.resource_type as [Type],
lo.resource_description,
lo.request_mode,
lo.request_owner_type,
lo.request_status,
case when lo.resource_type='OBJECT' then OBJECT_NAME(lo.resource_associated_entity_id)
when lo.resource_associated_entity_id IS NULL OR lo.resource_associated_entity_id=0
then NULL
else OBJECT_NAME(p.object_id)
end as Associated_Entity,
wt.blocking_session_id,wt.resource_description
from
sys.dm_tran_locks lo with(nolock)
left join sys.partitions p with(nolock)
on lo.resource_associated_entity_id=p.partition_id
left join sys.dm_os_waiting_tasks wt with(nolock)
on lo.lock_owner_address=wt.resource_address
where lo.request_session_id>50
and lo.request_session_id=56
order by [Session] ,[TYPE]

上面可以看到,56在获取共享资源1:307:1时,遇到了等待,当然这里的等待还是被53阻塞了,但是等待会有多种原因的等待,我们查

一下当前的等待信息:

--current wait info
select wait_type,COUNT(0) as num_waiting_tasks,
SUM(wait_duration_ms) as total_wait_time_ms
from sys.dm_os_waiting_tasks with(nolock)
where session_id>50
group by wait_type
order by wait_type

这里可以看到是锁等待(Wait_Type),还有很多资源类型的等待,值的重点关注的有:
  Memory:CMEMTHREAD ,RESOURCE_SEMAPHORE
     CMEMTHREAD:
       说明和原因:计划缓存出现问题的标志(大量计划加入或者移出);
       解决:     使用参数化的查询或者设置数据库强制参数化(forced parameterization)

     RESOURCE_SEMAPHORE:
       说明和原因:内存密集型查询无法获得请求的内存;其他进程消耗了太多的内存;
       解决:     为数据库添加合适的索引或者增加内存

  IO:IO_COMPLETION,ASYNC_IO_COMPLETION,WRITELOG,PAGEIOLATCH_*

  CPU: CXPACKET,SOS_SCHEDULER_YIELD
       CXPACKET:
          说明和原因:并行处理等待类型,并行同步等待;
          解决:     可以通过修改并行度的值(或者禁用)解决;
       SOS_SCHEDULER_YIELD:
          说明和原因:任务执行到时间片尾,让出调度器给其他任务运行;
          解决:     需要处理能力更好的CPU
 
  Network:ASYNC_NETWORK_IO,DBMIRROR_SEND
       ASYNC_NETWORK_IO: 网卡带宽饱和或者客户端不能及时把结果取走;
       DBMIRROR_SEND:  网络带宽不足以支持镜像事务量或者镜像数据库超出限额;

  锁阻塞:LCK_*    


我们可以统计下,我们数据库最多的20种等待类型:

--total wait info
select top 20 wait_type,SUM(waiting_tasks_count) waiting_tasks_count,
SUM(wait_time_ms)as total_wait_time_ms,
SUM(signal_wait_time_ms) as total_signal_wait_time_ms
from sys.dm_os_wait_stats with(nolock)
where wait_type not in
--system wait type
('LAZYWRITER_SLEEP','REQUEST_FOR_DEADLOCK_SEARCH','SQLTRACE_BUFFER_FLUSH',
'XE_TIMER_EVENT','FT_IFTS_SCHEDULER_IDLE_WAIT','LOGMGR_QUEUE','CHECKPOINT_QUEUE',
'SLEEP_TASK','BROKER_IO_FLUSH','BROKER_TASK_STOP','BROKER_TO_FLUSH','BROKER_EVENTHANDLER')
group by wait_type
order by total_wait_time_ms desc

通过这个我们可以从中看出DB等待主要集中在哪些方面,如果是在CPU、IO、Memory、Lock等上面等待时间很长,说明我们

的数据库需要做某些方面的优化了。

    以上就是从阻塞和等待方面,对运行时间异常的语句做初步排查的过程,欢迎大家拍砖。
posted @ 2012-01-18 14:29 大斌锅 阅读(3) 评论(0) 编辑
  2012年1月10日
多希望有一天突然惊醒,发现自己在高三的一节课上睡着了,现在经历的一切都是一场梦,桌上满是你的口水。你告诉同桌,说做了个好长的梦。同桌骂你白痴,叫你好好听课。你看着窗外的球场,一切都那么熟悉,一切还充满希望。
posted @ 2012-01-10 14:00 大斌锅 阅读(6) 评论(0) 编辑
  2011年12月6日
跟踪标志说明

260

打印有关扩展存储过程动态链接库 (DLL) 的版本控制信息。有关__GetXpVersion()的详细信息,请参阅创建扩展存储过程。

作用域:全局或会话

1204

返回参与死锁的锁的资源和类型,以及受影响的当前命令。

作用域:仅全局

1211

基于内存不足或基于锁数禁用锁升级。SQL Server 数据库引擎不会将行锁或页锁升级到表锁。

使用此跟踪标志可生成过多的锁数目。这样会降低数据库引擎的性能,或因为内存不足而导致 1204 错误(无法分配锁资源)。有关详细信息,请参阅锁升级(数据库引擎)。

如果同时设置了跟踪标志 1211 和 1224,则 1211 优先于 1224。但是,由于在所有情况下(甚至在内存紧张的情况下)跟踪标志 1211 都禁止升级,因此建议使用 1224。这有助于在使用多个锁时避免“锁不足”错误。

作用域:全局或会话

1222

以不符合任何 XSD 架构的 XML 格式,返回参与死锁的锁的资源和类型,以及受影响的当前命令。

作用域:仅全局

1224

基于锁数禁用锁升级。但是,内存不足仍可激活锁升级。如果锁对象使用的内存量超出下列条件之一,数据库引擎会将行锁或页锁升级为表(或分区)锁:

  • 数据库引擎所用内存的 40%,使用地址窗口化扩展插件 (AWE) 的内存分配除外。只有在sp_configurelocks参数设置为 0 时,这才适用。

  • 使用sp_configurelocks参数配置的锁内存的 40%。有关详细信息,请参阅设置服务器配置选项。

如果同时设置了跟踪标志 1211 和 1224,则 1211 优先于 1224。但是,由于在所有情况下(甚至在内存紧张的情况下)跟踪标志 1211 都禁止升级,因此建议使用 1224。这有助于在使用多个锁时避免“锁不足”错误。

注意:
也可以使用ALTER TABLE语句的 LOCK_ESCALATION 选项控制到表级或 HoBT 级粒度的锁升级。

作用域:全局或会话

2528

禁用 DBCC CHECKDB、DBCC CHECKFILEGROUP 和 DBCC CHECKTABLE 执行的对象并行检查。默认情况下,并行度由查询处理器自动确定。最大并行度的配置就像并行查询的最大并行度一样。有关详细信息,请参阅max degree of parallelism 选项。

通常应使并行 DBCC 保持启用状态。对于 DBCC CHECKDB,查询处理器重新求值,并对检查的每个表或每批表自动调整并行度。有时,检查可能在服务器几乎处于空闲状态时启动。如果管理员知道在检查完成前负载将增加,则可能需要手动减小并行度或禁用并行度。

禁用对 DBCC 的并行检查可能导致 DBCC 的完成时间变长,如果运行 DBCC 时启用了 TABLOCK 功能并关闭了并行度,则表可能被锁定更长时间。

作用域:全局或会话

3205

默认情况下,如果磁带机支持硬件压缩,则 DUMP 或 BACKUP 语句会使用该功能。利用此跟踪标志,可以禁用磁带机的硬件压缩。此选项在您需要与不支持压缩的其他站点或磁带机交换磁带时很有用。

作用域:全局或会话

3226

默认情况下,每个成功的备份操作都会在 SQL Server 错误日志和系统事件日志中添加一个条目。如果非常频繁地创建日志备份,这些成功消息会迅速累积,从而产生一个巨大的错误日志,使查找其他消息变得非常困难。

使用这一跟踪标志,可以取消这些日志条目。如果您频繁地运行日志备份,并且没有任何脚本依赖于这些条目,则这种做法非常有用。

3608

禁止 SQL Server 自动启动和恢复除master数据库之外的任何数据库。在访问数据库时将启动并恢复该数据库。可能无法运行某些功能,如快照隔离和读提交快照。用于移动系统数据库和移动用户数据库。请不要在正常操作中使用。

3625

限制错误消息中返回的信息量。有关详细信息,请参阅元数据可见性配置。

作用域:仅全局

4616

使 应用程序角色可以看到服务器级元数据。在 SQL Server 中,应用程序角色无法访问自身数据库以外的元数据,因为应用程序角色与服务器级主体不相关联。这是对早期版本的 SQL Server 的行为的更改。设置此全局标志将禁用新的限制,并允许应用程序角色访问服务器级元数据。

作用域:仅全局

6527

禁止在 CLR 集成中第一次发生内存不足异常时生成内存转储。默认情况下,SQL Server 在 CLR 中第一次发生内存不足异常时会生成小内存转储。该跟踪标志的行为如下所示:

  • 如果用作一个启动跟踪标志,则永远不生成内存转储。但是,如果使用了其他跟踪标志,则可能会生成内存转储。

  • 如果在正在运行的服务器上启用此跟踪标志,则从此时开始不会自动生成内存转储。但是,如果已经由于 CLR 中的内存不足异常生成了内存转储,则此跟踪标志将没有任何效果。

作用域:仅全局

7806

在 SQL Server Express 上启用专用管理员连接 (DAC)。默认情况下,在 SQL Server Express 上不保留 DAC 资源。有关详细信息,请参阅使用专用管理员连接。

作用域:仅全局

 

使用以下方法之一可将跟踪标志设置为开或关:

  • 使用 DBCC TRACEON 和 DBCC TRACEOFF 命令。

    以 DBCC TRACEON 2528 为例,若要在全局作用域内启用跟踪标志,请在使用 DBCC TRACEON 时使用 -1 参数:DBCC TRACEON (2528, -1)。若要关闭全局跟踪标志,请在使用 DBCC TRACEOFF 时使用 -1 参数。

  • 使用-T启动选项可以指定跟踪标志在启动期间设置为开。

    -T启动选项将全局启用跟踪标志。使用启动选项无法启动会话级别的跟踪标志。有关启动选项的详细信息,请参阅使用 SQL Server 服务启动选项。

使用 DBCC TRACESTATUS 命令确定哪些跟踪标志当前是活动的。

行为更改

在 SQL Server 2000 中,通过简单的 DBCC TRACEON (1204) 足以将死锁报表记录到错误日志中。在 SQL Server 2008 中,则必须全局启用标志,这是因为会话级别的标志对死锁监视器线程不可见。

posted @ 2011-12-06 11:53 大斌锅 阅读(8) 评论(0) 编辑
  2011年11月29日
爱国主义:一堆随时可以被任何野心家所点燃,去照亮他的名字的易燃垃圾。
——安卜罗斯.皮尔斯

除非你把爱国主义从人类中驱逐出去,否则你将永远不会拥有一个宁静的世界。爱国主义是一种有害的、精神错乱的白痴形式。爱国主义就是让你确信这个国家比所有其他的国家都要出色,只因为你生在这里。
——乔治.肖伯纳

那些没有自尊的人仍然可以是爱国的,他们可以为少数牺牲多数。他们热爱他们坟墓的泥土,但他们对那种可以使他们的肉体生机勃勃的精神却毫无同情心。爱国主义是他们脑袋里的蛆。
——亨利.大卫.梭罗

“我首先是一个人,其次才是印度人”
——甘地

“把沦为异族奴隶之苦告诉国人,是很必要的,但是切莫使人得出结论:那么,我们倒不如做自己人的奴隶罢”
——鲁迅

要人家為它而死的國家,就讓它滅亡好了
——《战争证言征集广告》里的日本青年

“若有人问:我们究竟应当不应当爱国?我们便大声答道:……我们爱的是国家为人民谋幸福的国家,不是人民为国家做牺牲的国家。”
——陈?独?秀早就在《我们究竟应不应当爱国》

爱国者的责任就是保护国家不受政府侵犯。
----托马斯.潘恩

如 果你说中国不好,可能被视为西奴;如果你说美国好,就会被视为美狗;如果你说不想做中国人,想做美国人,你将是十恶不赦的汉奸。如果你什么都不说,只是悄 悄把中国国籍变成美国国籍,你将会是一个成功人士;若你同时能献身于主旋律文化,教导中国人怎样才算爱国,你就是一个海外赤子了。?

中国汉奸纳粹分子向西方德国马克思西特勒苏联纳粹摇尾乞怜,已经62年了。
posted @ 2011-11-29 10:07 大斌锅 阅读(13) 评论(0) 编辑
  2011年9月26日
摘要: The report parameter 'param1' is read-only and cannot be modified. (rsReadOnlyReportParameter) Search SQL Server Reporting Services Forum Search All SQL Server Forums Search All MSDN Forums Ask a questionFriday, April 06, 2007 2:52 AManbanb0Recent Achievements100First Forums Replyanb's .阅读全文
posted @ 2011-09-26 21:19 大斌锅 阅读(16) 评论(0) 编辑
  2011年8月23日
摘要: Office 2010 VL 大客户版下载、激活及集成SP1 2010-06-24 21:34:35| 分类: Office | 标签: |字号大中小 订阅 本文链接:http://oicu.cc.blog.163.com/blog/static/123039471201052493435747/发信人: oicu (Oh! I see you!), 信区: OfficeSoft标 题: Office 2010 VL 大客户版下载、激活及集成SP1发信站: 水木社区 (Thu Jun 24 21:26:22 2010), 站内先看文件名,去搜索下载:SW_DVD5_Office_Profess阅读全文
posted @ 2011-08-23 13:51 大斌锅 阅读(110) 评论(0) 编辑
  2011年8月11日
摘要: 控件:Microsoft .NET Framework 3.5 的 Microsoft 图表控件(Microsoft Chart Controls for Microsoft .NET Framework 3.5)– 包含英文版,中文版。上面提供的链接是中文版的,可以更改为英文版。语言包:Microsoft Chart Controls for Microsoft .NET Framework 3.5 Language Pack Microsoft .NET Framework 3.5 的Microsoft 图表控件 的语言包,包含23中语言。Microsoft Chart Controls 阅读全文
posted @ 2011-08-11 17:26 大斌锅 阅读(23) 评论(0) 编辑
  2011年8月1日
摘要: 基于AppDomain的"插件式"开发2011-08-01 09:58 by 空逸云, 295 visits, 收藏, 编辑 很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统,这个WinService系统管理的形形色色各种各样的服务,这些服务也是各个"插件式"的类库,例如: public interface IJob { void Run(DateTime time); } public class Col阅读全文
posted @ 2011-08-01 11:36 大斌锅 阅读(21) 评论(0) 编辑
  2011年6月2日
摘要: 新概念英语第三册mp3点此进入:http://www.tingclass.com/lesson/mp3/nce3us/新概念英语第二册mp3点此进入:http://www.tingclass.com/lesson/mp3/nce2us/商务英语口语900句点此进入:http://www.tingclass.com/lesson/mp3/buz900c/走遍美国点此进入:http://www.tingclass.com/lesson/mp3/usa/李阳疯狂英语365句点此进入:http://www.tingclass.com/lesson/mp3/crazy365/李阳疯狂英语发音宝典点此进入阅读全文
posted @ 2011-06-02 13:04 大斌锅 阅读(31) 评论(0) 编辑
  2011年5月12日
摘要: 通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务。这样是使工作简单了,但是却和提供Web服务的URL、方法名、参数绑定在一起了,这是VS.NET自动为我们生成Web服务代理的限制。如果哪一天发布Web服务的URL改变了,则我们需要重新让VS.NET生成代理,并重新编译。在某些情况下,这可能是不能忍受的,我们需要动态调用WebService的能力。比如我们可以把Web服务的URL保存在配置文件中,这样,当服务URL改变时,只需要修改配置文件就可以了。 说了这么多,实际上我们要实现这样的功能:public 阅读全文
posted @ 2011-05-12 12:26 大斌锅 阅读(75) 评论(0) 编辑