[WSUS]クリーンアップウィザードでエラーとなる

Windows

概要

WSUS管理マネージャーよりクリーンアップウィザードを実行しても,途中で「ノードのリセット」画面が表示され完了しない。がタイムアウト発生したりする。

以下の手順は WSUS のデータベースとして,Windows Internal Database (WID) を使用している環境の場合

手順

方法は3つ

A.索引の再構築をしてから,クリーンアップウィザードを再実行

1. SQL Server Mnagement Studio をサーバーにインストール

すでにインストールされている場合は不要

インストールがおわれば,管理者とて実行で起動しサーバー名を以下のものにして,管理者ユーザーで接続する

\.\pipe\MICROSOFT##WID\tsql\query

2.メンテナンススクリプトを実行

スクリプトファイルは以下のサイトにある。wsusdbmaintenance-sql をダウンロードします。

SQL Server Mnagement Studio を利用して,上記で配布されているスクリプトを WSUS データーベースに対して実行する。

/****************************************************************************** 
This sample T-SQL script performs basic maintenance tasks on SUSDB 
1. Identifies indexes that are fragmented and defragments them. For certain 
   tables, a fill-factor is set in order to improve insert performance. 
   Based on MSDN sample at http://msdn2.microsoft.com/en-us/library/ms188917.aspx 
   and tailored for SUSDB requirements 
2. Updates potentially out-of-date table statistics. 
******************************************************************************/ 
 
USE SUSDB; 
GO 
SET NOCOUNT ON; 
 
-- Rebuild or reorganize indexes based on their fragmentation levels 
DECLARE @work_to_do TABLE ( 
    objectid int 
    , indexid int 
    , pagedensity float 
    , fragmentation float 
    , numrows int 
) 
 
DECLARE @objectid int; 
DECLARE @indexid int; 
DECLARE @schemaname nvarchar(130);  
DECLARE @objectname nvarchar(130);  
DECLARE @indexname nvarchar(130);  
DECLARE @numrows int 
DECLARE @density float; 
DECLARE @fragmentation float; 
DECLARE @command nvarchar(4000);  
DECLARE @fillfactorset bit 
DECLARE @numpages int 
 
-- Select indexes that need to be defragmented based on the following 
-- * Page density is low 
-- * External fragmentation is high in relation to index size 
PRINT 'Estimating fragmentation: Begin. ' + convert(nvarchar, getdate(), 121)  
INSERT @work_to_do 
SELECT 
    f.object_id 
    , index_id 
    , avg_page_space_used_in_percent 
    , avg_fragmentation_in_percent 
    , record_count 
FROM  
    sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f 
WHERE 
    (f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1) 
    or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0) 
    or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0) 
 
PRINT 'Number of indexes to rebuild: ' + cast(@@ROWCOUNT as nvarchar(20)) 
 
PRINT 'Estimating fragmentation: End. ' + convert(nvarchar, getdate(), 121) 
 
SELECT @numpages = sum(ps.used_page_count) 
FROM 
    @work_to_do AS fi 
    INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id 
    INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id 
 
-- Declare the cursor for the list of indexes to be processed. 
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do 
 
-- Open the cursor. 
OPEN curIndexes 
 
-- Loop through the indexes 
WHILE (1=1) 
BEGIN 
    FETCH NEXT FROM curIndexes 
    INTO @objectid, @indexid, @density, @fragmentation, @numrows; 
    IF @@FETCH_STATUS < 0 BREAK; 
 
    SELECT  
        @objectname = QUOTENAME(o.name) 
        , @schemaname = QUOTENAME(s.name) 
    FROM  
        sys.objects AS o 
        INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id 
    WHERE  
        o.object_id = @objectid; 
 
    SELECT  
        @indexname = QUOTENAME(name) 
        , @fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END 
    FROM  
        sys.indexes 
    WHERE 
        object_id = @objectid AND index_id = @indexid; 
 
    IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0) 
        SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE'; 
    ELSE IF @numrows >= 5000 AND @fillfactorset = 0 
        SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)'; 
    ELSE 
        SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD'; 
    PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command; 
    EXEC (@command); 
    PRINT convert(nvarchar, getdate(), 121) + N' Done.'; 
END 
 
-- Close and deallocate the cursor. 
CLOSE curIndexes; 
DEALLOCATE curIndexes; 
 
 
IF EXISTS (SELECT * FROM @work_to_do) 
BEGIN 
    PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20)) 
    SELECT @numpages = @numpages - sum(ps.used_page_count) 
    FROM 
        @work_to_do AS fi 
        INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id 
        INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id 
 
    PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20)) 
END 
GO 
 
 
--Update all statistics 
PRINT 'Updating all statistics.' + convert(nvarchar, getdate(), 121)  
EXEC sp_updatestats 
PRINT 'Done updating statistics.' + convert(nvarchar, getdate(), 121)  
GO 

メモ
実行時間はかなり長い。場合のも夜が定期メンテナンスで30分はかかります。全くしたことがなければ,数時間かかることもあります。

3.クリーンアップウィザードを実行

WSUS管理マネージャーにて実行する。

上記のSQLでは索引を再構築してSQLサーバーのパフォーマンスを上げることにあります。SQLを実行したとしても,クリーンアップウィザードにてやはりノードのリセットが表示される場合は,以下のBの方法で作業します。

B.Power Shellでの作業

Windows Server 2012 以降の WSUS の場合,以下のコマンドをPower Shell で実行する

#古いコンピューターを削除する
Invoke-WsusServerCleanup -CleanupObsoleteComputers

#廃止された更新を削除する
Invoke-WsusServerCleanup -CleanupObsoleteUpdates

#不要な更新ファイルを削除する
Invoke-WsusServerCleanup -CleanupUnneededContentFiles

#廃止されたリビジョンを削除する
Invoke-WsusServerCleanup -CompressUpdates

その他必要に応じて使えそうなパラメーターは
https://docs.microsoft.com/ja-jp/powershell/module/updateservices/Invoke-WsusServerCleanup?view=windowsserver2016-ps

C. データベースのクエリ実行タイムアウトの時間を増やす

SUSDB に対して以下のSQLを実行する。規定は 600秒 となっている。とりあず 6000秒としたりさらに増やしたりする。変更後の再起動は不要

USE SUSDB ;
GO
EXEC sp_configure 'remote query timeout', 6000 ;
GO
RECONFIGURE ;
GO

肥大化を予防するために毎日クリーンアップを自動実行させる

タスクスケジューラーで クリーンアップ用のスクリプトを毎日自動実行させることで対応させます。

  1. WSUS_ClenaUP.os1 の作成
Start-Transcript "C:\WSUS\WSUS_Cleanup.log"
echo "WSUSクリーンアップ中です。。この画面はこのままにしてください。"
Invoke-WsusServerCleanup -CompressUpdates
Invoke-WsusServerCleanup -CleanupObsoleteUpdates
Invoke-WsusServerCleanup -CleanupObsoleteComputers
Invoke-WsusServerCleanup -CleanupUnneededContentFiles
Invoke-WsusServerCleanup -DeclineExpiredUpdates
Invoke-WsusServerCleanup -DeclineSupersededUpdates
Stop-Transcript

メモ帳とかで作成します。1行目がログの出力先なので適当に変更してください。

2.タスクスケジューラーへの登録

必要な設定項目は以下のとおり
 最上位の特権で実行する ON
 プログラム C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
 引数 C:\WSUS\WSUS_CleanUP.ps1 ・・・上記のファイルの保存場所

プロパティ

Windows Server 2012 R2
Windows Server 2019

コメント

スポンサーリンク
タイトルとURLをコピーしました