Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Microsoft is giving away 50,000 FREE Microsoft Certification exam vouchers. Get Fabric certified for FREE! Learn more

Reply
nielsvdc
Advocate I
Advocate I

Mirroring, DTAP workspaces and branches

We have 3 workspaces for our development, test and production environments and each environment has it's own branch. We created a mirroring item in development to sync data from a SQL server to Fabric. The mirroring item supports syncing with a git repo.

We are using Azure DevOps to deploy code to another environment branch and use the Update from Git API to update the target workspace.

 

When updating the workspace using the API, we get the error:

Updating Fabric workspace update from git has failed: {'errorCode': 'GitSyncFailed', 'moreDetails': [{'errorCode': 'Git_InvalidResponseFromWorkload', 'message': 'An error occurred while processing the operation', 'relatedResource': {'resourceId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'resourceType': 'MountedRelationalDatabase'}}], 'message': 'Failed to sync between Git and the workspace'}.

 

Updating from Git works when we do it manually by clicking the Update All button in the workspace. But when we look at the mirroring item, we see the error message:

Code: SqlChangeFeedError, Type: UserError, Message: This SQL Database can only be mirrored once across Fabric workspaces

 

So, using mirroring does not really work in a DTAP environment. Anyone has any advise?

1 ACCEPTED SOLUTION
v-zhengdxu-msft
Community Support
Community Support

Hi @nielsvdc 

 

Why Manual Update Works but API Fails is Manual "Update All" might skip re-provisioning the mirroring item if it already exists, whereas the API could be reapplying the full Git state, attempting to recreate the mirroring item and triggering the error.

 

The error occurs because Fabric allows a SQL database to be mirrored only once across all workspaces. When deploying via the API, the mirroring configuration is likely recreated in each environment workspace, violating this constraint. Here's a structured solution:
Create a central workspace solely for mirroring the SQL database. This workspace is not part of your DTAP branches, ensuring no other workspace mirrors the same database.


Use Fabric's data sharing features (e.g., shortcuts, data products, or shared datasets) to reference the mirrored data in your dev/test/prod workspaces, and avoid re-mirroring in each environment; instead, reference the central mirrored dataset.

 

Remove mirroring configurations from environment-specific branches. The Git repo should only include code that doesn’t trigger re-mirroring. Use environment-specific parameters(e.g., connection strings) to point to the shared mirrored data or their own databases.


Use Separate SQL Databases for Each Environment: 

If strict environment isolation is required, provision dedicated SQL databases for dev, test, and prod.
Mirror each database in its respective workspace. This avoids conflicts since each is a unique database.


Leverage Fabric Deployment Pipelines:
Instead of Git sync, use Fabric’s deployment pipelines to promote content (including mirrored data) from dev → test → prod.
Deployment pipelines handle dependencies like mirrored items without re-mirroring.

 

Modify API Deployment Logic:
Before invoking the Update from Git API, ensure the target workspace does not include mirroring items.
Use the API to sync only non-mirroring components (e.g., reports, datasets) and reference the shared mirrored data.

 

 

Best Regards

Zhengdong Xu
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

2 REPLIES 2
nielsvdc
Advocate I
Advocate I

Before posting ther question I was thinking the same thing. Unfortunately there is only one source production database that we can work with. What we are going to do is create the mirrored database in a separate workspace without a repository attached. Then in each environment workspace we create a landing Lakehouse and create shortcuts to the tables in the mirrored database. I think shortcuts are currently in preview for git integration, so these should be deployed automatically to each environment.

v-zhengdxu-msft
Community Support
Community Support

Hi @nielsvdc 

 

Why Manual Update Works but API Fails is Manual "Update All" might skip re-provisioning the mirroring item if it already exists, whereas the API could be reapplying the full Git state, attempting to recreate the mirroring item and triggering the error.

 

The error occurs because Fabric allows a SQL database to be mirrored only once across all workspaces. When deploying via the API, the mirroring configuration is likely recreated in each environment workspace, violating this constraint. Here's a structured solution:
Create a central workspace solely for mirroring the SQL database. This workspace is not part of your DTAP branches, ensuring no other workspace mirrors the same database.


Use Fabric's data sharing features (e.g., shortcuts, data products, or shared datasets) to reference the mirrored data in your dev/test/prod workspaces, and avoid re-mirroring in each environment; instead, reference the central mirrored dataset.

 

Remove mirroring configurations from environment-specific branches. The Git repo should only include code that doesn’t trigger re-mirroring. Use environment-specific parameters(e.g., connection strings) to point to the shared mirrored data or their own databases.


Use Separate SQL Databases for Each Environment: 

If strict environment isolation is required, provision dedicated SQL databases for dev, test, and prod.
Mirror each database in its respective workspace. This avoids conflicts since each is a unique database.


Leverage Fabric Deployment Pipelines:
Instead of Git sync, use Fabric’s deployment pipelines to promote content (including mirrored data) from dev → test → prod.
Deployment pipelines handle dependencies like mirrored items without re-mirroring.

 

Modify API Deployment Logic:
Before invoking the Update from Git API, ensure the target workspace does not include mirroring items.
Use the API to sync only non-mirroring components (e.g., reports, datasets) and reference the shared mirrored data.

 

 

Best Regards

Zhengdong Xu
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Helpful resources

Announcements
MarchFBCvideo - carousel

Fabric Monthly Update - March 2025

Check out the March 2025 Fabric update to learn about new features.

March2025 Carousel

Fabric Community Update - March 2025

Find out what's new and trending in the Fabric community.

"); $(".slidesjs-pagination" ).prependTo(".pagination_sec"); $(".slidesjs-pagination" ).append("
"); $(".slidesjs-play.slidesjs-navigation").appendTo(".playpause_sec"); $(".slidesjs-stop.slidesjs-navigation").appendTo(".playpause_sec"); $(".slidesjs-pagination" ).append(""); $(".slidesjs-pagination" ).append(""); } catch(e){ } /* End: This code is added by iTalent as part of iTrack COMPL-455 */ $(".slidesjs-previous.slidesjs-navigation").attr('tabindex', '0'); $(".slidesjs-next.slidesjs-navigation").attr('tabindex', '0'); /* start: This code is added by iTalent as part of iTrack 1859082 */ $('.slidesjs-play.slidesjs-navigation').attr('id','playtitle'); $('.slidesjs-stop.slidesjs-navigation').attr('id','stoptitle'); $('.slidesjs-play.slidesjs-navigation').attr('role','tab'); $('.slidesjs-stop.slidesjs-navigation').attr('role','tab'); $('.slidesjs-play.slidesjs-navigation').attr('aria-describedby','tip1'); $('.slidesjs-stop.slidesjs-navigation').attr('aria-describedby','tip2'); /* End: This code is added by iTalent as part of iTrack 1859082 */ }); $(document).ready(function() { if($("#slides .item").length < 2 ) { /* Fixing Single Slide click issue (commented following code)*/ // $(".item").css("left","0px"); $(".item.slidesjs-slide").attr('style', 'left:0px !important'); $(".slidesjs-stop.slidesjs-navigation").trigger('click'); $(".slidesjs-previous").css("display", "none"); $(".slidesjs-next").css("display", "none"); } var items_length = $(".item.slidesjs-slide").length; $(".slidesjs-pagination-item > button").attr("aria-setsize",items_length); $(".slidesjs-next, .slidesjs-pagination-item button").attr("tabindex","-1"); $(".slidesjs-pagination-item button").attr("role", "tab"); $(".slidesjs-previous").attr("tabindex","-1"); $(".slidesjs-next").attr("aria-hidden","true"); $(".slidesjs-previous").attr("aria-hidden","true"); $(".slidesjs-next").attr("aria-label","Next"); $(".slidesjs-previous").attr("aria-label","Previous"); //$(".slidesjs-stop.slidesjs-navigation").attr("role","button"); //$(".slidesjs-play.slidesjs-navigation").attr("role","button"); $(".slidesjs-pagination").attr("role","tablist").attr("aria-busy","true"); $("li.slidesjs-pagination-item").attr("role","list"); $(".item.slidesjs-slide").attr("tabindex","-1"); $(".item.slidesjs-slide").attr("aria-label","item"); /*$(".slidesjs-stop.slidesjs-navigation").on('click', function() { var itemNumber = parseInt($('.slidesjs-pagination-item > a.active').attr('data-slidesjs-item')); $($('.item.slidesjs-slide')[itemNumber]).find('.c-call-to-action').attr('tabindex', '0'); });*/ $(".slidesjs-stop.slidesjs-navigation, .slidesjs-pagination-item > button").on('click keydown', function() { $.each($('.item.slidesjs-slide'),function(i,el){ $(el).find('.c-call-to-action').attr('tabindex', '-1'); }); var itemNumber = parseInt($('.slidesjs-pagination-item > button.active').attr('data-slidesjs-item')); $($('.item.slidesjs-slide')[itemNumber]).find('.c-call-to-action').attr('tabindex', '0'); }); $(".slidesjs-play.slidesjs-navigation").on('click', function() { $.each($('.item.slidesjs-slide'),function(i,el){ $(el).find('.c-call-to-action').attr('tabindex', '-1'); }); }); $(".slidesjs-pagination-item button").keyup(function(e){ var keyCode = e.keyCode || e.which; if (keyCode == 9) { e.preventDefault(); $(".slidesjs-stop.slidesjs-navigation").trigger('click').blur(); $("button.active").focus(); } }); $(".slidesjs-play").on("click",function (event) { if (event.handleObj.type === "click") { $(".slidesjs-stop").focus(); } else if(event.handleObj.type === "keydown"){ if (event.which === 13 && $(event.target).hasClass("slidesjs-play")) { $(".slidesjs-stop").focus(); } } }); $(".slidesjs-stop").on("click",function (event) { if (event.handleObj.type === "click") { $(".slidesjs-play").focus(); } else if(event.handleObj.type === "keydown"){ if (event.which === 13 && $(event.target).hasClass("slidesjs-stop")) { $(".slidesjs-play").focus(); } } }); $(".slidesjs-pagination-item").keydown(function(e){ switch (e.which){ case 37: //left arrow key $(".slidesjs-previous.slidesjs-navigation").trigger('click'); e.preventDefault(); break; case 39: //right arrow key $(".slidesjs-next.slidesjs-navigation").trigger('click'); e.preventDefault(); break; default: return; } $(".slidesjs-pagination-item button.active").focus(); }); }); // Start This code is added by iTalent as part of iTrack 1859082 $(document).ready(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); $("#tip2").attr("aria-hidden","true").addClass("hidden"); $(".slidesjs-stop.slidesjs-navigation, .slidesjs-play.slidesjs-navigation").attr('title', ''); $("a#playtitle").focus(function(){ $("#tip1").attr("aria-hidden","false").removeClass("hidden"); }); $("a#playtitle").mouseover(function(){ $("#tip1").attr("aria-hidden","false").removeClass("hidden"); }); $("a#playtitle").blur(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); }); $("a#playtitle").mouseleave(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); }); $("a#play").keydown(function(ev){ if (ev.which ==27) { $("#tip1").attr("aria-hidden","true").addClass("hidden"); ev.preventDefault(); return false; } }); $("a#stoptitle").focus(function(){ $("#tip2").attr("aria-hidden","false").removeClass("hidden"); }); $("a#stoptitle").mouseover(function(){ $("#tip2").attr("aria-hidden","false").removeClass("hidden"); }); $("a#stoptitle").blur(function(){ $("#tip2").attr("aria-hidden","true").addClass("hidden"); }); $("a#stoptitle").mouseleave(function(){ $("#tip2").attr("aria-hidden","true").addClass("hidden"); }); $("a#stoptitle").keydown(function(ev){ if (ev.which ==27) { $("#tip2").attr("aria-hidden","true").addClass("hidden"); ev.preventDefault(); return false; } }); }); // End This code is added by iTalent as part of iTrack 1859082