Tagged with Performance

Microsoft Dynamics CRM 4.0 Indexing Service

Le service d’indexation est requis pour le fonctionnement de Microsoft Dynamics CRM… rien d’excitant.

Microsoft Dynamics CRM utilise ce service uniquement pour indexer les fichiers d’aide du CRM. Le service d’indexation doit donc être installé et démarré aussi bien sur le serveur que les clients pour Outlook avec mode hors ligne. (Outlook client with offline mode)

Cependant, le service d’indexation peut prendre une quantité considérable de ressources sur le serveur où est installé Microsoft Dynamics CRM. Voir CPU et Page Fault.

SpotLightOnIndexingService

En ajoutant le service d’indexation au serveur, le service crée automatiquement un index, nommé System, qui inclus tous les répertoires sur tout les disques locaux attachés au système d’exploitation. Un autre index, nommé Web est ajouté lorsque IIS est installé. En activant le service, les catalogues par défaut sont aussi démarrés et utilisent les ressources du système.

IndexingServiceCRM

 

Arrêtez l’indexation des autres catalogues pour maximiser l’utilisation des ressources du serveur. Laissez uniquement le catalogue Microsoft CRM Help.

Vous pourriez aussi arrêter l’indexation de Microsoft CRM Help et l’application fonctionnerait probablement. Cependant cette approche n’est pas supportée par Microsoft.

Sous Windows Server 2003, le service d’indexation se trouve dans la console gestion de l’ordinateur, dans Services and Applications.

Sous Windows Server 2008,  http://bradmarsh.net/index.php/2008/01/07/2008-server-where-is-indexing-service/

Tagged , , , , ,

Performance des Workflows et traitements asynchrones

Vous pouvez remarquer des problèmes de performances avec les Workflows dans Microsoft Dynamics CRM 4.0 dans un déploiement de grande envergure.

Habituellement, vous aurez déjà ajouté la clé de registre suivante afin de supprimer automatiquement les Workflows complétés.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM

DWORD AsyncRemoveCompletedWorkflows = 1

Cette configuration est tirée de l’article:

« The AsyncOperationBase and WorkflowLogBase tables grow very large and performance issues occur when you use many workflows in Microsoft Dynamics CRM 4.0

KB968755

Cependant, cette clé s’applique seulement aux entrées des tables AsyncOperationBase  et WorkflowLogBasequi possèdent un OperationType correspondant à 10. Donc seulement les opérations de type Workflows seront supprimées lorsqu’elles seront complétées.

Pour connaitre le nom d’une opération que vous voyez dans la table AsyncOperationBase, référez-vous au SDK de Microsoft Dynamics CRM, ou en ligne :

AsyncOperationType Class: http://msdn.microsoft.com/en-us/library/bb930133.aspx

AsyncOperationStatus Class: http://msdn.microsoft.com/en-us/library/bb930132.aspx

Il ne faut pas oublier que, le fait de configurer la clé de registre ci-dessus, ne supprime pas les vieilles entrées de la table AsyncOperationBase : elle épure seulement les nouvelles. Ceci dit, si vous configurez cette clé un certain temps après le déploiement, vous devez supprimer des entrées dans AsyncOperationBase. L’article KB968520 explique clairement comment faire le ménage. Cette étape est primordiale!

« Performance is slow if the AsyncOperationBase table becomes too large in Microsoft Dynamics CRM 4.0 »


Malgré tout, vous réaliserez après un certain temps que la table AsyncOperationBase se remplit rapidement et que les performances se dégradent à nouveau malgré la modification  expliquée plus haut.

Exécutez d’abord cette requête SQL pour connaitre le nombre d’entrées qui pourraient être supprimées :

USE MicrosoftCRM_MSCRM
GO
SELECT COUNT(AsyncOperationId)
FROM AsyncOperationBase WITH (NOLOCK)
WHERE OperationType in (1, 9, 12, 25, 27, 10)
AND StateCode = 3 AND StatusCode IN (30,32)

Ensuite, pour connaitre le type d’opérations qui peuvent être supprimées :

 

