Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# 4 space indentation
[*.py]
charset = utf-8
indent_style = space
indent_size = 4

15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "PowerShell: Launch Current File",
"type": "PowerShell",
"request": "launch",
"script": "${file}",
"args": []
}
]
}
6 changes: 3 additions & 3 deletions AzureSQLMaintenance.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Change Log:
if object_id('AzureSQLMaintenance') is null
exec('create procedure AzureSQLMaintenance as /*dummy procedure body*/ select 1;')
GO
ALTER PROCEDURE [AzureSQLMaintenance]
ALTER PROCEDURE [dbo].[AzureSQLMaintenance]
(
@operation nvarchar(10) = null,
@mode nvarchar(10) = 'smart',
Expand Down Expand Up @@ -77,14 +77,14 @@ begin
raiserror(' "0" (Default) using non resumable index rebuild.',0,0)
raiserror(' "1" using resumable index rebuild when it is supported.',0,0)
raiserror(' ',0,0)
raiserror('@RebuildHeaps(bit) [optional]',0,0)
raiserror('@LogToTable(bit) [optional]',0,0)
raiserror(' Logging option: @LogToTable(bit)',0,0)
raiserror(' 0 - (Default) do not log operation to table',0,0)
raiserror(' 1 - log operation to table',0,0)
raiserror(' for logging option only 3 last execution will be kept by default. this can be changed by easily in the procedure body.',0,0)
raiserror(' Log table will be created automatically if not exists.',0,0)
raiserror(' ',0,0)
raiserror('@LogToTable(bit) [optional]',0,0)
raiserror('@RebuildHeaps(bit) [optional]',0,0)
raiserror(' Rebuild HEAPS to fix forwarded records issue on tables with no clustered index',0,0)
raiserror(' 0 - (Default) do not rebuild heaps',0,0)
raiserror(' 1 - Rebuild heaps based on @mode parameter, @mode=dummy will rebuild all heaps',0,0)
Expand Down
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use an official Python runtime as a parent image
FROM python:3.8-slim

# Set the working directory to /app
WORKDIR /app

# Install the SQL Server tools (sqlcmd) and ODBC drivers
RUN apt-get update \
&& apt-get install -y curl \
&& apt-get install -y gnupg \
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y mssql-tools \
&& apt-get install vim -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/


# Copy the current directory contents into the container at /app
COPY . /app

# Install any Python dependencies specified in requirements.txt
#RUN pip install -r requirements.txt

# Define the default command to run your Python script with sqlcmd
CMD ["python", "maintenance.py"]
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# AzureSQL
# Uniper Azure DB Maintenance

Anything that is related to Azure SQL DB
The procedure AzureSQLMaintenance.txt is used for automated runbooks created in the https://github.com/uniper/uniper-terraform
repository.

AzureSQLMaintenance.txt - https://techcommunity.microsoft.com/t5/azure-database-support-blog/how-to-maintain-azure-sql-indexes-and-statistics/ba-p/368787

75 changes: 75 additions & 0 deletions maintenance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
import subprocess

# Define your SQL Server connection details
server = os.environ['MAINTENANCE_DB_CONNECTION_URL']
database = os.environ['MAINTENANCE_DB_NAME']
username = os.environ['DB_USERNAME']
password = os.environ['DB_PASSWORD']

# creatating procedure in DB
def procedure_execution_on_db(query_name):
try:
procedure_execution = subprocess.run(
query_name, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

if procedure_execution.returncode == 0:
print("Procedure has been executed successfully")
else:
print("Error Occured:")
print(procedure_execution.stderr)
except subprocess.CalledProcessError as e:
print("Error running sqlcmd command:")
print(e.stderr)

def main():
# Creating procedure in DB
procedure_creation_from_file = os.path.abspath("/app/AzureSQLMaintenance.txt")
creating_procedure_command = [
"/opt/mssql-tools/bin/sqlcmd",
"-S", server,
"-d", database,
"-U", username,
"-P", password,
"-i", procedure_creation_from_file,
"-t", "65534",
"-l", "60"
]
print(f"Creating procedure in DB: for Server {server} and db {database}")
procedure_execution_on_db(creating_procedure_command)

# Triggering maintenance procedure for indexes...
procedure_for_indexes = "exec [dbo].[AzureSQLMaintenance] @Operation='index',@mode='smart',@LogToTable=1"
triggering_procedure_index_command = [
"/opt/mssql-tools/bin/sqlcmd",
"-S", server,
"-d", database,
"-U", username,
"-P", password,
"-Q", procedure_for_indexes,
"-t", "65534",
"-l", "60"
]

print(f"Triggering maintenance procedure for indexes on Server {server} and db {database}")
procedure_execution_on_db(triggering_procedure_index_command)

# Triggering maintenance procedure for statistics...
procedure_for_statistics = "exec [dbo].[AzureSQLMaintenance] @Operation='statistics',@mode='dummy' ,@LogToTable=1"
triggering_procedure_statistics_command = [
"/opt/mssql-tools/bin/sqlcmd",
"-S", server,
"-d", database,
"-U", username,
"-P", password,
"-Q", procedure_for_statistics,
"-t", "65534",
"-l", "60"
]

print(f"Triggering maintenance procedure for statistics on Server {server} and db {database}")
procedure_execution_on_db(triggering_procedure_statistics_command)

if __name__ == "__main__":

main()