Ga naar hoofdinhoud

Archivering

Archivering verplaatst oudere rijen uit het history-schema (HIS/ODS) naar Parquet-bestanden in de Azure Data Lake. Zo blijft de actieve datawarehouse-database klein en goedkoop, terwijl de oudere historie bewaard blijft als kolomgeoriënteerde bestanden — en via een automatisch onderhouden union-view gewoon meequeryt met de live tabel.

Archivering werkt in drie stappen per tabel, binnen één run van de Dynamic Archiving Workflow YRES:

  1. Kopiëren — de rijen die aan de archiveringsregel voldoen gaan als Parquet naar het archive/-pad in de Data Lake.
  2. Verifiëren & opschonen (purge)[LoadManagement].[spArchivePurge] telt de rijen die nu aan de regel voldoen en verwijdert ze alleen bij een exacte match met het aantal gekopieerde rijen. Wijkt de telling af (er is tussendoor geladen), dan wordt er niets verwijderd en kun je de run veilig opnieuw draaien.
  3. Union-view verversen[LoadManagement].[spArchiveMaintainView] genereert per tabel de view [<HIS-schema>].[<Target>_IncArchive] die de live tabel en de gearchiveerde Parquet-bestanden als één geheel toont.
Eerst proefdraaien, dan pas opschonen

De purge staat standaard uit (instelling ArchivingPurgeEnabled = 0). In die stand kopieert de workflow alleen naar de Data Lake en wordt er niets verwijderd — ideaal om de configuratie en de Parquet-uitvoer te controleren. Zet daarna ArchivingPurgeEnabled op 1 om echt op te schonen — dit is de enige schakelaar van de purge. (AllowDeletesFromDB speelt hier bewust geen rol: die instelling gaat over het droppen van objecten, niet over het verwijderen van data.)

Twee archiveringsmodi per tabel

Archivering is opt-in per tabel en kent twee modi, ingesteld op LoadManagement.UsedTables (via spMaintainTable):

ModusWat wordt gearchiveerdTypisch gebruik
CLOSEDAlleen afgesloten SCD2-versies: rijen met isCurrent = 0 waarvan de ETL_EndDate ouder is dan de bewaartermijn. De actuele rij blijft altijd in de database.Historie-opschoning zonder functioneel effect: de actuele stand blijft compleet.
BUSINESSEchte data op basis van een datumkolom in de dataset (de ArchivingColumn), bv. facturen ouder dan 10 jaar — inclusief actuele rijen.Wettelijke/functionele retentie: "alles ouder dan X jaar mag het datawarehouse uit".

De configuratiekolommen:

Kolom (UsedTables)Betekenis
ArchivingModeNULL = uit, CLOSED of BUSINESS.
ArchivingColumnAlleen bij BUSINESS: de datasetkolom met de businessdatum (moet in de Dictionary bestaan).
ArchivingRetention + ArchivingRetentionUnitDe bewaartermijn: een aantal YEAR / MONTH / DAY (bv. 10 + YEAR).
ArchivingClauseGeavanceerd: een vrije WHERE-clausule die de modus overstemt — voor uitzonderingsgevallen zoals een Unix-timestampkolom. Bij BUSINESS mag zo'n clausule alleen datakolommen gebruiken (geen ETL_*/isCurrent).

De configuratie wordt direct bij het opslaan gevalideerd (spMaintainTable): een onbekende modus, BUSINESS zonder datumkolom of clausule, of een ontbrekende bewaartermijn levert meteen een duidelijke foutmelding op — in plaats van dat de archivering stilletjes uit blijft staan.

Uit die configuratie bouwt de function [LoadManagement].[fxArchivingPredicate] één archiveringsconditie, met de grensdatum als vaste literal — zodat de kopieer- en opschoonstap binnen één run gegarandeerd exact dezelfde regel gebruiken. Het resultaat verschijnt als ArchivingScript (FROM <HIS-schema>.<Target> WHERE <conditie>) op de contractview [LoadManagement].[vwExtractor]; de workflow pakt alleen tabellen waar dit script gevuld is.

Gearchiveerde data komt niet terug (BUSINESS)

Bij BUSINESS-archivering kan een verwijderde rij nog in het bronsysteem bestaan. Daarom blokkeert de laadmachine (spHIS_InsertAndUpdate) bij deze modus alle binnenkomende rijen die in de "gearchiveerde ruimte" vallen (businessdatum ouder dan de grens): ze bereiken HIS nooit meer, ook niet via een FULL- of IMAGE-load. Het aantal geblokkeerde rijen wordt per load gelogd (Blocked archived-space rows in page in de monitoring). Tip: zet het LoadFilter van zo'n tabel gelijk aan de archiveringsgrens, dan haalt de bron-extractie die oude data ook niet meer op. CLOSED heeft deze blokkering niet nodig: de actuele rij blijft immers gewoon in de database staan.