SELECT OperationType, COUNT(*)
FROM AsyncOperationBase WITH (NOLOCK)
WHERE OperationType in (1, 9, 12, 25, 27, 10)
AND StateCode = 3 AND StatusCode IN (30,32)
GROUP BY OperationType

Avec le KB968755 expliqué plus haut, vous ne devriez pas avoir de résultat pour l’OperationType 10, car il correspond aux Workflows et sont supprimés automatiquement.

Ceci peut répondre à votre besoin si vous utilisez seulement des Workflows. Si vous utilisez les Plugins à grande échelle, ce qui est fort probable, cela ne sera pas suffisant!

Lorsque vous utilisez vigoureusement les plugins que vous avez ajoutés, vous remarquerez beaucoup d’entrées dans la table AsyncOperationBase pour l’OperationType  1. Ce type correspond aux Workflows Expension Tasks ou Events. Par défaut, ces entrées ne sont pas épurées automatiquement. (Bien souvent, même si le DeletionStateCode est changé.)

Pour que les Events soient épurés automatiquement, il faut mettre en place une deuxième clé de registre :

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM

DWORD AsyncRemoveCompletedJobs = 1

« The Workflow Expansion Task records cause the AsyncOperationBase table in the MSCRM database to grow too large in Microsoft Dynamics CRM 4.0»

KB957871

Ah oui… j’ose espérer que c’est le cas, mais vous devez au moins avoir mis en place la mise à jour cumulative 3 de Microsoft Dynamics CRM 4.0 pour que les clés de registre soient prises en compte.

Donc en résumé, pour garder performantes les tables utilisées par le service de traitements asynchrones, il faut :

  • Avoir bien planifié l’utilisation des Workflows et des Plugins dans CRM 4.0 ;)
  • Effectuer le ménage initial des tables
  • Supprimer automatiquement les Completed Workflows via la clé de registre.
  • Supprimer automatiquement les Workflow Expension Tasks via l’autre clé de registre.
  • Lire le Optimizing and Maintaining Performance Microsoft Dynamics CRM 4.0
Tagged , , , , ,

Importation d’entités personnalisées

Si vous importez une grande quantité de personnalisations ou des entités généreusement modifiées, vous pouvez être confronté à des messages d’erreur comme ceux-ci :

Source : MSCRMWebService

Category : None

Event ID : 19457
Customization Import failed. Error: ExecuteNonQuery requires an open and available Connection.

Source: ASP.NET

Category: Web Event

Event ID: 1309

Event code: 3001

Event message: The request has been aborted.
Exception type: HttpException
Exception message: Request timed out.

Request path: /tools/systemcustomization/ImportCustomizations/…

Deux articles publiés dans la base de connaissance de Microsoft peuvent vous venir en aide

Malheureusement, il est bien possible que cela ne règle pas votre problème et que vous ne soyez toujours pas en mesure d’importer l’ensemble des personnalisations. Voici une suggestion pour y arriver :

1)      Dans Settings – Customizations, cliquez sur Import Customizations

2)      Choississez l’Import File puis cliquez sur Upload

3) Sélectionnez seulement une entité à la fois puis cliquez sur Import Selected Customizations

4)      Répétez l’étape 3 pour chacune des entités personnalisées à importer.

5)      Lorsque chacune des entités aura été importée individuellement, cliquez sur More Actions, puis sur Import All Customizations

6)      Publier toutes les personnalisations
Un peu d’explications, quand même : Il semble que le mécanisme d’importation de personnalisations ne soit pas extrêmement robuste. En fait, il nous abandonne au moment d’importer beaucoup d’entités personnalisées d’un seul coup et également lorsqu’on importe un petit groupe d’entités mais très personnalisées. La suggestion ci-dessus propose de charger le fichier d’import, d’importer les entités fortement personnalisées une par une puis finalement d’importer le fichier au complet.  De plus, il est important de noter que lorsque les entités sont importées une par une, les nouvelles relations vers de nouveaux attributs ne sont pas importés. C’est pour cela qu’il est primordial de réimporter l’ensemble du fichier de perso d’un seul coup avant de publier les modifications. Cela nous assure que toutes les relations entre les entités personnalisées sont importées.

