Create an SQL 2016 AlwaysOn Availability Group – Lab

Server Configuration

  • 2x Windows Server 2016 virtual servers; Server01, Server02
  • Disk Config:
    • Apps Disk on SCSI Controller 0
    • SQL DB Disk on SCSI Controller 1
    • SQL Log Disk on SCSI Controller 1
    • SQL TempDB Disk on SCSI Controller 2
  • SQL 2016 with SP2 Installed using DEFAULT instance
  • SQL Server service account and computer accounts granted access to backup share
  • An empty database called db1 on Server01
  • Latest Windows Updates applied
  • File Share configured on a third server for hosting the file share witness

Prepare Cluster

Install Failover Clustering

Install-WindowsFeature Failover-Clustering -IncludeManagementTools
Test-Cluster -Node Server01, Server02

Configure Failover Clustering

New-Cluster -Name SQLAAG01 -Node Server01, Server02 -StaticAddress 192.168.0.120
Set-ClusterQuorum -NodeAndFileShareMajority \\Server03\AAGFSW$

Configure SQL AlwaysOn

Set Parameters

#Parameters
$Domain = "sqldev.local"
$SQLBackup = "\\Server01\backups"
$DB = "DB01"
$Server01Object = Get-Item "SQLSERVER:\Sql\Server01\DEFAULT"
$Server02Object = Get-Item "SQLSERVER:\Sql\Server02\DEFAULT"
$Server01Nm = $Server01Object.Name
$Server02Nm = $Server02Object.Name
$Server01Instance = "DEFAULT"
$Server02Instance = "DEFAULT"
$ReplicaPort = "5022"
$FailoverMode = "Automatic"
$AvailabilityMode = "SynchronousCommit"
$EndpointURLSrv01 = "$Server01Nm" + "." + "$Domain" + ":" + "$ReplicaPort"
$EndpointURLSrv02 = "$Server02Nm" + "." + "$Domain" + ":" + "$ReplicaPort"
$AGName = "AG01"

Enable AlwaysOn

Import-Module sqlps
Enable-SqlAlwaysOn -ServerInstance Server01 -Force
Enable-SqlAlwaysOn -ServerInstance Server02 -Force

Create AlwaysOn Group

# Backup the database
Backup-SqlDatabase -Database "$DB" -BackupFile "$SQLBackup\$DB.bak" -ServerInstance "$Server01Nm"
Backup-SqlDatabase -Database "$DB" -BackupFile "$SQLBackup\$DB.log" -ServerInstance "$Server01Nm" -BackupAction Log

# Restore the database and log on node2
Restore-SqlDatabase -Database "$DB" -BackupFile "$SQLBackup\$DB.bak" -ServerInstance "$Server02Nm" -NoRecovery
Restore-SqlDatabase -Database "$DB" -BackupFile "$SQLBackup\$DB.log" -ServerInstance "$Server02Nm" -RestoreAction Log -NoRecovery

# Create an in-memory representation of the primary replica.
$primaryReplica = New-SqlAvailabilityReplica -Name "$Server01Nm" -EndpointURL "TCP://$EndpointURLSrv01" -AvailabilityMode "$AvailabilityMode" -FailoverMode "$FailoverMode" -Version $Server01Object.Version -AsTemplate

# Create an in-memory representation of the secondary replica.
$secondaryReplica = New-SqlAvailabilityReplica -Name "$Server02Nm" -EndpointURL "TCP://$EndpointURLSrv02" -AvailabilityMode "$AvailabilityMode" -FailoverMode "$FailoverMode" -Version $Server02Object.Version -AsTemplate

# Create the availability group
New-SqlAvailabilityGroup -Name "$AGName" -Path "SQLSERVER:\SQL\$Server01Nm\$Server01Instance" -AvailabilityReplica @($primaryReplica,$secondaryReplica) -Database "$DB"

Verify in SQL whether it’s created properly

Check the ports:

SELECT type_desc, port FROM sys.tcp_endpoints;
GO

Check the endpoints are started:

SELECT state_desc FROM sys.database_mirroring_endpoints;
GO

Start an endpoint:

ALTER ENDPOINT Endpoint_Mirroring
STATE = STARTED
AS TCP (LISTENER_PORT = 1433)
FOR database_mirroring (ROLE = ALL);
GO

Check permissions:

SELECT 'Metadata Check';
SELECT EP.name, SP.STATE,
CONVERT(nvarchar(38), suser_name(SP.grantor_principal_id))
AS GRANTOR,
SP.TYPE AS PERMISSION,
CONVERT(nvarchar(46),suser_name(SP.grantee_principal_id))
AS GRANTEE
FROM sys.server_permissions SP , sys.endpoints EP
WHERE SP.major_id = EP.endpoint_id
ORDER BY Permission,grantor, grantee;
GO

Continue the Availability Group configuration

# Join the secondary replica to the availability group.
Join-SqlAvailabilityGroup -Path "SQLSERVER:\SQL\$Server02Nm\$Server02Instance" -Name "$AGName"

# Join the secondary database to the availability group.
Add-SqlAvailabilityDatabase -Path "SQLSERVER:\SQL\$Server02Nm\$Server02Instance\AvailabilityGroups\$AGName" -Database "$DB"

This is an alternate scripting method to create an Availability Group

# Alternative way to create the group
$PrimaryServer = Get-Item "SQLSERVER:\SQL\Server01\DEFAULT"
$SecondaryServer = Get-Item "SQLSERVER:\SQL\Server02\DEFAULT"
$PrimaryReplica = New-SqlAvailabilityReplica -Name "Server01" -EndpointUrl "TCP://Server01.sqldev.local:5022" -FailoverMode "Automatic" -AvailabilityMode "SynchronousCommit" -AsTemplate -Version 13
$SecondaryReplica = New-SqlAvailabilityReplica -Name "Server02" -EndpointUrl "TCP://Server02.azuredev.local:5022" -FailoverMode "Automatic" -AvailabilityMode "SynchronousCommit" -AsTemplate -Version 13
New-SqlAvailabilityGroup -InputObject $PrimaryServer -Name "AG01" -AvailabilityReplica ($PrimaryReplica, $SecondaryReplica) -Database @("DB01")

Configure Listener

New-SqlAvailabilityGroupListener -Name AG01-Listener ` -StaticIp '192.168.0.121/255.255.255.0' ` -Path SQLSERVER:\Sql\$Server01\$Server01Instance\AvailabilityGroups\$AGName

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.