Quantcast
Channel: SQL Server Integration Services forum
Viewing all articles
Browse latest Browse all 24688

SSISDB (2017 CU8) running in Always on Group - Maintenance procedure bug (cleanup_server_retention_window)?

$
0
0

Hi,

Since upgrading to SQL 2017 (from 2017), the SSIS maintenance job keeps failing.  The job step is the following..

  DECLARE @role int
SET @role =(SELECT [role] FROM [sys].[dm_hadr_availability_replica_states] hars
             INNER JOIN [sys].[availability_databases_cluster] adc
                    ON hars.[group_id] = adc.[group_id]
                    WHERE hars.[is_local] = 1 AND adc.[database_name] ='SSISDB')
IF DB_ID('SSISDB') IS NOT NULL AND(@role IS NULL OR @role = 1)
       EXEC [SSISDB].[internal].[cleanup_server_retention_window]

However it fails with the error message"A cursor with the name 'execution_cursor' does not exist."

After looking through the proc, it de-allocated the cursor then tries to access it again within the while loop.  So we are deleting 1000 records from the SSIS history at a time, but then hit the error.  Whilst I could modify the procedure, I thought i'd see if anyone else encounted this.

SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO


CREATE PROCEDURE [internal].[cleanup_server_retention_window]
WITH EXECUTE AS 'AllSchemaOwner'
AS
    SET NOCOUNT ON
    
    DECLARE @enable_clean_operation bit
    DECLARE @retention_window_length int
    DECLARE @server_operation_encryption_level int
    
    DECLARE @caller_name nvarchar(256)
    DECLARE @caller_sid  varbinary(85)
    DECLARE @operation_id bigint
    
    EXECUTE AS CALLER
        SET @caller_name =  SUSER_NAME()
        SET @caller_sid =   SUSER_SID()
    REVERT
         
    
    BEGIN TRY
        SELECT @enable_clean_operation = CONVERT(bit, property_value) 
            FROM [catalog].[catalog_properties]
            WHERE property_name = 'OPERATION_CLEANUP_ENABLED'
        
        IF @enable_clean_operation = 1
        BEGIN
            SELECT @retention_window_length = CONVERT(int,property_value)  
                FROM [catalog].[catalog_properties]
                WHERE property_name = 'RETENTION_WINDOW'
                

            IF @retention_window_length <= 0 
            BEGIN
                RAISERROR(27163    ,16,1,'RETENTION_WINDOW')
            END
            SELECT @server_operation_encryption_level = CONVERT(int,property_value)  
                FROM [catalog].[catalog_properties]
                WHERE property_name = 'SERVER_OPERATION_ENCRYPTION_LEVEL'

            IF @server_operation_encryption_level NOT in (1, 2)       
            BEGIN
                RAISERROR(27163    ,16,1,'SERVER_OPERATION_ENCRYPTION_LEVEL')
            END
            INSERT INTO [internal].[operations] (
                [operation_type],  
                [created_time], 
                [object_type],
                [object_id],
                [object_name],
                [status], 
                [start_time],
                [caller_sid], 
                [caller_name]
                )
            VALUES (
                2,
                SYSDATETIMEOFFSET(),
                NULL,                     
                NULL,                     
                NULL,                     
                1,      
                SYSDATETIMEOFFSET(),
                @caller_sid,            
                @caller_name            
                ) 
            SET @operation_id = SCOPE_IDENTITY() 
            
            DECLARE @temp_date datetimeoffset
            DECLARE @rows_affected bigint
            DECLARE @delete_batch_size int

            
            SET @delete_batch_size = 1000  
            SET @rows_affected = @delete_batch_size
            
            SET @temp_date = DATEADD(day, -@retention_window_length, SYSDATETIMEOFFSET())
            
            CREATE TABLE #deleted_ops (operation_id bigint, operation_type smallint)
            DECLARE execution_cursor CURSOR GLOBAL FOR SELECT operation_id FROM #deleted_ops  WHERE operation_type = 200

			DECLARE @sqlString_operation_messages_scaleout   nvarchar(1024)
            DECLARE @sqlString_event_messages_scaleout       nvarchar(1024)
            DECLARE @sqlString_event_message_context_scaleout        nvarchar(1024)

            IF @server_operation_encryption_level = 1
            BEGIN
                DECLARE @execution_id bigint
                DECLARE @sqlString              nvarchar(1024)
                DECLARE @sqlString_cert         nvarchar(1024)
                DECLARE @key_name               [internal].[adt_name]
                DECLARE @certificate_name       [internal].[adt_name]

            WHILE (@rows_affected = @delete_batch_size)
            BEGIN
                DELETE TOP (@delete_batch_size)
                    FROM [internal].[operations] 
                        OUTPUT DELETED.operation_id, DELETED.operation_type INTO #deleted_ops
                    WHERE ( [end_time] <= @temp_date
                    OR ([end_time] IS NULL AND [status] = 1 AND [created_time] <= @temp_date ))
                SET @rows_affected = @@ROWCOUNT
            OPEN execution_cursor
            FETCH NEXT FROM execution_cursor INTO @execution_id
            WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @key_name = 'MS_Enckey_Exec_'+CONVERT(varchar,@execution_id)
                SET @certificate_name = 'MS_Cert_Exec_'+CONVERT(varchar,@execution_id)
                SET @sqlString_operation_messages_scaleout = 'delete from [internal].[operation_messages_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                SET @sqlString_event_messages_scaleout = 'delete from [internal].[event_messages_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                SET @sqlString_event_message_context_scaleout  = 'delete from [internal].[event_message_context_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                        SET @sqlString = 'DROP SYMMETRIC KEY '+ @key_name
                        SET @sqlString_cert = 'DROP CERTIFICATE '+ @certificate_name
                        BEGIN TRY
                    EXECUTE sp_executesql @sqlString
                            EXECUTE sp_executesql @sqlString_cert
                            EXECUTE sp_executesql @sqlString_operation_messages_scaleout
                            EXECUTE sp_executesql @sqlString_event_messages_scaleout
                            EXECUTE sp_executesql @sqlString_event_message_context_scaleout
                        END TRY

                        BEGIN CATCH
                            
                        END CATCH

                FETCH NEXT FROM execution_cursor INTO @execution_id
            END
            CLOSE execution_cursor
                    TRUNCATE TABLE #deleted_ops
                END
                DROP TABLE #deleted_ops

            DEALLOCATE execution_cursor
            END
            ELSE BEGIN
                WHILE (@rows_affected = @delete_batch_size)
                BEGIN
                    DELETE TOP (@delete_batch_size)
                        FROM [internal].[operations] 
                         OUTPUT DELETED.operation_id, DELETED.operation_type INTO #deleted_ops
                        WHERE ( [end_time] <= @temp_date
                        OR ([end_time] IS NULL AND [status] = 1 AND [created_time] <= @temp_date ))
                    SET @rows_affected = @@ROWCOUNT

                      OPEN execution_cursor
            FETCH NEXT FROM execution_cursor INTO @execution_id
             WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @sqlString_operation_messages_scaleout = 'delete from [internal].[operation_messages_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                SET @sqlString_event_messages_scaleout = 'delete from [internal].[event_messages_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                SET @sqlString_event_message_context_scaleout  = 'delete from [internal].[event_message_context_scaleout] where operation_id = '+CONVERT(varchar,@execution_id)
                BEGIN TRY
                    EXECUTE sp_executesql @sqlString_operation_messages_scaleout
                    EXECUTE sp_executesql @sqlString_event_messages_scaleout
                    EXECUTE sp_executesql @sqlString_event_message_context_scaleout
                END TRY
                BEGIN CATCH 
                END CATCH
                FETCH NEXT FROM execution_cursor INTO @execution_id
            END
            CLOSE execution_cursor
                    TRUNCATE TABLE #deleted_ops
            DEALLOCATE execution_cursor
               END
                DROP TABLE #deleted_ops
            END
            UPDATE [internal].[operations]
                SET [status] = 7,
                [end_time] = SYSDATETIMEOFFSET()
                WHERE [operation_id] = @operation_id                                  
        END
    END TRY
    BEGIN CATCH
        IF @server_operation_encryption_level = 1
        BEGIN
        IF (CURSOR_STATUS('local', 'execution_cursor') = 1 
            OR CURSOR_STATUS('local', 'execution_cursor') = 0)
        BEGIN
            CLOSE execution_cursor
            DEALLOCATE execution_cursor            
        END
        END
        UPDATE [internal].[operations]
            SET [status] = 4,
            [end_time] = SYSDATETIMEOFFSET()
            WHERE [operation_id] = @operation_id;       
        THROW
    END CATCH
    RETURN 0

GO


Viewing all articles
Browse latest Browse all 24688

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>