Geen nieuwe data geladen vanuit Exact Online

Sinds 01-07-2021 wordt er geen nieuwe data meer geladen in de database vanuit Exact Online met Data Replicator 20.1.464. De eerste foutmelding in de logfile gaat af op:

create or replace table eol_mrd_open@inmemorystorage
as
select /*+ ods(false) */ *
from   MailMessagesReceived
where  recipientstatus in (10,20,25,30)

select /*+ ods(true, interval '20 minutes') */ count(*) from eol_mrd_open@inmemorystorage

Dit materialiseert per Exact Online abonnement van de geselecteerde administraties van aangesloten klanten de lijst van berichten.

De foutmelding is:

Fout itgenclr039: External error in Invantive Data Hub.

Cannot insert duplicate key row in object 'dbo.dc_tables' with unique index 'dc_tbe_uk_5'. The duplicate key value is (imy_eol_mrd_open_r).
The statement has been terminated.
2021-07-13 20:01:41.369 Error itgenclr039: System.Data.SqlClient.SqlException
ValidationException
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Invantive.Data.AnsiSqlProviderBase.PassthroughSqlAction(GlobalState owner, ExecutionOptions executionOptions, String actionSql, ParameterList parameters, String loggingTableName)
...
   at Invantive.Data.AnsiSqlProviderBase.InsertReturnAffectedCount(GlobalState owner, ExecutionOptions executionOptions, EntityFieldCollection entityFields, ParameterList parameterValues, Object identifiedBy, Object attachTo)
   at Invantive.Data.Providers.DataCache.DataCacheProvider.MaintainTable(GlobalState owner, ExecutionOptions executionOptions, String sourceDataContainerId, IDataProvider dataSourceProvider, ObjectDefinition objectDefinition, Boolean autoCreate, YieldedResultSet yieldedResultSetSample, DcDataContainer& dcDataContainer)
   at Invantive.Data.Providers.DataCache.DataCacheProvider.YMK(GlobalState , ExecutionOptions , String , IDataProvider , String , ObjectDefinition , YieldedResultSet , DcDataContainer& , DcTable& , DcPartition& )
   at Invantive.Data.Providers.DataCache.DataCacheProvider.MaintainTablePartitionVersion(GlobalState owner, ExecutionOptions executionOptions, String sourceDataContainerId, IDataProvider dataSourceProvider, String partitionName, ObjectDefinition objectDefinition, Decimal version, YieldedResultSet yieldedResultSetSample, Nullable`1 numberOfRows, Nullable`1 estimatedSizeCharacters, String refreshOrigin, DcDataContainer& dcDataContainer, DcTable& dcTable, DcPartition& dcPartition, DcTablePartition& dcTablePartition)
   at Invantive.Data.Providers.DataCache.DataCacheProvider.MaintainTablePartitionVersionFactsOnePartitionAllVersions(GlobalState owner, ExecutionOptions executionOptions, ObjectDefinition objectDefinition, DatabaseColumnDefinitionCollection resultFields, Boolean mayReplaceWithCachedData, String sourceDataContainerId, String partitionCode, IDataProvider dataSourceProvider, QueryObject originalQueryObject, Nullable`1 maxAgeDataMs, String refreshOrigin)
...

Daarna treedt nog een foutmelding op bij:

begin
   xxdru_use_active; 
end;

namelijk:

itgensql151: Unknown field or parameter ‘spn.data_container_alias’

Hoe kan ik deze beiden oplossen?

Beste is een los topic maken per vraag.

itgensql151 op spn.data_container_alias

De itgensql151 is eenvoudig; het is een aanroep van een stored procedure.

De broncode zou op de server moeten staan en waarschijnlijk is de stored procedure na een upgrade niet bijgewerkt. spn.data_container_alias klinkt als een query op SystemPartitions@DataDictionary. Hiervan is afgelopen jaar ergens de kolom data_container_alias hernoemd in provider_data_container_alias.

itgenclr039 bij materialiseren tabel

De itgenclr039 foutcode is een generieke foutmelding uit Microsoft SQL Server. Alle foutcodes die beginnen met itgenclr betreffen foutmeldingen waarbij Invantive geen specifieke afhandeling heeft.

In dit geval gaat het om het toevoegen van een rij in de tabel dc_tables:

Cannot insert duplicate key row in object ‘dbo.dc_tables’ with unique index ‘dc_tbe_uk_5’. The duplicate key value is (imy_eol_mrd_open_r).

De tabel dc_tables bevat de metadata (het zogenaamde “repository”) van Invantive Data Replicator.

De automatisch bepaalde viewnaam imy_eol_mrd_open_r is al geregistreerd voor een andere tabel. De andere tabel die deze viewnaam al gebruikt is te vinden met een query op dc_tables.

Waarschijnlijk is per abuis een keer met een andere tabelnaam of instellingen gewerkt. Het advies is om advies in te winnen om te achterhalen of hier een grotere oorzaak in de lokale omgeving achter zit of dat het om een eenmalig foutje gaat, en dit dan als kan meteen te laten rechttrekken qua setup.

Na verdere analyse bleek de itgenclr039 voor de logical overall view imy_eol_mrd_open_r opgewekt te worden door de upgrade van 17.32 naar 20.1.

Elk Invantive Data Replicator repository kan gegevens bevatten van meerdere “datacontainers”. Elke datacontainer verwijst naar een bronsysteem.

In dit geval is tussen 17.32 en 20.1 de naam van de in-memory datacontainer gewijzigd van InMemoryStorage naar memory. De gewijzigde naam leidt tot registratie van een nieuwe datacontainer.

Reparatie

De logische viewnaam imy_eol_mrd_open_r is handmatig gewijzigd in een unieke waarde:

Data containers voor in-memory driver

Daarna is het Data Replicator repository geopend met het statement:

select /*+ ods(true, interval '20 minutes') */ count(*) from eol_mrd_open@inmemorystorage

Tenslotte is de oude datacontainer verwijderd met (documentatie):

alter persistent cache drop datacontainer 'InMemoryStorage'

Meerdere Datacontainers op een Repository

De foutmelding met code itgenclr039 op de index dc_tbe_uk_5 treedt ook wel eens op bij het inrichten van een repository met bijvoorbeeld meerdere Exact Online abonnementen. Elke datacontainer krijgt dan - tenzij expliciet gewijzigd - het voorvoegsel eol_ en achtervoegsel _r.

Als de naamstructuur voor de logical overall views voor de datacontainers niet verschillend ingesteld zijn, dan zullen identieke viewnamen gegenereerd worden. Exact Online abonnement 1 leidt dan evenals Exact Online abonnement 2 voor de tabel TransactionLinesIncremental tot eol_transactionlinesincremental_r.

De dubbele viewnamen kunnen vermeden worden. Laad een willekeurige tabel met bijvoorbeeld:

select count(*) from NAME@ALIAS

En wijzig daarna het voorvoegsel of achtervoegsel voor nieuw gegenereerde viewnamen:

alter persistent cache set datacontainer '...' logical overall view name prefix '...'

of

alter persistent cache set datacontainer '...' logical overall view name postfix '...'

Daarna kan de willekeurige tabel verwijderd worden die gebruikt is om de datacontainer te activeren:

alter persistent cache drop table table NAME@ALIAS

Alle volgende acties worden dan met de nieuwe prefix en postfix uitgevoerd.

Gecontroleerd Doorgaan

Om de impact van een dergelijk laadprobleem te beperken, kan het Invantive SQL script uitgebreid worden met statements om door te gaan bij een foutmelding. De foutmelding wordt onthouden en leidt op het einde alsnog tot een nette detecteerbare exitcode.

Voeg hiervoor het volgende statement tussen:

local on error continue

Vanaf het moment dat foutmeldingen weer moeten leiden tot meteen eindigen zet je:

local on error exit failure

Meer tips over local on error zijn te vinden in de handleiding.