Published on

May 25, 2019

Using Crontab for Automated Tasks in SQL Server on Linux

SQL Server Agent is a powerful tool for running automated tasks in SQL Server. However, it is not included in the SQL Server Express edition. On Windows, many users rely on Task Scheduler to achieve similar functionality in SQL Server Express. In this article, we will explore how to use crontab to accomplish the same idea in SQL Server on Linux.

Please note that this article is specific to Ubuntu and was written using a lxd container running 16.04.6 LTS (on a Ubuntu 18.04.2 LTS host) with SQL Server 2017 Express for Linux and mssql-tools installed. While other Linux distributions can achieve similar results, the syntax for commands may differ.

Creating a Service Account

First, we need to create an account on Ubuntu and a corresponding SQL login. We’ll start by creating the agent user on the Linux side:

sudo useradd sqlagent -r
cd /var/opt
sudo mkdir sqlagent
sudo chown sqlagent: sqlagent/
sudo chmod 770 sqlagent/
sudo usermod -d /var/opt/sqlagent sqlagent
sudo chmod g+s sqlagent/

This creates a system account and a directory in the default installation location for SQL Server on Linux (/var/opt/mssql). We also add ourselves to the new group to control the files for the new account.

Next, we’ll create a SQL login with appropriate permissions:

USE master;
GO
CREATE LOGIN sqlagent WITH PASSWORD = 'AA9DA9E7-9271-47D4-918B-5827CF5D87AA', DEFAULT_LANGUAGE = BRITISH, CHECK_EXPIRATION = OFF;
GO
USE lxd;
GO
CREATE USER sqlagent FROM LOGIN sqlagent;
ALTER ROLE db_owner ADD MEMBER sqlagent;
GO

Make sure to change the password and set permissions relevant to your instance. We’ll store these login details in a directory named “.secret” for security purposes.

Create a Script to Run the Tasks

Now that we have an account and SQL login, we need to create a script that can be used in crontab to run our SQL commands. Create a file named “agent.sh” in the sqlagent’s home directory:

touch agent.sh
sudo chmod 770 agent.sh
nano agent.sh

In the “agent.sh” file, insert the following code:

#!/bin/bash
# Get the credentials from the file
source .secret/.sqlagent
# Read the parameter (name of the .sql file to run)
#$1 = name of sql file to run
file="sql/$1"
# Get start date and determine log file to write to
starttime=$(date)
log="log/$(date +%Y%m%d).log"
echo "/*** Starting Agent task $1 at $starttime ***/" >> $log
# Check if the file exists
if [ -f "$file" ]; then
    # Use sqlcmd to run the file and store the output in a variable
    output=$(/opt/mssql-tools/bin/sqlcmd -U $Login -P $Password -i "$file")
    endtime=$(date)
    if [ -z $output ]; then
        # Task completed with no output
        echo "/*** Completed Agent task $1 at $endtime ***/" >> $log
    else
        # Task completed with output
        echo "/*** Completed Agent task $1 at $endtime with output ***/" >> $log
        echo "$output" >> $log
    fi
else
    # File was not found, so add an error to the log
    echo "/*** Failed Agent task $1, file was not found ***/" >> $log
fi

You can now test if this works by creating the necessary directories and a test SQL file to run:

mkdir log
mkdir sql
echo "PRINT @@VERSION;" > ./sql/version.sql
sudo su sqlagent # Switch to the sqlagent account
cd ~ # Make sure we are in the home directory
./agent.sh version.sql
cat ./log/20190524.log # Note: Use the correct date for when you are doing this

Setting up Crontab

Now that we have the accounts, login, and script, we can finally set up crontab. We’ll start by creating a crontab file:

crontab -e

Select your preferred CLI text editor and add the following line at the bottom of the file:

# SQL Agent Tasks go below here:

This will create a crontab file. Copy this file to the sqlagent’s home directory:

cp /var/spool/cron/crontabs/sqlagent crontab

Edit the crontab file and add the following line at the very bottom:

# Update crontab jobs - Do not remove
* * * * * crontab ~/crontab 2> ~/lastinstall.cron

This will copy the settings in the crontab’s home directory every minute. If the copy fails, the error will be stored in the “lastinstall.cron” file for review. Push the update to crontab:

crontab ~/crontab
exit # Return to the normal user

Now you can start adding tasks to crontab. For example, to create a daily backup for a database, create a .sql file in the sql directory and put the relevant SQL code in the file:

BACKUP DATABASE lxd
TO DISK = '/var/opt/mssql/backups/lxd.bak';

Edit the crontab file and add the following line after the appropriate comment:

0 1 * * * ~/agent.sh backup_lxd.sql

This will run the SQL code in the “backup_lxd.sql” file every day at 01:00. Check the contents of the relevant log file to see the results of the backup task.

Limitations and Additional Notes

There are a few limitations and additional considerations to keep in mind when using crontab for automated tasks in SQL Server on Linux:

  • Crontab runs once a minute, so the most frequent task you can schedule is every minute using “* * * * *”.
  • Tasks scheduled with crontab may not run immediately after saving the crontab file. There may be a delay of up to a minute.
  • Crontab does not have built-in support for running tasks on specific dates, such as the 2nd Monday of the month. You may need to create multiple instances of the same task or use a task that checks the date and conditionally runs the desired task.
  • If the SQL instance needs access to files, you need to grant the appropriate permissions to the mssql user or group.
  • Remember to check that crontab has successfully installed the file after making any edits.
  • Be mindful of case sensitivity when providing file names in the script.

Using crontab for automated tasks in SQL Server on Linux provides a flexible and reliable solution for scheduling and running tasks. While it may have some limitations compared to SQL Server Agent, it offers a viable alternative for SQL Server Express editions on Linux.

For more information on crontab, refer to the crontab(5) and cron(8) manual pages.

Thank you for reading!

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.