Ensuring a Remote Server is Available Checking the Circuit Ensuring a Remote Server is Available Ed Wagner
About Your Presenter Senior DBA at RDA Group, Global Market Research and Consulting 23 years experience working with databases Frequent poster on SQLServerCentral.com Specialize in high-performance T-SQL I actually enjoy this stuff. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
Background A Special Email System We’re required to send automatically- generated email to our customers in China on both a manual and scheduled basis. China likes to keep everything inside China and is hostile to receiving email from outside China. To get around that, we set up an SMTP server in Hong Kong with a VPN tunnel. That’s where the trouble starts. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Problem The “Tunnel” Occasionally Collapsed The tunnel was found to collapse from time to time. We had to know if the tunnel was up to be able to send email through it. Having “lost” or “not sent” emails is not an option. To support automatic “email sent” tracking, any fix had to be a part of the existing email system, which consists of stored procedures that call SQL Server’s database mail engine. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
Restrictions on Solutions They want it REAL BAD! Must be inexpensive to develop. Must be inexpensive to implement. No additional 3rd party solutions. Needed NOW! Must be easily used by existing stored procedures. Because of that, cannot be an OS-only solution. Did I mention they need it NOW and it has to be inexpensive? Just because they want it “real bad”, we don’t need give it to them that way. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Solution Keep it Simple and Inexpensive ICMP traffic was permitted by both firewalls, so a DOS “ping” would work. Write a procedure to use a ping to see if the remote server is up. If not, continue trying until it responds or the predefined time period elapses. The return value tells the calling procedure if the server is up. Since the developers who will be calling the procedure cannot use xp_cmdshell, define the procedure to execute as owner and grant execute permission on the procedure to the developer. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Code - Initialization CREATE PROCEDURE dbo.VerifyChinaMailServer WITH EXECUTE AS OWNER AS BEGIN ------------------------------------------------------------------------------------- --Initialization SET NOCOUNT ON; --Local variables DECLARE @dtmEnd Datetime, @strCmd Varchar(200); --Setup to try to ping the remote server for up to 5 minutes SELECT @dtmEnd = DATEADD(minute, 5, GETDATE()), --Only try for 5 minutes @strCmd = 'ping ChinaMailServer1 -n 1 -w 1000 | findstr Reply'; --Create a temp table to capture the results of our DOS command IF OBJECT_ID('tempdb.dbo.#ping', 'u') IS NOT NULL DROP TABLE #ping; CREATE TABLE #ping ( Response Varchar(200), ID Integer not null identity (1, 1)); Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Code – Ping the Server --------------------------------------------------------------------------------------- --Ping the destination server. If not there, ping again until it’s time to give up WHILE GETDATE() < @dtmEnd --While we're still within the time limit... BEGIN --Make sure the command shell is still enabled IF (SELECT CONVERT(Integer, value_in_use) FROM sys.configurations WHERE name = 'xp_cmdshell') = 0 EXECUTE sp_configure 'xp_cmdshell', 1; RECONFIGURE; END; --Ping the remote server and trap the results INSERT INTO #ping(Response) EXECUTE master.dbo.xp_cmdshell @strCmd; --If any non-null row is returned in the response, a reply was received --so we can break out of the loop immediately IF (SELECT MAX(ID) FROM #ping WHERE Response IS NOT NULL) IS NOT NULL BREAK; --A 1-second max time is built in to our ping command, so no need to pause Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Code – Is Server There? ----------------------------------------------------------------------------- --Return the status of the remote server IF (SELECT MAX(ID) FROM #ping WHERE Response IS NOT NULL) IS NOT NULL RETURN 1; --Ping successful. Server IS available ELSE RETURN 0; --Ping NOT successful. Server is NOT available --Housekeeping DROP TABLE #ping; END; Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
The Code – Example Usage --Declare an obviously named variable DECLARE @intOK Integer; --Get the availability status of the remote server EXECUTE @intOK = dbo.VerifyChinaMailServer; SELECT @intOK; Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved
Conclusion Takeaways: This is an example of being given a problem by systems, using what we already know to use to solve the problem, and make it available to others to use WITHOUT elevating THEIR privs. Takeaways: Even with all the tools available today, DOS is still our friend. It keeps us from reinventing the wheel and prevents the “Tower of Babel”. When used properly, xp_cmdshell is very useful. When configured properly, it is also safe. (larger discussion) There actually ARE times when a loop is appropriate. Ensuring a Remote Server is Available 07 September 2015 © Copyright by Ed Wagner - All Rights Reserved