serverless-mysql icon indicating copy to clipboard operation
serverless-mysql copied to clipboard

AWS Lambda execution does not terminate when using mysql.end() but does when using mysql.quit()

Open notmessenger opened this issue 5 years ago • 11 comments

I am experiencing the same issue reported in https://github.com/jeremydaly/serverless-mysql/issues/50

Using Node v12.13.1 with this code:

const mysql = require('serverless-mysql')()

exports.handler = async (event) => {
  mysql.config({
    host     : <VALUE>,
    user     : <VALUE>,
    password : <VALUE>,
    database : <VALUE>,
    ssl      : true
  })

  const results = await mysql.query('SELECT * FROM table WHERE id = ?', <VALUE>)

  await mysql.end()

  console.log(results)
}

Results are logged but the Lambda execution does not terminate and eventually times out.

Removing the await from before mysql.end() does not change any of the behavior.

Replacing mysql.end() with mysql.quit() causes the Lambda to terminate as expected.

Changing the Node version to v10.17.0 does not change any of the behavior.

notmessenger avatar Dec 02 '19 18:12 notmessenger

The result of this query:

mysql.query(`SELECT IF(@@max_user_connections > 0, LEAST(@@max_user_connections,@@max_connections), @@max_connections) AS total, IF(@@max_user_connections > 0,true,false) AS userLimit`)

is [ RowDataPacket { total: 500, userLimit: 0 } ]

notmessenger avatar Dec 02 '19 18:12 notmessenger

The result of this query:

mysql.query(`SELECT COUNT(ID) as total, MAX(time) as max_age FROM information_schema.processlist WHERE (user = ? AND @@max_user_connections > 0) OR true`, <VALUE>)

is [ RowDataPacket { total: 1, max_age: 0 } ]

notmessenger avatar Dec 02 '19 18:12 notmessenger

The result of this query:

mysql.query(`SELECT ID, time FROM information_schema.processlist WHERE command = "Sleep" AND time >= ? AND user = ? ORDER BY time DESC`, [60*15, <VALUE>)

is []

notmessenger avatar Dec 02 '19 18:12 notmessenger

MySQL info:

Variable Name Vale
innodb_version 5.5.61-MariaDB-38.13
protocol_version 10
slave_type_conversions
version 5.5.64-MariaDB
version_comment MariaDB Server
version_compile_machine x86_64
version_compile_os Linux

notmessenger avatar Dec 02 '19 19:12 notmessenger

When use await mysql.end() none of

  • onClose
  • onKill
  • onKillError
  • onRetry
  • onError

fire but using await mysql.quit() onClose does

notmessenger avatar Dec 02 '19 21:12 notmessenger

I have not tried this library with MariaDB. It is possible that it does not support the cleanup functions.

jeremydaly avatar Dec 14 '19 20:12 jeremydaly

The same issue, AWS lambda console says: Task timed out after 3.00 seconds

            const result = await mysql.query(`INSERT INTO ${MySqlInfo.TableName} (
                DEVICE_ID,
                IP,
                COUNTRY,
                STATE,
                DEVICE_WIDTH,
                DEVICE_HEIGHT,
                WEBVIEW_WIDTH,
                TIME,
                AFTER_LOAD,
                SCROLL_LOG,
                URL_LOG,
                ACCEL_LOG,
                OPEN_WHERE,
                TOKEN
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, [
                    props.DEVICE_ID,
                    props.IP,
                    props.COUNTRY,
                    props.STATE,
                    props.DEVICE_WIDTH,
                    props.DEVICE_HEIGHT,
                    props.WEBVIEW_WIDTH,
                    props.TIME,
                    props.AFTER_LOAD,
                    props.SCROLL_LOG,
                    props.URL_LOG,
                    props.ACCEL_LOG,
                    props.OPEN_WHERE,
                    props.TOKEN

                ], 
                 function (err:any, results:any, fields:any) {


                    
                    console.log("connection released")

                     if (err) throw err;
                 else{
                     console.log('Inserted ' + results.affectedRows + ' row(s).');
                     

                 }
             })
             await mysql.end();
             mysql.quit();

i got the error like that before, when i changed connection instead of pool connection, and .release() instead of .end() it was resolved.

I have resolved this problem with removing await in front of mysql.query:

            const result = mysql.query(`INSERT INTO ${MySqlInfo.TableName} (
                DEVICE_ID,
                IP,
                COUNTRY,
                STATE,
                DEVICE_WIDTH,
                DEVICE_HEIGHT,
                WEBVIEW_WIDTH,
                TIME,
                AFTER_LOAD,
                SCROLL_LOG,
                URL_LOG,
                ACCEL_LOG,
                OPEN_WHERE,
                TOKEN
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, [
                    props.DEVICE_ID,
                    props.IP,
                    props.COUNTRY,
                    props.STATE,
                    props.DEVICE_WIDTH,
                    props.DEVICE_HEIGHT,
                    props.WEBVIEW_WIDTH,
                    props.TIME,
                    props.AFTER_LOAD,
                    props.SCROLL_LOG,
                    props.URL_LOG,
                    props.ACCEL_LOG,
                    props.OPEN_WHERE,
                    props.TOKEN

                ], 
                 function (err:any, results:any, fields:any) {


                    
                    console.log("connection released")

                     if (err) throw err;
                 else{
                     console.log('Inserted ' + results.affectedRows + ' row(s).');
                     

                 }
             })
             await mysql.end();
             mysql.quit();

After removing await, AWL lambda console says: Duration: 70.36 ms Billed Duration: 100 ms Memory Size: 128 MB to 400 ms

inceabdullah avatar Jan 10 '20 08:01 inceabdullah

Are you setting context.callbackWaitsForEmptyEventLoop = false; in your Lambda handler?

kernwig avatar Feb 20 '20 16:02 kernwig

I'm also running into this issue, though with RDS MySQL rather than mariaDB. The basic setup is otherwise the same as @notmessenger, though using ES6 modules and Typescript

import serverlessMysql, { ServerlessMysql } from "serverless-mysql";
const mysql: ServerlessMysql = serverlessMysql({
    config: {
        host: process.env.DB_HOST,
        database: process.env.DB_NAME,
        user: process.env.DB_USER,
        password: process.env.DB_PASSWORD,
    },
    connUtilization: .01
})

export const handler = async (event: S3Event) => {
    const count = await mysql.query('SELECT count(1) FROM table_name')
    await mysql.end()
    console.log(count)
}

This is true with context.callbackWaitsForEmptyEventLoop = false; as well. If I update await mysql.end() to mysql.quit() it correctly ends the lambda, but that doesn't seem like a real solution given the differences between end and quit.

At this point I'm a bit stumped on solutions.

Dantaro avatar Sep 21 '20 16:09 Dantaro

Hi @Dantaro, did you eventually find the cause for this? or another solution other than using the quit method?

RyanD1996 avatar Mar 11 '21 11:03 RyanD1996

Hi Everyone, I'm with the same issue, but I'm using MariaDB and I saw @jeremydaly said that maybe for Maria is not supported, is that correct ?

as Maria's users can we have any fix in future ? Or can we try to colaborate with this fixes ?

sanchezz985 avatar Mar 26 '21 19:03 sanchezz985