osql/sqlcmd 工具是一个 SqlServer的命令提示符工具,我们可以使用它运行 Transact-SQL 语句和脚本文件。该工具所在目录:C:Program FilesMicrosoft SQL Server110ToolsBinn
交互式输入 Transact-SQL 语句,如下
C:UsersAdministrator>osql -E 1> set nocount on; 2> go 1> select getdate(); 2> go ----------------------- 2015-06-20 18:02:18.053 1> exit C:UsersAdministrator>
osql的作用不仅仅局限于此,其他参数如下
强大之处在于:该工具可以结合存储过程,检查并输出锁、闩等资源的阻塞情况。
- 创建存储过程:sp_blocker_pss80
- 创建SQL脚本:定时执行sp_blocker_pss80存储过程
- 在osql命令中调用该SQL脚本,并将结果输出到文件
以下分别是sp_blocker_pss80、SQL脚本、osql命令示例及对应的输出结果
use master GO if exists (select * from sysobjects where id = object_id('dbo.sp_blocker_pss80') and sysstat & 0xf = 4) drop procedure dbo.sp_blocker_pss80 GO create procedure dbo.sp_blocker_pss80 (@latch int = 0, @fast int = 1, @appname sysname='PSSDIAG') as --version 16SP3 if is_member('sysadmin')=0 begin print 'Must be a member of the sysadmin group in order to run this procedure' return end set nocount on SET LANGUAGE 'us_english' declare @spid varchar(6) declare @blocked varchar(6) declare @time datetime declare @time2 datetime declare @dbname nvarchar(128) declare @status sql_variant declare @useraccess sql_variant set @time = getdate() declare @probclients table(spid smallint, ecid smallint, blocked smallint, waittype binary(2), dbid smallint, ignore_app tinyint, primary key (blocked, spid, ecid)) insert @probclients select spid, ecid, blocked, waittype, dbid, case when convert(varchar(128),hostname) = @appname then 1 else 0 end from sysprocesses where blocked!=0 or waittype != 0x0000 if exists (select spid from @probclients where ignore_app != 1 or waittype != 0x020B) begin set @time2 = getdate() print '' print '8.2 Start time: ' + convert(varchar(26), @time, 121) + ' ' + convert(varchar(12), datediff(ms,@time,@time2)) insert @probclients select distinct blocked, 0, 0, 0x0000, 0, 0 from @probclients where blocked not in (select spid from @probclients) and blocked != 0 if (@fast = 1) begin print '' print 'SYSPROCESSES ' + ISNULL (@@servername,'(null)') + ' ' + str(@@microsoftversion) select spid, status, blocked, open_tran, waitresource, waittype, waittime, cmd, lastwaittype, cpu, physical_io, memusage, last_batch=convert(varchar(26), last_batch,121), login_time=convert(varchar(26), login_time,121),net_address, net_library, dbid, ecid, kpid, hostname, hostprocess, loginame, program_name, nt_domain, nt_username, uid, sid, sql_handle, stmt_start, stmt_end from master..sysprocesses where blocked!=0 or waittype != 0x0000 or spid in (select blocked from @probclients where blocked != 0) or spid in (select spid from @probclients where blocked != 0) print 'ESP ' + convert(varchar(12), datediff(ms,@time2,getdate())) print '' print 'SYSPROC FIRST PASS' select spid, ecid, waittype from @probclients where waittype != 0x0000 if exists(select blocked from @probclients where blocked != 0) begin print 'Blocking via locks at ' + convert(varchar(26), @time, 121) print '' print 'SPIDs at the head of blocking chains' select spid from @probclients where blocked = 0 and spid in (select blocked from @probclients where spid != 0) if @latch = 0 begin print 'SYSLOCKINFO' select @time2 = getdate() select spid = convert (smallint, req_spid), ecid = convert (smallint, req_ecid), rsc_dbid As dbid, rsc_objid As ObjId, rsc_indid As IndId, Type = case rsc_type when 1 then 'NUL' when 2 then 'DB' when 3 then 'FIL' when 4 then 'IDX' when 5 then 'TAB' when 6 then 'PAG' when 7 then 'KEY' when 8 then 'EXT' when 9 then 'RID' when 10 then 'APP' end, Resource = substring (rsc_text, 1, 16), Mode = case req_mode + 1 when 1 then NULL when 2 then 'Sch-S' when 3 then 'Sch-M' when 4 then 'S' when 5 then 'U' when 6 then 'X' when 7 then 'IS' when 8 then 'IU' when 9 then 'IX' when 10 then 'SIU' when 11 then 'SIX' when 12 then 'UIX' when 13 then 'BU' when 14 then 'RangeS-S' when 15 then 'RangeS-U' when 16 then 'RangeIn-Null' when 17 then 'RangeIn-S' when 18 then 'RangeIn-U' when 19 then 'RangeIn-X' when 20 then 'RangeX-S' when 21 then 'RangeX-U' when 22 then 'RangeX-X'end, Status = case req_status when 1 then 'GRANT' when 2 then 'CNVT' when 3 then 'WAIT' end, req_transactionID As TransID, req_transactionUOW As TransUOW from master.dbo.syslockinfo s, @probclients p where p.spid = s.req_spid print 'ESL ' + convert(varchar(12), datediff(ms,@time2,getdate())) end -- latch not set end else print 'No blocking via locks at ' + convert(varchar(26), @time, 121) print '' end -- fast set else begin -- Fast not set print '' print 'SYSPROCESSES ' + ISNULL (@@servername,'(null)') + ' ' + str(@@microsoftversion) select spid, status, blocked, open_tran, waitresource, waittype, waittime, cmd, lastwaittype, cpu, physical_io, memusage, last_batch=convert(varchar(26), last_batch,121), login_time=convert(varchar(26), login_time,121),net_address, net_library, dbid, ecid, kpid, hostname, hostprocess, loginame, program_name, nt_domain, nt_username, uid, sid, sql_handle, stmt_start, stmt_end from master..sysprocesses print 'ESP ' + convert(varchar(12), datediff(ms,@time2,getdate())) print '' print 'SYSPROC FIRST PASS' select spid, ecid, waittype from @probclients where waittype != 0x0000 if exists(select blocked from @probclients where blocked != 0) begin print 'Blocking via locks at ' + convert(varchar(26), @time, 121) print '' print 'SPIDs at the head of blocking chains' select spid from @probclients where blocked = 0 and spid in (select blocked from @probclients where spid != 0) if @latch = 0 begin print 'SYSLOCKINFO' select @time2 = getdate() select spid = convert (smallint, req_spid), ecid = convert (smallint, req_ecid), rsc_dbid As dbid, rsc_objid As ObjId, rsc_indid As IndId, Type = case rsc_type when 1 then 'NUL' when 2 then 'DB' when 3 then 'FIL' when 4 then 'IDX' when 5 then 'TAB' when 6 then 'PAG' when 7 then 'KEY' when 8 then 'EXT' when 9 then 'RID' when 10 then 'APP' end, Resource = substring (rsc_text, 1, 16), Mode = case req_mode + 1 when 1 then NULL when 2 then 'Sch-S' when 3 then 'Sch-M' when 4 then 'S' when 5 then 'U' when 6 then 'X' when 7 then 'IS' when 8 then 'IU' when 9 then 'IX' when 10 then 'SIU' when 11 then 'SIX' when 12 then 'UIX' when 13 then 'BU' when 14 then 'RangeS-S' when 15 then 'RangeS-U' when 16 then 'RangeIn-Null' when 17 then 'RangeIn-S' when 18 then 'RangeIn-U' when 19 then 'RangeIn-X' when 20 then 'RangeX-S' when 21 then 'RangeX-U' when 22 then 'RangeX-X'end, Status = case req_status when 1 then 'GRANT' when 2 then 'CNVT' when 3 then 'WAIT' end, req_transactionID As TransID, req_transactionUOW As TransUOW from master.dbo.syslockinfo print 'ESL ' + convert(varchar(12), datediff(ms,@time2,getdate())) end -- latch not set end else print 'No blocking via locks at ' + convert(varchar(26), @time, 121) print '' end -- Fast not set print 'DBCC SQLPERF(WAITSTATS)' dbcc sqlperf(waitstats) Print '' Print '*********************************************************************' Print 'Print out DBCC Input buffer for all blocked or blocking spids.' Print '*********************************************************************' declare ibuffer cursor fast_forward for select distinct cast (spid as varchar(6)) as spid from @probclients where (spid <> @@spid) and ((blocked!=0 or (waittype != 0x0000 and ignore_app = 0)) or spid in (select blocked from @probclients where blocked != 0)) open ibuffer fetch next from ibuffer into @spid while (@@fetch_status != -1) begin print '' print 'DBCC INPUTBUFFER FOR SPID ' + @spid exec ('dbcc inputbuffer (' + @spid + ')') fetch next from ibuffer into @spid end deallocate ibuffer Print '' Print '*******************************************************************************' Print 'Print out DBCC OPENTRAN for active databases for all blocked or blocking spids.' Print '*******************************************************************************' declare ibuffer cursor fast_forward for select distinct cast (dbid as varchar(6)) from @probclients where dbid != 0 open ibuffer fetch next from ibuffer into @spid while (@@fetch_status != -1) begin print '' set @dbname = db_name(@spid) set @status = DATABASEPROPERTYEX(@dbname,'Status') set @useraccess = DATABASEPROPERTYEX(@dbname,'UserAccess') print 'DBCC OPENTRAN FOR DBID ' + @spid + ' ['+ @dbname + ']' if @Status = N'ONLINE' and @UserAccess != N'SINGLE_USER' dbcc opentran(@dbname) else print 'Skipped: Status=' + convert(nvarchar(128),@status) + ' UserAccess=' + convert(nvarchar(128),@useraccess) print '' if @spid = '2' select @blocked = 'Y' fetch next from ibuffer into @spid end deallocate ibuffer if @blocked != 'Y' begin print '' print 'DBCC OPENTRAN FOR DBID 2 [tempdb]' dbcc opentran ('tempdb') end print 'End time: ' + convert(varchar(26), getdate(), 121) end -- All else print '8 No Waittypes: ' + convert(varchar(26), @time, 121) + ' ' + convert(varchar(12), datediff(ms,@time,getdate())) + ' ' + ISNULL (@@servername,'(null)') GO
创建一个SQL脚本文件:checkblk.sql
WHILE 1=1 BEGIN EXEC master.dbo.sp_blocker_pss80 -- Or for fast mode -- EXEC master.dbo.sp_blocker_pss80 @fast=1 -- Or for latch mode -- EXEC master.dbo.sp_blocker_pss80 @latch=1 WAITFOR DELAY '00:00:15' END GO
osql命令示例如下:
C:>osql -E -S server -i checkblk.sql -o checkresult.txt -w 2000
server:表示服务器的机器名
checkblk.sql:表示输入的脚本文件
checkresult.txt:表示输出的结果文件
参数详情请使用命令 osql /? 查看
执行结果如下: