question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Server: PROTOCOL_CONNECTION_LOST when connecting with mysqli

See original GitHub issue

We are using mysql2 proxy example and see a fatal PROTOCOL_CONNECTION_LOST exception after several sql queries have successfully executed. MySQL version is 5.7.

My guess is that we are not handling the sequenceId correctly somewhere as we also see Warning: got packets out of order. Expected 2 but received 0.

For testing, the proxy code is as per the vanilla example with the exception that we set the sequencId to 0 in the authCallback and to 1 on query. Here is the full code:

"use strict";

const mysql = require("mysql2");
const ClientFlags = require("mysql2/lib/constants/client.js");

const server = mysql.createServer();
server.listen(3300);

server.on("connection", (conn) => {
  console.log("connection");

  conn.serverHandshake({
    protocolVersion: 10,
    serverVersion: "node.js rocks",
    connectionId: 1234,
    statusFlags: 2,
    characterSet: 8,
    capabilityFlags: 0xffffff,
    authCallback: () => {
      conn.writeOk();
      conn.sequenceId = 0;
    },
  });

  conn.on("field_list", (table, fields) => {
    console.log("field list:", table, fields);
    conn.writeEof();
  });

  const remote = mysql.createConnection({
    user: "root",
    database: "wordpress",
    host: "127.0.0.1",
    password: "supersecret",
    port: 3310,
  });

  conn.on("query", (sql) => {
    console.log(`${sql}\n`);
    conn.sequenceId = 1;
    remote.query(sql, function (err) {
      // overloaded args, either (err, result :object)
      // or (err, rows :array, columns :array)
      if (Array.isArray(arguments[1])) {
        // response to a 'select', 'show' or similar
        const rows = arguments[1],
          columns = arguments[2];
        conn.writeTextResult(rows, columns);
      } else {
        // response to an 'insert', 'update' or 'delete'
        const result = arguments[1];
        conn.writeOk(result);
      }
    });
  });

  conn.on("end", remote.end.bind(remote));
});

Connecting a wordpress site, when loading, it fires a few sql queries and I see:

connection
SELECT @@SESSION.sql_mode

Warning: got packets out of order. Expected 6 but received 0
SET SESSION sql_mode='IGNORE_SPACE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Warning: got packets out of order. Expected 2 but received 0
events.js:291
      throw er; // Unhandled 'error' event
      ^

Error: Connection lost: The server closed the connection.
    at Socket.<anonymous> (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:91:31)
    at Socket.emit (events.js:314:20)
    at TCP.<anonymous> (net.js:673:12)
