Node and MySQL connection to database - mysql

I need t o provide the MySQL connection for modules, so I provide the code like this:
var express = require('express');
var mysql = require('mysql')
var app = express();
var connection = mysql.createConnection({
host: '149.xxx.xx.x',
user: 'User',
password: 'Password',
database: 'DataBase',
port: 1443,
});
connection.connect(
function(error) {
console.log(error.code); // 'ECONNREFUSED'
console.log(error.fatal); // true
console.log(error.sql);
console.log(error.sqlMessage);
}
);
and after some time (about 1-2 minutes) I received an error from those console.logs:
ECONNRESET
true
undefined
undefined
I think maybe it's the timeout because of my "nonactivity", but when I'm trying to do the query the errors are the same.
Have any idea what is wrong? I checked it from DataGrip and the data are correct.

Ok, I found one small bug here. The database is MS SQL Server (microsoft). I'm trying now using the library called mssql to connect to that database, provide some code:
var config = {
server: "149.xxx.xx.x",
database: "Database",
user: "User",
password: "Password",
connectionTimeout: 300000,
requestTimeout: 300000,
pool: {
idleTimeoutMillis: 300000,
max: 100
}
};
function getEmp() {
var connection = new sql.Connection(config);
var req = new sql.Request(connection);
connection.connect(function (error) {
if(error) {
console.log(error);
return;
}
req.query('Procedure', function(err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
connection.close();
});
});
}
getEmp();
and I receive the error:
{ ConnectionError: Failed to connect to 149.xxx.xx.x:1433 - connect ETIMEDOUT 149.xxx.xx.x:1433
at Connection.<anonymous> (/Users/phuzarski/Learning/NodeJS/srv-express/node_modules/mssql/lib/tedious.js:353:25)
at Connection.g (events.js:292:16)
at emitOne (events.js:96:13)
at Connection.emit (events.js:188:7)
at Connection.socketError (/Users/phuzarski/Learning/NodeJS/srv-express/node_modules/tedious/lib/connection.js:791:12)
at Socket.<anonymous> (/Users/phuzarski/Learning/NodeJS/srv-express/node_modules/tedious/lib/connection.js:33:15)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1277:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
name: 'ConnectionError',
message: 'Failed to connect to 149.xxx.xx.x:1433 - connect ETIMEDOUT 149.xxx.xx.x:1433',
code: 'ESOCKET' }
For sure the data are correct- DataGrip is connecting fine here.
I found at google the similar problem, the problem was Disabled TCP/IP. I checked this one and it's Enabled with this port 1443.

Related

Facing issue with mysql database with node js

i have created express app with mysql database.
when i call mysql query it works fine and then i call my view. loading view take few minute(2-3 min) and app crashed with bellow error.
events.js:287
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:205:27)
Emitted 'error' event on Connection instance at:
at Connection._handleProtocolError (C:\Users\AMW\Desktop\dishmize\dishmize\node_modules\mysql\lib\Connection.js:423:8)
at Protocol.emit (events.js:310:20)
at Protocol.EventEmitter.emit (domain.js:482:12)
at Protocol._delegateError (C:\Users\AMW\Desktop\dishmize\dishmize\node_modules\mysql\lib\protocol\Protocol.js:398:10)
at Protocol.handleNetworkError (C:\Users\AMW\Desktop\dishmize\dishmize\node_modules\mysql\lib\protocol\Protocol.js:371:10)
at Connection._handleNetworkError (C:\Users\AMW\Desktop\dishmize\dishmize\node_modules\mysql\lib\Connection.js:418:18)
at Socket.emit (events.js:310:20)
at Socket.EventEmitter.emit (domain.js:482:12)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3) {
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read',
fatal: true
}
[nodemon] app crashed - waiting for file changes before starting...
i already spend 8- 10 hours.
please help me to resolve this issue.
thanks
Update:
const options = {
user: config.get('MYSQL_USER'),
password: config.get('MYSQL_PASSWORD'),
database:config.get('DATABASE'),
host: config.get('HOST'),
port: 3306
}
const connection = mysql.createConnection(options);
connection.connect( function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:"); throw err;
} else {
console.log("Connection established.");
}
});
use below
const options = { connectionLimit :10, user:config.get('MYSQL_USER'), password: config.get('MYSQL_PASSWORD'), database:config.get('DATABASE'), host: config.get('HOST'), port: 3306 }
const connection_pool = mysql.createPool(options);
connection_pool.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
provide connectionLimit according to you use this is pool size of connection

Reusing Mysql Connection in Lambda on AWS

