tags:

views:

419

answers:

6

Consider setting up a connection to a RDBMS, then yanking the network plug. (You'll get the same effect if the connection goes through a NAT gateway, and the gateway decides to purge that connection.)

At that point the RDBMS server is waiting for a query, or whatever, which will never occur. And the TCP connection won't be closed by tha client since that's not on that network anymore. Presumably the server will not close it either since it still believes the connection to be open.

Do typical RDBMS handle this with timeouts and/or implementing a simple keepalive mechanism over TCP ? Anyone have any experience with this for Oracle,SQL Server and MySQL ?

Edit; More digging suggests mysql purges connections after 8 hours of inactivity.

+1  A: 

It's a pretty broad question. Let me give you a broad answer.

In the client/server days this would have been a bigger problem, since clients maintained persistent connections to the database. Nowadays, for scalability and other reasons, applications are generally written in a "disconnected" fashion, whereby they make a connection to the database to obtain their data, and then promptly disconnect. In other words, applications request connections on an as needed basis.

When an operation occurs that is "atomic" (i.e. the entire operation must complete successfully from beginning to end), that operation is wrapped in a transaction. If the database connection is severed at any time during the transaction, the database system will "roll back" the operation, placing any affected records in the same state they were before the transaction was started.

Timeouts insure that any stray connections to the database do not stay open forever.

Robert Harvey
+2  A: 

When the underlying TCP connection is dropped either by the client or the server, the TCP/IP stack on the other side detects this and notifies the application. You can be sure the database server closes the connection (and rolls back any uncommitted transaction).

Update: A network failure just looks to each side like the other went away. Both sides would set socket timeouts, do retries, etc. so they could handle these failures gracefully. Jonathan brings up an interesting sub-issue in the comments, turns out the server does an implicit transaction commit if the client explicitly disconnects without terminating a transaction either way.

Jim Ferrans
Beware: under some circumstances, I believe Oracle commits, rather than rolls back, an uncommitted transaction when the client 'goes away'.
Jonathan Leffler
The issue is the TCP connection will not be closed.There's not sent any info from the client to the server if you yank out the network plug that the TCP connection is closed. If you yank it while the server has un'acked data in transition it'll timeout on the TCP level. Otherwise you have to implement it on the application level (and the question is if RDBMS, in particular Oracle,SQL server,MySQL does this.)
nos
That would be a serious bug.
Jim Ferrans
The serious bug would be for the DBMS to commit an uncommitted transaction.
Jim Ferrans
The basis for my comment is: http://search.cpan.org/~timb/DBI-1.608/DBI.pm#disconnect
Jonathan Leffler
Jonathan, thanks, this is a very interesting point! I also found: http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/basic.htm#sthref74 Even if the client disables auto-commit, as is the case when in a transaction, if the client sends an explicit disconnect without first explicitly committing or rolling back the transaction, an *implicit commit* of the transaction takes place. That's a different scenario than a network error, and it preserves the key ACID goal of never committing an uncommitted transaction. This almost feels like an "it's not a bug, it's a feature" though.
Jim Ferrans
@Jim - thanks for the clarification; I used cautious terms because I didn't fully understand the context (but now I understand better).
Jonathan Leffler
A: 

The specific situation you're talking about doesn't really happen. Just because a connection is established, doesn't imply that the RDBMS is "waiting" for a query to arrive. It may simply note the existence of the connection, start an asynchronous read operation, then go on about its business.

If it were a problem to have the async read never complete, then of course, the RDBMS could implement a periodic "ping" mechanism that would determine if the connection is still open. As I think you already know, a TCP/IP connection is only open if it's open on both ends, so if the RDBMS sent a "ping" to a client that is no longer there, then the write would time out the connection, and the server end would close. One would expect the RDBMS to notice that, and destroy any server-side resources associated with the connection.

John Saunders
Starting an async read is pretty much "waiting for a query". And as you say the RDBMS could send a 'ping' every know and then to check if the other end is still there. Do they do that ? Do Oracle do that ? MySQL, SQL Server ?You would not believe the amount of stale connection that piles up on a custom server application that doesn't have any keepalive mechanisms over the months. Investigation showed the casuse to be a) People closing their notebook and leaving for home - resulted in not closing a TCP connection.b) Crappy NAT gateways dropping connection after 10 minuts without activity
nos
@nos: starting an async read is not the same as waiting for a query, depending on your implementation. In Windows or .NET, this is a matter of a completion port, not of a thread blocking. I don't know how any given RDBMS implements this, and I hope I didn't suggest that I did know. You should ask specific vendors this question. It's possibly taken care of as part of their protocols.
John Saunders
@nos: Look into TCP keepalive.
derobert
A: 

Database connections are typically pooled so you don't have to incur the penalty of establishing the connection every time. Application servers provide this facility and they typically provide flexibility to flush the connection pool and re-establish all the connections in their pool when this stale connections state is detected.

zkarthik
A: 

The Oracle JDBC driver provides a proprietery ping() method on the connection class, which returns true if the connection is considered "active".

Unfortunately, ping() was implemented by an idiot. It sends a "select 'x' from dual" query to the server, which is far from being a low-impact query due to the presense of the literal 'x' which gives the query cache a hard time.

We used to call ping() from our app server every time a connection was borrowed from the pool, until it almost killed our oracle server.

Not recommended.

skaffman
A: 

In SQL Server, the connection (you can see this with sp_who) is closed and uncommitted transactions are rolled back.

What I've seen on the client is that a subsequent attempt on the same connection from the client (in the case of the VPN or NAT being reconnected) usually results in a Transport Error at the client side and a new connection is created in the case of SSMS for subsequent batches in the same window.

Cade Roux