Closed DeltaVetal26 closed 6 years ago
Hey there,
It looks like the mysql server is timing out. I don't know how your script is supposed to work but mysql will close the connection if it doesn't receive any request for some time.
I guess you could increase the wait_timeout or set PDO::ATTR_PERSISTENT to true using R::getDatabaseAdapter()->getDatabase()->getPDO()->setAttribute()
.
You could also (and that's how I'd do it I think) check if the connection is still active and reconnect if needed before making a request.
Note: I may be wrong and the issue may lie elsewhere.
Lyn
@Lynesth
Thanks for the advice! I increased wait_timeout from 10 to 30 seconds, after 7 requests I saw this warning again. How can I make sure that the connection was active? The request was successful even when a warning was displayed.
Hmmm, just to make sure we're hunting the right issue, could you call those before executing your requests, which should force closing and reopening the connection:
R::getDatabaseAdapter()->getDatabase()->close();
R::getDatabaseAdapter()->getDatabase()->connect();
Let me know if this fixes your problem.
@Lynesth
Now everything works without warnings) Is this the final solution to the problem or disguise? I'm curious what caused this problem
Ok so there currently isn't a way to do that directly using RedBean but here are different approaches:
1) Use a very high timeout 2) Use the previous code I gave you, disconnecting from the DB and reconnecting each time 3) Make a dummy query to check if you need to reconnect. Something like this:
// Just to prevent repeating this every time assign it to a variable before the loop if possible
$dbHandler = R::getDatabaseAdapter()->getDatabase();
// Then before making your queries, do something like
try {
$dbHandler->getPDO()->query( 'SELECT 1' );
} catch (PDOException $e) {
$dbHandler->close();
$dbHandler->connect();
}
// Your queries
Not sure which would be the most efficient.
@gabordemooij I think we need a real testConnection() functions that actually tests the connection ;)
@Lynesth
I will use the previous code. Thank you very much!
@DeltaVetal26 No problem :)
I think the 3rd code might be the most efficient one (if it works, everything is untested) because making a simple SELECT statement is very light on data transfer and server load compared to a reconnect. So my guess would be that, unless you expect to have exceeded the timeout almost everytime, the 3rd code should be better.
@Lynesth
$dbHandler = R::getDatabaseAdapter()->getDatabase();
// Then before making your queries, do something like
try {
$dbHandler->getPDO()->query( 'SELECT owner FROM session WHERE evid = 001' );
} catch (PDOException $e) {
$dbHandler->close();
$dbHandler->connect();
}
$state = R::getCell( 'SELECT mode FROM evsmode WHERE prta = ? ', array($key));
$sess_db = R::dispense('session');
$sess_db->evid = $numb;
$sess_db->evcid = $stationid;
R::store($sess_db);
$statuscheck = R::findOne('session', evid = ?', array($numb));
The warning appears again. I did something wrong?
Ok so, my bad I forgot the @
. But you really just have to do a SELECT 1
to test the connection, it'll be very fast. Tell me if this works and removes the errors.
$dbHandler = R::getDatabaseAdapter()->getDatabase();
// Then before making your queries, do something like
try {
@$dbHandler->getPDO()->query( 'SELECT 1' );
} catch (PDOException $e) {
$dbHandler->close();
$dbHandler->connect();
}
$state = R::getCell( 'SELECT mode FROM evsmode WHERE prta = ? ', array($key));
$sess_db = R::dispense('session');
$sess_db->evid = $numb;
$sess_db->evcid = $stationid;
R::store($sess_db);
$statuscheck = R::findOne('session', evid = ?', array($numb));
The problem was the absence of @. Now all is well. Thank you! :)
No problem ;)
Don't close the issue yet though, I'd like to have @gabordemooij's opinion on this.
We could extend the testConnection function to test a specific SQL scenario maybe?
However, the MySQL server should not behave this way. You have to figure out why the connection is lost. Have you checked your max allowed packet setting?
[mysqld]
max_allowed_packet=16M
@gabordemooij
Yes
This problem occurs in different places. First everything is in order, after several requests a warning may appear. @Lynesth helped me solve the problem by checking the connection before queries to the database
If I guessed correctly, you are using https://github.com/walkor/Workerman which is some script that runs in an endless loop waiting for requests. You first start a database connection then use it when needed but if the time between 2 requests to that script is too long, the MySQL connection will be closed, hence the error.
You could try using Workerman's Timer to "ping" the database every X seconds with a simple SELECT 1
(or even DO 1
to keep it even shorter). This should prevent the issue you're encountering. You could even reset the timer if a real request has been made so that you don't make too many of those.
Note: I don't know how to use Workerman, so not sure of the feasibility of the above ideas.
@Lynesth
Yes. This is a WebSocket server through which I manage devices. Every time I connect to this server, authorization with requests to the database is performed. It uses a loop.
Your code fixed the problem, and now I do not see any warnings.
Hi!
I'm using RedBean for my WebSocket server and often see this warning when I run queries against the database:
This does not always happen, only after a few requests. How to fix it?
I`m using: