One of the recommendations in Microsoft’s Preferred Architecture for Exchange Server 2013 is to distribute active database copies evenly across all members of a database availability group.
As with the namespace model, each DAG within the site resilient datacenter pair operates in an unbound model with active copies distributed equally across all servers in the DAG. This model provides two benefits:
- Ensures that each DAG member’s full stack of services is being validated (client connectivity, replication pipeline, transport, etc.).
- Distributes the load across as many servers as possible during a failure scenario, thereby only incrementally increasing resource utilization across the remaining members within the DAG.
You can achieve an even distribution of active database copies in your DAG by applying a combination of PowerShell scripts and activation preference configuration.
Reviewing Your Activation Preference Distribution
To review the current configuration of your database availability group you can use two PowerShell scripts. The first script is RedistributeActiveDatabases.ps1 which is available in the $exscripts folder of any server or management workstation that has the Exchange management tools installed.
To look at the current database distribution use RedistributeActiveDatabases.ps1 with the -ShowDatabaseDistributionByServer switch.
[PS] C:\>Set-Location $exscripts [PS] C:\...\scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG1 -ShowDatabaseDistributionByServer ServerName : SYDEX2 TotalDbs : 4 ActiveDbs : 2 PassiveDbs : 2 PreferenceCountList : {0, 4, 0, 0} MountedDbs : 2 DismountedDbs : 0 DagName : DAG1 ServerName : MELEX1 TotalDbs : 4 ActiveDbs : 0 PassiveDbs : 4 PreferenceCountList : {0, 0, 4, 0} MountedDbs : 0 DismountedDbs : 0 DagName : DAG1 ServerName : SYDEX1 TotalDbs : 4 ActiveDbs : 2 PassiveDbs : 2 PreferenceCountList : {4, 0, 0, 0} MountedDbs : 2 DismountedDbs : 0 DagName : DAG1 ServerName : MELEX2 TotalDbs : 4 ActiveDbs : 0 PassiveDbs : 4 PreferenceCountList : {0, 0, 0, 4} MountedDbs : 0 DismountedDbs : 0 DagName : DAG1
The detail we’re most interested in at this stage is the PreferenceCountList. For the DAG member SYDEX1 the value is “{4, 0, 0, 0}” which means:
- 4 database copies on SYDEX1 with Activation Preference 1
- 0 database copies on SYDEX1 with AP of 2, 3, or 4
A better visual representation of the database AP layout can be gathered by running Get-DAGApMap.ps1 (available on Github), which generates a CSV of the configuration that is easier to read.
[PS] C:\Scripts\>.\Get-DagApMap.ps1
The DAG shown above is clearly not balanced, so what can we do about that?
Balancing Activation Preferences for a Database Availability Group
Although we can manually change the activation preference values for each of the database copies it would be quite tedious to do so for a large DAG. Instead, we can use RedistributeActiveDatabases.ps1 again, this time with the -BalanceActivationPreferences switch. If you don’t want to be prompted for each change that is made add the -Confirm:$false switch as well.
[PS] C:\...\scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG1 -BalanceActivationPreferences *************************************** Balance DAG DBs Tuesday, April 28, 2015 12:20:05 PM *************************************** Dag : DAG1 ServerCount : 4 DatabaseCount : 4 CopiesCount : 16 -------------------------- Starting Site Distribution -------------------------- SiteName TotalDbs ActiveDbs PassiveDbs PreferenceCountList MountedDbs DismountedDbs DagName -------- -------- --------- ---------- ------------------- ---------- ------------- ------- Melbourne-Datacenter 8 0 8 {0, 0, 4, 4} 0 0 DAG1 Sydney-Datacenter 8 4 4 {4, 4, 0, 0} 4 0 DAG1 ---------------------------- Starting Server Distribution ---------------------------- ServerName TotalDbs ActiveDbs PassiveDbs PreferenceCountList MountedDbs DismountedDbs DagName ---------- -------- --------- ---------- ------------------- ---------- ------------- ------- MELEX1 4 0 4 {0, 0, 4, 0} 0 0 DAG1 MELEX2 4 0 4 {0, 0, 0, 4} 0 0 DAG1 SYDEX1 4 2 2 {4, 0, 0, 0} 2 0 DAG1 SYDEX2 4 2 2 {0, 4, 0, 0} 2 0 DAG1 ---------------------------------------- Starting Activation Preference Balancing ---------------------------------------- Database copy 'DB01\MELEX1': Activation Preference = 1 Database copy 'DB01\MELEX2': Activation Preference = 2 Database copy 'DB01\SYDEX1': Activation Preference = 3 Database copy 'DB01\SYDEX2': Activation Preference = 4 Database copy 'DB02\MELEX1': Activation Preference = 2 Database copy 'DB02\MELEX2': Activation Preference = 3 Database copy 'DB02\SYDEX1': Activation Preference = 4 Database copy 'DB02\SYDEX2': Activation Preference = 1 Database copy 'DB03\MELEX1': Activation Preference = 3 Database copy 'DB03\MELEX2': Activation Preference = 4 Database copy 'DB03\SYDEX1': Activation Preference = 1 Database copy 'DB03\SYDEX2': Activation Preference = 2 Database copy 'DB04\MELEX1': Activation Preference = 4 Database copy 'DB04\MELEX2': Activation Preference = 1 Database copy 'DB04\SYDEX1': Activation Preference = 2 Database copy 'DB04\SYDEX2': Activation Preference = 3
After the script has finished running we can use the same methods shown earlier to review the configuration.
[PS] C:\...\scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG1 -ShowDatabaseDistributionByServer ServerName : SYDEX2 TotalDbs : 4 ActiveDbs : 2 PassiveDbs : 2 PreferenceCountList : {1, 1, 1, 1} MountedDbs : 2 DismountedDbs : 0 DagName : DAG1 ServerName : MELEX1 TotalDbs : 4 ActiveDbs : 0 PassiveDbs : 4 PreferenceCountList : {1, 1, 1, 1} MountedDbs : 0 DismountedDbs : 0 DagName : DAG1 ServerName : SYDEX1 TotalDbs : 4 ActiveDbs : 2 PassiveDbs : 2 PreferenceCountList : {1, 1, 1, 1} MountedDbs : 2 DismountedDbs : 0 DagName : DAG1 ServerName : MELEX2 TotalDbs : 4 ActiveDbs : 0 PassiveDbs : 4 PreferenceCountList : {1, 1, 1, 1} MountedDbs : 0 DismountedDbs : 0 DagName : DAG1
Notice now that each DAG member has a PreferenceCountList of “{1, 1, 1, 1}” indicating an evenly balanced DAG as far as activation preferences go.
And again we can use Get-DAGApMap.ps1 to see it in CSV format instead.
Rebalancing the Database Availability Group
Now that the activation preferences are evenly distributed, what about the active database copies themselves? We can look at the current active database copies by running Get-MailboxDatabaseCopyStatus.
[PS] C:\>Get-MailboxDatabaseCopyStatus * -Active | Select Name,Status,MailboxServer,ActivationPreference
Or rather we could, if not for this bug which has been present in every build of Exchange 2013 up to CU8 so far. A fix may be forthcoming in a later build.
Fortunately we can use RedistributeActiveDatabases.ps1 again with the -ShowDatabaseCurrentActives switch.
[PS] C:\...\scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG1 -ShowDatabaseCurrentActives *************************************** Balance DAG DBs Tuesday, April 28, 2015 12:33:15 PM *************************************** Dag : DAG1 ServerCount : 4 DatabaseCount : 4 CopiesCount : 16 -------------------------- Starting Site Distribution -------------------------- SiteName TotalDbs ActiveDbs PassiveDbs PreferenceCountList MountedDbs DismountedDbs DagName -------- -------- --------- ---------- ------------------- ---------- ------------- ------- Melbourne-Datacenter 8 0 8 {2, 2, 2, 2} 0 0 DAG1 Sydney-Datacenter 8 4 4 {2, 2, 2, 2} 4 0 DAG1 ---------------------------- Starting Server Distribution ---------------------------- ServerName TotalDbs ActiveDbs PassiveDbs PreferenceCountList MountedDbs DismountedDbs DagName ---------- -------- --------- ---------- ------------------- ---------- ------------- ------- MELEX1 4 0 4 {1, 1, 1, 1} 0 0 DAG1 MELEX2 4 0 4 {1, 1, 1, 1} 0 0 DAG1 SYDEX1 4 2 2 {1, 1, 1, 1} 2 0 DAG1 SYDEX2 4 2 2 {1, 1, 1, 1} 2 0 DAG1 DbName : DB02 ActiveOnPreferenceAtStart : 1 ActiveServerAtStart : SYDEX2 ActiveOnPreferenceAtEnd : ActiveServerAtEnd : IsOnMostPreferredCopy : True MoveStatus : NoMoveAttempted DbName : DB01 ActiveOnPreferenceAtStart : 4 ActiveServerAtStart : SYDEX2 ActiveOnPreferenceAtEnd : ActiveServerAtEnd : IsOnMostPreferredCopy : False MoveStatus : NoMoveAttempted DbName : DB03 ActiveOnPreferenceAtStart : 1 ActiveServerAtStart : SYDEX1 ActiveOnPreferenceAtEnd : ActiveServerAtEnd : IsOnMostPreferredCopy : True MoveStatus : NoMoveAttempted DbName : DB04 ActiveOnPreferenceAtStart : 2 ActiveServerAtStart : SYDEX1 ActiveOnPreferenceAtEnd : ActiveServerAtEnd : IsOnMostPreferredCopy : False MoveStatus : NoMoveAttempted ---------------- Summary of Moves ---------------- Successfully moved : 0 Moved to less preferred : 0 Failed to move : 0 Not moved : 4 Start time : Tuesday, April 28, 2015 12:33:07 PM End time : Tuesday, April 28, 2015 12:33:15 PM Duration : 00:00:08.3172669
The sections of the output above like this one tell us what we want to know.
DbName : DB02 ActiveOnPreferenceAtStart : 1 ActiveServerAtStart : SYDEX2 ActiveOnPreferenceAtEnd : ActiveServerAtEnd : IsOnMostPreferredCopy : True MoveStatus : NoMoveAttempted
In the example above the database DB02 is active on server SYDEX2, which has an AP of 1.
Finally, if we want to rebalance the DAG so that each database is active on its AP=1 copy, we can run RedistributeActiveDatabases.ps1 with the -BalanceDbsByActivationPreference switch. Use -Confirm:$false if you don’t want to be prompted for each switchover.
[PS] C:\...\scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG1 -BalanceDbsByActivationPreference -Confirm:$false
[adrotate banner=”49″]
Would adding a flange to the crevice aid the flux capacitance too?
As John Mohler said, is it possible to move all db copies depending on the activation preference? For example, i have 3 servers, s1, s2 and s3. s1 and s2 are in one site, and s3 in other site. all copies os server 3 have AP 3. I would like to move all db to server3 by activation preference.
Thank you in advance.
Quick question… We see latency issues on DB’s and sometime, just moving the DB to a new server and back fixes the problem. Can this script move all db copies to ActivationPreference 2? Would you use the -activationpreference 2 switch?
Verey usefull, thanks !
https://blogs.technet.microsoft.com/exchange/2016/06/16/dag-activation-preference-behavior-change-in-exchange-server-2016-cu2/
2016 CU2 will do this automatically..
looks good, does it work in Exchange 2016 as well?
Yep.
Hi Paul,
May I ask is it possible that this script for redistribution of databases can cause unhealthy DB copies or any problems with databases?
Hi Paul
Thanks this is very helpful.
But I would like to go even a step further.
Not only divide the load of your databases but also divide the user load across the different databases.
The thing I would like to achieve is to get an even load (mailbox size wise) across all databases.
So not based on how many users there are on a database but based on mailbox sizes so that you get databases with almost identical sizes.
What are your thoughts on this?
Is it useful and possible to script this?
Thanks in advance.