My MariaDB server is timing out my C++ client (using libmariadb) after 600 seconds (10 minutes) of inactivity, and I'm not sure why, because I can't find any configured timeouts that specify that number.
Here's my code, where I execute a simple SELECT query, wait 11 minutes, then run that same query again and get a "server gone" error:
#include <iostream>
#include <unistd.h>
#include <errmsg.h>
#include <mysql.h>
int main(int, char**)
{
// connect to the database
MYSQL* connection = mysql_init(NULL);
my_bool reconnect = 0;
mysql_options(connection, MYSQL_OPT_RECONNECT, &reconnect); // don't implicitly reconnect
mysql_real_connect(connection, "127.0.0.1", "testuser", "password",
"my_test_db", 3306, NULL, 0);
// run a simple query
mysql_query(connection, "select 5");
mysql_free_result(mysql_store_result(connection));
std::cout << "First query done...\n";
// sleep for 11 minutes
sleep(660);
// run the query again
if(! mysql_query(connection, "select 5"))
{
std::cout << "Second query succeeded after " << seconds << " seconds\n";
mysql_free_result(mysql_store_result(connection));
}
else
{
if(mysql_errno(connection) == CR_SERVER_GONE_ERROR)
{
// **** this happens every time ****
std::cout << "Server went away after " << seconds << " seconds\n";
}
}
// close the connection
mysql_close(connection);
connection = nullptr;
return 0;
}
The stdout of the server process reports that it timed out my connection:
$ sudo journalctl -u mariadb
...
Jul 24 17:58:31 myhost mysqld[407]: 2018-07-24 17:58:31 139667452651264 [Warning] Aborted connection 222 to db: 'my_test_db' user: 'testuser' host: 'localhost' (Got timeout reading communication packets)
...
Looking at a tcpdump capture, I can also see the server sending the client a TCP FIN packet, which closes the connection.
The reason I'm stumped is because I haven't changed any of the default timeout values, none of which are even 600 seconds:
MariaDB [(none)]> show variables like '%timeout%';
+-------------------------------------+----------+
| Variable_name | Value |
+-------------------------------------+----------+
| connect_timeout | 10 |
| deadlock_timeout_long | 50000000 |
| deadlock_timeout_short | 10000 |
| delayed_insert_timeout | 300 |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_print_lock_wait_timeout_info | OFF |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| thread_pool_idle_timeout | 60 |
| wait_timeout | 28800 |
+-------------------------------------+----------+
So why is the server timing out my connection? Based on the documentation, I would have thought it would have been because of the wait_timeout server variable, but it's left at the default of 8 hours...
BTW I'm using MariaDB 10.0 and libmariadb 2.0 (from the Ubuntu Xenial Universe repo)
Edit: here's an image of a tcpdump capture catching the disconnect. My Wireshark filter is tcp.port == 55916, so I'm looking at traffic to/from this one client connection. The FIN packet that the server sends is packet 1199, exactly 600 seconds after the previous packet (884).
wait_timeout is tricky. From the same connection do
SHOW SESSION VARIABLES LIKE '%timeout%';
SHOW SESSION VARIABLES WHERE VALUE BETWEEN 500 AND 700;
You should be able to workaround the issue by executing
mysql_query("SET ##wait_timeout = 22222");
Are you connected as 'root' or not?
More connector details:
See: https://dev.mysql.com/doc/refman/5.5/en/mysql-options.html
CLIENT_INTERACTIVE: Permit interactive_timeout seconds of inactivity (rather than wait_timeout seconds) before closing the connection. The client's session wait_timeout variable is set to the value of the session interactive_timeout variable.
https://dev.mysql.com/doc/relnotes/connector-cpp/en/news-1-1-5.html (MySQL Connector/C++ 1.1.5)
It is also possible to get and set the statement execution-time limit using the MySQL_Statement::getQueryTimeout() and MySQL_Statement::setQueryTimeout() methods.
There may also be a TCP/IP timeout.
I'm not sure about the exact reason. But I'm sure wait_timeout is not the only thing which has an effect on this. According to the only error message you have included in your question, it seems like there was a problem reading the packet.
Got timeout reading communication packets
I believe it was more like MariaDB had an issue reading the packet rather than attempting to connect or so. I also had a look at the MariaDB client library, and found this block;
if (ma_net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg), 0))
{
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
{
my_set_error(mysql, CR_NET_PACKET_TOO_LARGE, SQLSTATE_UNKNOWN, 0);
goto end;
}
end_server(mysql);
if (mariadb_reconnect(mysql))
goto end;
if (ma_net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg), 0))
{
my_set_error(mysql, CR_SERVER_GONE_ERROR, SQLSTATE_UNKNOWN, 0);
goto end;
}
}
https://github.com/MariaDB/mariadb-connector-c/blob/master/libmariadb/mariadb_lib.c
So it seems like it sets the error code to server gone away when it get a packet size issue. I suggest you to change the max_allowed_packet variable to some large value and see whether it has any effect.
SET ##global.max_allowed_packet = <some large value>;
https://mariadb.com/kb/en/library/server-system-variables/#max_allowed_packet
I hope it will help, or at least it will set you in some path to solve the problem :) and finally, I think you should handle the disconnects in your code rather than relying on the timeouts.
Galera cluster with Haproxy Load balancing. Change this parameter on haproxy
settings
defaults
timeout connect 10s
timeout client 30s
timeout server 30s
Related
I am trying to connect to a MySql RDS instance from a Lambda function and getting an ETIMEDOUT error
The Lambda is not part of a VPC
The RDS instance is available publicly, I can connect to it from my laptop using MySqlWorkbench
The RDS instance's security group has inbound rules configured for all ports and 0.0.0.0/0
The Lambda's execution role has many policies (probably too many) including RDSFullAccess, LambdaVPCAccessExecutionRole, ec2:*, even AdministratorAccess!)
Again, the code executes locally, connects to and queries the RDS instance just fine. Executing the same code in Lambda throws the ETIMEDOUT error
Similar posts are resolved by adding the Lambda to the RDS instance's VPC, or by configuring the inbound rules on the database's security group. Nothing seems to work.
Since I can connect to the database from my laptop just fine, my hunch is that it's a problem with the Lambda
Are there additional policies I should attach to the Lambda's execution role?
Is there any other reason the Lambda would time out connecting to a publicly available database?
Additional info:
The Lambda is not running in a VPC. It runs on Node and connects to MySql using the mysql package v2.18.1 and is deployed using Serverless with the following config:
foo:
handler: functions/handlers.foo
timeout: 20
events:
- http:
path: /path/{pathParameter}/foo
method: get
cors: true
caching:
enabled: true
ttlInSeconds: 3600
cacheKeyParameters:
- name: request.path.pathParameter
In the Lambda I try connecting with this function (which, again, works fine when I execute the function on my laptop):
function openDbConnection() {
let connection = mysql.createConnection({
host: 'db-name.cgwxrjuo6oyd.us-east-1.rds.amazonaws.com',
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: 'db-name'
});
try {
connection.connect(function(err) {
console.log("Database is ", connection.state)
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
} catch (error) {
console.log("Database is ", connection.state)
console.log("Error connecting to MySql: ", error);
}
return connection;
}
The database username and password are retrieved from environment variables that are published to the Lambda with Serverless using a .env.yml file:
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: '20201221'
environment: ${file(.env.yml):}
Below are the Cloudwatch logs for a single execution, which I'm having trouble making sense of. Entries appear out of sequence:
| timestamp | message |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1626209636788 | START RequestId: e3e3ceb7-bb55-4c3e-8392-38e08401f679 Version: $LATEST |
| 1626209636791 | 2021-07-13T20:53:56.790Z adfc1cd5-e4be-40b7-970c-d38acabeb199 INFO Database is disconnected |
| 1626209636791 | 2021-07-13T20:53:56.791Z adfc1cd5-e4be-40b7-970c-d38acabeb199 ERROR error: connect ETIMEDOUT |
| 1626209636791 | 2021-07-13T20:53:56.791Z adfc1cd5-e4be-40b7-970c-d38acabeb199 INFO An error occured querying MySql: connect ETIMEDOUT |
| 1626209636792 | 2021-07-13T20:53:56.792Z adfc1cd5-e4be-40b7-970c-d38acabeb199 INFO Database is disconnected |
| 1626209636792 | 2021-07-13T20:53:56.792Z adfc1cd5-e4be-40b7-970c-d38acabeb199 ERROR error: Connection lost: The server closed the connection. |
| 1626209636793 | 2021-07-13T20:53:56.792Z adfc1cd5-e4be-40b7-970c-d38acabeb199 INFO An error occured querying MySql: Connection lost: The server closed the connection. | 1626209636803 | END RequestId: e3e3ceb7-bb55-4c3e-8392-38e08401f679 |
| 1626209636803 | REPORT RequestId: e3e3ceb7-bb55-4c3e-8392-38e08401f679 Duration: 9.32 ms Billed Duration: 10 ms Memory Size: 1024 MB Max Memory Used: 79 MB |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I'm using Salt to provision cloud servers but I'm having problems with MySQLdb producing the correct permissions for MySQL. If I was executing the SQL directly it would be:
GRANT ALL ON `install\_%`.* TO 'installer'#'localhost';
The sls file contains:
installer_local_install_grants:
mysql_grants.present:
- grant: all privileges
- database: install\_%.*
- user: installer
- host: localhost
- escape: False
Which produces this error:
Function: mysql_grants.present
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1560, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/states/mysql_grants.py", line 187, in present
grant, database, user, host, grant_option, escape, ssl_option, **connection_args
File "/usr/lib/python2.7/dist-packages/salt/modules/mysql.py", line 1666, in grant_add
_execute(cur, qry['qry'], qry['args'])
File "/usr/lib/python2.7/dist-packages/salt/modules/mysql.py", line 505, in _execute
return cur.execute(qry, args)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
TypeError: * wants int
With debug in salt turned on the relevant line prior to submitting to MySQLdb is:
Doing query: GRANT ALL PRIVILEGES ON install\_%.* TO %(user)s#%(host)s args: {'host': 'localhost', 'user': 'installer'}
So it seems Salt is outputting the correct code but MySQLdb is not handling some part of the query correctly. The query is missing the back ticks but I'm really not sure how to get those in.
With the escape removed or set to True the grants look like:
+-----------+-----------------+------------------+
| Host | Db | User |
+-----------+-----------------+------------------+
| localhost | install\\_\% | installer |
+-----------+-----------------+------------------+
When it should look like:
+-----------+-----------------+------------------+
| Host | Db | User |
+-----------+-----------------+------------------+
| localhost | install\_% | installer |
+-----------+-----------------+------------------+
OK, would you open an issue referencing this SO post? Thanks!
https://github.com/saltstack/salt/issues/new
Firstly please apologies for how vague this post may be but I'm completely at a loss as to what could be occurring here.
I've been having an issue with a site I've developed for a client where it seemingly, randomly loses connection to the MySQL server and requires a reboot of the server for the site to become available again.. I've a number of other SS sites in my portfolio and not a single other one has experienced this before.
The site can run for a few days or an hour or sometimes a couple of weeks before having this issue and I've not been able to pin down what actually triggers it, though it appears to be related to some kind of usage of the CMS. The client will report that it will lose the connection when he's trying to upload a photo or write a blog post. I've posted the error at the bottom of the post to not clutter things.
Thinking it was an issue with the server set up, I set up a brand new digital ocean droplet and migrated the site over to there, but the issue remains so it leads me to believe it's something within the framework or my site config (old server was running on CentOs and the new one is Ubuntu).
This is the only site I have set up using composer. A novice to composer, I followed the instructions on the SS site to achieve this. My composer.json is below. Does it look like I have any issues here?:
{
"name": "silverstripe/installer",
"description": "The SilverStripe Framework Installer",
"require": {
"php": ">=5.3.2",
"silverstripe/cms": "3.1.6",
"silverstripe/framework": "3.1.6",
"silverstripe-themes/simple": "*",
"silverstripe/blog": "dev-master",
"undefinedoffset/sortablegridfield": "dev-master"
},
"config": {
"process-timeout": 600
},
"minimum-stability": "dev"
}
I've not made any changes to the core. Nothing unusual in there but my _config.php is:
<?php
global $project;
$project = 'mysite';
global $databaseConfig;
$databaseConfig = array(
"type" => 'MySQLDatabase',
"server" => 'localhost',
"username" => 'root',
"password" => 'xxxxxx',
"database" => 'mysite',
"path" => '',
);
// Set the site locale
i18n::set_locale('en_US');
Director::set_environment_type('dev');
Security::setDefaultAdmin("fraser","xxxxxxx");
Can anyone think of any reason why the connection would be dropping to the MySQL server? Is there anything else I should check? Do you need any more information from me?
[Warning] mysqli::mysqli(): (HY000/2003): Can't connect to MySQL server on '127.0.0.1' (111)
GET /
Line 68 in /var/www/mysite/framework/model/MySQLDatabase.php
Source
59 * - password: The password to log on with
60 * - database: The database to connect to
61 * - timezone: (optional) The timezone offset. For example: +12:00, "Pacific/Auckland", or "SYSTEM"
62 */
63 public function __construct($parameters) {
64 if(!empty($parameters['port'])) {
65 $this->dbConn = new MySQLi($parameters['server'], $parameters['username'], $parameters['password'],
66 '', $parameters['port']);
67 } else {
68 $this->dbConn = new MySQLi($parameters['server'], $parameters['username'], $parameters['password']);
69 }
70
71 if($this->dbConn->connect_error) {
72 $this->databaseError("Couldn't connect to MySQL database | " . $this->dbConn->connect_error);
73 }
74
Trace
mysqli->mysqli(<filtered>,<filtered>,<filtered>)
MySQLDatabase.php:68
MySQLDatabase->__construct(Array)
DB.php:174
DB::connect(<filtered>)
main.php:127
{closure}(ErrorControlChain)
call_user_func(Closure,ErrorControlChain)
ErrorControlChain.php:125
ErrorControlChain->step()
ErrorControlChain.php:117
ErrorControlChain->execute()
main.php:154
require_once(/var/www/mysite/framework/main.php)
index.php:65
[User Error] Couldn't connect to MySQL database | Can't connect to MySQL server on '127.0.0.1' (111)
GET /
Line 598 in /var/www/mysite/framework/model/MySQLDatabase.php
Source
589 }
590
591 public function databaseError($msg, $errorLevel = E_USER_ERROR) {
592 // try to extract and format query
593 if(preg_match('/Couldn\'t run query: ([^\|]*)\|\s*(.*)/', $msg, $matches)) {
594 $formatter = new SQLFormatter();
595 $msg = "Couldn't run query: \n" . $formatter->formatPlain($matches[1]) . "\n\n" . $matches[2];
596 }
597
598 user_error($msg, $errorLevel);
599 }
600
601 /**
602 * Return a boolean type-formatted string
603 *
604 * #param array $values Contains a tokenised list of info about this data type
Trace
Couldn't connect to MySQL database | Can't connect to MySQL server on '127.0.0.1' (111)
MySQLDatabase.php:598
MySQLDatabase->databaseError(Couldn't connect to MySQL database | Can't connect to MySQL server on '127.0.0.1' (111))
MySQLDatabase.php:72
MySQLDatabase->__construct(Array)
DB.php:174
DB::connect(<filtered>)
main.php:127
{closure}(ErrorControlChain)
call_user_func(Closure,ErrorControlChain)
ErrorControlChain.php:125
ErrorControlChain->step()
ErrorControlChain.php:117
ErrorControlChain->execute()
main.php:154
require_once(/var/www/mysite/framework/main.php)
index.php:65
I use Xcode 3.2.1 (I am on snow leopard for some reasons) with mysql :
Server version: 5.6.15 MySQL Community Server (GPL) +
mysql-connector-c-6.1.3-osx10.6-x86_64
I am passing a request to mysql_query() as follows.
// mysql request
request = [NSString stringWithFormat:#"UPDATE consult SET summary='%#', pheno='%#' WHERE idConsult=%#", sum, phe, idc];
if (mysql_query(mysqlCnx,[request UTF8String])) {
db_finish_with_error(mysqlCnx);
}
When the request size is more than 4MB, I get a SIGPIPE with the following stack trace :
#0 0x7fff896d791e in sendto
#1 0x100065a92 in vio_write
#2 0x10004d2a2 in net_write_packet
#3 0x10004d3ac in net_write_buff
#4 0x10004d6e2 in net_write_command
#5 0x100048e3c in cli_advanced_command
#6 0x100046bdd in mysql_real_query
#7 0x1000093f9 in -[ConsultList mysqlUpdateResumePhenoFields:] at ConsultList.m:163
4#8 0x10000a565 in -[ConsultList okConsult:] at ConsultList.m:367
Any known issue ?
Here was the solution :
/etc/my.cnf
[mysqld]
max_allowed_packet=120M
as root :
chown 644 /etc/my.cnf
mysql> set global max_allowed_packet = 125829120;
Query OK, 0 rows affected (0,00 sec)
mysql> show variables like 'max_allowed_packet';
+--------------------+-----------+
| Variable_name | Value |
+--------------------+-----------+
| max_allowed_packet | 125829120 | << 120MB !
+--------------------+-----------+
I have got the following exception
Mysql Caught Exception = Can't create UNIX socket (24).
I know that UNIX system error 24. That's "too many open files."
I refered this question ,:OperationalError: (2001, "Can't create UNIX socket (24)")
But I need to understand the exact problem.
In my code I execute multiple select query and store the result,not using free_result method in between.
Can it be the case of this error : Can't create UNIX socket (24)
Here is my code :
pthread_mutex_lock(&mysqlMutex);
mysql = mysql_init(NULL);
my_bool reconnect = 1;
MYSQL* connection;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
connection = mysql_real_connect( server,user,password, database_name, 0, NULL, 0 );
if(connection == NULL)
{
//Connection failed.Exception Handling
}
//Execute query :SELECT * from user ;
mysql_query(mysql, getuser_query);
MYSQL_RES *mysql_res = mysql_store_result(mysql);
// Query # 2
// SELECT * from usergroup.
mysql_query(m_pMysql, userGroup_query);
mysql_res = mysql_store_result(mysql);
// Query # 3
// Query # 4
At the last:
//free mysql memory
mysql_free_result(mysql_res);
mysql_close(mysql);
pthread_mutex_unlock(&mysqlMutex);
You are perhaps opening too many simultaneous connections to mysql server. You need to increase available FDs to mysql process. You can usually do so with /etc/security/limits* in your linux distro.
You can also look at this question: Mysql decrease opened files