After the tip https://www.mssqltips.com/sqlservertip/5526/how-to-setup-and-use-a-sql-server-stretch-database/ I made a video to show step by step how to enable stretch database.
The common way to replicate data and objects from one server to another is using transactional replication. As you know, SQL Server processes all actions within the database using Transact-SQL statements. Each completed statement is called a transaction. In transactional replication, each committed transaction is replicated to the subscriber as it occurs.
“Sometimes” can occur a problem and the process don’t work accordingly. The fist step I like to do is run sp_whoisactive in the servers (Publisher, Distributor and Subscriber), you can see if there are any process blocking the replication.
Next, is to see the publisher and subscriber agents, if there is any issue they will show, like for example login locked.
To have more information what’s happening I like to query the system view MSrepl_Transactions in the distribution database, this view contains one row for each replicated transaction and with that information run the procedure sp_browsereplcmds specifying the seqno start @xact_seqno_start = N’0x0000014F000034B0001C’ for example.
The procedure sp_browserreplcmds returns a record set with the commands stored in the distribution database. It show like a table like below.
In a post about how update works I showed what happened when run an update with the same values. SQL Server is smart enough to see that and not changing anything and register minimum log.
Another day I saw a comment to avoid updating records when none of the values are changing.
Avoid updating records when none of the values are changing. This still does a write and, if the table is in replication or change tracking, still causes the row to be propagated out to other servers. If you are updating a potentially large number of records, make sure to only update the ones where the new value doesn’t equal the old value.
Let’s see how the update behavior when update 10 millions rows but without any change and see if will be any row propagation to another server.
My Lab contains two servers and a demo database replicated from SQL01 to SQL02.
It’s configured a transaction replication to send the articles and I’m using a table created with the code:
CREATE TABLE tblMillionsRows ( id BIGINT NOT NULL IDENTITY PRIMARY KEY, largeColumn NVARCHAR(MAX) DEFAULT REPLICATE('TESTE',100), smallColumn NVARCHAR(150) DEFAULT 'DEMO', dateColumn DATETIME DEFAULT GETDATE() ); GO
INSERT INTO dbo.tblMillionsRows ( largeColumn, smallColumn, dateColumn ) DEFAULT VALUES GO 2000000
It will take a while to insert all rows. The next step is add this table in the replication.
DECLARE @publication AS sysname; DECLARE @table AS sysname; DECLARE @filterclause AS nvarchar(500); DECLARE @filtername AS nvarchar(386); DECLARE @schemaowner AS sysname; SET @publication = N'SQL01_demo_tb01'; SET @table = N'tblMillionsRows'; SET @schemaowner = N'dbo'; EXEC sp_addarticle @publication = @publication, @article = @table, @source_object = @table, @source_owner = @schemaowner, @schema_option = 0x80030F3, @vertical_partition = N'true', @type = N'logbased', @filter_clause = @filterclause; EXEC sp_articlecolumn @publication = @publication, @article = @table; EXEC sp_startpublication_snapshot @publication = 'SQL01_demo_tb01', @publisher = 'SQL01'
With all set, let’s do some tests. First updating the heap table and seeing if something is replicated.
UPDATE tblMillionsRows SET smallColumn = N'DEMO' WHERE id < 10000 GO
After the update, I ran the script below to see the transactions and commands available to replicate and nothing changed.
SELECT * FROM distribution.dbo.MSrepl_Commands SELECT * FROM distribution.dbo.MSrepl_Transactions EXEC sp_browsereplcmds
But, when I change one row running the update below I could see a new command to replicate in the another server.
UPDATE tblMillionsRows SET smallColumn = N'DEMO1' WHERE id < 10000 GO
In conclusion, SQL Server won’t replicate updates that don’t change the value. You can see more about updates in my post.
Be careful when doing updates, because if the table is replicated and you change millions rows the transaction replication will create one command for each updated row.
When thinking about migration the most common issue is downtime. There are some methods that require downtime like backup/restore or less downtime using Log Shipping.
You can choose several different methods to migrate your database. For example, methods that require downtime include:
- Backup the database, manually copy the backup file to the machine and then restore the database there. This method is simple and the use of compression minimizes the time that is required.
- Perform a backup to an Azure Blob storage account, and then restore the database from that backup. This method removes the necessity to manually copy the backup file.
- Detach the database, copy the files to an Azure Blob storage and then attach them to the SQL Server instance. Use this method if you plan to store database files in Azure Blob storage permanently instead of on a hard disk.
- Log Shipping, use a backup/restore process and the downtime depends on the transaction log file backup copying a small file in the process. This method is simple and is necessary a connection between the machines and permission to copy the backup files.
Methods that not require downtime:
- AlwaysOn, adding a new secondary replica after replication has completed, you can failover to make the machine the primary replica. For Azure virtual machine use the Add Azure Replica Wizard.
- Transactional Replication will minimize downtime, but don’t have an AlwaysOn deployment in your SQL Server system.
If you need help to decide which method is better for your scenario, feel free to contact me.