NAV Migration

Die Umstellung von NAV2009 auf neuere Versionen ist zwar gut dokumentiert und mit entsprechenden Werkzeugen ausreichend unterstützt. Allerdings muss man bei großen Datenbanken mit erheblichen Laufzeiten rechnen.

Wir arbeiten zur Zeit an einer reinen SQL Lösung zur Migration von NAV2009 auf NAV2017, NAV2018 und Business Central, die flexibel die Daten umstellt. Dabei sprechen wir von einem „Automatisiertem Datentransfer zwischen NAV-Datenbanken per SQL“. Das bedeutet, dass man direkt von einer NAV Version auf eine neuere NAV Version umsteigen kann – das betrifft natürlich nur die Daten. Die Anwendung ist ein völlig anderes Thema.

Status

Entwicklungsstand

Die Migrationsroutinen sind verfügbar, aber durch aktuelle Projekte erfolgen regelmäßig Aktualisierungen und Erweiterungen.

Beispiel Dokumentation

Zur Zeit arbeiten wir an einer Dokumentation, die die Migration der CRONUS NAV2009 auf NAV2017 beschreibt.

Einsatz

Laufzeiten sind immer sehr schwierig zu vergleichen. Hier hängt es davon ab, wie die Verbindung zu den Servern ist.

Migration vonnachDatenvolumenLaufzeit
NAV2009NAV2018650 GB6 Std.
NAV2009NAV201710 GB15 Min.
NAV5NAV201775 GB1,5 Std.

Aktuell wurden Datenbanken bis zu einer Größe von 800 GB in wenigen Stunden vollständig migriert.

Die Lösung befindet sich aktuell in der Entwicklung und bei Pilot-Anwendern im Test. Sollten Sie daran Interesse haben, so nehmen Sie einfach Kontakt mit uns auf.

Technische Dokumentation

Vorbemerkung

Die vorliegenden Skripte wurden zur Unterstützung des Migrations-Prozesses von einer klassischen Navision-Version auf eine der neueren RTC-Versionen geschaffen. Generell stellt sich die Problematik, dass die integrierten Migrations-Werkzeuge für größere Datenbanken untauglich sind, da die Performance extrem schlecht ist. Aus diesem Grund wird häufig der Weg einer neu angelegten Datenbank gewählt, in die anschließend gewählte Daten übertragen werden. Der Weg über Dateien ist umständlich und auch hier ist keine Performance zu gewinnen. Entsprechende SQL-Skripte per Hand zu erstellen ist aufgrund der timestamp-Spalten und ggf. unterschiedlichen Feld-Anzahl/Namen ebenfalls mühselig. Außerdem ist es erforderlich den vollständigen Transfer zu dokumentieren.

Diese Skripte vereinfachen und automatisieren diese Arbeitsschritte so weit möglich, indem Mapping-Tabellen von Tabelle zu Tabelle und von Feld zu Feld angelegt werden, daraus dynamische SQL-Commands für den Transfer erzeugt und ausgeführt werden und die Transfer-Ergebnisse übersichtlich in einer Tabelle protokolliert werden.

Zur Prüfung der Vollständigkeit werden standardmäßig die Anzahl Datensätze in der Quelle und nach Transfer im Ziel festgestellt. Zusätzlich kann wahlweise eine Prüfsumme über eine Spalte der Tabelle definiert werden, die dann in der Quelle und nach Transfer im Ziel gebildet wird.

Darüber hinaus sind Skripte zur Migration der Dimensionsposten unter SQL enthalten, die verwendet werden können um beliebige Dimensionsposten-Tabellen vom klassischen Format in das neue Dimension Set-Format zu übertragen.

Zuletzt ist zu beachten, dass trotz erfolgreichem Transfer und übereinstimmenden Prüfsummen keine automatische Garantie gegeben werden kann, dass die Funktionalität in der neuen Version vollständig gegeben ist! Es ist immer möglich, dass sich Logiken geändert haben oder neue Felder hinzugekommen sind, die zur Vollständigkeit gefüllt werden müssen. Dies ist im Vorfeld der Migration sorgfältig zu prüfen und durch Tests zu verifizieren.

Wichtige Hinweise

Je nach Größe der zu transferierenden Tabellen sollten entsprechende Vorkehrungen vor dem Transfer getroffen werden. Zunächst ist zu beachten, dass durch den Transfer großer Datenmengen auch entsprechend große Transaktions-Protokolle in der Ziel-Datenbank entstehen. Wenn sich die Ziel-Datenbank noch nicht im Echt-Betrieb befindet sollte in Erwägung gezogen werden dort für die Dauer des Transfers das Wiederherstellungsmodell auf Einfach zu setzen. Außerdem sollte die Datenbank-Datei bereits vor dem Transfer auf die zu erwartende Gesamt-Größe nach Transfer vergrößert werden, um Performance-Verluste durch automatische Vergrößerung on-the-fly zu verhindern. Hier sollte großzügig bemessen werden, da auch die Umstellung auf Unicode in der neuen Version einen nicht unerheblichen Größenzuwachs bewirkt!

