1

When we say we have created a connection between a database and an application (that can be stored in connection pool), what really a "connection" means here?

  • Does it got anything to do with establishing a TCP/ TLS connection?

  • Does it load the database schema with every connection?

  • What happens to a connection (that are already loaded in application connection pool) when the database schema changes, and there is an active transaction going on?

Vishrant
  • 15,456
  • 11
  • 71
  • 120

3 Answers3

0

"A Connection" is nothing but details of a Socket, with extra details (like username, password, etc.). Each connection have a different socket connection.

For example:

Connection 1:

Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]

Connection 2:

Socket[addr=localhost/127.0.0.1,port=1030,localport=51246]

I have created two connection in a single JVM process to demonstrate how the server knows in which Socket the reply is to be sent. A socket, if I define in terms of UNIX is a special file that is used for inter-process communication:

srwxr-xr-x. 1 root root 0 Mar  3 19:30 /tmp/somesocket

When a socket is created (i.e., when this special socket file is created; how to create a socket? and this) operating system creates a file descriptor that points to that file. Server distinguishes the Socket with following attributes: Ref.

{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}

PROTOCOL: I have used postgres as an example, the socket connection in postgres driver is done with SocksSocketImpl which is a TCP socket implementation (RFC 1928)

Coming back the two connections I have created, if you look closely the localport for both the connections are different, so the server clearly understands where it has to send the reply back.

Now there are limitations on the number of files (or file descriptors) that you can open in an operating system, thus it's recommended not to keep your connections dangling (called connection leak)

Does it load the database schema with every connection?

Answer: No, it's the ResultSet that takes care of it.

What happens to a connection when the database schema changes

Answer: Connection and database schema are two different things. Connection just defines how to communicate with another process. Database schema is a contract between application and database, an application might throw errors that the contract is broken, or it may simply ignore it.


If you are interested in digging more, you should add a breakpoint to a connection object and below is how it looks like (see FileDescriptor)

connection = {Jdbc4Connection@777} 
args = {String[0]@776} 
connection = {Jdbc4Connection@777} 
 _clientInfo = null
 rsHoldability = 2
 savepointId = 0
 logger = {Logger@778} 
 creatingURL = "dbc:postgresql://localhost:1030/postgres"
  value = {char[40]@795} 
  hash = 0
 openStackTrace = null
 protoConnection = {ProtocolConnectionImpl@780} 
  serverVersion = "10.7"
  cancelPid = 19672
  cancelKey = 1633313435
  standardConformingStrings = true
  transactionState = 0
  warnings = null
  closed = false
  notifications = {ArrayList@796}  size = 0
  pgStream = {PGStream@797} 
   host = "localhost"
   port = 1030
   _int4buf = {byte[4]@802} 
   _int2buf = {byte[2]@803} 
   connection = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
    created = true
    bound = true
    connected = true
    closed = false
    closeLock = {Object@811} 
    shutIn = false
    shutOut = false
    impl = {SocksSocketImpl@812} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
     server = null
     serverPort = 1080
     external_address = null
     useV4 = false
     cmdsock = null
     cmdIn = null
     cmdOut = null
     applicationSetProxy = false
     impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
      exclusiveBind = true
      isReuseAddress = false
      timeout = 0
      trafficClass = 0
      shut_rd = false
      shut_wr = false
      socketInputStream = {SocketInputStream@819} 
       eof = false
       impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
       temp = null
       socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
        created = true
        bound = true
        connected = true
        closed = false
        closeLock = {Object@811} 
        shutIn = false
        shutOut = false
        impl = {SocksSocketImpl@812} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
         server = null
         serverPort = 1080
         external_address = null
         useV4 = false
         cmdsock = null
         cmdIn = null
         cmdOut = null
         applicationSetProxy = false
         impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
         timeout = 0
         trafficClass = 0
         shut_rd = false
         shut_wr = false
         socketInputStream = null
         socketOutputStream = null
         fdUseCount = 0
         fdLock = {Object@815} 
         closePending = false
         CONNECTION_NOT_RESET = 0
         CONNECTION_RESET_PENDING = 1
         CONNECTION_RESET = 2
         resetState = 0
         resetLock = {Object@816} 
         stream = false
         socket = null
         serverSocket = null
         fd = {FileDescriptor@817} 
         address = null
         port = 0
         localport = 0
        oldImpl = false
       closing = false
       fd = {FileDescriptor@817} 
        fd = 1260
        handle = -1
        parent = {SocketInputStream@819} 
         eof = false
         impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
         temp = null
         socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
         closing = false
         fd = {FileDescriptor@817} 
          fd = 1260
          handle = -1
          parent = {SocketInputStream@819} 
           eof = false
           impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
            exclusiveBind = true
            isReuseAddress = false
            timeout = 0
            trafficClass = 0
            shut_rd = false
            shut_wr = false
            socketInputStream = {SocketInputStream@819} 
            socketOutputStream = {SocketOutputStream@820} 
            fdUseCount = 0
            fdLock = {Object@821} 
            closePending = false
            CONNECTION_NOT_RESET = 0
            CONNECTION_RESET_PENDING = 1
            CONNECTION_RESET = 2
            resetState = 0
            resetLock = {Object@822} 
            stream = true
            socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
            serverSocket = null
            fd = {FileDescriptor@817} 
            address = {Inet4Address@823} "localhost/127.0.0.1"
            port = 1030
            localport = 51099
           temp = null
           socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
           closing = false
           fd = {FileDescriptor@817} 
           path = null
           channel = null
           closeLock = {Object@826} 
           closed = false
          otherParents = {ArrayList@833}  size = 2
          closed = false
         path = null
         channel = null
         closeLock = {Object@826} 
         closed = false
        otherParents = {ArrayList@833}  size = 2
        closed = false
       path = null
       channel = null
       closeLock = {Object@826} 
       closed = false
      socketOutputStream = {SocketOutputStream@820} 
       impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
       temp = {byte[1]@843} 
       socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
       closing = false
       fd = {FileDescriptor@817} 
       append = false
       channel = null
       path = null
       closeLock = {Object@844} 
       closed = false
      fdUseCount = 0
      fdLock = {Object@821} 
      closePending = false
      CONNECTION_NOT_RESET = 0
      CONNECTION_RESET_PENDING = 1
      CONNECTION_RESET = 2
      resetState = 0
      resetLock = {Object@822} 
      stream = true
      socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
      serverSocket = null
      fd = {FileDescriptor@817} 
      address = {Inet4Address@823} "localhost/127.0.0.1"
      port = 1030
      localport = 51099
     timeout = 0
     trafficClass = 0
     shut_rd = false
     shut_wr = false
     socketInputStream = null
     socketOutputStream = null
     fdUseCount = 0
     fdLock = {Object@815} 
     closePending = false
     CONNECTION_NOT_RESET = 0
     CONNECTION_RESET_PENDING = 1
     CONNECTION_RESET = 2
     resetState = 0
     resetLock = {Object@816} 
     stream = false
     socket = null
     serverSocket = null
     fd = {FileDescriptor@817} 
     address = null
     port = 0
     localport = 0
    oldImpl = false
   pg_input = {VisibleBufferedInputStream@805} 
   pg_output = {BufferedOutputStream@806} 
   streamBuffer = null
   encoding = {Encoding@807} "UTF-8"
   encodingWriter = {OutputStreamWriter@808} 
  user = "postgres"
  database = "postgres"
  executor = {QueryExecutorImpl@800} 
  logger = {Logger@778} 
 compatible = "9.0"
 dbVersionNumber = "10.7"
 commitQuery = {SimpleQuery@783} "COMMIT"
 rollbackQuery = {SimpleQuery@784} "ROLLBACK"
 _typeCache = {TypeInfoCache@785} 
 prepareThreshold = 5
 autoCommit = true
 readOnly = false
 bindStringAsVarchar = true
 firstWarning = null
 timestampUtils = {TimestampUtils@786} 
 typemap = null
 fastpath = null
 largeobject = null
 metadata = null
 copyManager = null
Vishrant
  • 15,456
  • 11
  • 71
  • 120
-1

Here the connection you are talking about means the opening function that the application invokes to open and read/modify/delete the database or childs of it.

For example if we talk about a PHP file (used to load websites requests in server, like HTML) or a HTML file, where you login in a page that has as name: https://example.com/login.php (PHP) or https://example.com/login.html (HTML) and the page requires to access the adatabase of the users to check if the credentials you insert are correct, if the values given (for e.g: username:"demoUser" and password:"password*1234"), exists in the databse as rows in a specific table. The database can contain infinite tables and infinite rows inside. An example of a simple database with only one table called Users: username | password | date_created // Table columns

"demoUser" | "password" | "23-03-2019" // Example showed above

"user1213" | "passw0rd" | "04-02-2019" //Second user example then here above if the application need to verify if the value exist in this database, the operating system of the application will access the database with a simple file reading file is normally with .db and then it will read each rows to find the values.

To do this the code in the login.php/login.html pages invokes the server that runs the file and the server open the database and then the server take the query(what the code request to check in the database), and execute it as if the database was a simple file with (for e.g:) .db. The connection here stands as the query the

Gabry
  • 22
  • 1
  • 2
-1

To put it in simple words. A "Database connection" is a link between your application process and Database's serving process.

Client side:
When you create a connection your application stores information like: what database address is, what socket is used for the connection, what server process is responsible for processing your requests and etc. This information depends on a connection driver implementation and differs from database to database.

Server side:
When a request from a client application arrives, a database performs authentication and authorization of the client and creates a new process or a thread which is responsible for serving it. Implementation and data loaded by this server process is also vendor-dependent and differs from database to database.
This process of 'preparing' a database for serving a new client takes a good amount of time, and that's where connection pools come to help.

Connection pool:
Connection pool is basically used to reduce the need for openning new connections and wasting time on authentication, authorization, creating server process etc. It allows reusing already established connections.
What happens to a connection (that are already loaded in application connection pool) when the database schema changes, and there is an active transaction going on?
First of all, a database does not know about any connection pools. For the databse it's a client-side feature. What happens also depends on a particular database and its implementation. Usually databases have a blocking mechanism to prevent objects from modifying while they are still in use and vice-versa.

Pavel Smirnov
  • 4,611
  • 3
  • 18
  • 28
  • I know what a connection driver is (and it differs vender to vender) and that server authenticate and application saves it in connection pool. The question is about what a "connection" really is, let me give you an example, in a TCP 3 way connection handshake, the OS maintains a queue until an acknowledge is received. But again what is a "connection" and does it store schema? what happens to a connection if the schema change? – Vishrant Mar 23 '19 at 20:28
  • it would be more helpful if you deep dive into explaining "is a link" how it is created (TCP/ Socket...) what happens to that link if the database schema changes – Vishrant Mar 23 '19 at 20:31
  • @Vishrant, both TCP and Socket. And this connection has nothing to do with database schema. If schema changes - the link is still active (do not confuse with transaction). – Pavel Smirnov Mar 23 '19 at 20:35
  • Then interesting post to look for https://stackoverflow.com/questions/2783813/postgres-error-cached-plan-must-not-change-result-type this error is thrown when there is an active connection and the schema is changed. – Vishrant Mar 23 '19 at 20:39
  • @Vishrant, this is just a part of the blocking mechanism I wrote about. But the "conneciton" is still alive. It's just the message from the database (using the connection) that some action can not be performed. If the connection you're talking about would not exist, the user would not even recieve this message. – Pavel Smirnov Mar 23 '19 at 20:43