Record aggiornato di SQL Server su filegroup di sola lettura?


8

Ho un database molto grande nel nostro data warehouse in cui abbiamo implementato il partizionamento per gestire manutenzione e backup. I record di una certa età vengono infine migrati in un gruppo di file di sola lettura una volta al mese.

Occasionalmente il nostro processo ETL tenta di aggiornare i record più vecchi che sono già stati migrati nell'archivio e prevediamo che questi falliscano. Tuttavia, ho almeno due esempi recenti in cui il record in test viene aggiornato anche quando sembra essere in una partizione nel gruppo di file di sola lettura nel nostro ambiente di test (query sys.partition_functionse sys.partition_range_values).

Un record identico in produzione provoca l'errore previsto quando si tenta di aggiornare il record. Le due volte in cui l'abbiamo colto finora l'aggiornamento non riesce in produzione ma ha esito positivo nel test (mai viceversa).

Fatti rilevanti per l'ambiente:

  • SQL Server 2012 SP3 CU3 (build 11.0.6537.0)
  • Il test è un'edizione per sviluppatori, la produzione è un'impresa
  • Può fornire gli altri come richiesto: Gravemente sconcertato in questo momento ...

AGGIORNAMENTO 2016-08-19

I nuovi record sono stati aggiornati in qualche modo durante la notte. Confermato che si trovava nel gruppo di file di sola lettura. Ho scoperto che posso aggiornare i record che sono stati inseriti contemporaneamente (cioè sono anche sulla stessa partizione nel filegroup di sola lettura). Ho identificato un singolo record sulla stessa partizione e sono stato in grado di aggiornare il record più volte. Tenta di aggiornare il record che ha aggiornato durante la notte provoca l'errore previsto.

AGGIORNAMENTO 2016-08-11

Gli aggiornamenti continuano a verificarsi durante l'elaborazione notturna durante il test sulla partizione di sola lettura. Il tentativo di aggiornare gli stessi record dal processo non riesce. Tentativo di aggiornare gli stessi record durante l'accesso come l'utente che l'ha aggiornato in precedenza non è riuscito. Non riesco nemmeno a duplicare il problema aggiornando un record simile che non è stato ancora toccato dal processo notturno.

AGGIORNAMENTO 2016-08-04

Ho scoperto oggi che non si limita a quella singola tabella poiché ho scoperto un'altra occorrenza dello stesso comportamento su una tabella diversa utilizzando lo stesso schema di partizione.

AGGIORNAMENTO 2016-08-03

L'esecuzione dello script da questo script MSDN conferma ciò che ottengo quando utilizzo le viste helper della partizione di Kendra Little ph.FilegroupDetaile ph.ObjectDetailda questa demo . Il record in questione risiede nella partizione n. 2 (il valore della colonna di partizione per il record in questione è 18-03-2015)

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

Codice per mettere la tabella sulla partizione (non ci sono altri indici)

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'istruzione di aggiornamento che dovrebbe fallire (tramite 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"

AGGIORNAMENTO 2017-02-21

Quindi, dopo tutto questo tempo, abbiamo scoperto che in qualche modo quando la partizione attiva più vecchia veniva unita all'archivio, una sezione di record non veniva spostata su disco dal gruppo di file attivo al gruppo di file di archivio. La query seguente mostra che i record della partizione 2 sono stati mappati su ActiveFG mentre l'ispezione dello schema di partizionamento effettivo mostra che quegli stessi record devono essere ordinati nel gruppo di file Archive dalla funzione di partizione.

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;

Ho eseguito il backup di tutti i partizionamenti nei database effettivamente in uso e ho conservato una versione di quella che era stata interrotta per funzionare con il ticket Microsoft. Devo rivedere il piano di partizionamento con il nostro team DW, ma ammetterò di essere un po 'timido nel tentare di nuovo.

Microsoft non è stata in grado di duplicare questo comportamento e quindi al momento viene eseguita con il ticket. Sembrano pronti a scrollarselo di dosso e presumere che non sia presente nel 2014/2016? Non riescono a replicarlo nei loro laboratori nonostante la mia capacità di farlo continuare a esistere nel database anche dopo averlo ripristinato dal backup nel mio sistema.


Ho eseguito il backup di tutti i partizionamenti nei database effettivamente in uso e ho conservato una versione di quella che era stata interrotta per funzionare con il ticket MS. Ho bisogno di rivedere il piano di partizionamento con il nostro team DW, ma ammetterò di essere un
po

Risposte:


1

Ho una confessione da fare.

Una volta, quando ero giovane, ho creato un processo ETL iniziato con la modifica dei filegroup di sola lettura in lettura-scrittura, facendo il suo lavoro ETL e quindi ripristinandoli in sola lettura.

Quindi, nel caso in cui tu abbia un collega che era diabolico come me (ero giovane, avevo bisogno di soldi), puoi provare con:

  1. Cambia il nome del filegroup di sola lettura - in questo modo, se qualcuno ha degli script hardcoded che alterano il filegroup in base al nome, i loro script falliranno e tu prenderai il colpevole. O un po 'più difficile:

  2. Utilizzare Profiler o Eventi estesi per tenere traccia di chiunque esegua un ALTER DATABASE.


Avevamo effettivamente fornito una sceneggiatura al team di DW per apportare questa modifica in modo che non dovessero svegliarci di notte nelle rare ma attese occasioni in cui il loro lavoro fosse fallito. Abbiamo anche un trigger di controllo a livello di server (su DDL_SERVER_LEVEL_EVENTS) che imposta gli hit delle proprietà di lettura / scrittura del gruppo di file. Ci invia lo script SQL, l'utente e l'indirizzo IP che devono essere esaminati dal team DBA.
Toosuto,

Sebbene possa sembrare che siano abbastanza subdoli da usare il nostro script per modificare le impostazioni del gruppo di file prima del loro processo ETL, non sono tecnicamente abbastanza consapevoli da cercare e disabilitare il nostro trigger.
Toosuto,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.