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_functions
e 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.FilegroupDetail
e ph.ObjectDetail
da 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.