Darüber hinaus sollte die Tempdb mind. so groß wie die größte zu transferierende Tabelle sein und es sollte sichergestellt werden, dass im Falle einer automatischen Vergrößerung der tempdb keine Probleme auf dem Datenträger entstehen! Eine mögliche Vorgehensweise ist die tempdb auf die erwartete maximal nötige Größe zu vergrößern und automatische Vergrößerung zu deaktivieren. Damit bricht der Transfer im Falle einer Überschreitung ab und es kann im Anschluss eruiert werden, ob eine weitere Vergrößerung sinnvoll ist oder der Transfer angepasst werden muss.

Einrichtung

  • Zunächst muss auf dem Ziel-Server ein Verbindungsserver auf den Quell-Server angelegt werden. Für den Verbindungsserver sind keine besonderen Einstellungen zu berücksichtigen, wichtig ist nur, dass der verwendete Benutzer lesenden Zugriff auf alle zu transferierenden Tabellen plus die Tabelle Object hat.
  • Anlegen der SQL-Objekte in der Ziel-Datenbank. Dazu müssen folgende Skript-Dateien geöffnet und ausgeführt werden:
    • dbo.KT_Transfer Tables Setup.Table
    • dbo.KT_Transfer Fields Setup.Table
    • dbo.KT_Transfer Tables Log.Table
    • dbo.usp_Print.StoredProcedure
    • dbo.KT_getEmptyValueForNavColumn.UserDefinedFunction
    • dbo.KT_getNavTableFieldList.UserDefinedFunction
    • dbo.KT_getValidNavTableName.UserDefinedFunction
    • dbo.KT_sp_copyNavTableDataFromRemote.StoredProcedure
    • dbo.KT_sp_TransferTables.StoredProcedure

Damit werden alle benötigten Tabellen, Funktionen und Prozeduren angelegt. Details zu den einzelnen Stroed Procedures und Funktionen sind Modulbeschreibung verfügbar.

  • Öffnen der Datei Install_Script. Dieses Skript legt drei weitere Funktionen an, die generisch erzeugt werden müssen. Das ist erforderlich, da hier der Name des Verbindungsservers und der Quell-Datenbank eingesetzt werden muss und Funktionen kein dynamisches SQL erlauben. Im Kopf des Skripts müssen die beiden Parameter entsprechend angegeben werden und das Skript ausgeführt werden.
  • Alle SQL-Objekte sind nun angelegt. Jetzt muss das Mapping erzeugt werden. Ausgangspunkt ist das Mapping der Tabellen, welches in der Tabelle dbo.KT_Transfer Tables Setup abgelegt wird. Im Grunde wird hier definiert welche NAV-Tabellen ID in der alten Version welcher ID in der neuen Version entspricht. In den meisten Fällen ist das identisch, vor allem aber bei Custom-Tables ist das häufig anders. Hier müssen nur die Tabellen definiert werden, die auch transferiert werden sollen. Die Skript-Datei Generate Transfer Tables Setup Standard Tables liefert einen guten Ausgangspunkt für den Transfer von Standard-Tabellen und kann auf die eigenen Bedürfnisse angepasst werden.
  • Nachdem das Mapping der Tabellen steht, kann das Mapping der Felder erzeugt werden. Hierfür hat das Install_Script die Funktion getDefaultTransferFieldsSetup erzeugt, das in einem Insert-Kommando in die Tabelle KT_TransferFieldsSetup verwendet werden kann. Die Funktion ordnet die Felder automatisch anhand des Namens zu und erstellt ein entsprechendes Mapping. Felder zu denen es auf der anderen Seite keine Entsprechung gibt werden ebenfalls ins Mapping aufgenommen, werden jedoch beim späteren Transfer nicht berücksichtigt bzw. mit einem Standard-Wert gefüllt. Bei Bedarf können entweder die Funktion oder das Ergebnis in der Tabelle beliebig angepasst werden.
  • Letzter Schliff: in der Tabelle KT_TransferTablesSetup lassen sich auf Wunsch ein paar weitere Parameter manuell ergänzen. Zum Einen können in den Feldern [From Table Checksum Column] und [To Table Checksum Column] Spalten zur automatischen Generierung von Prüfsummen vor und nach dem Transfer definiert werden. Außerdem kann für die Vereinfachung von wiederholten Transfers für gewünschte Tabellen das Feld [trunc] auf 1 gesetzt werden, wodurch bei einem erneuten Transfer kein Delete sondern ein Truncate auf die vorhandenen Daten ausgeführt wird, was die Performance erheblich verbessert. Zu beachten ist allerdings, dass ein Truncate bei Tabellen mit SumIndexFields nicht möglich ist!

Außerdem muss noch für Tabellen deren Primärschlüssel ein AutoIncrement-Feld ist das Feld [AutoIncrement] auf 1 gesetzt werden, da dies von der Generierungs-Routine derzeit noch nicht automatisch erkannt wird.

Anwendung