Deze garantie blijft ook overeind als je de configuratie later verandert of uitzet — zie het purge-geheugen hieronder.

Wanneer draait archivering?

Archivering is een aparte workflow (Dynamic Archiving Workflow YRES), los van de normale load. Hij draait wanneer je hem expliciet start — handmatig of via een eigen trigger — met dezelfde scope- en tierparameters als de gewone load:

ParameterStandaardBetekenis
Source / Schema / TableALLBeperk de run tot één bron, schema of tabel.
RunningTierCurrentSchaal de database tijdelijk op tijdens de run.
RevertToTierPreviousTier waarnaar na afloop wordt teruggeschaald.

De ForEach over de tabellen draait parallel (batchCount: 3); de pipeline zelf heeft concurrency: 1 — er draait nooit meer dan één archiveer-workflow tegelijk.

Hoe het werkt (op hoofdlijnen)

Handmatige run / trigger (Source, Schema, Table, RunningTier, RevertToTier)
→ (optioneel) Set DB Tier → schaal de database tijdelijk op
→ Get tables (Lookup) → SELECT … FROM [LoadManagement].[vwExtractor]
WHERE [ArchivingScript] IS NOT NULL
→ ForEach per tabel (parallel):
Copy data → 'SELECT * ' + ArchivingScript
→ Parquet op archive/… (AzureDataLakeStorage_ARCHIVE)
Purge archived rows → [LoadManagement].[spArchivePurge]
telt opnieuw; verwijdert alleen bij exacte match,
gefaseerd (batches), gegate door ArchivingPurgeEnabled
Maintain archive view → [LoadManagement].[spArchiveMaintainView]
ververst de <Target>_IncArchive-unionview
→ (optioneel) Set DB Tier Back → schaal de database terug

Net als bij een gewone load is ADF de generieke uitvoerder en zit de logica in SQL: het ArchivingScript begint bewust met FROM, zodat er zowel een SELECT * (kopiëren) als een DELETE (opschonen) vóór geplakt kan worden — beide draaien daardoor op exact dezelfde rijenselectie.

Wat er in de Data Lake landt

De Copy-stap schrijft het resultaat als Parquet naar een eigen archiefpad (dataset AzureDataLakeStorage_ARCHIVE), gescheiden van de gewone Data Lake-loads:

archive / <Source> / <TargetSchema> / <Target> / <jaar> / <maand> / <Target>-<timestamp>.parquet

De geëxporteerde rijen behouden alle SCD2-frameworkkolommen (KeyHash, RowHash, ETL_Date, ETL_EndDate, isCurrent en de RowID), zodat het archief dezelfde structuur heeft als de bron in HIS.

Live + archief als één geheel: de _IncArchive-views

