пятница, 25 апреля 2014 г.

100% CPU после установки Workflow Manager 1.0

Столкнулся с такой проблемой: после установки апдейтов на Workflow Manager 1.0 ушёл в 100% процессор и логи заспамили ошибками типа:

Failed SQL command after 1 tries with error '229'. Exception: System.Data.SqlClient.SqlException (0x80131904): The EXECUTE permission was denied on the object 'InsertTrackingAndStatus', database 'WFInstanceManagementDB', schema 'dbo'.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()
   at System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
   at System.Data.SqlClient.SqlCommand.EndExecuteNonQuery(IAsyncResult asyncResult)
   at Microsoft.Workflow.Management.ExecuteNonQueryAsyncResult.OnEndExecuteSql(IAsyncResult result)
   at Microsoft.Workflow.Management.ExecuteSqlAsyncResult.EndAsyncResult(IAsyncResult result)
   at Microsoft.Workflow.Common.BackoffRetryAsyncResult.IsolateWithRetry(IAsyncResult result)
   at Microsoft.Workflow.Common.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
ClientConnectionId:03eb9da5-56d7-4023-8802-d7844811bac2  Command Details:   SQL Text          : InsertTrackingAndStatus
  SQL Parameters    : 
    > @StatusRecords = Microsoft.Workflow.Management.SqlDataAccessProvider+InstanceStatusValuesCollection
    > @MetadataWithInstanceId = Microsoft.Workflow.Management.SqlDataAccessProvider+MetadataValuesWithInstanceIdCollection
    > @Variables = Microsoft.Workflow.Management.SqlDataAccessProvider+VariablesCollection
    > @TrackingRecords = 
    > @StatusHistoryRecords = 
    > @DebugTraceRecords = Microsoft.Workflow.Management.SqlDataAccessProvider+DebugTraceRecordValuesCollection
    > @RollingStatusHistoryWindowSize = 1000
    > @RollingDebugTraceWindowSize = 5000

Чинится просто, нужно выполнить скрипт на БД WFInstanceManagementDB и WFResourceManagementDB, этим мы дадим необходимые права для роли, под которой действует учётка Workflow Manager 1.0:

IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = N'WFServiceOperators' AND type = 'R')
    BEGIN
                   -- Grant all permissions of stored procedures and tables
                   DECLARE @ObjectName sysname, @ObjectType char(20), @Cmd varchar(300)
                   DECLARE ObjectCursor CURSOR LOCAL FAST_FORWARD
                   FOR SELECT name, type FROM sys.objects UNION SELECT name, 'WFUDT' FROM sys.types WHERE is_user_defined = 1

                   OPEN ObjectCursor
                   FETCH ObjectCursor INTO @ObjectName, @ObjectType
                   WHILE (@@fetch_status <> -1)
                   BEGIN                              
                                  SET @Cmd =
                                    CASE @ObjectType
                                                  WHEN 'P' THEN N'GRANT EXECUTE ON [' + @ObjectName + N'] TO [WFServiceOperators]'  
                                                  WHEN 'WFUDT' THEN N'GRANT CONTROL, REFERENCES ON TYPE::[' + @ObjectName + N'] TO [WFServiceOperators]'  
                                                  ELSE ''
                                    END

                                  IF @Cmd <> ''
                                  BEGIN
                                                 EXEC(@Cmd)
                                  END
                                  FETCH ObjectCursor INTO @ObjectName, @ObjectType
                   END
                   CLOSE ObjectCursor
                   DEALLOCATE ObjectCursor
    END
    GO