Wednesday, November 10, 2010
Expired Subscriptions in SQL Server
Currently I am working on a huge setup of servers which utilizes replication quite extensively. Each of these servers has about 4 to 10 publication and around 10 to 40 Subscribers running 24x7. An issue, I was facing quite regularly on many subscribers was that they tend to expire and then the second step of the replication job simply goes in the retry mode.
I investigated the issue by first finding the replication and then going into one of the tables in 'Distribution' database of my distributor. The table is dbo.MSsubscriptions. It is a very usefull table with the complete info about all the Subscriptions configured on this distributor. It contains the following columns of our interest -
publisher_database_id, publisher_db, subscriber_db and status
if you look for the value of the status column corresponding to the right Publisher and Subscriber Database, it would be either 0, 1 or 2.
Status 0 = Inactive,
Status 1 = Subscribed and
Status 2 = Active.
Now all you have to do is to change this value for it to start working normally. You can use a simple update statement like this -
UPDATE distribution.msdb.MSsubscriptions
SET status = 2
WHERE publisher_db = 'MyPubDB' and
subscriber_db = 'MySubscriberDB' and
status = 0
After running this query wait for a couple of minutes for the replication job to retry and it should be running smoothly. I am still trying to find out the way to completely eliminate this problem so that subscriptions do not expire at all. Will update you soon on that. In the meantime, if you have a solution, you can post it in the comments.
Hope it helps.
Thursday, April 22, 2010
sp_replcmds Error
I was setting up a transacitonal replication today, when I came accross this error with my LogReader Agent. Both the Publisher and Subscriber setups gave me a success message and then when I checked the data on the subscriber, it wasn't there.
I tried to find the reason for that with the help of job logs and the error it gave me was ---
"The process could not execute 'sp_replcmds' on 'MyMachineName'.
Status: 0, code: 15517, text: 'Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission. '
The actual solution to the problem was far away from what it reflected in the error messsage. The real problem was that my published database did not had any owner assigned to it. (and may be SQL Server is using the owner account to execute sp_replcmds in the background which if doesn't exists, defaults to dbo. SQL Server does it quite often!!!!) As soon as I assigned the owner to my database, stopped the service and started it again.... bingo... it started working.
Hope, the post is going to be usefull for you as well.
Friday, April 3, 2009
How to get the logins which are mapped to different Users
Hi friends,
Sorry for this long inactivity but I was a bit busy with one of my clients from Mexico Republic working in Europe.
This guy is an IT Auditor and he has a lot of queries regarding security and auditing in SQL Server. I will keep writing about the queries posed by him. So here is the first and a simple one.
He wanted to find out the way to get a list of all logins, well categorized by different criteria. eg. He wanted a list of all windows logins mapped as a SQL Server Login. All windows users mapped as SQL Login and all these logins mapped to which database as which user along with their default database.
So, for this query we need a few system catalog views. First is the sys.server_principals. This is really a good place to look for when you want to see all the server logins along with which server level role they are registered in the server (eg. sysadmin, serveradmin etc.). Another is the sys.sysusers. This is the catalog view which will give you the information about users mapped in different databases. Remember that this catalog view can give different results for different databases.
So here is that simple query, use it or modify it according to your own needs. DECLARE @i int, @ctr int, @dbname nchar(50)
SELECT @i = COUNT(name) FROM sys.databases
SET @ctr = 1
WHILE (@ctr <= @i) BEGIN SELECT @dbname = name from sys.databases WHERE database_id = @ctr
SELECT @dbname [Database Name]
EXECUTE('USE ' + @dbname + '; Select P.name [Server Login Name], S.name [Database User Name] , default_database_name [Default Database]' +
'FROM sys.server_principals P INNER JOIN sys.sysusers S ' +
'ON P.sid = S.sid WHERE S.name != ''dbo''')
SET @ctr = @ctr + 1
END
Thursday, February 5, 2009
SQL Backups and Transaction Log
Recently I was involved in testing the performance of SQL Server 2005 in the event of an external attack. I used a machine with Pentium Dual Core 2.0 GHz, 3 GB RAM and sufficient amount of hard disk space.
I used a script to create 2 simple Products and Orders Tables and tried to insert 100,000,000 (A hundred million) rows into it. I used windows system monitor to monitor a few things. The important ones are
- Free space in tempdb
- Data File Space of my database
- Log file space of my database
- Lock request per second and
- Page writes per second
The whole insertion part was in a single transaction.The script kept running for around 25 min. and then the Management studio gave me an error of "Insufficient Memory Resource". The transaction was automatically cancelled. By that time around 4,700,000 rows were transferred in the database.
The data file size at that time was around 59 MB, but the Transaction Log size was grown upto a whopping 5.87 GB. Well all this was still very OK for me, but then I started taking the backups of the database.
I started with a full database backup. I thought, according to my knowledge, that it won't have any effect on the Log file size. but the full database backup brought down the "Used Log File Space" down to 1/10th of its size.
After that I tried to take the Log backup and it had no effect on the size of the database. can u guess why? Because the full backup already committed the inactive portion of my transaction log and removed them. And there were no new transactions to be transferred. So the used space in log file remain unchanged. Then I used the DBCC SHRINKDATABASE command using WITH TRUNCATE option. Before executing this command the log file size was still 5.87 GB. What do you think, was the size of this database after execution of this command?
If you said 5.87 GB you are......... wrong. It's not 5.87 GB, not 4 GB, not 1 GB......, not even 200 MB. It was just 2.31 MB. Any guesses about how it turned out to be so small? Because the data insert operation was performed in a transaction and the transaction was rolled back when OS returned me the error of Insufficient resources. That error rolled back the transaction. But even then, the transaction was available in the transaction log. When we truncated the transaction log, the whole Rolled back transaction got removed from the transaction log. Another thing that even I was not able to find a reason for was, as soon as I used DBCC SHRINKDATABASE, for some strange reason, the "Used Transaction Log Space" shoot up for a few seconds and then started coming down. If anybody has the reason for that, he/she can write a comment.
Hope that may give you some insight about the backups and Transaction Logs.