Na elke geslaagde kopie ververst spArchiveMaintainView per tabel de view [<HIS-schema>].[<Target>_IncArchive>: een UNION ALL van de live tabel en de gearchiveerde Parquet-bestanden, gelezen met Azure SQL data virtualization (OPENROWSET over een external data source op de Data Lake). Afnemers die ook de gearchiveerde historie nodig hebben, bevragen simpelweg deze view in plaats van de tabel.

  • De view dedupliceert op de interne RowID met voorrang voor de live rij — een proefrun in copy-only-modus of een herstart kan dezelfde rijen immers twee keer in het archief zetten.
  • De kolomlijst en datatypes worden bij elke archiveringsrun opnieuw gegenereerd uit de live tabel, dus kolomwijzigingen volgen vanzelf.
  • View-onderhoud kan archivering nooit blokkeren: lukt het niet (bv. rechten nog niet ingericht), dan wordt dat gelogd en gaat de archivering gewoon door. De view verschijnt automatisch bij de eerstvolgende run nadat het probleem is opgelost.
Rechten voor de union-views

De views lezen het Data Lake rechtstreeks vanuit SQL. Daarvoor moet eenmalig per omgeving zijn ingericht: een system-assigned managed identity op de logical SQL-server, Storage Blob Data Reader voor die identity op de Data Lake-container, en de instelling ArchiveLakeLocation (adls://<container>@<account>.dfs.core.windows.net). Zolang dat niet gebeurd is, werkt archiveren zelf gewoon — alleen de views worden overgeslagen (met een melding in de monitoring). Data virtualization is een preview-feature van Azure SQL Database.

Purge-geheugen: consistent, ook na configuratiewijzigingen

Elke geslaagde, geverifieerde purge wordt vastgelegd in [LoadManagement].[ArchiveLog]: één rij per opschoning, met exact de conditie waarmee de rijen verwijderd zijn. De laadmachine past bij elke load alle onthouden condities toe, bovenop de actuele archiveringsregel.

Dat maakt het gedrag voorspelbaar in situaties die voorheen om oplettendheid vroegen:

  • Configuratie gewijzigd (langere bewaartermijn, andere kolom) — de rijen die onder de oude regel zijn opgeschoond, blijven geblokkeerd en sluipen niet terug in HIS.
  • Archivering uitgezet — al opgeschoonde data blijft opgeschoond; het archief in de Data Lake en de _IncArchive-view blijven gewoon leesbaar.
  • Bewust terughalen — wil je opgeschoonde rijen wél opnieuw laden, verwijder dan de ArchiveLog-rijen van die tabel; de eerstvolgende load neemt ze weer mee (het Parquet-archief blijft daarnaast altijd beschikbaar).

Het geheugen blijft compact: een nieuwe purge op dezelfde kolom vervangt oudere, ruimere regels, zodat er per tabel maar een handvol rijen staat.

De instellingen

Instelling ([Config].[Settings])StandaardWat het regelt
ArchivingPurgeEnabled0 (Nee)Hoofdschakelaar — en enige gate — van de opschoonstap. 0 = alleen kopiëren (proefdraaien), 1 = na geverifieerde kopie ook verwijderen uit HIS. De bestaande instelling AllowDeletesFromDB speelt bewust géén rol bij de purge: die gaat over het droppen van objecten, niet over dataverwijdering.
ArchiveLakeLocationleegadls://…-locatie van de Data Lake voor de union-views; wordt door provisioning gevuld. Leeg = views worden overgeslagen.

De health checks (vwYresChecks, groep 7) bewaken de configuratie: BUSINESS zonder datumkolom, een ArchivingColumn die niet in de Dictionary bestaat, een ontbrekende bewaartermijn, een clausule op ETL_-kolommen en een purge die aanstaat terwijl ArchiveLakeLocation leeg is (check 7.14 — het archief is dan niet vanuit SQL leesbaar), worden allemaal gesignaleerd. Ook het purge-geheugen wordt bewaakt: check 7.15 waarschuwt als een onthouden blokkering verwijst naar een kolom die niet meer in de selectie zit (elke load zou daarop stuklopen), en check 7.16 laat zien wélke tabellen nog een actief purge-geheugen hebben terwijl de huidige configuratie geen blokkering meer instelt — handig om te begrijpen waarom opgeschoonde rijen niet terugkomen, en waar je moet zijn als je dat wél wilt.

Vervallen: settings-gestuurde standaard-archivering

Oudere versies bevatten een alternatieve opzet (vwArchivingExtractor met de instellingen DefaultArchivingDate/DefaultArchivingLoadtypes) die automatisch alle DELTA-tabellen zou archiveren. Sinds v1.56 is archivering bewust een expliciete keuze per tabel; de deploy ruimt de oude view en instellingen zelf op.

Monitoring

Archiveringsruns verschijnen in de gewone monitoringschermen: de stappen per tabel loggen als Process = 'load' (zichtbaar in vwLoads/vwMonitor, met de HIS-tabel als target) en de workflowstappen als Process = 'Workflow' (zichtbaar in vwWorkflow). Daarnaast schrijven de archiveringsprocedures detailstappen met Process = 'Archiving': de verificatietellingen (gekopieerd vs. nu aanwezig), het aantal verwijderde rijen, overgeslagen purges (schakelaar uit) en het view-onderhoud. Mislukt de verificatie, dan faalt de run zichtbaar met de reden in de log — en is opnieuw draaien altijd veilig, want er is dan niets verwijderd.

Verschil met de load types

Archivering staat los van de load types. Een load type bepaalt wat er bij het laden met de history-tabel gebeurt; archivering bepaalt wat er met oude rijen gebeurt. Let in het bijzonder op:

  • OVERWRITE wist de history bij elke load — daar valt weinig te archiveren.
  • FULL, DELTA, IMAGE, RELOAD en de andere types bouwen wél SCD2-historie op; juist die tabellen profiteren van CLOSED-archivering.
  • Tabellen uit bestandsbronnen doen (nog) niet mee met archivering.

Zie ook Load types, Historie & SCD2, de begrippenlijst en Views & pipelines.