An elastic jobs runs as a cloud service in your Azure environment and allows you to execute a T-SQL script across one or more databases in:
Elastic jobs can be scheduled as and when required. Job successes and failures are logged for troubleshooting and you can also enable retries after a failure.
Elastic jobs are commonly used for:
Elastic jobs can be used for deploying schema changes across, running database maintenance jobs such as index rebuild, collecting database performance data, or updating reference data in a shard set.
Elastic jobs can be used to aggregate data from a shard set and into a single reporting table. The reporting table can then be fed to Power BI, SSRS, or any of the reporting or visualization tools for creating reports. Normally, you would have to connect to each and every shard in a shard set to run the report query and insert the data into a single reporting table. Elastic jobs makes it easier to do this, wherein you only have to schedule the T-SQL and it is automatically executed on the shards.
An elastic job runs as a cloud service in your Azure environment. The following diagram illustrates the architecture and components of an elastic job:
An elastic job consists of the following four components:
This is an Azure SQL Database that stores the job metadata and state. The default service tier of the control database is Standard S0.
This is an Azure Cloud Service which is hosted in your Azure environment. The job service is responsible for launching and tracking jobs.
Azure Service Bus is a Microsoft offering that allows a Microsoft Service or an application to interact with other applications or services. In elastic jobs, Job Service uses the Azure Service Bus internally for the coordination of work. Azure Service Bus isn't shown in the architecture diagram.
Azure Storage is used to log diagnostic data resulting from job execution for troubleshooting and debugging job failures.
Here's how an elastic job works:
ShardMapRefresh
: Executes a query against the shard map manager to find out all the available shardsScriptSplit
: Splits the scripts into individual batches with "GO" as a delimiterExpandJob
: Creates child jobs for each database in the group or collectionScriptExecution
: Executes the script against the given database with specified credentialsDacpac
: Applies the dacpac to a database with the given credentialsThis section explains how to create an elastic pool using the Azure portal through the following scenario: Mike plans to create an index on the Customer table on all the databases in Toyfactory Ltd. He creates an index using an elastic job through the Azure portal. The below steps are to be followed:
toyfactorypool
under the overview blade. Click the pool's name to open the toyfactorypool
overview blade:toyfactorypool
overview blade, click on Create job to create an elastic job:__ElasticDatabaseJob
resource group.__ElasticDatabaseJob
. You should see the following resources under the __ElasticDatabaseJob
resource group:toysfactorypool
overview blade and click Create job. In the Job credentials blade, provide the Azure SQL Server Database admin login and password for the control database, which were given in step 5:Click Ok to continue.
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE NAME = 'IX_PaymentDays' AND object_id = Object_id('Sales.Customers')) BEGIN CREATE INDEX ix_paymentdays ON Sales.Customers(paymentdays) END
For example, in the given create index query, if you don't include IF NOT Exists (to verify that an index with the same name doesn't exist in the customers table), the job will fail if the index with the same name exists in the table.
CreateCustomersPaymentDaysIndex
job blade:SELECT DB_Name() AS DatabaseName,Name AS IndexName FROM sys.indexes WHERE object_id=Object_id('Sales.Customers')
Let’s go back to our example of ToyStore Ltd. Mike finds out that the
toystore
sharded databases can be put into an elastic pools to save cost and get the benefits of vertical stability. In order to do a proof of concept, he uses PowerShell to create an elastic pool and add databases to that elastic pool. He also writes down PowerShell script to delete the elastic pool after he is done with the proof of concept. In this activity, we will create a new elastic pool, add databases to the elastic pool, and delete the elastic pool using PowerShell using the following steps:
PowerShell_ISE.exe
in the run command window and hit Enter. This will open a new PowerShell ISE editor window. This is where you'll write the Power Shell commands:C:CodeLesson07
directory. In the file name textbox, type Manage-ElasticPool
and click Save to save the file:Manage-ElasticPool.ps1
file, one after another. The code's explanation, wherever required, is given in the following code snippet and in the comments within the code snippet.param ( [parameter(Mandatory=$true)] [String] $ResourceGroup, [parameter(Mandatory=$true)] [String] $SqlServer, [parameter(Mandatory=$true)] [String] $UserName, [parameter(Mandatory=$true)] [String] $Password, [parameter(Mandatory=$true)] [parameter(Mandatory=$false)] [int] $eDTU, [parameter(Mandatory=$false)] [int] $MaxeDTU, [parameter(Mandatory=$false)] [int] $MineDTU=0, [parameter(Mandatory=$false)] [String] $AzureProfileFilePath, [parameter(Mandatory=$false)] # Create/Remove an elastic Pool [String] $Operation = "Create", # Comma delimited list of databases to be added to the pool [parameter(Mandatory=$false)] [String] $DatabasesToAdd )
ResourceGroup
: The name of the resource group in which the elastic pool will be created. It should be the same as that of the Azure SQL Server.SqlServer
: The Azure SQL Server name in which the elastic pool has to be created.UserName
: The Azure SQL Server database admin username.Password
: The Azure SQL Server database admin password.ElasticPoolName
: The name of the elastic pool to be created or deleted.eDTU
: The elastic pool eDTU.MaxeDTU
: The maximum eDTU available per database in the pool.MineDTU
: The minimum eDTU available per database in the pool.AzureProfileFilePath
: The full path of the JSON file that has your Azure profile information.Operation
: The operation to be performed. Accepts two values: Create and Remove.DatabasesToAdd
: A comma-delimited list of the databases to be added to the elastic pool.# log the execution of the script Start-Transcript -Path ".LogManage-ElasticPool.txt" -Append # Set AzureProfileFilePath relative to the script directory if it's not provided as parameter if([string]::IsNullOrEmpty($AzureProfileFilePath)) { $AzureProfileFilePath="....MyAzureProfile.json" } #Login to Azure Account if((Test-Path -Path $AzureProfileFilePath)) { … # Provide your Azure Credentials in the login dialog box $profile = Login-AzureRmAccount $SubscriptionID = $profile.Context.Subscription.SubscriptionId } #Set the Azure Context Set-AzureRmContext -SubscriptionId $SubscriptionID | Out-Null
Manage-ElasticPool.txt
file created under the Log
directory within the parent directory of the Manage-ElasticPool.ps1
script.json
file provided by the AzureProfileFilePath
variable. If found, then it sets the PowerShell context to the subscription ID, as specified in the profile file, otherwise it asks to manually log in to the Azure account to set the context.#Check if the pool exists Get-AzureRmSqlElasticPool -ElasticPoolName $ElasticPoolName -ServerName $SqlServer -ResourceGroupName $ResourceGroup -ErrorVariable notexists -ErrorAction SilentlyContinue if($Operation -eq "Create") { if([string]::IsNullOrEmpty($ElasticPoolEdition)) … $CreateElasticPool = @{ ElasticPoolName = $ElasticPoolName; Edition = $ElasticPoolEdition; Dtu = $eDTU; DatabaseDtuMin = $MineDTU; DatabaseDtuMax = $MaxeDTU; ServerName = $SqlServer; ResourceGroupName = $ResourceGroup; }; New-AzureRmSqlElasticPool @CreateElasticPool; } else { Write-Host "Elastic pool $ElasticPoolName already exists!!!" -ForegroundColor Green }
Get-AzureRmSqlElasticPool
cmdlet to get the details of the given elastic pool name. If the elastic pool with the specified name is found in the given resource group, it succeeds; otherwise, it returns an error: "Get-AzureRmSqlElasticPool : ResourceNotFound: The Resource 'Microsoft.Sql/servers/toyfactory/elasticpools/adasdas' under resource group 'toystore' was not found".notexists
variable specified in the ErrorVariable
parameter.New-AzureRmSqlElasticPool
to create the elastic pool if the specified operation is create ($operation
parameter) and the $notexists
variable isn't empty. # Add databases to the pool if([string]::IsNullOrEmpty($DatabasesToAdd) -and $Operation -eq "Create") { Write-Host "Please provide a valid value for DatabasesToAdd parameter" -ForegroundColor yellow Write-Host "Exiting...." -ForegroundColor Yellow break; } $Databases = $DatabasesToAdd.Split(','); foreach($db in $Databases) { Write-Host "Adding database $db to elastic pool $ElasticPoolName " -ForegroundColor Green Set-AzureRmSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $SqlServer -DatabaseName $db -ElasticPoolName $ElasticPoolName } }
#remove an elastic pool if($Operation -eq "Remove") { #Get all databases in the elastic pool $epdbs = Get-AzureRmSqlElasticPoolDatabase -ElasticPoolName $ElasticPoolName -ServerName $SqlServer -ResourceGroupName $ResourceGroup # iterate through the databases and take them out of the pool. foreach($item in $epdbs) { $db = $item.DatabaseName; #Take database out of pool … #Remove elastic pool Write-Host "Removing Elastic Pool $ElasticPoolName " -ForegroundColor Green $RemovePool = @{ ResourceGroupName = $ResourceGroup; ServerName = $SqlServer; ElasticPoolName = $ElasticPoolName; }; Remove-AzureRmSqlElasticPool @RemovePool -Force; }
$operation
parameter is set to Remove. An elastic pool can't be removed or deleted if it has databases assigned to it. First, the code gets all the databases in an elastic pool using the cmdlet Get-AzureRmSqlElasticPoolDatabase
.Set-AzureRmSqlDatabase
.Remove-AzureRmSqlElasticPool
cmdlet.Manage-ElasticPool.ps1
script in it. For example, if the script is at the C:CodeLesson07
directory, then run the following command to switch to this directory:cd C:CodeLesson07
Note
If you created
toyfactorypool
earlier in the chapter, then run this command to delete the pool. If you don't have an existing pool, then proceed to the next step, which is creating a pool.
If you have an existing pool and you don't want to remove it, then you will have to create a pool and a separate set of databases for it:
.Manage-ElasticPool.ps1 -ResourceGroup toystore -SqlServer toyfactory -UserName sqladmin -Password Packt@pub2 -ElasticPoolName toyfactorypool -Operation Remove -AzureProfileFilePath C:CodeMyAzureProfile.json
.Manage-ElasticPool.ps1 -ResourceGroup toystore -SqlServer toyfactory -UserName sqladmin -Password Packt@pub2 -ElasticPoolName toyfactorypool -ElasticPoolEdition Standard -eDTU 100 -MaxeDTU 100 -MineDTU 10 -AzureProfileFilePath C:CodeMyAzureProfile.json -Operation Create -DatabasesToAdd "toystore_Shard_1_50,toystore_Shard_50_100,toystore_Shard_100_150,toystore_Shard_150_200"
toyfactoryelasticpool
with eDTU 100 and the databases, as specified by the DatabasesToAdd
parameter.3.144.123.155