%3CLINGO-SUB%20id%3D%22lingo-sub-1221049%22%20slang%3D%22en-US%22%3ELesson%20Learned%20%23122%3A%20Checks%20to%20perform%20on%20your%20database%20before%20using%20Data%20Sync%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1221049%22%20slang%3D%22en-US%22%3E%3CP%3EDuring%20these%20last%20days%20I've%20been%20working%20with%20some%20service%20requests%20related%20with%20DataSync%20based%20on%20some%20limitations%20of%20this%20feature%20has.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EBefore%20using%20DataSync%20I%20would%20like%20to%20share%20with%20you%20this%20post%20that%20includes%20some%20checks%20to%20be%20performed%20before%20using%20Datasync.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EFollowing%20you%20could%20find%20some%20of%20these%20checks%20to%20be%20done%3A%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CSTRONG%3EThe%20user%20that%20connects%20to%20DataSync%20has%20access%20to%20more%20than%20500%20tables.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3EIn%20this%20situation%2C%20you%20have%20to%20reduce%20this%20number%20because%20it%20is%20limitation%20of%20DataSync.%20You%20have%20two%20possible%20solutions%3A%3CUL%3E%0A%3CLI%3E%3CSTRONG%3ECreate%20a%20new%20schema%2C%20that%20basically%2C%20you%20need%20to%20follow%20up%20the%20next%20steps%3A%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3ECREATE%20schema%20AzureSync%3C%2FLI%3E%0A%3CLI%3ECREATE%20schema%20DataSync%3C%2FLI%3E%0A%3CLI%3ECREATE%20USER%20AzureSync%20WITH%20PASSWORD%3D'x'%20%2C%20DEFAULT_SCHEMA%3DAzureSync%3C%2FLI%3E%0A%3CLI%3EGRANT%20CONTROL%20ON%20Schema%3A%3AAzureSync%20To%20AzureSync%3C%2FLI%3E%0A%3CLI%3EGRANT%20CONTROL%20ON%20Schema%3A%3ADataSync%20To%20AzureSync%3C%2FLI%3E%0A%3CLI%3ECREATE%20TABLE%20AzureSync.Table1%20(ID%20Int%20primary%20key)%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3ECreate%20a%20new%20user%20and%20provided%20control%20to%20some%20specific%20tables.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3ECREATE%20USER%20Azuresync%20With%20Password%3D'xxxxxx'%3C%2FLI%3E%0A%3CLI%3ECREATE%20schema%20DataSync%3C%2FLI%3E%0A%3CLI%3EGRANT%20CONTROL%20object%3A%3Atablename%20to%20AzureSync.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EThe%20database%20has%20not%20enabled%20Snapshot%20isolation%20level.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3EYou%20need%20to%20enable%20it%2C%20following%20this%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fdotnet%2Fframework%2Fdata%2Fadonet%2Fsql%2Fsnapshot-isolation-in-sql-server%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3EURL%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EThe%20length%20of%20name%20of%20the%20tables%2Fcolumns%20are%20more%20than%2050%20chars.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3EDataSync%20will%20create%20triggers%20joining%20table%20name%20plus%20GUID%20and%20other%20text%2C%20in%20this%20case%2C%20you%20could%20reach%20the%20maxium%20length%20of%20an%20object%20of%20128%20characters.%26nbsp%3B%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EThe%20user%20that%20performs%20the%20provisioning%20process%20has%20not%20permissions%20to%20create%20triggers%20that%20DataSync%20needs%20to%20create%2Frun%20in%20every%20table%20selected%20to%20be%20synced.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3ECREATE%20USER%20AzureSync%20WITH%20PASSWORD%3D'x'%26nbsp%3B%3C%2FLI%3E%0A%3CLI%3EGRANT%20CONTROL%20ON%20object%3A%3Atablename%20to%20AzureSync%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EIt%20is%20needed%20to%20provision%20all%20the%20tables%20manually%20due%20to%20some%20non-clustered%20indexes%20that%20maintain%20the%20integrity%20referential%20has%20the%20same%20name.%26nbsp%3B%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3EOur%20suggestion%20is%20that%20all%20the%20non-clustered%20indexes%20have%20an%20unique%20name.%20We%20found%20that%20when%20we%20are%20using%20as%20constraints%20to%20maintain%20the%20referential%20integrity%20between%20tables%2C%20DataSync%20creates%20a%20constraints%20and%20if%20the%20index%20has%20the%20same%20name%20you%20are%20going%20to%20have%20an%20error%20because%20there%20is%20not%20possible%20to%20have%20constraints%20with%20same%20name.%3C%2FLI%3E%0A%3CLI%3ETo%20provisioning%20manually%20the%20tables%2C%20basically%2C%20you%20need%20to%20script%20out%20the%20tables%20using%20SQL%20Server%20Management%20Studio%20and%20execute%20it%20in%20the%20target%20database.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EThe%20user%20has%20not%20CONTROL%20access%20to%20the%20schema%20DataSync.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3E%3CSTRONG%3EWe%20need%20to%20create%20the%20schema%20Datasync%3C%2FSTRONG%3E%20-%26nbsp%3BCREATE%20schema%20DataSync%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EAnd%20grant%20the%20permission%20CONTROL%20to%20this%20schema%3C%2FSTRONG%3E%20-%26nbsp%3BGRANT%20CONTROL%20ON%20Schema%3A%3ADataSync%20To%20%3CUSERNAME%3E%3C%2FUSERNAME%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3EAnd%20finally%2C%20the%20collation%20of%20the%20destination%20and%20source%20are%20different.%3C%2FSTRONG%3E%3CUL%3E%0A%3CLI%3EWe%20need%20that%20the%20source%20database%20and%20destination%20will%20have%20same%20collation.%20Remember%20that%20DataSync%20checks%20the%20structure%20of%20the%20tables%20of%20the%20different%20members.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20order%20to%20validate%20these%20checks%2C%20I%20created%20the%20following%20TSQL%20that%20perform%20these%20validations%2C%20all%20feedback%20and%20improvement%20are%20welcome%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EUser%20with%20access%20to%20mor%20than%20500%20tables.%3C%2FLI%3E%0A%3CLI%3ESnapshot%20isolation%20level.%3C%2FLI%3E%0A%3CLI%3EName%20tables%2Fcolumns%20with%20more%20than%2050%20chars.%3C%2FLI%3E%0A%3CLI%3ECheck%20permissions%20to%20DataSync%20Schema%20and%20tables%20in%20the%20source%20database.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAlso%2C%20remember%2C%20that%20we%20have%20the%20following%20PowerShell%20script%20that%20you%20could%20run%20once%20DataSync%20has%20been%20created%20to%20review%20if%20everything%20is%20correct%3A%26nbsp%3B%3CU%3E%3CA%20href%3D%22https%3A%2F%2Fnam06.safelinks.protection.outlook.com%2F%3Furl%3Dhttps%253A%252F%252Fgithub.com%252Fmicrosoft%252FAzureSQLDataSyncHealthChecker%26amp%3Bdata%3D02%257C01%257Cpalomag%2540microsoft.com%257Ce2e9ccf27c0f4fbc466708d7bf9d86f5%257C72f988bf86f141af91ab2d7cd011db47%257C1%257C0%257C637188555640195698%26amp%3Bsdata%3DD8deqYVGPMQA3ekhVNffW0GYl0Y%252Fcyn7EbOr1YFROKA%253D%26amp%3Breserved%3D0%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Fmicrosoft%2FAzureSQLDataSyncHealthChecker%3C%2FA%3E%3C%2FU%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EEnjoy!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E-------------------------------------------------------%3C%2FP%3E%0A%3CP%3E--%20Script%20to%20validate%20my%20database%20to%20use%20DataSync%3C%2FP%3E%0A%3CP%3E--------------------------------------------------------%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIF%20(SELECT%20ISNULL(COUNT(*)%2C0)%20FROM%20sys.tables%20where%20sys.tables.is_ms_shipped%3D0)%26gt%3B%3D500%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%231%3A%20Fail%20-%20You%20have%20more%20than%20500%20tables'%3C%2FP%3E%0A%3CP%3EELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%231%3A%20Success%20-%20You%20do%20not%20have%20the%20maximum%20tables%20to%20Sync'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3E--%20Review%20if%20you%20have%20permissions%20to%20DataSync%20Schema%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3EDECLARE%20%40tablename%20sysname%2C%20%40object_id%20bigint%2C%20%40nTemporal%20int%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3EDECLARE%20TablesCursor%20CURSOR%20FOR%20SELECT%20Name%2C%20OBJECT_ID%20FROM%20sys.tables%20where%20sys.tables.is_ms_shipped%3D0%20order%20by%20Name%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOPEN%20TablesCursor%26nbsp%3B%3C%2FP%3E%0A%3CP%3EFETCH%20NEXT%20FROM%20TablesCursor%20INTO%20%40tablename%2C%20%40object_id%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWHILE%20%40%40FETCH_STATUS%20%3D%200%26nbsp%3B%3C%2FP%3E%0A%3CP%3EBEGIN%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'%20'%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'Control%20%232%3A%20Table%3A%20'%20%2B%20%40tablename%20%2B%20'--%20'%20%2B%20CONVERT(varchar(200)%2C%40object_id)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20DECLARE%20PermissionsCursor%20CURSOR%20FOR%20SELECT%20TOP%201%20grantee_principal_id%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20FROM%20sys.database_permissions%20p%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20WHERE%20major_id%20%3D%20%40object_id%20and%20grantee_principal_id%20%3D%20USER_ID()%20AND%20permission_name%3D'CONTROL'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20OPEN%20PermissionsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BFETCH%20NEXT%20FROM%20PermissionsCursor%20INTO%20%40nTemporal%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BIF%20%40%40FETCH_STATUS%20%3D%200%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'%20-----%26gt%3B%20Has%20enough%20permissions'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20ELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'%20-----%26gt%3B%20Fail%20-%20Has%20not%20enough%20permissions'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BCLOSE%20PermissionsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20DEALLOCATE%20PermissionsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20IF%20LEN(%40TableName)%26gt%3B50%20PRINT%20'%26nbsp%3B%20-----%26gt%3B%20Fail%20-%20The%20name%20of%20the%20table%20reached%20the%20maximum%20length'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20DECLARE%20ColsCursor%20CURSOR%20FOR%20SELECT%20TOP%201%20object_id%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20FROM%20sys.columns%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BWHERE%20object_id%20%3D%20%40object_id%20AND%20len(name)%26gt%3B50%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20OPEN%20ColsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BFETCH%20NEXT%20FROM%20ColsCursor%20INTO%20%40nTemporal%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BIF%20%40%40FETCH_STATUS%20%3D%200%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'%20-----%26gt%3B%20Fail%20-%20The%20length%20of%20some%20column%20name%20of%20this%20table%20is%20reached%20the%20maximum%20allowed'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20ELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPRINT%20'%20-----%26gt%3B%20The%20length%20of%20some%20column%20name%20of%20this%20table%20is%20not%20reached%20the%20maximum%20allowed'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BCLOSE%20ColsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20DEALLOCATE%20ColsCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BFETCH%20NEXT%20FROM%20TablesCursor%20INTO%20%40tablename%2C%20%40object_id%26nbsp%3B%3C%2FP%3E%0A%3CP%3EEND%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3ECLOSE%20TablesCursor%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3EDEALLOCATE%20TablesCursor%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E---%3C%2FP%3E%0A%3CP%3E--%20Check%20if%20DataSync%20schema%20is%20created%20and%20has%20control%20permissions%3C%2FP%3E%0A%3CP%3E----%3C%2FP%3E%0A%3CP%3EIF%20(SELECT%20ISNULL(COUNT(*)%2C0)%20FROM%20sys.schemas%20where%20name%3D'DataSync')%3D1%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%233%3A%20You%20have%20the%20schema%20DataSync%20created'%3C%2FP%3E%0A%3CP%3EELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%233%3A%20Fail%20-%20You%20do%20not%20have%20the%20schema%20DataSync%20created'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3E--%20Review%20if%20you%20have%20permissions%20to%20DataSync%20Schema%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3EIF%20HAS_PERMS_BY_NAME('DATASYNC'%2C%20'SCHEMA'%2C%20'CONTROL')%3D1%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%234%3A%20You%20have%20control%20permission%20in%20DataSync%20schema'%3C%2FP%3E%0A%3CP%3EELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%234%3A%20You%20do%20not%20have%20control%20permission%20in%20DataSync%20Schema'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3E--%20Review%20if%20you%20have%20permissions%20to%20DataSync%20Schema%3C%2FP%3E%0A%3CP%3E-----------%3C%2FP%3E%0A%3CP%3EIF%20(SELECT%20snapshot_isolation_state%20FROM%20sys.databases%20where%20name%3Ddb_name())%20%3D%201%20AND%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%20(SELECT%20is_read_committed_snapshot_on%20FROM%20sys.databases%20where%20name%3Ddb_name())%20%3D%201%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%20Print%20'Check%20%235%3A%20You%20have%20snapshot%20isolation%20level'%3C%2FP%3E%0A%3CP%3EELSE%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3BPrint%20'Check%20%235%3A%20You%20dont%20have%20snapshot%20isolation%20level'%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1221049%22%20slang%3D%22en-US%22%3E%3CP%3EDuring%20these%20last%20days%20I've%20been%20working%20with%20some%20service%20requests%20related%20with%20DataSync%20based%20on%20some%20limitations%20of%20this%20feature%20has.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EBefore%20using%20DataSync%20I%20would%20like%20to%20share%20with%20you%20this%20post%20that%20includes%20some%20checks%20to%20be%20performed%20before%20using%20Datasync.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1221049%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3Eon%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E