I have a lot of lambda invocations and I am always querying database so I want my lambda to be able to reusing connection, so I am establishing connection in constructor, like this:
let mysqlConnection = mysql.createConnection({
host: process.env.HOST,
user: process.env.DB_USER,
password: process.env.BDB_PWD,
port: process.env.DB_PORT,
database: process.env.DB_NAME
});
dbConn.connect(function(err) {
if (err) {
throw new Error('Error during connecting to db');
} else {
console.log("Database is connected");
}
});
And I have callbackWaitsForEmptyEventLoop set to false in my handler:
exports.handler = (event, context) => {
context.callbackWaitsForEmptyEventLoop = false;
event.Records.forEach(record => {
processEvent(JSON.parse(record.body), context);
});
};
When mysql connection fails I am destroying mysql connection, my query in provessEvent function looks like this:
mysqlConnection.query(sql, values, function (err, rows) {
if (err) {
mysqlConnection.destroy();
context.fail();
}
}
But I am getting a lambda errrors from time to time. I guess sometimes lambda wants to reuse a connection which is not available.
"Error: Error during connecting to db",
" at Handshake.<anonymous> (/var/task/lambda.js:34:13)",
" at Handshake.<anonymous> (/var/task/node_modules/mysql/lib/Connection.js:525:10)",
" at Handshake._callback (/var/task/node_modules/mysql/lib/Connection.js:491:16)",
" at Handshake.Sequence.end (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)",
" at Protocol.handleNetworkError (/var/task/node_modules/mysql/lib/protocol/Protocol.js:369:14)",
" at Connection._handleNetworkError (/var/task/node_modules/mysql/lib/Connection.js:421:18)",
" at Connection._handleConnectTimeout (/var/task/node_modules/mysql/lib/Connection.js:417:8)",
" at Object.onceWrapper (events.js:286:20)",
" at Socket.emit (events.js:198:13)",
" at Socket.EventEmitter.emit (domain.js:448:20)"
Is there anything could I do to prevent this situation? Or should I destroy connection and connect once again?
I found this useful tool that could help you, https://github.com/jeremydaly/serverless-mysql you need just to install a npm module and configure it. Check also the #connection-backoff section.
I do not use MySQL but Mongodb in some projects. callbackWaitsForEmptyEventLoop was help.
'use strict';
const mysql = require('mysql'); // require mysql
// If 'client' variable doesn't exist
if (typeof client === 'undefined') {
// Connect to the MySQL database
var client = mysql.createConnection({
// your connection info
});
client.connect()
}
module.exports.handler = (event, context, callback) => {
// This will allow us to freeze open connections to a database
context.callbackWaitsForEmptyEventLoop = false;
client.query('SELECT * FROM `books`', function (error, results) {
callback(null, results)
});
}
Refer to AWS document and this tutorial

How do I connect local nodeJS server with MySQL which is running on AWS?

Here is my code to connect with MYSQL, I am getting connection timeout error :
This is my connection file to connect with MYSQL :
/*
* #sqlConnection
* Creates the connection, makes the query and close it to avoid concurrency conflicts.
*/
var mysql = require('mysql');
var sqlConnection = function sqlConnection(sql, values, next) {
// It means that the values hasnt been passed
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection({
"host": process.env.dbHost,
"user": process.env.dbUser,
"password": process.env.dbPass,
"database": process.env.dbName,
"port":process.env.dbPort
});
connection.connect(function (err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err + '\n');
}
else {
console.log("Connection is available");
}
});
connection.query(sql, values, function (err) {
connection.end(); // close the connection
if (err) {
throw err;
}
// Execute the callback
next.apply(this, arguments);
});
};
module.exports = sqlConnection;
This is the error what I am getting :
Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/home/himanshu/node_modules/mysql/lib/Connection.js:411:13)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:106:13)
at Socket.emit (events.js:208:7)
at Socket._onTimeout (net.js:420:8)
at ontimeout (timers.js:482:11)
at tryOnTimeout (timers.js:317:5)
at Timer.listOnTimeout (timers.js:277:5)
--------------------
I think I am doing something wrong in the config file which looks like, I don't know what to provide in db HOST or How actually I can connect with aws mysql db :
dbHost=00.00.000.000 // aws instance ip
dbName=HIMANSHU
dbUser=ROOT
dbPass=PASSWORD
dbPort=3360
#Himanshu Just check the Inbound rule of your Instance.
As per your code, it looks like you are running MySQL in your EC2 machine.
So just make sure, you have allowed 3306 port in your Inbound rules and outbound rules also

ETIMEOUT error | Google Cloud SQL database with NodeJS

