Enregistrement mis à jour de SQL Server sur un groupe de fichiers en lecture seule?


8

J'ai une très grande base de données dans notre entrepôt de données où nous avons implémenté le partitionnement pour gérer la maintenance et les sauvegardes. Les enregistrements d'un certain âge sont finalement migrés vers un groupe de fichiers en lecture seule une fois par mois.

Parfois, notre processus ETL tente de mettre à jour des enregistrements plus anciens qui ont déjà été migrés vers l'archive et nous nous attendons à ce qu'ils échouent. Cependant, j'ai au moins deux exemples récents où l'enregistrement dans test est mis à jour même lorsqu'il semble être dans une partition sur le groupe de fichiers en lecture seule dans notre environnement de test (interrogation sys.partition_functionset sys.partition_range_values).

Un enregistrement identique en production entraîne l'échec attendu lors de la tentative de mise à jour de l'enregistrement. Les deux fois où nous avons détecté cela jusqu'à présent, la mise à jour échoue en production mais réussit au test (jamais l'inverse).

Faits pertinents sur l'environnement:

  • SQL Server 2012 SP3 CU3 (build 11.0.6537.0)
  • Le test est une édition développeur, la production est une entreprise
  • Peut en fournir d'autres comme demandé: sérieusement perplexe en ce moment ...

MISE À JOUR 2016-08-19

Avait mis à jour de nouveaux enregistrements en quelque sorte du jour au lendemain. Confirmé qu'il se trouvait dans le groupe de fichiers en lecture seule. J'ai découvert que je peux mettre à jour les enregistrements qui ont été insérés en même temps (c'est-à-dire qu'ils se trouvent également sur la même partition du groupe de fichiers en lecture seule). J'ai identifié un seul enregistrement sur la même partition et j'ai pu mettre à jour l'enregistrement plusieurs fois. Tente de mettre à jour l'enregistrement qui a été mis à jour pendant la nuit entraîne l'échec attendu.

MISE À JOUR 2016-08-11

Les mises à jour continuent de se produire pendant le traitement nocturne du test sur la partition en lecture seule. La tentative de mise à jour des mêmes enregistrements à partir du processus échoue. La tentative de mise à jour des mêmes enregistrements en étant connecté en tant qu'utilisateur qui l'a mis à jour a échoué. Je suis également incapable de reproduire le problème en mettant à jour un enregistrement similaire qui n'a pas encore été touché par le processus nocturne.

MISE À JOUR 2016-08-04

J'ai découvert aujourd'hui qu'il ne se limitait pas à cette seule table car j'ai découvert une autre occurrence du même comportement sur une table différente en utilisant le même schéma de partition.

MISE À JOUR 2016-08-03

L'exécution du script à partir de ce script MSDN confirme ce que j'obtiens lorsque j'utilise les vues d'aide de partition de Kendra Little ph.FilegroupDetailet à ph.ObjectDetailpartir de cette démo . L'enregistrement en question réside dans la partition # 2 (la valeur de la colonne de partition pour l'enregistrement en question est le 2015-03-18)

Filegroup     Low Boundary     UpperBoundary
Archive  (RO) NULL             1900-01-01
Archive  (RO) 1900-01-01       2015-04-01
ActiveFG (RW) 2015-04-01       2015-07-01
ActiveFG (RW) 2015-07-01       2015-10-01
ActiveFG (RW) 2015-10-01       2015-01-01
ActiveFG (RW) 2016-01-01       2016-04-01
ActiveFG (RW) 2016-04-01       2016-07-01
ActiveFG (RW) 2016-07-01       2016-10-01
ActiveFG (RW) 2016-10-01       2017-01-01
ActiveFG (RW) 2017-01-01       2115-01-01
ActiveFG (RW) 2115-01-01       NULL

Code pour mettre la table sur la partition (il n'y a pas d'autres index)