During these last days I've been working with some service requests related with DataSync based on some limitations of this feature has. 

 

Before using DataSync I would like to share with you this post that includes some checks to be performed before using Datasync. 

 

Following you could find some of these checks to be done:  

 

  • The user that connects to DataSync has access to more than 500 tables.
    • In this situation, you have to reduce this number because it is limitation of DataSync. You have two possible solutions:
      • Create a new schema, that basically, you need to follow up the next steps:
        • CREATE schema AzureSync
        • CREATE schema DataSync
        • CREATE USER AzureSync WITH PASSWORD='x' , DEFAULT_SCHEMA=AzureSync
        • GRANT CONTROL ON Schema::AzureSync To AzureSync
        • GRANT CONTROL ON Schema::DataSync To AzureSync
        • CREATE TABLE AzureSync.Table1 (ID Int primary key)
      • Create a new user and provided control to some specific tables.
        • CREATE USER Azuresync With Password='xxxxxx'
        • CREATE schema DataSync
        • GRANT CONTROL object::tablename to AzureSync.
  • The database has not enabled Snapshot isolation level.
    • You need to enable it, following this URL
  • The length of name of the tables/columns are more than 50 chars.
    • DataSync will create triggers joining table name plus GUID and other text, in this case, you could reach the maxium length of an object of 128 characters. 
  • The user that performs the provisioning process has not permissions to create triggers that DataSync needs to create/run in every table selected to be synced.
    • CREATE USER AzureSync WITH PASSWORD='x' 
    • GRANT CONTROL ON object::tablename to AzureSync
  • It is needed to provision all the tables manually due to some non-clustered indexes that maintain the integrity referential has the same name. 
    • Our suggestion is that all the non-clustered indexes have an unique name. We found that when we are using as constraints to maintain the referential integrity between tables, DataSync creates a constraints and if the index has the same name you are going to have an error because there is not possible to have constraints with same name.
    • To provisioning manually the tables, basically, you need to script out the tables using SQL Server Management Studio and execute it in the target database.
  • The user has not CONTROL access to the schema DataSync.
    • We need to create the schema Datasync - CREATE schema DataSync
    • And grant the permission CONTROL to this schema - GRANT CONTROL ON Schema::DataSync To <UserName>
  • And finally, the collation of the destination and source are different.
    • We need that the source database and destination will have same collation. Remember that DataSync checks the structure of the tables of the different members.

 

