SQL Server on linux has been out for a bit now and I’ve played around a little (seehere) but haven’t really used it in “anger” nor will I for the foreseeable future if I’m honest. Nevertheless it’s an area that I find very interesting as I know very little when it comes to the Linux operating system and as it’s such a huge area, it’s something that I want to learn more about.
I feel the best way to learn is to actually try and do something with it. Sure, I could sit down and read articles on the web but I learn best by doing. So I began to think about what would be the first thing I’d try and do if presented with an instance of SQL Server running on Linux that I had to manage.
Right, well being a DBA, setting up backups and restores I guess but I want something a little more involved. How about setting up a warm standby instance! Log shipping! It’s perfect as it’s a fairly simple process within SQL but should teach me a bit about the Linux environment (copying files etc.) as SQL on Linux doesn’t have an Agent so this have to be done manually.
But before I go through how I set this up…
DISCLAIMERS! I have published this as a purely academic exercise, I wanted to see if I could do it. At no point should this be considered to have followed best practices. This should NOT be used in a production environment. There are probably better ways of doing this, if you have one then let me know.Here goes!
What I’m going to do is setup two instances of SQL Server running on linux and log ship one database from one to another. So the first thing I did was get two VMs running Ubuntu 16.04.1 LTS which can be download from here .
Once both servers were setup (remember to enable ssh) I then went about getting SQL setup, I’m not going to go through the install in this post as the process is documented fully here . Don’t forget to also install the SQL Tools, full guide is here .
N.B. when installing the tools I’ve always just run:-
sudo apt-get install mssql-toolsThe link will tell you to add unixodbc-dev to the end of the statement but that’s caused me issues in the past. I’ve also always had to run the optional step:
ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmdOtherwise I get sqlcmd: command not found
Anyway, once that’s setup verify that you can connect to both instances, either by sqlcmd on the server or through SSMS remotely.
Ok, now we need to create folders on both servers to hold the scripts and backups needed. So in your favourite shell (I’m using bash on windows), ssh into your first server and run:
mkdir SQLScriptsmkdir SQLBackups
This will create two folders in your default home location, for me that’s… /home/andrew
Next thing to do is sort out access to these folders so that SQL Server can write backups to them. I found this kinda tricky if I’m honest as linux permissions are completely new to me but this is how I went about it.
When SQL Server is installed a group called mssql is created. What I’m going to do is add my user into that group and then change the ownership and group access to these folders to that group. So, run:-
sudo usermod -a -G mssql andrewThis change can then be verified by running:-
id andrewN.B.- You’ll have to log out and then back in for this to take effect
Then we can change the permissions on the folders:-
sudo chown mssql SQLScriptssudo chown mssql SQLBackups
sudo chgrp mssql SQLScripts
sudo chgrp mssql SQLBackups
I also need to modify what the owner and group members can do in those folders. I’ve played around with these permissions a bit and the best configuration I’ve found is set by running:
sudo chmod 770 SQLScriptssudo chmod 770 SQLBackups
This will allow the owner of the folder (mssql) and members of the group mssql to do what they want. More details on setting permissions in linux can be found here .
Once that’s done you can verify the change by running:-
ls -al
On server 2 run all the above scripts to setup the same folders and permissions. Once that’s done we also need to setup an Archive folder (only on server 2) to move the transaction log backups into once they are restored. So run the following (same code as above really):-
cd /home/andrew/SQLBackupsmkdir Archive
sudo chown mssql Archive
sudo chgrp mssql Archive
sudo chmod 770 Archive

Once that’s done we can initialize a database for log shipping. So in your first instance of SQL we will create a login to run the backups, create a database, create a user for the login (with membership of the db_backupoperator role), take a full backup and then take a log backup:-
USE [master];GO
CREATE LOGIN [logshipper] WITH PASSWORD='Testing11@@',CHECK_POLICY=OFF,CHECK_EXPIRATION=OFF;
GO
CREATE DATABASE [LogShipped];
GO
BACKUP DATABASE [LogShipped]
TO DISK = 'C:\home\andrew\SQLBackups\LogShipped.bak';
GO
BACKUP LOG [LogShipped]
TO DISK = 'C:\home\andrew\SQLBackups\LogShipped.trn';
GO
USE [LogShipped];
GO
CREATE USER [logshipper] FOR LOGIN [logshipper];
GO
ALTER ROLE [db_backupoperator] ADD MEMBER [logshipper];
GO
N.B.- note that SQL Server does recognise linux pathways. SQL thinks that the backup folder we created lives at C:\home\andrew\SQLBackups not /home/andrew/SQLBackups
Now we push these over to the secondary server so that we can restore them. To do this I’m going to use a program called scp , so back in your shell session on the first server, navigate to your SQLBackups folder and run:
scp LogShipped.bak andrew@192.168.xx.xx:/home/andrew/SQLBackupsscp LogShipped.trn andrew@192.168.xx.xx:/home/andrew/SQLBackups
Before you’ll be able to restore the database backups we need to allow the SQL Server instance on server 2 to be able to read the files we’ve just transferred over. To do this, ssh to server 2 and run:-
cd /home/andrew/SQLBackupschmod 666 LogShipped.bak
chmod 666 LogShipped.trn
Ok, once the files are on the secondary server, connect to the second instance of SQL via SSMS to restore the database and transaction log backups as normal when setting up log shipping:-
USE [master];GO
RESTORE DATABASE [LogShipped]
FROM DISK = 'C:\home\andrew\SQLBackups\LogShipped.bak'
WITH NORECOVERY;
GO
RESTORE LOG [LogShipped]
FROM DISK = 'C:\home\andrew\SQLBackups\LogShipped.trn'
WITH NORECOVERY;
GO
Now we need to create a login to perform the restores:-
USE [master];GO
CREATE LOGIN [logshipper] WITH PASSWORD='Testing11@@',CHECK_POLICY=OFF,CHECK_EXPIRATION=OFF;
GO
ALTER SERVER ROLE [dbcreator] ADD MEMBER [logshipper];
GO N.B.- I’ve noticed that even though the above permissions are correct to restore the log, this won’t work with sqlcmd. The work around I have is to make the logshipper login a me