Microsoft SQL Server Always On availability groups let you replicate databases across multiple SQL Server Enterprise instances.
Similar to SQL Server Failover Cluster Instances, Always On availability groups use Windows Server Failover Clustering (WSFC) to implement high availability. However, the two features differ in the following ways:
Always On availability groups | Failover cluster instances | |
---|---|---|
Scope of fail-over | Group of databases | Instance |
Storage | Not shared | Shared |
For a more detailed comparison, see Comparison of failover cluster instances and availability groups.
Always On availability groups support multiple availability modes. This tutorial shows how you can deploy Always On availability groups in synchronous commit mode to implement high availability for one or more databases.
In the setup, you will create three VM instances. Two VM instances, node-1
and
node-2
serve as cluster nodes and run SQL Server.
A third VM instance, witness
, is used to achieve a
quorum
in a failover scenario.
The three VM instances are distributed over three zones and share a common subnet.
Using a SQL Server Always On availability group, an example database, bookshelf
,
is synchronously replicated across the two SQL Server instances.
In an on-premises Windows cluster environment, Address Resolution Protocol (ARP) announcements trigger IP address failover. Google Cloud, however, disregards ARP announcements. Consequently, you must implement one of the following two options: using an internal load balancer and a distributed network name (DNN).
The article assumes that you have already deployed Active Directory on Google Cloud and that you have basic knowledge of SQL Server, Active Directory, and Compute Engine. For more information about Active Directory on Google Cloud, see section Before you begin.
Using a SQL Server Always On availability group, an example database, bookshelf
,
is synchronously replicated across the two SQL Server instances. A distributed
network name (DNN) listener in front of the cluster provides a single endpoint
for SQL Server clients.
For more information about DNN, see Configure a DNN listener for an availability group.
This diagram includes the following:
- Two VM instances in the same region and different zones for the failover
cluster called
node-1
andnode-2
. One hosts the primary replica of the SQL Server database while the other node hosts the secondary replica. - A third VM called
witness
serves as a file share witness to provide a tie-breaking vote and achieve a quorum for failover. - A DNN listener in front of the cluster provides a single endpoint for SQL Server clients.
Objectives
- Deploy a WSFC comprising two SQL Server VM instances, and a third VM instance that acts as a file share witness.
- Create an availability group with synchronous commit.
- Configure a distributed network name (DNN) to route traffic to your availability group with SQL Server
- Verify that the setup is working by simulating a failover.
Costs
This tutorial uses billable components of Google Cloud, including:
Use the pricing calculator to generate a cost estimate based on your projected usage.
Before you begin
To complete the tasks in this tutorial, ensure the following:
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- You have an Active Directory domain with at least one domain controller. You can create an Active Directory domain using Managed Microsoft AD. Alternatively, you can deploy a custom Active Directory environment on Compute Engine and set up a private DNS forwarding zone that forwards DNS queries to your domain controllers.
-
You have an Active Directory user that has permission to join computers to
the domain and can sign in by using RDP. If you're using Managed Microsoft
AD, you can use the
setupadmin
user. For more information about Active Directory user account provisioning, see Active Directory user account provisioning - A Google Cloud project and a Virtual Private Cloud (VPC) with connectivity to your Active Directory domain controllers.
- A subnet to use for the Windows Server Failover Cluster VM instances.
Prepare your project and network
To deploy your SQL Server Always On availability groups, you must prepare your Google Cloud project and VPC for the deployment. The following sections discuss how you can do this in detail.
Configure your project and region
To prepare your Google Cloud project for the deployment of SQL Server Always On availability groups, do the following:
In the Google Cloud console, open Cloud Shell by clicking the Activate Cloud Shell button.
Initialize the following variables.
VPC_NAME=
VPC_NAME
SUBNET_NAME=SUBNET_NAME
Replace the following:
VPC_NAME
: name of your VPCSUBNET_NAME
: name of your subnet
Set your default project ID.
gcloud config set project
PROJECT_ID
Replace
PROJECT_ID
with the ID of your Google Cloud project.Set your default region.
gcloud config set compute/region
REGION
Replace
REGION
with the ID of the region you want to deploy in.
Create firewall rules
To allow clients to connect to the SQL Server and the communication between the cluster nodes you need to create several firewall rules. You can use network tags to simplify the creation of these firewall rules, as follows:
- The two cluster nodes are annotated with the
wsfc-node
tag. - All servers (including the
witness
) are annotated with thewsfc
tag.
To create firewall rules that use these network tags, use the following steps:
- Return to your existing Cloud Shell session.
Create firewall rules to allow traffic between cluster nodes.
SUBNET_CIDR=$(gcloud compute networks subnets describe $SUBNET_NAME --format=value\('ipCidrRange'\)) gcloud compute firewall-rules create allow-all-between-wsfc-nodes \ --direction=INGRESS \ --action=allow \ --rules=tcp,udp,icmp \ --enable-logging \ --source-tags=wsfc \ --target-tags=wsfc \ --network=$VPC_NAME \ --priority 10000 gcloud compute firewall-rules create allow-sql-to-wsfc-nodes \ --direction=INGRESS \ --action=allow \ --rules=tcp:1433 \ --enable-logging \ --source-ranges=$SUBNET_CIDR \ --target-tags=wsfc-node \ --network=$VPC_NAME \ --priority 10000
Create VM instances
Create and deploy two VM instances for the failover cluster. At any point in time, one of these VMs hosts the primary replica of the SQL Server database while the other node hosts the secondary replica. The two VM instances must:
- have failover clustering and SQL Server installed.
- have Compute Engine WSFC support enabled.
You use a SQL Server premium image which has SQL Server 2022 preinstalled.
To provide a tie-breaking vote and achieve a quorum for the failover scenario, deploy a third VM that serves as a file share witness using the following steps:
- Return to your existing Cloud Shell session.
Create a specialized script for the WSFC nodes. This script installs the necessary Windows features and creates firewall rules for WSFC and SQL Server.
cat << "EOF" > specialize-node.ps1 $ErrorActionPreference = "stop" # Install required Windows features Install-WindowsFeature Failover-Clustering -IncludeManagementTools Install-WindowsFeature RSAT-AD-PowerShell # Open firewall for WSFC netsh advfirewall firewall add rule name="Allow WSFC health check" dir=in action=allow protocol=TCP localport=59998 # Open firewall for SQL Server netsh advfirewall firewall add rule name="Allow SQL Server" dir=in action=allow protocol=TCP localport=1433 # Open firewall for SQL Server replication netsh advfirewall firewall add rule name="Allow SQL Server replication" dir=in action=allow protocol=TCP localport=5022 # Format data disk Get-Disk | Where partitionstyle -eq 'RAW' | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel 'Data' -Confirm:$false # Create data and log folders for SQL Server md d:\Data md d:\Logs EOF
Create the VM instances. On the two VMs that serve as cluster nodes, attach an additional data disk and enable the Windows Server Failover Clustering by setting the metadata key
enable-wsfc
totrue
:REGION=$(gcloud config get-value compute/region) ZONE1=
ZONE1
ZONE2=ZONE2
ZONE3=ZONE3
PD_SIZE=200 MACHINE_TYPE=n2-standard-8 gcloud compute instances create node-1 \ --zone $ZONE1 \ --machine-type $MACHINE_TYPE \ --subnet $SUBNET_NAME \ --image-family sql-ent-2022-win-2022 \ --image-project windows-sql-cloud \ --tags wsfc,wsfc-node \ --boot-disk-size 50 \ --boot-disk-type pd-ssd \ --boot-disk-device-name "node-1" \ --create-disk=name=node-1-datadisk,size=$PD_SIZE,type=pd-ssd,auto-delete=no \ --metadata enable-wsfc=true \ --metadata-from-file=sysprep-specialize-script-ps1=specialize-node.ps1 gcloud compute instances create node-2 \ --zone $ZONE2 \ --machine-type $MACHINE_TYPE \ --subnet $SUBNET_NAME \ --image-family sql-ent-2022-win-2022 \ --image-project windows-sql-cloud \ --tags wsfc,wsfc-node \ --boot-disk-size 50 \ --boot-disk-type pd-ssd \ --boot-disk-device-name "node-2" \ --create-disk=name=node-2-datadisk,size=$PD_SIZE,type=pd-ssd,auto-delete=no \ --metadata enable-wsfc=true \ --metadata-from-file=sysprep-specialize-script-ps1=specialize-node.ps1 gcloud compute instances create "witness" \ --zone $ZONE3 \ --machine-type e2-medium \ --subnet $SUBNET_NAME \ --image-family=windows-2022 \ --image-project=windows-cloud \ --tags wsfc \ --boot-disk-size 50 \ --boot-disk-type pd-ssd \ --metadata sysprep-specialize-script-ps1="add-windowsfeature FS-FileServer"Replace ZONE1, ZONE2, ZONE3 based on the zones you are using.
To join the three VM instances to Active Directory, do the following for each of the three VM instances:
Monitor the initialization process of the VM by viewing its serial port output.
gcloud compute instances tail-serial-port-output
NAME
Replace
NAME
with the name of the VM instance.Wait for a few minutes until you see the output
Instance setup finished
, then press Ctrl+C. At this point, the VM instance is ready to be used.Create a username and password for the VM instance.
Connect to the VM by using Remote Desktop and sign in using the username and password created in the previous step.
Right-click the Start button (or press Win+X) and click Windows PowerShell (Admin).
Confirm the elevation prompt by clicking Yes.
Join the computer to your Active Directory domain and restart.
Add-Computer -Domain
DOMAIN -Restart
Replace
DOMAIN
with the DNS name of your Active Directory domain.Enter the credentials of an account that has permissions to join a VM to the domain
Wait for the VM to restart. You have now joined the VM instance to the Active Directory.
Deploying the failover cluster
You can now use the VM instances to deploy a Windows Server Failover Cluster and SQL Server. The following sections discuss how you can do this in detail.
Preparing SQL Server
Create a new user account in Active Directory for SQL Server using the following steps.
- Connect to
node-1
by using Remote Desktop. Sign in with your domain user account. - Right-click the Start button (or press Win+X) and click Windows PowerShell (Admin).
- Confirm the elevation prompt by clicking Yes.
Create a domain user account for SQL server and the SQL agent and assign a password:
$Credential = Get-Credential -UserName sql_server -Message 'Enter password' New-ADUser ` -Name "sql_server" ` -Description "SQL Admin account." ` -AccountPassword $Credential.Password ` -Enabled $true -PasswordNeverExpires $true
To configure SQL Server, perform the following steps on both node-1
and
node-2
, use the following steps:
- Open SQL Server Configuration Manager.
- In the navigation pane, select SQL Server Services.
- In the list of services, right-click SQL Server (MSSQLSERVER) and select Properties.
Under Log on as, change the account as follows:
- Account name:
DOMAIN\sql_server
whereDOMAIN
is the NetBIOS name of your Active Directory domain. - Password: Enter the password you chose previously.
- Account name:
Click OK.
When prompted to restart SQL Server, select Yes.
SQL Server now runs under a domain user account.
Create file shares
Create two file shares on the VM instance witness
so that it can
store SQL Server backups and act as a file share witness:
- Connect to
witness
by using Remote Desktop. Sign in with your domain user account. - Right-click the Start button (or press Win+X) and click Windows PowerShell (Admin).
- Confirm the elevation prompt by clicking Yes.
Create a witness file share and grant yourself and the two cluster nodes access to the file share.
New-Item "C:\QWitness" –type directory icacls C:\QWitness\ /grant 'node-1$:(OI)(CI)(M)' icacls C:\QWitness\ /grant 'node-2$:(OI)(CI)(M)' New-SmbShare ` -Name QWitness ` -Path "C:\QWitness" ` -Description "SQL File Share Witness" ` -FullAccess $env:username,node-1$,node-2$
Create another file share to store backups and grant SQL Server full access:
New-Item "C:\Backup" –type directory New-SmbShare ` -Name Backup ` -Path "C:\Backup" ` -Description "SQL Backup" ` -FullAccess $env:USERDOMAIN\sql_server
Create the failover cluster
To create the failover cluster, use the following steps:
- Return to the Remote Desktop session on
node-1
. - Right-click the Start button (or press Win+X) and click Windows PowerShell (Admin).
- Confirm the elevation prompt by clicking Yes.
Create a new cluster.
New-Cluster ` -Name sql-cluster ` -Node node-1,node-2 ` -NoStorage ` -ManagementPointNetworkType Distributed
Return to the PowerShell session on
witness
and grant the virtual computer object of the cluster permission to access the file share.icacls C:\QWitness\ /grant 'sql-cluster$:(OI)(CI)(M)' Grant-SmbShareAccess ` -Name QWitness ` -AccountName 'sql-cluster$' ` -AccessRight Full ` -Force
Return to the PowerShell session on
node-1
and configure the cluster to use the file share onwitness
as a cluster quorum.Set-ClusterQuorum -FileShareWitness \\witness\QWitness
Verify that the cluster was created successfully.
Test-Cluster
You might see some warnings that can be safely ignored:
WARNING: System Configuration - Validate All Drivers Signed: The test reported some warnings.. WARNING: Network - Validate Network Communication: The test reported some warnings.. WARNING: Test Result: HadUnselectedTests, ClusterConditionallyApproved Testing has completed for the tests you selected. You should review the warnings in the Report. A cluster solution is supported by Microsoft only if you run all cluster validation tests, and all tests succeed (with or without warnings).
You can also launch the Failover Cluster Manager MMC snap-in to review the cluster's health by running
cluadmin.msc
.If you're using Managed AD, add the computer account used by the Windows cluster to the Cloud Service Domain Join Accounts group so that it can join computers to the domain.
Add-ADGroupMember ` -Identity "Cloud Service Domain Join Accounts" ` -Members sql-cluster$
Enable Always On availability groups on both nodes.
Enable-SqlAlwaysOn -ServerInstance node-1 -Force Enable-SqlAlwaysOn -ServerInstance node-2 -Force
Creating an availability group
You now create a sample database bookshelf
, include it in a new availability
group named bookshelf-ag
and configure high availability.
Creating a database
Create a new database. For the purpose of this tutorial, the database doesn't need to contain any data.
- Return to the Remote Desktop session on
node-1
. - Open the SQL Server Management Studio.
- In the Connect to server dialog, verify the server name is set to
node-1
and select Connect. - In the menu, select File > New > Query with current connection.
Paste the following SQL script into the editor:
-- Create a sample database CREATE DATABASE bookshelf ON PRIMARY ( NAME = 'bookshelf', FILENAME='d:\Data\bookshelf.mdf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB) LOG ON ( NAME = 'bookshelf_log', FILENAME='d:\Logs\bookshelf.ldf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB) GO USE [bookshelf] SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON GO -- Create sample table CREATE TABLE [dbo].[Books] ( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Title] [nvarchar](max) NOT NULL, [Author] [nvarchar](max) NULL, [PublishedDate] [datetime] NULL, [ImageUrl] [nvarchar](max) NULL, [Description] [nvarchar](max) NULL, [CreatedById] [nvarchar](max) NULL, CONSTRAINT [PK_dbo.Books] PRIMARY KEY CLUSTERED ([Id] ASC) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO -- Create a backup EXEC dbo.sp_changedbowner @loginame = 'sa', @map = false; ALTER DATABASE [bookshelf] SET RECOVERY FULL; GO BACKUP DATABASE bookshelf to disk = '\\witness\Backup\bookshelf.bak' WITH INIT GO
The script creates a new database with a single table and performs an initial backup to
witness
.Select Execute to run the SQL script.
Configure high availability
You can now configure high availability for the availability group using either T-SQL or Server Management Studio.
Using T-SQL
To configure high availability for the availability group using T-SQL, use the following steps:
Connect to
node-1
and then execute the following script to create thebookshelf-ag
availability group.CREATE LOGIN [
NET_DOMAIN
\sql_server] FROM WINDOWS; GO USE [bookshelf]; CREATE USER [NET_DOMAIN
\sql_server] FOR LOGIN [NET_DOMAIN
\sql_server]; GO USE [master]; CREATE ENDPOINT bookshelf_endpoint STATE=STARTED AS TCP (LISTENER_PORT=5022) FOR DATABASE_MIRRORING (ROLE=ALL); GO GRANT CONNECT ON ENDPOINT::[bookshelf_endpoint] TO [NET_DOMAIN
\sql_server] GOConnect to
node-2
and execute the following script.CREATE LOGIN [
NET_DOMAIN
\sql_server] FROM WINDOWS; GO CREATE ENDPOINT bookshelf_endpoint STATE=STARTED AS TCP (LISTENER_PORT=5022) FOR DATABASE_MIRRORING (ROLE=ALL); GO GRANT CONNECT ON ENDPOINT::[bookshelf_endpoint] TO [NET_DOMAIN
\sql_server] GOOn
node-1
and then execute the following script to create thebookshelf-ag
availability group.USE master; GO CREATE AVAILABILITY GROUP [bookshelf-ag] WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY, CLUSTER_TYPE = WSFC, DB_FAILOVER = ON ) FOR DATABASE [bookshelf] REPLICA ON N'node-1' WITH ( ENDPOINT_URL = 'TCP://node-1:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO) ), N'node-2' WITH ( ENDPOINT_URL = 'TCP://node-2:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO) ); GO
Connect to
node-2
and then execute the following script to join the secondary replica to the availability group and enable automatic seeding.USE master; GO ALTER AVAILABILITY GROUP [bookshelf-ag] JOIN; ALTER AVAILABILITY GROUP [bookshelf-ag] GRANT CREATE ANY DATABASE;
Check the status of the availability group.
SELECT * FROM sys.dm_hadr_availability_group_states; GO
You should see
synchronization_health_desc
asHEALTHY
.
Using SQL Server Management Studio
To configure high availability for the availability group using SQL Server Management Studio, use the following steps:
- In the Object Explorer window, right-click Always On High Availability and then select New Availability Group Wizard.
- On the Specify Options page, set the availability group name to
bookshelf-ag
, then select Next. - On the Select Databases page, select the
bookshelf
database, then select Next. On the Specify Replicas page, select the Replicas tab.
- Select Add replica.
In the Connect to server dialog, enter the server name
node-2
and select Connect.The list of availability replicas now contains SQL Server instances,
node-1
andnode-2
.Set the Availability mode to Synchronous commit for both instances.
Set Automatic failover to Enabled for both instances.
Select Next.
On the Select Data Synchronization page, select Automatic Seeding.
On the Validation page, verify that all checks are successful. You can ignore the availability group listener check.
On the Summary page, select Finish.
On the Results page, select Close.
Configure a DNN listener for the availability group
A DNN listener serves as a single endpoint for SQL Server clients. To configure a DNN listener, use the following steps:
- Return to the PowerShell session on
node-1
. Execute the following script to create a DNN listener.
$Ag='bookshelf-ag' $Port='
DNN_PORT
' $Dns='DNN_NAME
' # create the DNN resource with the port as the resource name Add-ClusterResource -Name $Port -ResourceType "Distributed Network Name" -Group $Ag # set the DNS name of the DNN resource Get-ClusterResource -Name $Port | Set-ClusterParameter -Name DnsName -Value $Dns # start the DNN resource Start-ClusterResource -Name $Port # add the Dependency from availability group resource to the DNN resource Set-ClusterResourceDependency -Resource $Ag -Dependency "[$Port]" # restart the availability group resource Stop-ClusterResource -Name $Ag Start-ClusterResource -Name $AgReplace
DNN_PORT
with the DNN listener port. The DNN listener port must be configured with a unique port. For more information, see Port considerations.Replace
DNN_NAME
with the DNN listener name.Create firewall rules for DNN listener port on both
node-1
andnode-2
.netsh advfirewall firewall add rule name="Allow DNN listener" dir=in action=allow protocol=TCP localport=
DNN_PORT
Test the failover
You are now ready to test if the failover works as expected:
- Return to the PowerShell session on
witness
. Run the following script.
while ($True){ $Conn = New-Object System.Data.SqlClient.SqlConnection $Conn.ConnectionString = "Server=
DNN_NAME
,DNN_PORT
;Integrated Security=true;Initial Catalog=master" $Conn.Open() $Cmd = New-Object System.Data.SqlClient.SqlCommand $Cmd.Connection = $Conn $Cmd.CommandText = "SELECT SERVERPROPERTY('ServerName')" $Adapter = New-Object System.Data.SqlClient.SqlDataAdapter $Cmd $Data = New-Object System.Data.DataSet $Adapter.Fill($Data) | Out-Null $Data.Tables[0] + (Get-Date -Format "MM/dd/yyyy HH:mm:ss") Start-Sleep -Seconds 2 }Replace
DNN_NAME
with the DNN listener name andDNN_PORT
with the DNN listener port.Every 2 seconds, the script connects to SQL Server by using the availability group listener, and queries the server name.
Leave the script running.
Return to the Remote Desktop session on
node-1
to trigger a failover.- In SQL Server Management Studio, navigate to Always On High Availability > Availability Groups > bookshelf-ag (Primary) and right-click the node.
- Select Failover.
- On the Select new primary replica page, verify that
node-2
is selected as new primary replica and that the Failover readiness column indicatesNo data loss
. Then select Next. - On the Connect to replica page, select Connect.
- In the Connect to server dialog, verify that the server name is
node-2
and click Connect. - Select Next and then Finish.
- On the Results page, verify that the failover was successful.
Return to the PowerShell session on
witness
.Observe the output of the running script and notice that the server name changes from
node-1
tonode-2
as a result of the failover.Stop the script by pressing
Ctrl+C
.
Clean up
After you finish the tutorial, you can clean up the resources that you created so that they stop using quota and incurring charges. The following sections describe how to delete or turn off these resources.
Deleting the project
The easiest way to eliminate billing is to delete the project that you created for the tutorial.
To delete the project:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.