March 27, 2013 at 4:10 PM

BizTalk provides out-of-the-box functionality to include your custom BizTalk database in the standard backup procedure. 
You can find all details on MSDN.  Here’s a small synopsis:

 

  • Execute these scripts against your custom database
    • %BTSINTALLDIR%\Schema\Backup_Setup_All_Procs.dsl
    • %BTSINTALLDIR%\Schema\Backup_Setup_All_Tables.dsl

 

  • Add the SQL Agent account to the BTS_BACKUP_USERS role of your custom database

 

  • Modify the adm_OtherBackupDatabases table of the BizTalkMgmtDb, add a record for your custom database

 

        image

 

However, when I executed the BizTalk Backup Job after this change, I got the following exception:

 

  • [SQLSTATE 01000] (Message 4035)  BACKUP LOG is terminating abnormally. [SQLSTATE 42000] (Error 3013)  BACKUP LOG cannot be performed because there is no current database backup.

 

The cause was the fact that it is not possible to take a transactional backup of a database, if you didn’t take a full backup first.  This issue was fixed by executing the stored procedure sp_ForceFullBackup of the BizTalkMgmtDb.  Now the custom database had a initial full backup and the BizTalk Backup Job executed successfully.  This result was an extra database backup:

 

image

Posted in: BizTalk | Database | Infrastructure | SQL Server

Tags:


February 22, 2012 at 11:22 AM

Microsoft BizTalk Server 2010 ships with some assemblies that assist you with the administration and deployment of your BizTalk environment.  During the development of an automated deployment plan, we were able to perform most of the deployment tasks at a BizTalk application level, by using these assemblies:

 

Microsoft.BizTalk.ExplorerOM

 

-       Create/delete applications

-       Control receive locations

-       Control orchestrations

-       Control send ports

-       Control send port groups

-       Control application references

 

Microsoft.BizTalk.ApplicationDeployment

 

-       Add/remove resources

 

Microsoft.BizTalk.Deployment

 

-       Import/export bindings

 

Microsoft.BizTalk.Operations

 

-       Query for active service instances         

 

Remark that all of the used objects can be initialized by three parameters:

      -    SqlServerName

-    BizTalkMgmtDbName

-    ApplicationName

 

 

The object "BizTalk Group" is defined by the SqlServerName and the BizTalkMgmtDbName.  A "BizTalk Application" is defined by its BizTalk Group and the ApplicationName.  However, these assemblies have totally no notion of the object "BizTalk Server".  They only support operations at a database level (BizTalk Group), but some deployment tasks need to be executed on a BizTalk Server level:

 

- Install/uninstall assemblies to the Global Assembly Cache

- Control host instances

 

For both actions we needed to be able to dynamically determine which BizTalk Servers are part of the already defined BizTalk Group. After some research, we found two options to implement this logic:

 

Windows Management Instrumentation

 

WMI has some support for BizTalk via the WMI namespace “root\\MicrosoftBizTalkServer”.  We are able to loop though all configured host instances, by executing a query on the MSBTS_HostInstance class.  As each host instance runs on a BizTalk Server, it’s easy to implement some logic that retrieves all BizTalk Servers.

 

private List<string> GetBizTalkServers()
{
     List<string> btsServers = new List<string>();

     EnumerationOptions wmiEnumerationOptions = new EnumerationOptions { ReturnImmediately = false };
     ObjectQuery wmiQuery = new ObjectQuery("SELECT * FROM MSBTS_HostInstance");
     using (ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("root\\MicrosoftBizTalkServer", wmiQuery.QueryString, wmiEnumerationOptions))
     {
          ManagementObjectCollection hostInstanceCollection = wmiSearcher.Get();
          foreach (ManagementObject hostInstance in hostInstanceCollection.Cast<ManagementObject>())
          {
                string btsServer = hostInstance["Name"].ToString().Split(' ').Last();
                if (btsServers.Contains(btsServer) == false)
                {
                     btsServers.Add(btsServer);
                }
          }
      } 

      return btsServers;
}

Custom SQL Server Query

 

Another option is to retrieve the information directly from the BizTalkMgmtDb.  The table adm_Server actually contains a list of all BizTalk Servers that are part of the BizTalk Group.  So this simple .NET code is able to return us the needed information:

 

 

private List<string> GetBizTalkServers()
{
     List<string> btsServers = new List<string>();

     SqlConnection sqlConnection = new SqlConnection(String.Format(CultureInfo.CurrentCulture, "Server={0};Database={1};Integrated Security=SSPI;", SqlServerName, MgmtDatabase));
     SqlCommand sqlCommand = new SqlCommand("SELECT Name FROM [dbo].[adm_Server]", sqlConnection);

     sqlConnection.Open();

     SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();

     while (sqlDataReader.Read())
     {
          btsServers.Add(sqlDataReader["Name"].ToString());
     }

     sqlConnection.Close();

     return btsServers;
}

 

 

Conclusion

 

It's pretty easy to retrieve a list of all BizTalk Servers that are part of a BizTalk Group.  A limitation of the WMI approach is that this will only work when it's executed on one of the BizTalk Servers.  So I prefer the SQL approach, because this will also work for remote execution.

 

Toon Vanhoutte

Posted in: BizTalk | Cluster | Deployment | General | Infrastructure

Tags:


October 11, 2011 at 10:08 AM

On one of the BizTalk environments hosted by Codit we recently migrated our shared storage. 

The environment contains 2 2-node clusters (for the BizTalk and SQL environment). 

Once the particularities figured out this proved to be a painless process:

 

Preparation

 First we prepared the new storage as we normally would: connect to the new iSCSI Target and prepare the disks. We provided the new partitions with temporary drive letters and added the new storage to the clustered applications.

 

Data Migration

Before migrating the data we took all BizTalk and SQL services down.

With the services offline we copied the data from the old to the new disks. 

To retain permissions data was copied using XCopy:

xcopy source destination /O /X /E /H /K

/E- Copies folders and subfolders, including empty ones. 

/H- Copies hidden and system files also. 

/K- Copies attributes. Typically, Xcopy resets read-only attributes.

/O- Copies file ownership and ACL information.

/X  Copies file audit settings (implies /O).-

 

Note: This is not necessary for the cluster quorum..

 

Cluster Reconfiguration

Moving the quorum disk is painless using the Failover Cluster Management mmc:

 

 Once the quorum is moved we replace the old storage with the new:

Start by giving the old disks (except the quorum disk) a new temporary drive letter. 

 Give the new disks the drive letter of the disk they are replacing.

 In the Failover Cluster mmc, in the properties of the services replace the dependency to the old storage.

 

Clean-up

Delete the old disks from the cluster storage.

Log off from and delete the old portal.

 

We used this procedure on 4 of our clusters without any issues, apart from the downtime. 

The time configuring was limited, most of the time was ‘lost’ copying over the data.