Hi all,

Here's to hoping that a SQL Server guru is hiding among the ranks of DaniWeb members.

I have two servers, DB01 - the production database server and BKP01 - the backup server, that are in two different geographical locations. Since some queries on DB01 are accessing BKP01 there exists a link in DB01 and it works perfectly. Now I would like to know how I can verify the availability of BKP01 from DB01? If the physical link is cut, for any reason, I want to be able to switch all the backups to DB01 automatically.

I have tried by shutting down the SQL Server instance on BKP01 and then trying queries like these:

IF EXISTS (SELECT @@version FROM BKP01.master.sys.databases )
PRINT 'DBName available.'
ELSE
PRINT 'DBName not available.'

and

BEGIN TRY
    SELECT @@version FROM BKP01.master.sys.databases
    print @@error
    PRINT 'DBName available.'
END TRY
BEGIN CATCH
    PRINT 'DBName not available.'
END CATCH
print @@error

but SQL Server never gets past the 'SELECT @@version ..." part of these queries and then fails horribly spewing the following error messages:

OLE DB provider "SQLNCLI10" for linked server "BKP01" returned message "Login timeout expired".
OLE DB provider "SQLNCLI10" for linked server "BKP01" returned message "A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.".
Msg 53, Level 16, State 1, Line 0
Named Pipes Provider: Could not open a connection to SQL Server. (53)

I hope that some kind soul on Daniweb will help me in the right direction.

Thanks

Yomet

Just a thought - is there a way of incorporating shell commands like PING into a T-SQL procedure? In that case I could, possibly, use that to test the availability of the BKP01 server.

Yomet

The closest you're going to get is with a system stored proc called sp_testlinkedserver. Use the following snippet to do what you need:

BEGIN TRY
    exec sp_testlinkedserver BKP01
    print @@error
    PRINT 'DBName available.'
END TRY
BEGIN CATCH
    print @@error
    PRINT 'DBName not available.'
END CATCH

This should at least get you started. Good luck!

Hi BitBit,

Thanks for your input but unfortunately it does not work. It gives the same behaviour as my previous attempts and crashes as soon as ANY code tries to access the linked server. The part where the server works just fine but when I cut the connection nothing works.

I even tried to catch ONLY error 53 like this:

exec sp_testlinkedserver BKP01
    IF @@error = 53 
        PRINT 'DBName not available.'
    ELSE
        PRINT 'DBName available.'

but to no avail.

I even tried a circumvented way, tried to get away from the crashing of SQL Server, like this:

CREATE PROCEDURE dbo.sp__IsLinkedDBAvailable
@DB SYSNAME
AS
BEGIN
    EXEC sp_testlinkedserver @DB
    RETURN 100
END


DECLARE @RetVal int;
SELECT @RetVal = 0;
EXEC @RetVal = sp__IsLinkedDBAvailable BKP01
SELECT @RetVal;

But I still get the same error. Since the PROC is called by the outside code the crash must happen when the sp_testlinkedserver executes - correct?

Still looking for a solution.

Yomet

is there a way of incorporating shell commands like PING into a T-SQL procedure?

Yes. This page has a demonstration of such.

However, let it be said that shell access via SQL is regarded as a high security risk and is often disabled, so it will depend on your level of access to the server whether you will be able to use those system procedures or not. Also, just because you can doesn't mean you should... if it is the only workable solution, then just make sure you and your team/admins know what it's doing and have some configuration & monitoring in place to ensure the system access is protected.

@Hearth,

Thanks for the tip and the link. The solution does not currently work since the security forbids it. However, I will keep this as a possible solution if everything else fails.

Yomet

Finally, after discussing with the other DBA, we agreed that enabling "xp_cmdshell" does not pose too big a security risk and decided to enable this xp in order to use a mixed solution.

I put together a Stored Procedure from both the ping and osql solutions from this page (http://sqlserver2000.databases.aspfaq.com/how-do-i-prevent-linked-server-errors.html) and is therefore now able to see not only if the SQL Server is available but also if it's SQL Server or the physical server that is unavailable.

Thanks Hearth for giving me part of the solution.

Yomet

P.S. Here's the final solution I am using

SET NOCOUNT ON; 

CREATE TABLE #foo (dbname SYSNAME NULL); 

INSERT INTO #foo 
EXEC master..xp_cmdshell 'osql -S BKP01 -d Master -U sa -P wtyx21d -Q "SELECT Name FROM sysdatabases"'; 

IF EXISTS (SELECT 1 
           FROM #foo 
           WHERE LTRIM(RTRIM(dbname)) = N'master') 
BEGIN 
    PRINT 'Feel free to use linked server.'; 
END 
ELSE 
BEGIN 
    TRUNCATE TABLE #foo
    INSERT INTO #foo
    EXEC master..xp_cmdshell 'ping BKP01'; 

    IF EXISTS (SELECT 1 
               FROM #foo 
               WHERE dbname LIKE '%TTL%') 
    BEGIN 
        PRINT 'Linked server SQL not available.';
    END 
    ELSE 
    BEGIN 
        PRINT 'Linked server HOST not available.'; 
    END 
END 

DROP TABLE #foo;

Hi Yomet, you might want to try something like this and reduce or integrate the xp_cmdshell call.

DECLARE @LSName VARCHAR(50)

SET @LSName = '' --linked server name

BEGIN 
    IF EXISTS (SELECT 1 FROM sys.servers WHERE is_linked = 1 AND name = @LSName)
        BEGIN
            BEGIN TRY
                SELECT 1 
                FROM --use distributed query here... linkedserver.<database>.<schema>.<object>
            END TRY
            BEGIN CATCH
                --This is where bad things will go if server 1 can't talk with linked server
                PRINT 'Linked server SQL not available'
            END CATCH
        END
    ELSE
        BEGIN
            --linked server not configured, do work
            PRINT 'Linked Server not configured'
        END
END
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.