Archive | Replication RSS feed for this section

The Case of the Undroppable Database

This was funny….

Once Upon A Time there was an Orphan Database

I needed to drop a formerly-logshipped database on our warm standby server. When attempting to drop it, I found that it failed because it was a logshipped database from a replication publisher. Hmm.

The database was still in standby/read only mode, so I couldn’t run any system sprocs in the database itselt to clean up replication. Uh oh.

My colleague Gina suggested I just run a restore command with recovery to bring it online so I could run those sproc and then strip out replication. Sounds great!

But that didn’t work, because the file it needed to bring it online had been deleted from the file system at some point. Someone must have figured it was OK since this database hadn’t been actively logshipped in a while. Oh boy.

At this point, Think Very Carefully About What You Don’t Want To Do

Now, remember that this is a warm standby server, and is not customer facing. So I considered stopping sql, renaming the files, starting sql, and then seeing if I could drop the database. However, it seemed that this was not likely to work anyway, because there are those pesky records in the master database with metadata, showing that this is a replicated database. And it also just seems like a messy, klugy way to go about the issue.

So Why Not Just Edit the Metadata in Master?

I thought that some updates to that metadata were still possible in the post-sql 9 world, and looked into DAC connections and single user mode. I am very happy to say that situations almost NEVER come up when I have to even consider how to udpate metadata in master. Even on a non-customer facing database, it’s a bad idea.

But even if you want to do it for this, it’s not going to work, since most of the tables were moved into the resource database with SQL 2005 and can’t be updated. Sorry!

A Happy Ending

My colleague Robin very quickly came up with the right solution, which works perfectly. It’s fast, easy, harmless, and requires no updating of system tables or even DAC connections.

• Create a new empty db named x
• Back up db x
• Restore over your read only/standby database with the backup of X (using the with replace option)

VOILA, your database is online and empty, and no longer marked as replicated in the metadata. It’s now totally droppable!

Overall, this was a really fun, if weird little problem to work through.

Comments { 0 }

What Articles are being Replicated, and How Big are They?

I needed to quickly report on what articles are being replicated from a database yesterday, and it was helpful to include the size of the articles, number of rows, and the subscriber information.

The system tables make this pretty quick work– just run the following against your publisher and you’ll be able to document this easily.

select
	publicationName= sp.name
	, tableType=case p.index_id when 1 then 'Clustered Index' else 'Heap' end
	, p.index_id
	, articleName=ar.name
	, sub.srvname
	, ar.dest_table
	, totalSizeGB = cast(sum(au.total_pages)*8./1024./1024. as numeric(10,1))
	, numRows = (select top 1 [rows] from sys.partitions p2 where p2.object_id=o.object_id and p2.index_id in (0,1))
	, createDate= o.create_date
	, modifyDate= o.modify_date
	, droppedGB = cast(sum(case au.[type] when 0 then au.total_pages else 0 end)*8./1024./1024. as numeric(10,1))
	, inRowGB = cast(sum(case au.[type] when 1 then au.total_pages else 0 end)*8./1024./1024. as numeric(10,1))
	, LOBGB = cast(sum(case au.[type] when 2 then au.total_pages else 0 end)*8./1024./1024. as numeric (10,1))
	, rowOverflowGB = cast(sum(case au.[type] when 3 then au.total_pages else 0 end)*8./1024./1024. as numeric(10,1))
from sysarticles ar
left join syspublications sp on sp.pubid=ar.pubid
left join syssubscriptions sub on
	ar.artid=sub.artid
	and dest_db !='virtual'
left join sys.objects o on ar.objid= o.object_id
left join sys.partitions AS p (NOLOCK) on
	p.object_id = o.object_id
	and p.index_id in (1,0)
left join sys.allocation_units AS au (NOLOCK) on
		au.container_id = p.partition_id
		and p.index_id in (1,0)
group by
	sp.name
	, ar.name
	, sub.srvname
	, ar.dest_table
	, o.name
	, o.object_id
	, o.create_date
	, o.modify_date
	, p.index_id
order by
	1
Comments { 0 }

Replication Undelivered Commands: Monitoring and Reporting

This post is to share a script I’ve been working on periodically over the last couple of months to monitor and report on replication latency at the distributor. I use this in monitoring transactional replication with a stand-alone distributor.

The basic purpose for the script is:

  • Check the number of undelivered commands for all active publications
  • Log the data found to a table (which is collected on a centralized server so the history can be displayed graphically in Reporting Services 2008– that code not in this post)
  • When the number of undelivered commands is  higher than allowed, fail the job and send an email with a table highlighting the publications that are behind
  • Accept a parameter of dynamic length to allow specifying publications that should not be monitored as “production” (ie, do not alert in monitoring). Our repl servers are not SQL 2008 yet, so I use an XML wad rather than a TVP. I do love TVP’s for this type of thing though.
  • And be able to accomplish all these tasks from a non-system database.  (No custom monitoring code in system or application dbs!)

So this script shows not only how to check for undelivered commands, but also how to build a quick and easy HTML table to summarize data in emails. I always really like having as much data as possible about the state of the system in an email which is requesting investigation. (For monitoring tie in/SQL job failures are written to the event log which are then picked up.)

Note: there are some email addresses at the bottom of the sproc which I should have parameterized.  I am leaving this way because everyone should read the sproc thoroughly before installing it anywhere ;)

The table for Logging

I pull all results to a centralized server, so this table stays small

Continue Reading →

Comments { 1 }

Replication – Updates that Don't Flow Through

This past week at work we found an instance where a replicated table (transactional push) was out of sync on the subscriber. In evaluating how to address the situation, we did some testing in pre-production and discovered the following (using profiler)

  • If you update a row on the published  table by setting a date column to  itself, the row will not be updated at the subscriber. No check is performed to verify the value at the subscriber.
  • If you update a row on the published table by incrementing a date column by one millisecond, the row will not be updated at the subscriber.
  • If you update a row on the published table that is not at the subscriber, an error will result and the row will not be inserted.

The resolution we went with was to pause processing, re-push the article, reset the application, and use a verify process in our application to detect what had changed in the replicated table. Happily the  table was only 14GB so the whole thing went pretty smoothly.

Why was the table out of sync? I found the root cause, but that’s a different story.

Comments { 0 }