Sql-Server

Oracle OLEDB 連接在 SQL Server 中掛起:我可以重新啟動實例嗎?

  • October 20, 2017

此實例上有一個終止/回滾查詢,該查詢最初試圖通過 OLEDB 在遠端 Oracle 伺服器上執行 SELECT。這個查詢執行了兩天多才最終被取消。

在此處輸入圖像描述

SPID 69: transaction rollback in progress. 
Estimated rollback completion: 0%. Estimated time remaining: 0 seconds.

使用cports我發現所有打開的連接到遠端伺服器上的 1521 埠。在 cports 中,您可以關閉連接。

在此處輸入圖像描述

嘗試關閉連接後,已終止/回滾程序仍在阻止其他程序對其中一個表進行模式鎖定。

在此處輸入圖像描述

如何確定數據庫在重新啟動後是否不會進入 RECOVERY PENDING?

我可以使用任務管理器殺死程序,而不殺死 SQL Server 嗎?

在此處輸入圖像描述

編輯

這是匿名查詢:

  INSERT  INTO sometable 
           ( field1 ,  
             field2 ,  
             field3 ,  
             ...
           )  
           SELECT  some_fields
           FROM    someothertable f ( NOLOCK )  
                   INNER JOIN OPENQUERY([MYORACLE_LINKED_SERVER],

回滾所用的時間可能與查詢執行的時間一樣長或更長。

幾乎可以肯定的是,如果您重新啟動實例,則受正在進行的事務影響的任何數據庫都需要執行恢復,這將花費與目前正在發生的回滾一樣長或更長的時間。

建議?不要殺死 SQL Server。

此外,終止 dllhost.exe 程序不會停止回滾,因為 SQL Server 不再需要該程序來完成回滾。

您可以通過檢查以下內容來查看是否正在針對相關數據庫發生活動:

SELECT [Database] = d.name
   , FileName = mf.name
   , num_of_reads
   , [io_stall_read_ms]
   , AvgStallPerRead = CASE WHEN num_of_reads > 0 THEN io_stall_read_ms / num_of_reads ELSE 0 END
   , num_of_writes
   , [io_stall_write_ms]
   , AvgStallPerWrite = CASE WHEN num_of_writes > 0 THEN io_stall_write_ms / num_of_writes ELSE 0 END
   , [io_stall] 
   , sample_ms
FROM sys.dm_io_virtual_file_stats(NULL,NULL) iovfs
   INNER JOIN master.sys.master_files mf WITH (NOLOCK) ON iovfs.database_id = mf.database_id AND iovfs.file_id = mf.file_id
   INNER JOIN master.sys.databases d WITH (NOLOCK) ON iovfs.database_id = d.database_id
WHERE d.name = 'database_name_in_question';

連續執行幾次應該讓你看到num_of_writes增加。

這不會幫助您了解回滾的完整進度,但可以讓您查看是否有針對數據庫的磁碟活動。

您可以檢查以下查詢以查看針對相關數據庫的活動:

SELECT login_time
   , host_name
   , program_name
   , start_time
   , r.status
   , command
   , wait_type
   , last_wait_type
   , wait_time
   , wait_resource
   , percent_complete
   , estimated_completion_time
FROM sys.dm_exec_sessions S 
   INNER JOIN sys.dm_exec_requests R ON S.session_id = r.session_id
WHERE r.database_id = DB_ID('database_name_in_question');

通過在命令列中查找“ROLLBACK”(或類似內容)來查找發生回滾的會話。不幸的是,percent_complete 和estimated_completion_time 列對於查看回滾沒有用處。

如果您可以確定回滾活動的 SPID,則可以使用以下命令檢查回滾進度(對我來說是新手!)

KILL xx WITH STATUSONLY;

其中 xx 是 SPID。

有關詳細資訊,請參閱http://msdn.microsoft.com/en-us/library/ms173730.aspx

sys.dm_tran_database_transactions有關於正在進行的事務活動的非常詳細的資訊,包括回滾。

引用自:https://dba.stackexchange.com/questions/80827