In order to validate these checks, I created the following TSQL that perform these validations, all feedback and improvement are welcome:

 

  • User with access to mor than 500 tables.
  • Snapshot isolation level.
  • Name tables/columns with more than 50 chars.
  • Check permissions to DataSync Schema and tables in the source database.

 

Also, remember, that we have the following PowerShell script that you could run once DataSync has been created to review if everything is correct: https://github.com/microsoft/AzureSQLDataSyncHealthChecker

 

Enjoy!

 

-------------------------------------------------------

-- Script to validate my database to use DataSync

--------------------------------------------------------

 

IF (SELECT ISNULL(COUNT(*),0) FROM sys.tables where sys.tables.is_ms_shipped=0)>=500 

     Print 'Check #1: Fail - You have more than 500 tables'

ELSE

     Print 'Check #1: Success - You do not have the maximum tables to Sync'

 

-----------

-- Review if you have permissions to DataSync Schema

-----------

DECLARE @tablename sysname, @object_id bigint, @nTemporal int 

  

DECLARE TablesCursor CURSOR FOR SELECT Name, OBJECT_ID FROM sys.tables where sys.tables.is_ms_shipped=0 order by Name;

 

OPEN TablesCursor 

FETCH NEXT FROM TablesCursor INTO @tablename, @object_id 

  

