SQL Server擴充表字段長度,引發的意外KILLED/ROLLBACK


   這一段時間,因為系統升級,新系統產生的數據長度,比原來的數據長度要長,所以說要擴充一下字段長度。

alter table TableName alter column ColumnName varchar(50)    --修改字段長度sql

在執行的時候,有這樣一個情況。

例如Student表的Name字段長度是nvarchar(50),

假如想變成nvarchar(100),這種情況,立刻能執行成功。 

假如想變成nvarchar(20),這種情況,會執行很久。

 

有一些表沒啥問題,但是有一個表數據量較大,差不多有1億多,執行時間太長,還把所有數據表給鎖住了(如下圖)。不過這種情況數據還能用語句查詢。

 

 

①我就查詢出這個語句的spid。之后kill掉。

SELECT   session_id, r.status, r.start_time, r.command, s.text, r.wait_time, r.cpu_time, 
r.total_elapsed_time, r.reads, r.writes, r.logical_reads, r.transaction_isolation_level 
FROM sys.dm_exec_requests r 
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
WHERE R.STATUS='running'

kill 75

 

 

②但是連續kill了好幾遍,依然沒啥效果,還是提示鎖住。所有就繼續看下spid為75的狀態。

  方法1: 

select spid, blocked,waittime,lastwaittype,dbid,last_batch,open_tran,hostprocess,cmd from sysprocesses where spid = 75

 

   方法2:

USE master;    
GO    
EXEC sp_who '75' --指定process_id;    

 

 兩種方法查詢出來的都是KILLED/ROLLBACK,表示,現在數據在回滾。

 

③查詢一下,數據的回滾狀態。

KILL 75 WITH STATUSONLY; 

查了一下,這個情況要等好久,有的等兩三天的都有,最好的解決辦法無非是重啟。

----------------------------------------------------解決辦法------------------------------------------------

 網上找了好久,找了找到了一篇結決辦法。

1.查詢出處於阻塞的sql線程。

SET
TRANSACTION
ISOLATION
LEVEL
READ
UNCOMMITTED

SELECT

db_id(DB_NAME(er.[database_id])) [DBID]

,er.[session_id] AS [SessionID]

,er.[command] AS [CommandType]

,est.[text] [StatementText]

,er.[status] AS [Status]

,CONVERT(DECIMAL(5, 2), er.[percent_complete]) AS [Complete_Percent]

,CONVERT(DECIMAL(38, 2), er.[total_elapsed_time] / 60000.00) AS [ElapsedTime_m]

,CONVERT(DECIMAL(38, 2), er.[estimated_completion_time] / 60000.00) AS [EstimatedCompletionTime_m]

,er.[last_wait_type] [LastWait]

,er.[wait_resource] [CurrentWait]

FROM
sys.dm_exec_requests
AS er

INNER
JOIN
sys.dm_exec_sessions
AS es ON er.[session_id] = es.[session_id]

CROSS
APPLY sys.dm_exec_sql_text(er.[sql_handle]) est

WHERE er.[command] like
'Killed%'
View Code

附:查詢出正在執行的語句

SELECT   spid,
         blocked,
         DB_NAME(sp.dbid) AS DBName,
         program_name,
         waitresource,
         lastwaittype,
         sp.loginame,
         sp.hostname,
         a.[Text] AS [TextData],
         SUBSTRING(A.text, sp.stmt_start / 2,
         (CASE WHEN sp.stmt_end = -1 THEN DATALENGTH(A.text) ELSE sp.stmt_end
         END - sp.stmt_start) / 2) AS [current_cmd]
FROM     sys.sysprocesses AS sp OUTER APPLY sys.dm_exec_sql_text (sp.sql_handle) AS A
WHERE    spid > 50
ORDER BY blocked DESC, DB_NAME(sp.dbid) ASC, a.[text];
View Code

 

 

2.查到spid是75,根據spid查詢出來系統進程hostprocess為20540。

select spid, blocked,waittime,lastwaittype,dbid,last_batch,open_tran,hostprocess,cmd from sysprocesses where spid = 69
View Code

3.在執行這條語句的機器上,用cmd命令查詢出來。

tasklist|findstr 進程號

如:tasklist|findstr 75

 4.cmd中根據進程名稱殺死進程

 taskkill /f /t /im 進程名稱

如:taskkill /f /t /im /svchost.exe

 

如果不行,只有等,或者重啟了。

 

參考文章:1.SQL Server會話KILL不掉,一直處於KILLED /ROLLBACK狀態情形淺析

                  2. 數據庫某個進程一直處在KILLED/ROLLBACK

        3.百度 谷歌 新浪 執行 SQL 出現 Lock request time out period exceeded.

   ---------------------------------------------------------------------

歷史消耗

SELECT TOP 20
    total_worker_time/1000 AS [總消耗CPU 時間(ms)],execution_count [運行次數],
    qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 時間(ms)],
    last_execution_time AS [最后一次執行時間],max_worker_time /1000 AS [最大執行時間(ms)],
    SUBSTRING(qt.text,qs.statement_start_offset/2+1, 
        (CASE WHEN qs.statement_end_offset = -1 
        THEN DATALENGTH(qt.text) 
        ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 + 1) 
    AS [使用CPU的語法], qt.text [完整語法],
    qt.dbid, dbname=db_name(qt.dbid),
    qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
FROM sys.dm_exec_query_stats qs WITH(nolock)
CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE execution_count>1
ORDER BY  total_worker_time DESC

 

  SQL DBA思想的一些Ramblings

        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM