Connection Pools with MariaDB Connector/Node.js (Promise API)
This page is part of MariaDB's Documentation.
The parent of this page is: MariaDB Connector/Node.js with Promise API
Topics on this page:
Overview
Node.js developers can connect to MariaDB database products using MariaDB Connector/Node.js to use connection pools with the Promise API. Promise API is the default API. Connection pools enable the reuse of database connections to minimize the performance overhead of connecting to the database and the churn of opening and closing connections.
Connection pools hold connections open in a pool. When a process is done with the connection, the connection is returned to the pool rather than being closed, allowing MariaDB Connector/Node.js to acquire a connection as needed. MariaDB Connector/Node.js also supports clustering pools, for when you want a group of connection pools to multiple end points.
Connection Pools with Promise API
Connection pools can be used with Promise API. The Promise API provides the following functions in the Connection
object to create a connection pool:
Function | Return Type | Description |
---|---|---|
|
| The base function to create a connection pool. |
The createPool(options)
function does not return a Promise
, and therefore must be wrapped in a new Promise
object if returned directly from an async function.
The createPool(options)
options include the options from the createConnection(options)
function, which are discussed in Code Example: Connect.
The createPool(options)
function returns a Pool
object. The Pool
API provides several functions:
Function | Description |
---|---|
| Returns a |
| Gets a connection from the pool, runs a SQL statement, and returns the connection back to the pool. Returns a |
| Gets a connection from the pool, runs a batch of SQL statements, and returns the connection to the pool. Returns a |
| Ends or closes the connection pool and the underlying connections after all running queries have completed. Returns a |
Options
The createPool(options)
function supports the following pool-specific options:
Option | Description | Type | Default Value |
---|---|---|---|
| Timeout to get a new connection from pool in ms. In order to have connection error information, |
|
|
| Maximum number of connections in pool |
|
|
| Sets idle time after which a pool connection is released. Value must be lower than wait_ |
|
|
| Permits setting a minimum number of connections in pool. We recommend using a fixed pool, and so not setting this value.
|
|
|
| When asking for a connection to pool, the pool will validate the connection state. To avoid unnecessary verifications in the case of frequent reuse of connections, "minDelayValidation" permits disabling this validation if the connection has been borrowed recently. 0 means validation is done each time the connection is asked. (in ms) |
|
|
| After giving a connection back to the pool ( |
|
|
| When a connection is given back to pool, this option enables resetting the connection if the server allows it (only for MariaDB version >= 10.2.22 / 10.3.13). If disabled or server version doesn't allows reset, pool will only rollback open transaction if any. |
|
|
| Sets a timeout to log connection borrowed from pool. When a connection is borrowed from pool and this timeout is reached, a message will be logged to console indicating a possible connection leak. Another message will tell if the possible logged leak has been released. A value of 0 disables leak detection. |
|
|
Load Balancing
In addition to connection pools, MariaDB Connector/Node.js also supports pool clusters. A prerequisite is a cluster of nodes running MariaDB. Where a connection pool is a set of connections maintained to an individual server, in a pool clusters the Connector maintains a set of connection pools to different servers.
Pool clusters are useful in cases of large deployments in which your application needs to connect to different servers for different purposes or when you want to perform load balancing at an application level. The benefits of pool cluster are high availability, and load distribution.
Pool clusters provide connection pooling across the different servers in the cluster. Pool clusters do not provide data replication to the MariaDB servers in the cluster. For replication, use a
deployment.With Promise API, pool clusters can be used. The Promise API provides the following function to create a pool cluster:
Function | Return Type | Description |
---|---|---|
|
| The base function to create a pool cluster. |
The createPoolCluster(options) → PoolCluster
function does not return a Promise
, and therefore must be wrapped in a new Promise
object if its return value is returned directly from an async function.
The createPoolCluster(options)
function supports all of the options supported by the Pool API. Further, the Pool API options include the options from the createConnection(options)
function, which are discussed in Connect.
The createPoolCluster(options)
function supports the following additional options:
Option | Description | Type | Default Value |
---|---|---|---|
| Whether pool cluster can try to get connection from other pool if getting connection from one pool fails. |
|
|
| The error count for a single pool in obtaining a connection after which the pool is removed from the pool cluster. Set to |
|
|
| Timeout in milliseconds after which a pool is retried for a connection after a connection fails. The default value is 1000. |
|
|
| Specifies the default pool selector. A pool selector strategy is used in selecting which pool in the cluster to try a connection. 'RR' is for a round-robin selector. 'RANDOM' is to select randomly. 'ORDER' is to select in sequence or order in which added to the pool cluster. |
|
|
MariaDB Connector/Node.js Promise API supports the following load balancing selectors:
Load Balancing | Selector | Description |
---|---|---|
Order |
| Servers selected in the order in which they are listed. |
Random |
| Servers selected at random. |
Round-robin |
| Servers selected using round-robin. |
Code Example: Connection Pools
The following example shows how to use connection pools with the example table created in Setup for Examples.
// Required Modules
const mariadb = require("mariadb");
//Initialize Pool
const pool = mariadb.createPool({
host: "192.0.2.50",
user: "db_user",
password: "db_user_password",
database: "test",
connectionLimit: 100,
});
console.log("Total connections: ", pool.totalConnections());
console.log("Active connections: ", pool.activeConnections());
console.log("Idle connections: ", pool.idleConnections());
async function main() {
let conn;
try {
conn = await fetchConn();
// Use Connection
var rows = await get_contacts(conn);
for (i = 0, len = rows.length; i < len; i++) {
console.log("Total connections: ", pool.totalConnections());
console.log("Active connections: ", pool.activeConnections());
console.log("Idle connections: ", pool.idleConnections());
console.log(`${rows[i].first_name} ${rows[i].last_name} <${rows[i].email}>`);
}
} catch (err) {
// Manage Errors
console.log(err);
} finally {
// Close Connection
if (conn) conn.end();
}
}
// Fetch Connection
async function fetchConn() {
let conn = await pool.getConnection();
console.log("Total connections: ", pool.totalConnections());
console.log("Active connections: ", pool.activeConnections());
console.log("Idle connections: ", pool.idleConnections());
return conn;
}
//Get list of contacts
async function get_contacts(conn) {
return await conn.query("SELECT first_name, last_name, email FROM test.contacts");
}
main();
Use the
async
keyword to declare asynchronous functions.Use the
await
keyword with the function calls to asynchronous functions.Add an async function
fetchConn()
to fetch a connection from the connection pool. Use atry-catch-finally
statement in the function.Declare a constant using the
const
keyword calledpool
to create a new connection pool. Initialize a connection pool using thecreatePool(options)
function in themariadb
module.The
host
option sets the host as localhost.The
user
option sets the user name.The
password
option sets the password for thee user.The
database
option sets the database name totest
.The
connectionLimit
option sets the maximum number of connections in the pool. The default value is 10.The
minimumIdle
option sets a minimum number of connections in the pool. By default it is the same as theconnectionLimit
option value.Set
connectionLimit
option value to the number of connections that are estimated to be needed. Setting it too high creates an abundance of idle connections.The
idleTimeout
option sets the idle time (seconds) after which a connection is released. Default value is 1800 seconds (30 minutes).The
createPool(options)
function returns aPool
object.Because the
createPool(options)
function does not return aPromise
object, if the function is to be called asynchronously, function callcreatePool(options)
should be wrapped in a newPromise
object.The
Pool#getConnection()
function is used to get a connection from the connection pool.The
Pool#getConnection()
function returns aPromise
object.If
fetchConn()
is unable to obtain a connection from the connection pool, it creates a new connection using themariadb.createConnection(options)
function as fallback in thecatch
block and returns that instead.Add an async function
get_contacts(conn)
to run a SQL query with thequery()
function to get data for contacts using a statement.Loop over the contacts data returned using a
for
loop, and print thefirst_name
,last_name
, andemail
in each row of data.The total number of connections in the connection pool, the number of idle connections in the connection pool, and the number of active connections in the connection pool are logged to the console using functions
pool.totalConnections()
,pool.activeConnections()
, andpool.idleConnections()
respectively.These functions may be called at various stages of a connection pool use, such as just after a new connection pool is initialized, when a new connection is obtained from the pool, when a connection is passed as an argument to another async function, and when data retrieved by a query is looped through and logged to the console.
These connection counts could vary throughout the use of a connection pool.
Idle connections getting removed from a connection pool after the default timeout of 1800 seconds could greatly reduce the number of available connections.
In the script output, note the varying number of total, active, and idle connections in the connection pool.
Example output:
Total connections: 0
Active connections: 0
Idle connections: 0
Total connections: 1
Active connections: 1
Idle connections: 0
Total connections: 1
Active connections: 1
Idle connections: 0
SQL statement completed
Total connections: 100
Active connections: 1
Idle connections: 99
John Smith <john.smith@example.com>
Total connections: 100
Active connections: 1
Idle connections: 99
Jon Smith <jon.smith@example.com>
Total connections: 100
Active connections: 1
Idle connections: 99
Johnny Smith <johnny.smith@example.com>
Code Example: Load Balancing
The following example shows how to use a pool cluster with the example table created in Setup for Examples. The example assumes that the example table, and example data exists on all cluster nodes.
const mariadb = require("mariadb");
// Initialize Pool Cluster
const clust = mariadb.createPoolCluster();
// Create Connection Pool to server1 Server
clust.add("server1", {
host: "192.0.2.1",
user: "db_user",
password: "db_user_password",
database: "test",
connectionLimit: 5,
});
// Create Connection Pools to server2 Server
clust.add("server2", {
host: "192.0.2.2",
user: "db_user",
password: "db_user_password",
database: "test",
connectionLimit: 5,
});
// Create Connection Pools to server3 Server
clust.add("server3", {
host: "192.0.2.3",
user: "db_user",
password: "db_user_password",
database: "test",
connectionLimit: 5,
});
async function main() {
try {
var sql = "SELECT first_name, last_name, email FROM test.contacts";
var rows = await queryData(sql);
for (i = 0, len = rows.length; i < len; i++) {
console.log(`${rows[i].first_name} ${rows[i].last_name} <${rows[i].email}>`);
}
// Manage Errors
} catch (err) {
console.log(err);
} finally {
// Close Connection
}
}
async function queryData(sql) {
let conn;
var rows;
try {
conn = await clust.getConnection(/^server*$/, "RR");
return conn.query(sql);
} catch (err) {
console.error("Error Processing Query: ", err);
} finally {
if (conn) conn.end();
}
}
main();
Use the
async
keyword to declare asynchronous functions.Use the
await
keyword with the function calls to asynchronous functions.Declare a constant called
clust
with theconst
keyword to initialize a pool cluster using thecreatePoolCluster(options)
base function.The pool cluster is usable only after adding pools to the cluster.
Once you have created a pool cluster, use the
add()
method to add MariaDB servers to the cluster, providing them with an arbitrary name and a JSON object containing the connection configuration.The function syntax is
poolCluster.add(id, config)
. Theid
is the node identifier string. Theconfig
is the JSON for the pool options. These options are discussed in Connection Pools.For
host
the host name, public IPv4 address, or the public DNS may be used.Obtain a connection from the pool cluster using function
poolCluster.getConnection(pattern, selector)
.The pool selector
'RR'
is used.The pattern to use is
server*
, which selects any server with name starting withserver
in a round-robin.Load balancing is provided by using a Regular Expression to indicate a group of servers from which the Connector selects one.
To retrieve a connection from a specific server from the pool cluster, use the
getConnection()
function, providing the server name you want to reach.Send a SQL query to the database using the
query()
function.Close the connection with the
connection.end()
function to free up resources.
Example output:
John Smith <john.smith@example.com>
Jon Smith <jon.smith@example.com>
Johnny Smith <johnny.smith@example.com>