ALTER TABLE [dbo].[TABLE_NAME] ADD  CONSTRAINT [pk_TABLE_NAME] PRIMARY KEY CLUSTERED 
(
    [ETL_VERS_START_DTM] ASC,
    [ACCT_NO] ASC,
    [ACCT_TYPE] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ps_SmallTablesDate(ETL_VERS_START_DTM)

L'instruction de mise à jour qui devrait échouer (via Informatica):

UPDATE TABLE_NAME SET ETL_JOB_SEQ_NUM = ?, ETL_IUD_CD = ?, ETL_UPD_DTM = ?, ETL_DEL_DTM = ? WHERE ETL_VERS_START_DTM = ? AND ACCT_NO = ? AND ACCT_TYPE = ?
ETL_VERS_START_DTM (ETL_VERS_START_DTM:Date:): "03/17/2015 23:30:02.140000000"
ETL_JOB_SEQ_NUM (ETL_JOB_SEQ_NUM:Int:): "1173651"
ETL_IUD_CD (ETL_IUD_CD:Char.1:): "D"
ETL_UPD_DTM (ETL_UPD_DTM:Date:): "08/02/2016 02:32:45.000000000"
ETL_DEL_DTM (ETL_DEL_DTM:Date:): "08/02/2016 00:10:03.567000000"
ACCT_NO (ACCT_NO:Char.12:): "1234567890"
ACCT_TYPE (ACCT_TYPE:Char.3:): "OLN"

MISE À JOUR 2017-02-21

Donc, après tout ce temps, nous avons découvert qu'en quelque sorte, lorsque la plus ancienne partition active était fusionnée dans l'archive, une section d'enregistrements n'était pas déplacée sur le disque du groupe de fichiers actif vers le groupe de fichiers d'archive. La requête suivante montre que les enregistrements de la partition 2 ont été mappés à ActiveFG tandis que l'inspection du schéma de partitionnement réel montre que ces mêmes enregistrements doivent être triés dans le groupe de fichiers Archive par la fonction de partition.

SELECT  OBJECT_NAME(P.[object_id]) ,
    P.index_id ,
    P.partition_number ,
    F.name ,
    F.filegroup_guid
FROM    sys.allocation_units AU
    JOIN sys.partitions P ON P.partition_id = AU.container_id
    JOIN sys.filegroups F ON F.data_space_id = AU.data_space_id
WHERE   P.partition_number IN ( 1, 2, 3 )
    AND P.[object_id] = OBJECT_ID('TABLE_NAME')
ORDER BY P.partition_number;

J'ai annulé tout le partitionnement dans les bases de données en cours d'utilisation et conservé une version de celle qui a été cassée pour fonctionner avec le ticket Microsoft. Je dois réviser le plan de partitionnement avec notre équipe DW, mais je dois admettre que je suis timide à l'idée de recommencer.

Microsoft n'a pas été en mesure de reproduire ce comportement et a donc terminé avec le ticket pour le moment. Ils semblent prêts à hausser les épaules et à supposer qu'il n'est pas présent en 2014/2016? Ils ne semblent pas pouvoir le reproduire dans leurs laboratoires malgré ma capacité à le faire continuer d'exister dans la base de données même après que je l'ai restauré à partir de la sauvegarde dans mon système.


J'ai annulé tout le partitionnement dans les bases de données en cours d'utilisation et conservé une version de celle qui a été cassée pour fonctionner avec le ticket MS. Je dois réviser le plan de partitionnement avec notre équipe DW mais j'avouerai être un timide mais timide à l'idée de recommencer ...
toosuto

Réponses:


1

J'ai une confession à faire.

Une fois, quand j'étais jeune, j'ai construit un processus ETL commencé par changer les groupes de fichiers en lecture seule en lecture-écriture, faire son travail ETL, puis les remettre en lecture seule.

Donc, juste au cas où vous auriez un collègue qui était diabolique comme moi (j'étais jeune, j'avais besoin d'argent), vous pouvez tester par:

  1. Modifiez le nom du groupe de fichiers en lecture seule - de cette façon, si quelqu'un a des scripts codés en dur qui modifient le groupe de fichiers par son nom, ses scripts échoueront et vous attraperez le coupable. Ou, un peu plus dur:

  2. Utilisez le profileur ou les événements étendus pour suivre quiconque effectue une ALTER DATABASE.


Nous avions en fait fourni un script à l'équipe DW pour effectuer ce changement afin qu'ils n'aient pas à nous réveiller la nuit à l'occasion rare mais attendue de l'échec de leur travail. Nous avons également un déclencheur d'audit au niveau du serveur (sur DDL_SERVER_LEVEL_EVENTS) qui définit les hits de propriété de lecture / écriture du groupe de fichiers. Il nous envoie le script SQL, l'utilisateur et l'adresse IP à réviser par l'équipe DBA.
toosuto

Bien que je puisse leur sembler assez sournois pour utiliser notre script pour modifier les paramètres du groupe de fichiers avant leur processus ETL, ils ne sont tout simplement pas assez conscients techniquement pour rechercher et désactiver notre déclencheur.
toosuto
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.