sidorares / node-mysql2

:zap: fast mysqljs/mysql compatible mysql driver for node.js
https://sidorares.github.io/node-mysql2/
MIT License
4.07k stars 619 forks source link

[Need help]Streamming rows problem #322

Open dsonet opened 8 years ago

dsonet commented 8 years ago

I'm using a pool, get one connection to fetch rows, use another one to update rows back to mysql. When the dataset is very small, like 100 rows, it works. But when it's little bigger, it stuck, the updateRow seems never invoked.any one could help?

pool.getConnection(function (err, conn) {
    conn.query("SELECT * FROM table")
            .on('result', function (row) {
                conn.pause()
                updateRow(row, function(){conn.resume()}) //update it back
            })
})
function updateRow(row, resume) {
    pool.getConnection(function (err, conn) {
        conn.query('UPDATE table SET ....', function(err, result) {
            resume()
        })
    })   
}
dougwilson commented 8 years ago

If you pasted the full code, then you are missing the conn.release() call in your updateRow, which would cause the pool to get exhausted. Add conn.release() right before resume().

dsonet commented 8 years ago

@dougwilson Thanks for your reply. I released connection in updateRow. Finally I figure it out. The problem here is caused by the MyISAM engine. It use table block. Since I opreation the same table.

dsonet commented 8 years ago

But still strange is that I tried replace the updateRow simple as

function updateRow(row, resume) {
    setTimeout(resume, 100)
}

It's seems never reach the 'end' events. usually lasts about 6 minutes then just stuck.

tienvx commented 8 years ago

If you want to see the real error:

var connection = mysql.createConnection(config.db);
connection
    .query(sql)
    .on('result', callback);

In my case, the error is: Error: Connection lost: The server closed the connection. Maybe SELECT * FROM table is too big for mysql for streaming, I changed to SELECT id FROM table and the error gone.

sidorares commented 8 years ago

@tienvx how big is result in your case ( number of rows and columns?) can you post a schema so I can try to replicate?

tienvx commented 8 years ago

Hey @sidorares , sorry the schema is private so I can not post it.

The table have 110k rows, 17 columns (including 1 longtext column). Also in my case, the code is

pool.getConnection(function (err, conn) {
    conn.query("SELECT id, a, b, c, d, e, f FROM table")
            .on('result', function (row) {
                conn.pause()
                pushRowToRabbitmq(function () {
                      conn.resume();
                });
            })
})

Not the same with @dsonet .Hope it help.

sidorares commented 8 years ago

ok I'll just try to test it on a some 17x110k table and get back for more help if unable to reproduce

Do you get any errors if you do non-streaming version?

var connection = mysql.createConnection(config.db);
connection.query(sql, callback);
tienvx commented 8 years ago

There are no errors with non-streaming version.

sidorares commented 8 years ago

can't reproduce. What's in your callback? Is it heavy? It's supposet to be executed 100k times