Des ajustements ont été apportés dans l’Update Rollup 6 concernant l’importation de personnalisations.

Tagged , , , , , ,

Suivre le progrès de l’importation de personnalisations

L’importation de personnalisations peut générer une quantité considérable de maux de têtes. La situation devient particulièrement délicate lorsque vous importez un grand nombre de personnalisations d’un seul coup. Il se peut aussi que l’importation se corse lorsque vous importez des entités personnalisées dans un environnement complexe.

image002

Malheureusement, l’interface de Microsoft Dynamics CRM 4.0 ne présente pas de façon trop granulaire le progrès effectué lors de l’importation de personnalisations :

image004

Malheureusement, vous ne trouvez pas d’information dans les vues Filtrées dbo.FilteredImport, dbo.FilteredImportConfig, dbo.FilteredImportFile, dbo.FilteredImportLog ou dbo.FilteredImportMap.  Ces dernières contiennent plutôt les entrées relatives aux importations de données.

Pour avoir un niveau plus intéressant de détails concernant l’avancement de l’importation de personnalisations, exécuter la requête SQL suivante :

USE [MicrosoftCRM_MSCRM]
GO
SELECT * FROM dbo.[ImportJobBase] WITH (NOLOCK)
ORDER BY dbo.[ImportJobBase].[CreatedOn] DESC
--WHERE ImportJobID = '2E0CAEC7-D3BC-DE11-8053-0050569F2C14'

Avec la date et l’heure, déterminez l’entrée qui correspondant à la tâche d’importation en question.

USE [MicrosoftCRM_MSCRM]
GO
SELECT [CreatedOn], [Data] FROM dbo.[ImportJobBase] WITH (NOLOCK)
--ORDER BY dbo.[ImportJobBase].[CreatedOn] DESC
WHERE ImportJobID = '2EECAEC7-D3BC-DE11-8053-0050569F2C14'

Copier le contenu de la colonne Data dans un fichier XML

<?xml version="1.0" encoding="utf-8"?>
<importexportxml>
  <entities>
    <entity result="success" errorcode="0" errortext="">campaignactivity</entity>
    <entity result="success" errorcode="0" errortext="">reportcategory</entity>
    <entity>appointment</entity>
    <entity result="success" errorcode="0" errortext="">opportunity</entity>
    <entity result="success" errorcode="0" errortext="">uom</entity>
    <entity result="success" errorcode="0" errortext="">salesorder</entity>
    <entity>fax</entity>
    <entity>incidentresolution</entity>
    <entity result="success" errorcode="0" errortext="">pricelevel</entity>
    <entity result="success" errorcode="0" errortext="">bulkoperation</entity>
    <entity result="success" errorcode="0" errortext="">report</entity>
    <entity result="success" errorcode="0" errortext="">letter</entity>
    <entity result="success" errorcode="0" errortext="">salesliterature</entity>
    <entity result="success" errorcode="0" errortext="">role</entity>
    <entity result="success" errorcode="0" errortext="">productpricelevel</entity>
    <entity result="success" errorcode="0" errortext="">customeraddress</entity>
    <entity result="success" errorcode="0" errortext="">list</entity>
    <entity result="success" errorcode="0" errortext="">opportunityproduct</entity>
    <entity result="success" errorcode="0" errortext="">activitypointer</entity>
    <entity result="success" errorcode="0" errortext="">email</entity>
    <entity result="success" errorcode="0" errortext="">invoicedetail</entity>
    <entity result="success" errorcode="0" errortext="">contact</entity>
    <entity result="success" errorcode="0" errortext="">territory</entity>
    <entity result="success" errorcode="0" errortext="">uomschedule</entity>
    <entity result="success" errorcode="0" errortext="">contract</entity>
    <entity result="success" errorcode="0" errortext="">subject</entity>
    <entity result="success" errorcode="0" errortext="">team</entity>
    <entity result="success" errorcode="0" errortext="">campaign</entity>
    <entity result="success" errorcode="0" errortext="">account</entity>
    <entity result="success" errorcode="0" errortext="">invoice</entity>
    <entity result="success" errorcode="0" errortext="">campaignresponse</entity>
    <entity result="success" errorcode="0" errortext="">transactioncurrency</entity>
    <entity result="success" errorcode="0" errortext="">businessunit</entity>
    <entity result="success" errorcode="0" errortext="">phonecall</entity>
    <entity result="success" errorcode="0" errortext="">task</entity>
    <entity result="success" errorcode="0" errortext="">systemuser</entity>
    <entity result="success" errorcode="0" errortext="">serviceappointment</entity>
    <entity result="success" errorcode="0" errortext="">template</entity>
    <entity result="success" errorcode="0" errortext="">salesorderdetail</entity>
    <entity result="success" errorcode="0" errortext="">quotedetail</entity>
    <entity result="success" errorcode="0" errortext="">lead</entity>
    <entity result="success" errorcode="0" errortext="">quote</entity>
    <entity result="success" errorcode="0" errortext="">mailmergetemplate</entity>
    <entity result="success" errorcode="0" errortext="">product</entity>
    <entity result="success" errorcode="0" errortext="">incident</entity>
  </entities>
  <nodes>
    <node result="success" errorcode="0" errortext="">sitemap</node>
    <node result="success" errorcode="0" errortext="">isvconfig</node>
    <node result="success" errorcode="0" errortext="">relationshiproles</node>
  </nodes>
  <settings>
    <setting result="success" errorcode="0" errortext="">outlookSynchronization</setting>
    <setting result="success" errorcode="0" errortext="">marketing</setting>
  </settings>
  <securityroles></securityroles>
  <workflows></workflows>
  <languages>
    <language />
  </languages>
</importexportxml>

Vous aurez une idée des entités qui ont été importées avec succès, et celles qui ont moins bien passées.

Tagged , , , , , ,

SQL Server Auto Growth – SharePoint

Suite à un changement significatif du volume de documents acheminés dans SharePoint,  nous remarquons une grande augmentation du temps réponse du système et une détérioration générale de la performance. Parfois, la cause de ce problème peut être bien simple.

Voici un problème que je rencontre à l’occasion chez des clients. Notez que dans cet article, je mentionne un cas précis avec Microsoft Office SharePoint Server. Cependant, Celui-ci peut s’appliquer à n’importe quelle progiciel ou applicatif qui emmagasine ses données sur Microsoft SQL Server. ..

01

Lorsque Microsoft Office SharePoint Server créer des nouvelles Content Databases, certains paramètres de SQL  Server s’appliquent par défaut.

Un de ces paramètres est l‘Autogrowth des fichiers de base de données. Le paramètre par défaut de SQL  Server, pour les Data Files (.mdf) est 1Mo et 10% pour le Log File (.ldf).

Cela veut dire que…

Si un nouveau site est créé, importé, migré, ou qu’une série de documents est acheminée dans une librairie de document, l’action sera suspendue pendant que le SGDB alloue plus d’espace. À chaque fois que 1 nouveau Mo de données est emmagasiné dans la  Content Databases, SQL Server redimensionne le fichier de donnée.

De plus, si vous n’avez pas activé le  Database Instant File Initialization, chaque fois que SQL Server augmente la taille du fichier de donnée, l’espace ajoutée au fichier est écrasée par des zéros. L’Instant File Initialization permet de sauter l’étape de réécriture  des pages (data pages) avec des zéros, ce qui permet de réduire le temps du redimensionnement.

Il est possible que dans un scénario où beaucoup de documents sont chargés rapidement dans la librairie (ex : scanner…), que SQL Server ne soit pas en mesure de redimensionner ses fichiers .mdf au rythme que les données lui sont acheminées.

Un tel paramètre augmente le risque de fragmentation sur le disque et affecte la performance.

Si vous n’avez pas la chance d’avoir un administrateur de base de données qui veille sur l’infrastructure, je vous suggère de jeter un coup d’oeil à ce paramètre! De toute manière, je ne crois pas que vous devriez utiliser un paramètre comme l’Auto growth en production ;)

Référence :

Microsoft

http://support.microsoft.com/default.aspx/kb/315512

http://technet.microsoft.com/fr-fr/library/cc966414(en-us).aspx

Tagged , ,
Follow

Get every new post delivered to your Inbox.