Emitted 'error' event on Connection instance at:
    at Connection._notifyError (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:221:12)
    at Socket.<anonymous> (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:97:12)
    at Socket.emit (events.js:314:20)
    at TCP.<anonymous> (net.js:673:12) {
  fatal: true,

Now, if i reset the sequence id at the end of the remote.query, it gets s lot further (successfully completes multiple sql statements and then fails with the same error. Here is the code with the addition:

conn.on("query", (sql) => {
    console.log(`${sql}\n`);
    conn.sequenceId = 1;
    remote.query(sql, function (err) {
      // overloaded args, either (err, result :object)
      // or (err, rows :array, columns :array)
      if (Array.isArray(arguments[1])) {
        // response to a 'select', 'show' or similar
        const rows = arguments[1],
          columns = arguments[2];
        conn.writeTextResult(rows, columns);
      } else {
        // response to an 'insert', 'update' or 'delete'
        const result = arguments[1];
        conn.writeOk(result);
      }
      conn.sequenceId = 0;
    });
  });

Here is the output when executing with the additional conn.sequenceId = 0;:

connection
SELECT @@SESSION.sql_mode

SET SESSION sql_mode='IGNORE_SPACE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Warning: got packets out of order. Expected 2 but received 0
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'

SELECT option_value FROM wp_options WHERE option_name = 'WPLANG' LIMIT 1

SELECT * FROM wp_users WHERE user_login = 'ben' LIMIT 1

SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (1) ORDER BY umeta_id ASC

SELECT option_value FROM wp_options WHERE option_name = 'can_compress_scripts' LIMIT 1

SELECT option_value FROM wp_options WHERE option_name = 'theme_switched' LIMIT 1

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')  ORDER BY wp_posts.post_date DESC LIMIT 0, 10

SELECT FOUND_ROWS()

SELECT wp_posts.* FROM wp_posts WHERE ID IN (1)

SELECT  t.*, tt.*, tr.object_id FROM wp_terms AS t  INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format') AND tr.object_id IN (1) ORDER BY t.name ASC 

SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (1) ORDER BY meta_id ASC

SELECT option_value FROM wp_options WHERE option_name = '_site_transient_update_plugins' LIMIT 1

SELECT option_value FROM wp_options WHERE option_name = '_site_transient_update_themes' LIMIT 1

SELECT option_value FROM wp_options WHERE option_name = '_site_transient_update_core' LIMIT 1


                SELECT comment_approved, COUNT( * ) AS total
                FROM wp_comments

                GROUP BY comment_approved


SELECT * FROM wp_posts  WHERE (post_type = 'page' AND post_status = 'publish')     ORDER BY menu_order,wp_posts.post_title ASC

SELECT   wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish'))  ORDER BY wp_posts.post_date DESC LIMIT 0, 5

SELECT  wp_comments.comment_ID FROM wp_comments JOIN wp_posts ON wp_posts.ID = wp_comments.comment_post_ID WHERE ( comment_approved = '1' ) AND  wp_posts.post_status IN ('publish')  ORDER BY wp_comments.comment_date_gmt DESC LIMIT 0,5

SELECT wp_comments.* FROM wp_comments WHERE comment_ID IN (1)

SELECT comment_id, meta_key, meta_value FROM wp_commentmeta WHERE comment_id IN (1) ORDER BY meta_id ASC

SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM wp_posts  WHERE post_type = 'post' AND post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC 

SELECT  t.*, tt.* FROM wp_terms AS t  INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('category') AND tt.count > 0 ORDER BY t.name ASC 

SELECT term_id, meta_key, meta_value FROM wp_termmeta WHERE term_id IN (1) ORDER BY meta_id ASC

events.js:291
      throw er; // Unhandled 'error' event
      ^

Error: Connection lost: The server closed the connection.
    at Socket.<anonymous> (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:91:31)
    at Socket.emit (events.js:314:20)
    at TCP.<anonymous> (net.js:673:12)
Emitted 'error' event on Connection instance at:
    at Connection._notifyError (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:221:12)
    at Socket.<anonymous> (/Users/VisualStudio/node_modules/mysql2/lib/connection.js:97:12)
    at Socket.emit (events.js:314:20)
    at TCP.<anonymous> (net.js:673:12) {
  fatal: true,
  code: 'PROTOCOL_CONNECTION_LOST'
}

So it looks like we are not handling the sequenceId’s correctly. We would be very grateful for some advice 👍

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:17 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
sidorarescommented, Sep 21, 2020

1 is for COM_QUIT - php client might be closing connection ( and 3 is COM_QUERY )

thanks for more debug examples, investigating right now

1reaction
sidorarescommented, Sep 15, 2020

Hi @haganbt , thanks for more debug info

simple php mysqli “select 1+1” script worked for me with a server from https://github.com/sidorares/node-mysql2/tree/passthrough-auth-token branch. I’m currently attempting to provide example that would work with master

Read more comments on GitHub >

github_iconTop Results From Across the Web

PHP mysqli connect() Function - W3Schools
The connect() / mysqli_connect() function opens a new connection to the MySQL server. Syntax. Object oriented style: $mysqli -> new mysqli(host, username, ...
Read more >
Connections - Manual - PHP
Every PHP process is using its own mysqli connection pool. Depending on the web server deployment model, a PHP process may serve one...
Read more >
PHP Connect to MySQL Server - Tutorial Republic
In this tutorial you will learn how to connect to the MySQL server using PHP. ... PHP offers two different ways to connect...
Read more >
How to connect properly using mysqli - Treating PHP Delusions
On your local server it could be anything, while on a live site again it should be given to you by the admin...
Read more >
MySQLi - Connection - Tutorialspoint
You can establish the MySQL database using the mysql binary at the command prompt. Example. Here is a simple example to connect to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found