Nach Abschluss der Einrichtung ist die Transfer-Routine einsatzbereit. Zur Ausführung aller eingerichteten Transfers muss lediglich die Stored Procedure KT_sp_TransferTables ausgeführt werden. Als Parameter müssen noch einmal der Name des Verbindungsservers und der Quell-Datenbank angegeben werden. Anschließend werden der Reihe nach sämtliche eingerichteten Tabellen mit dem Kennzeichen [Active] = 1 transferiert. Der Fortschritt des Transfers kann im Management Studio im Fenster Meldungen nachverfolgt werden. Jeder Transfer-Schritt wird außerdem in der Tabelle KT_TransferTablesLog protokolliert. Hier werden auch die Informationen zu Anzahl Datensätzen in Quelle und Ziel, sowie ggf. die Prüfsummen protokolliert.

Alternativ kann auch der Transfer für eine einzelne Tabelle manuell ausgeführt werden, in dem die Stored Procedure KT_sp_copyNavTableDataFromRemote aufgerufen wird. Diese benötigt als Parameter ebenfalls den Namen des Verbindungsservers und der Quell-Datenbank, sowie die ID des gewünschten Tabellen-Mappings. Über den letzten Parameter doCopy kann zusätzlich festgelegt werden, ob der Transfer sofort ausgeführt werden soll oder nur das generierte Skript zurückgegeben werden soll. Dies ist besonders hilfreich zur Fehlersuche wenn der Transfer der Tabelle nicht erfolgreich ist oder das Skript anderweitig verwendet werden soll.

Hinweise zu besonderen Feld-Typen

Blob-Felder

Zum Transfer von Blob-Feldern aus klassischen Versionen in RTC-Versionen ist es zunächst erforderlich die Eigenschaft Compressed auf No zu setzen. Dies ist jedoch erst ab Client-Version 2009 möglich. Andernfalls kann der Inhalt des Blob-Feldes in der RTC-Version nicht verwendet werden. Dies liegt an unterschiedlichen Komprimierungsverfahren, die unter SQL nicht aufgelöst werden können. Ggf. müssen Blob-Felder daher im Nachgang auf einem anderen Weg übertragen werden und sollten dann im Field-Mapping auf Active = 0 gesetzt werden.

MediaSet

In Versionen ab 2017 werden Blob-Felder teilweise nicht mehr direkt im Datensatz gespeichert, sondern über eine sogenannte MediaSet ID in einer zentralen Tabelle abgelegt. In solchen Fällen füllt der Transfer das MediaSet-Feld mit einem leeren Default-Wert, der Blob-Inhalt wird nicht übertragen. Dieser muss im Nachgang auf einem anderen Weg übertragen werden.

neue id-Felder

In einigen Standard-Tabellen wurden von Microsoft neue AutoIncrement-Felder zur schnelleren Referenzierung angelegt. Diese neuen Felder werden beim Transfer automatisch mit einer fortlaufenden Nummer gefüllt. Jedoch werden keinerlei Referenzen aufgebaut, d.h. wenn diese Ids an anderer Stelle referenziert werden, ist diese Referenz im Nachgang durch eine weitere Routine anzulegen.

neue GUID-Felder

In einigen Standard-Tabellen sind außerdem neue GUID-Felder angelegt worden. Diese werden vom Transfer mit einer Null-GUID gefüllt.

Migration von Dimensionsposten

Der Skript-Sammlung liegen zusätzlich zwei Skripte zur Migration von Dimensionsposten aus dem alten Format in die neuen Dimension Sets bei. Diese Skripte sind völlig unabhängig von den Transfer-Skripten und bestehen aus drei Bausteinen:

SQL-Skript BuildDimSets

Diese Routine baut aus allen angegebenen Dimensionsposten-Tabellen einzigartige Dimension Sets auf und fügt diese zunächst in eine separate Tabelle mit 1:1 Aufbau zu den Original Dimension Sets ein.

NAV-Objekt-Datei

Diese Datei enthält eine Codeunit, die aus der zuvor aufgebauten separaten Dimension Sets-Tabelle in die Original-Tabelle überträgt. Dieser Schritt ist erforderlich, da Nav zusätzlich zu den Dimension Sets selbst eine Such-Tabelle vorhält, die nicht so einfach per SQL aufzubauen ist. Die Codeunit macht sich beim Kopieren aus der separaten Tabelle die Standard-Funktionen zunutze und baut somit auch die Such-Tabelle mit auf.

SQL-Skript AssignDimSets

Diese Routine durchläuft alle angegebenen Tabellen mit Relation zu den zuvor herangezogenen Dimensionsposten-Tabellen und ordnet die entsprechenden Dimension Sets zu.

Die SQL-Skripte müssen vor Ausführung mit den vorliegenden Verbindungsserver-Namen und Datenbank-Namen versehen werden und hinsichtlich der heranzuziehenden Dimensionsposten-Tabellen und damit verbundenen Tabellen angepasst werden. Außerdem muss die Tabelle für das Einfügen der Dimension Sets als Kopie der Original-Tabelle angelegt werden und die Codeunit mit der entsprechend verwendeten ID versehen werden.