WHILE @@FETCH_STATUS = 0 

BEGIN 

    PRINT ' ' 

    PRINT 'Control #2: Table: ' + @tablename + '-- ' + CONVERT(varchar(200),@object_id)

      

    DECLARE PermissionsCursor CURSOR FOR SELECT TOP 1 grantee_principal_id

                                         FROM sys.database_permissions p

                                         WHERE major_id = @object_id and grantee_principal_id = USER_ID() AND permission_name='CONTROL'

    OPEN PermissionsCursor

    FETCH NEXT FROM PermissionsCursor INTO @nTemporal 

    IF @@FETCH_STATUS = 0  

        PRINT ' -----> Has enough permissions'

       ELSE

           PRINT ' -----> Fail - Has not enough permissions'

      

    CLOSE PermissionsCursor

    DEALLOCATE PermissionsCursor

 

       IF LEN(@TableName)>50 PRINT '  -----> Fail - The name of the table reached the maximum length'

 

    DECLARE ColsCursor CURSOR FOR SELECT TOP 1 object_id

                                         FROM sys.columns

                                         WHERE object_id = @object_id AND len(name)>50

    OPEN ColsCursor

    FETCH NEXT FROM ColsCursor INTO @nTemporal 

    IF @@FETCH_STATUS = 0  

        PRINT ' -----> Fail - The length of some column name of this table is reached the maximum allowed'

       ELSE

           PRINT ' -----> The length of some column name of this table is not reached the maximum allowed'

     

    CLOSE ColsCursor

    DEALLOCATE ColsCursor

   

    FETCH NEXT FROM TablesCursor INTO @tablename, @object_id 

END  

CLOSE TablesCursor; 

DEALLOCATE TablesCursor

 

---

-- Check if DataSync schema is created and has control permissions

----

IF (SELECT ISNULL(COUNT(*),0) FROM sys.schemas where name='DataSync')=1 

     Print 'Check #3: You have the schema DataSync created'

ELSE

     Print 'Check #3: Fail - You do not have the schema DataSync created'

 

 

-----------

-- Review if you have permissions to DataSync Schema

-----------

IF HAS_PERMS_BY_NAME('DATASYNC', 'SCHEMA', 'CONTROL')=1 

     Print 'Check #4: You have control permission in DataSync schema'

ELSE

     Print 'Check #4: You do not have control permission in DataSync Schema'

 

-----------

-- Review if you have permissions to DataSync Schema

-----------

IF (SELECT snapshot_isolation_state FROM sys.databases where name=db_name()) = 1 AND

   (SELECT is_read_committed_snapshot_on FROM sys.databases where name=db_name()) = 1

   Print 'Check #5: You have snapshot isolation level'

ELSE

   Print 'Check #5: You dont have snapshot isolation level'