I have created a mysql database on google cloud that I'd like to access from a separate node web application (also running on google cloud). I am testing the connection locally on my computer first, and when I run the following code locally I can successfully establish a connection to my database and see the data in it.
'use strict';
// [START app]
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
const mysql = require('mysql');
var connection = mysql.createConnection({
host : 'Cloud SQL IP',
user : 'username',
password : 'password',
database : 'db_name'
});
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// Make globals.js accessible
app.use(express.static(__dirname + '/'));
app.get('/', (req, res) => {
connection.connect();
connection.query('SELECT * FROM Users', function (error, results, fields) {
if (error) throw error;
console.log(results);
});
connection.end();
res.status(200).send('Hello World!');
});
app.get('/login', (req, res) => {
res.status(200).send();
});
// [START server]
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
// [END app]
However when run this same code in my google app engine (for both debugging on port 8080 and fully deployed on https://myapp.appspot.com) I get the following timeout error:
{ Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/home/megan_cooper2900/project/node_modules/mysql/lib/Connection.js:419:13)
at Socket.g (events.js:292:16)
at emitNone (events.js:86:13)
at Socket.emit (events.js:185:7)
at Socket._onTimeout (net.js:338:8)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
--------------------
at Protocol._enqueue (/home/megan_cooper2900/project/node_modules/mysql/lib/protocol/Protocol.js:145:48)
at Protocol.handshake (/home/megan_cooper2900/project/node_modules/mysql/lib/protocol/Protocol.js:52:23)
at Connection.connect (/home/megan_cooper2900/project/node_modules/mysql/lib/Connection.js:130:18)
at app.get (/home/megan_cooper2900/journeyma/app.js:31:13)
at Layer.handle [as handle_request] (/home/megan_cooper2900/project/node_modules/express/lib/router/layer.js:95:5)
at next (/home/megan_cooper2900/project/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/megan_cooper2900/project/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/megan_cooper2900/project/node_modules/express/lib/router/layer.js:95:5)
at /home/megan_cooper2900/project/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/megan_cooper2900/project/node_modules/express/lib/router/index.js:335:12)
errorno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
fatal: true }
Why is this not working on the Google App Engine application?
In your connection configuration for mysql,host does not work on App Engine. You have to use socketPath . socketPath is the path to a unix domain socket to connect to. When used host and port are ignored. (transferred knowledge from using Loopback on App Engine flex. it had me banging my head for days lol). It's value is your Cloud SQL Instance connection name
so in your case, it should look like this: /cloudsql/my-project-12345:us-central1:mydatabase
var connection = mysql.createConnection({
socketPath : '/cloudsql/my-project-12345:us-central1:mydatabase',
user : 'username',
password : 'password',
database : 'db_name'
});
It's a similar process if you're using Postgres on GCloud which is answered here
I also did faced the same issue and I was using Kubernetes pods to access my CloudSQL instance. I got a fix by increasing the timeout in the configuration.
cloudSqlConfig: {
connectionLimit: 10,
host: 'your-host-ip',
user: process.env.DB_USERNAME,
password: process.env.DB_PASSKEY,
database: 'myDB',
connectTimeout: 20000,
waitForConnections: true,
queueLimit: 0
},

How to provide SERVICE_NAME in the connection options in mysql npm?

I have a JDBC connection string something like this
jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=OFF)(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1711))(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1712)))(CONNECT_DATA=(SERVICE_NAME=servicename)(SERVER=DEDICATED)))
I have created the connection as
var connection = mysql.createConnection({
host: "hostname",
port: "1711",
user: "user",
password: "password"
});
How do I also provide SERVICE_NAME (like the jdbc string) to the connection options?
I am getting the following error without it:
Error: connect ECONNREFUSED <some_ip>:1711
at Object.exports._errnoException (util.js:1028:11)
at exports._exceptionWithHostPort (util.js:1051:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
--------------------
EDIT:
Changing the port to 1712 gives me a different error after taking a lot of time.
Error: Connection lost: The server closed the connection.
at Protocol.end (..\node_modules\mysql\lib\protocol\Protocol.js:113:13)
at Socket.<anonymous> (..\node_modules\mysql\lib\Connection.js:109:28)
at emitNone (events.js:91:20)
at Socket.emit (events.js:186:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
EDIT: Sorry. I didn't see the database was oracle and started trying mysql directly.
I am assuming that your mysql server is running on port 1711 not default port.
And if you are getting Connection lost error mean there are something wrong on your network try to reconnect your server after sometime.
var conn;
function handleDisconnect() {
conn = mysql.createConnection(//your config);
conn.connect(function(err) {
if(err) {
console.log('error when connecting to database:', err);
setTimeout(handleDisconnectConnection, 5000);
}
});
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnectConnection();
} else {
throw err;
}
});
}
handleDisconnectConnection();
Hope that will work for you