libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] How to avoid "mysql server has gone away"?


From: Nader Zeid
Subject: Re: [libmicrohttpd] How to avoid "mysql server has gone away"?
Date: Sun, 12 Mar 2023 15:03:55 -0400

I'm not a contributor to this project, I'm just chiming in.
 
There's a lot to nitpick in this code snippet and it would be helpful to see expire_sessions itself. But I think there might be an important pitfall here. It's not likely that your server is "shutting down". Like every database I've worked with in my entire life, MySQL has a timeout to how long a client connection can remain idle before the server decides to close it. You have the option of increasing that timeout server-side, but this won't solve your problem. Here are a few approaches you can take to solve the problem.
  1. You can create a database connection only when you need it, i.e. do not maintain a connection pool or keep any connections open when MHD workers aren't doing anything. This isn't performant or scalable but it's 100% fault tolerant. Your database can go down, up, disappear and your web app will persist happily. In this context that would mean you create and close the connection entirely within expire_sessions, instead of reusing a connection.
  2. Or, detect that the reused connection has "gone away" from within expire_sessions, and deal with it on-the-fly. There are two ways you can do this:
    1. Ping the database before you send any MySQL statement. If the ping fails, throw out the connection and start a new one. Not the most performant but disputably easier to track/debug.
    2. Or, send your MySQL statement like you're currently doing, but detect the error code or really any connection error, throw out the connection, create a new one, and retry the statement. This is probably the solution you're looking for but requires a significant refactor if you're using the MySQL API directly.
Hope that helps!
 
 
On 2023-03-12 10:13 am, klemens wrote:

During longer idle-times of the server, when no queries to
mysql happen, mysql is shutting down and the server stops
with the message "mysql server has gone away". I try to
avoid this by making a "select now()" query every hour or
so, but it seems, I can't get out of the eventloop, the
func expire_sessions() where the query is done, is never
called:

    MHD_start_daemon (  0,
                        55301,
                        &on_client_connect, myclient_ip,
                        &create_response, NULL,
                        MHD_OPTION_NOTIFY_COMPLETED, &expire_sessions, NULL,
                        MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int)120,
                        MHD_OPTION_CONNECTION_LIMIT, (unsigned int)50,
                        MHD_OPTION_END
                     );
    if (NULL == vbad)
        return (emsg ("Can't create daemon"));
    while (1)
    {
        expire_sessions ();
        max = 0;
        FD_ZERO (&rs);
        FD_ZERO (&ws);
        FD_ZERO (&es);
        if (MHD_YES != MHD_get_fdset (vbad, &rs, &ws, &es, &max))
            break; /* fatal internal error */
        if (MHD_get_timeout (vbad, &mhd_timeout) == MHD_YES)
        {
            tv.tv_sec = mhd_timeout / 1000;
            tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
            tvp = &tv;
        }
        else
            tvp = NULL;
        if (-1 == select (max + 1, &rs, &ws, &es, tvp))
        {
            if (EINTR != errno)
            abort ();
        }
        MHD_run (vbad);

Could anyone please point out, what I'm doing wrong here. Thanks in
advanve.

Klemens.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]