none
Probleme de lenteur sur une application sur a la mise en place d'une replication transactionnelle RRS feed

  • Discussion générale

  • Bonjour,

      Nous avons un logiciel qui fonctionne avec une base de données sql server 2008. Nous voulons repliqué cette base d'un site A sur un site B, sur un mode transactionnel.

      Nous avons mis en place la replication sur le site A, mais à l'ajout du premier subscriber, le lancement de l'application est devenu très lent. Apres analyse des commandes repliquées, je me suis rendu compte que l'application lance des requetes de type "ALTER TABLE xxx CHECK CONSTRAINT xxx". Bref l'application lance au demarrage une verification de toutes les contraintes de clef etrantegere apparemment.

      Pour tenter de régler ce probleme, j'ai supprimé la réplication et en ai créé une nouvelle, en mettant les replications de schéma a "false". Même constat, l'applications est toujours très lente au démarrage bien que les commandes de type ALTER TABLE xxx CHECK CONSTRAINT ne soient plus répliquées....

      Quelqu'un aurait il une piste ?

    vendredi 2 novembre 2012 08:51

Toutes les réponses

  • Bonjour,

      Nous avons un logiciel qui fonctionne avec une base de données sql server 2008. Nous voulons repliqué cette base d'un site A sur un site B, sur un mode transactionnel.

      Nous avons mis en place la replication sur le site A, mais à l'ajout du premier subscriber, le lancement de l'application est devenu très lent. Apres analyse des commandes repliquées, je me suis rendu compte que l'application lance des requetes de type "ALTER TABLE xxx CHECK CONSTRAINT xxx". Bref l'application lance au demarrage une verification de toutes les contraintes de clef etrantegere apparemment.

      Pour tenter de régler ce probleme, j'ai supprimé la réplication et en ai créé une nouvelle, en mettant les replications de schéma a "false". Même constat, l'applications est toujours très lente au démarrage bien que les commandes de type ALTER TABLE xxx CHECK CONSTRAINT ne soient plus répliquées....

      Quelqu'un aurait il une piste ?


    jeudi 1 novembre 2012 15:50
  • - Merci de poster:
       * La commande complète passée par l'application (ALTER TABLE xxx CHECK CONSTRAINT xxx).
       * Le DDL d'un article sur l'abonné possédant une contrainte

    - Mauvaise idée de désactiver la réplication de DDL, qui concerne aussi l'ajout de colonne ou la modification de type de colonne sur les articles, et pas seulement les contraintes. A la première modification de    structure le distributeur va tomber et une resynchronisation sera nécessaire.


    David B.

    vendredi 2 novembre 2012 13:17
  • Bonjour,

      Je ne suis pas encore familier des terminologies sql server. Qu'entendez vous par DDL ?

    Cdlt

    vendredi 2 novembre 2012 15:49
  • C'est je suppose ce que tu entends par 'Réplication de schéma'. Le nom du paramètre de la procédure sp_changepublication est @property = 'replicate_ddl'. cf http://msdn.microsoft.com/en-us/library/ms188413.aspx. DDL = Data Definition Language, donc les ordres de modification de la structure des objets (CREATE, ALTER, DROP). Extrait:

    replicate_ddl : Data definition language (DDL) statements executed at the publisher are replicated. This property cannot be changed for non-SQL Server publications.

    Là ou je doute c'est que normalement un article contenant des contraintes est recréé avec les contraintes en NOT FOR REPLICATION sur l'abonné, c'est pourquoi je demande le script de création d'un des articles côté abonné (http://msdn.microsoft.com/en-us/library/ms152529%28v=sql.105%29.aspx)


    David B.



    vendredi 2 novembre 2012 15:57
  • Bon,  Je n'ai pas encore les DDL mais deja, voici ce que ca donner avec SQL Profiler sur le publisher lorsque j'ouvre le programme

    SET LOCK_TIMEOUT 1000;

    SELECT * FROM sys.triggers WHERE name='TG_DEL_F_BANQUEAFB'
    ALTER TABLE F_BANQUEAFB ENABLE TRIGGER TG_DEL_F_BANQUEAFB

    1 fois au moins par trigger, donc au moins 200 fois...

    ALTER TABLE F_REGTAX CHECK CONSTRAINT FKA_F_REGTAXE_TA_CODE10

    La encore, une fois par contrainte, donc au moins 200 fois...

    D'autre part, replicate_ddl est a 0 dans la publication.

    Comment dois-je faire pour récuperer les DDL sur l'abonné ?

    vendredi 2 novembre 2012 16:40
  • la ddl d'un articlesur l'abonné

    USE [MAES]
    GO

    /****** Object:  Table [dbo].[F_AGENDA]    Script Date: 11/02/2012 16:40:27 ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    SET ANSI_PADDING ON
    GO

    SET ARITHABORT ON
    GO

    CREATE TABLE [dbo].[F_AGENDA](
        [AD_Champ] [smallint] NULL,
        [AD_Evenem] [varchar](21) NULL,
        [AG_Domaine] [smallint] NULL,
        [AG_Interes] [varchar](19) NULL,
        [cbAG_Interes]  AS (CONVERT([varbinary](20),isnull([AG_Interes],''),0)),
        [AG_Debut] [smalldatetime] NULL,
        [AG_Fin] [smalldatetime] NULL,
        [AG_Veille] [smallint] NULL,
        [AG_Comment] [varchar](69) NULL,
        [AG_Type] [smallint] NULL,
        [AG_Confirme] [smallint] NULL,
        [AG_HeureDebut] [char](9) NULL,
        [AG_HeureFin] [char](9) NULL,
        [AG_Ignorer] [smallint] NULL,
        [AG_Continue] [smallint] NULL,
        [DL_No] [int] NULL,
        [cbDL_No] [int] NULL,
        [DE_No] [int] NULL,
        [cbDE_No] [int] NULL,
        [PP_No] [int] NULL,
        [cbPP_No] [int] NULL,
        [cbProt] [smallint] NULL,
        [cbMarq] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
        [cbCreateur] [char](4) NULL,
        [cbModification] [smalldatetime] NULL,
        [cbReplication] [int] NULL,
        [cbFlag] [smallint] NULL,
     CONSTRAINT [PK_CBMARQ_F_AGENDA] PRIMARY KEY CLUSTERED
    (
        [cbMarq] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO

    SET ANSI_PADDING OFF
    GO

    ALTER TABLE [dbo].[F_AGENDA]  WITH NOCHECK ADD  CONSTRAINT [FKA_F_AGENDA_DE_No] FOREIGN KEY([cbDE_No])
    REFERENCES [dbo].[F_DEPOT] ([DE_No])
    NOT FOR REPLICATION
    GO

    ALTER TABLE [dbo].[F_AGENDA] NOCHECK CONSTRAINT [FKA_F_AGENDA_DE_No]
    GO

    ALTER TABLE [dbo].[F_AGENDA]  WITH NOCHECK ADD  CONSTRAINT [FKA_F_AGENDA_DL_No] FOREIGN KEY([cbDL_No])
    REFERENCES [dbo].[F_DOCLIGNE] ([DL_No])
    NOT FOR REPLICATION
    GO

    ALTER TABLE [dbo].[F_AGENDA] NOCHECK CONSTRAINT [FKA_F_AGENDA_DL_No]
    GO

    ALTER TABLE [dbo].[F_AGENDA]  WITH NOCHECK ADD  CONSTRAINT [FKA_F_AGENDA_PP_No] FOREIGN KEY([cbPP_No])
    REFERENCES [dbo].[F_PROJETPLANNING] ([PP_No])
    NOT FOR REPLICATION
    GO

    ALTER TABLE [dbo].[F_AGENDA] NOCHECK CONSTRAINT [FKA_F_AGENDA_PP_No]
    GO

    ALTER TABLE [dbo].[F_AGENDA] ADD  DEFAULT ((0)) FOR [cbProt]
    GO

    ALTER TABLE [dbo].[F_AGENDA] ADD  DEFAULT ('CSQL') FOR [cbCreateur]
    GO

    ALTER TABLE [dbo].[F_AGENDA] ADD  DEFAULT (getdate()) FOR [cbModification]
    GO

    ALTER TABLE [dbo].[F_AGENDA] ADD  DEFAULT ((0)) FOR [cbReplication]
    GO

    ALTER TABLE [dbo].[F_AGENDA] ADD  DEFAULT ((0)) FOR [cbFlag]
    GO


    vendredi 2 novembre 2012 16:42
  • ALTER TABLE ... CHECK / NOCHECK ... ne fait qu'activer / désactiver une contrainte. Ca ne vérifie pas les contraintes. Quel est le temps d'exécution associé à chaque ALTER TABLE CHECK dans Profiler ? J'imagine que réplication ou pas ton application exécute ces appels de toutes manières. Il faut voir ce qui prend le plus de temps dans la trace Profiler de l'ouverture de l'application:

    SELECT into tempdb.guest.TRACE from fn_trace_gettable('C:\chemin\vers\mon\fichier\TRC.trc',default)
    GO
    select TOP 50
        TE.name, TR.TextData, TR.ObjectID, TR.Duration/1000/1000 Secs,
        TR.Reads, TR.Writes, TR.cpu, TR.SPID, TR.RowCounts,
        TR.HostName, TR.LoginName, TR.StartTime, TR.EndTime,
        TR.DatabaseName
    from tempdb.guest.TRACE TR
    inner join sys.trace_events TE on TE.trace_event_id = TR.EventClass
    order by TR.Duration/1000/1000 desc
    GO



    Dans le DDL de l'article sur l'abonné, on voit bien que les contraintes sont en NOT FOR REPLICATION, ce qui signifie qu'elles ne seront pas vérifiées lorsque la modification est porté par le distributeur (on part du principe que cette vérification a déjà été faite sur l'éditeur).

    David B.

    vendredi 2 novembre 2012 17:02
  • Ok, merci mais SQL server refuse d'executer cette requete ne passe pas (Syntaxe incorrecte vers le mot clef into).
    vendredi 2 novembre 2012 17:25
  • Pour repondre a ta question, oui l'application lance ces appels de toute maniere, avec ou sans replication (J'ai lancé le SQL profiler pour chaque cas).

    Quand j'avais visualisé le SQL profiler avec replication, j'avais constaté qu'aucune commande n'etait particulièrement lentes, mais que toutes prenaient approximativement 1s...

    Mais sans replication, l'application le fait beaucoup plus rapidement, j'imagine que la replication doit mettre des verrous sur certaines tables ou l'application, ce qui ralenti l'ensemble, non ?

    Dans ce cas, quelle serait la solution, lancer les réplications moins souvent, en différé ? est ce possible ?

    vendredi 2 novembre 2012 17:29
  • SELECT  * into tempdb.guest.TRACE from fn_trace_gettable('C:\chemin\vers\mon\fichier\TRC.trc',default)

    David B.

    vendredi 2 novembre 2012 18:19
  • Est-ce que le temps est le même avec ou sans la publication.
    Est-ce que la valeur de duration est 1 ou 1000 ? Par défaut profiler affiche en ms et en interne (dans la table tempdb.guest.TRACE par exemple) les temps sont en µs.

    David B.

    vendredi 2 novembre 2012 18:23
  • Alors :

      - Sans publication : Temps de réponse correct

      - Avec publication et sans abonnés : Temps de réponse correct (Sur le SQL Profiler, les requetes SELECT * FROM sys.triggers WHERE name='TG_DEL_F_BANQUEAFB' prennent environ 5ms chacune en duration et ALTER TABLE F_REGTAX CHECK CONSTRAINT FKA_F_REGTAXE_TA_CODE10 5ms chacune)

      - Avec publication et avec 1 abonné : Temps de réponse mauvais (Sur le SQL Profiler, les requetes SELECT * FROM sys.triggers WHERE name='TG_DEL_F_BANQUEAFB' prennent environ 5ms chacune en duration et ALTER TABLE F_REGTAX CHECK CONSTRAINT FKA_F_REGTAXE_TA_CODE10 400ms chacune)

    vendredi 2 novembre 2012 19:52
  • L'alter table check constraint ne logge que très peu de choses dans le journal, un accès à syscolpars, et trois accès à sysschobjs. Et l'activation de la souscription ne peut pas avoir d'incidence
    là dessus, la réplication est asynchrone, la seule chose qui pourrait avoir un impact c'est le log reader mais si les temps sont les mêmes avec ou sans la publication créée...

    Il faudrait pouvoir tracer les attentes lors du démarrage global.

    -- Créer la session XE
    IF EXISTS (
    	SELECT * FROM sys.server_event_sessions
    		WHERE name = 'MonitorWaits')
        DROP EVENT SESSION MonitorWaits ON SERVER
    GO
    
    CREATE EVENT SESSION MonitorWaits ON SERVER
    ADD EVENT sqlos.wait_info
    	(WHERE sqlserver.session_id = XX/*regarder dans Profiler le SPID de la connexion qui lance le programme */)
    ADD TARGET package0.asynchronous_file_target
        (SET FILENAME = N'X:\chemin\a\definir\EE_WaitStats.xel', 
        METADATAFILE = N'X:\chemin\a\definir\EE_WaitStats.xem')
    WITH (max_dispatch_latency = 1 seconds);
    GO
    -- Start the session
    ALTER EVENT SESSION MonitorWaits ON SERVER
    STATE = START;
    GO
    
    -- Lancer le démarrage de l'application
    
    -- Stopper la session
    ALTER EVENT SESSION MonitorWaits ON SERVER
    STATE = STOP;
    GO
    
    -- Vérifier si des lignes sont déjà présentes dans le fichier XEL
    SELECT COUNT (*)
    	FROM sys.fn_xe_file_target_read_file
    	('X:\chemin\a\definir\EE_WaitStats*.xel',
    	'X:\chemin\a\definir\EE_WaitStats*.xem', null, null);
    GO
    
    -- Agréger les résultats
    CREATE TABLE ##RawEventData (
    	Rowid		INT IDENTITY PRIMARY KEY,
    	event_data	XML);
    	
    GO
    
    
    INSERT INTO ##RawEventData (event_data)
    SELECT
        CAST (event_data AS XML) AS event_data
    FROM sys.fn_xe_file_target_read_file (
    	'X:\chemin\a\definir\EE_WaitStats*.xel',
    	'X:\chemin\a\definir\EE_WaitStats*.xem', null, null);
    GO
    
    SELECT
    	event_data.value (
    		'(/event/@timestamp)[1]',
    			'DATETIME') AS [Time],
    	event_data.value (
    		'(/event/data[@name=''wait_type'']/text)[1]',
    			'VARCHAR(100)') AS [Wait Type],
    	event_data.value (
    		'(/event/data[@name=''opcode'']/text)[1]',
    			'VARCHAR(100)') AS [Op],
    	event_data.value (
    		'(/event/data[@name=''duration'']/value)[1]',
    			'BIGINT') AS [Duration (ms)],
    	event_data.value (
    		'(/event/data[@name=''max_duration'']/value)[1]',
    			'BIGINT') AS [Max Duration (ms)],
    	event_data.value (
    		'(/event/data[@name=''total_duration'']/value)[1]',
    			'BIGINT') AS [Total Duration (ms)],
    	event_data.value (
    		'(/event/data[@name=''signal_duration'']/value)[1]',
    			'BIGINT') AS [Signal Duration (ms)],
    	event_data.value (
    		'(/event/data[@name=''completed_count'']/value)[1]',
    			'BIGINT') AS [Count]
    FROM ##RawEventData;
    GO
    
    -- Interroger la table pour voir le résultat
    SELECT
    	waits.[Wait Type],
    	COUNT (*) AS [Wait Count],
    	SUM (waits.[Duration]) AS [Total Wait Time (ms)],
    	SUM (waits.[Duration]) - SUM (waits.[Signal Duration])
    		AS [Total Resource Wait Time (ms)],
    	SUM (waits.[Signal Duration]) AS [Total Signal Wait Time (ms)]
    FROM 
    	(SELECT
    		event_data.value (
    			'(/event/@timestamp)[1]',
    				'DATETIME') AS [Time],
    		event_data.value (
    			'(/event/data[@name=''wait_type'']/text)[1]',
    				'VARCHAR(100)') AS [Wait Type],
    		event_data.value (
    			'(/event/data[@name=''opcode'']/text)[1]',
    				'VARCHAR(100)') AS [Op],
    		event_data.value (
    			'(/event/data[@name=''duration'']/value)[1]',
    				'BIGINT') AS [Duration],
    		event_data.value (
    			'(/event/data[@name=''signal_duration'']/value)[1]',
    				'BIGINT') AS [Signal Duration]
    	FROM ##RawEventData
    	) AS waits
    WHERE waits.op = 'End'
    GROUP BY waits.[Wait Type]
    ORDER BY [Total Wait Time (ms)] DESC;
    GO
    
    -- Cleanup
    DROP TABLE ##RawEventData;
    GO


    David B.


    dimanche 4 novembre 2012 10:22
  • Bonjour,

    Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mardi 6 novembre 2012 15:48
    Modérateur
  • Bonjour,

    Nous changeons le type de votre question à « Discussion générale » parce que vous n’êtes pas revenu avec les informations sollicitées. Si vous avez plus de temps pour réexaminer la question et fournir plus d'informations, n'hésitez pas à modifier le type du thread à « Question ». Si le problème est résolu, s’il vous plaît partagez la solution avec nous afin que la réponse puisse être trouvée et utilisée par d'autres membres de la communauté ayant des questions similaires.

    Merci !

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mercredi 7 novembre 2012 09:09
    Modérateur