我的程序是一个线程化的Mysql C客户端(用lmysqlclient_r编译,并从main调用mysql_library_init()),它包括在一些Mysql数据库中搜索一些域名。
struct:
的数组names
中的域名(t_thconf *th
变量)
typedef struct s_thconf
{
t_conf *conf;
char *ext;
char *origin;
char *name;
} t_thconf;
struct t_conf只包含mysql配置,如host_ip,用户,端口......发送到mysql_real_connect()。
我使用此Thread pool处理域名,其中每次调用db_domains_query都是一个作业,并按如下方式推送到作业队列中:
...
printf("Making threadpool with %d threads\n", 100);
threadpool thpool = thpool_init(100);
while (i < (int)nb_domains)
{
printf("%d %s\n", i, th[i].name);
thpool_add_work(*thpool, (void *)db_domains_query, (void *)&th[i]);
while ((thpool_jobqueue_length(*thpool) > QUEUE_UNIT))
usleep(200);
i += 1;
}
...
// Process one domain name, check if it's existing and update it
void db_domains_query(void *arg)
{
thconf *th = (t_thconf *) arg;
char query[500];
char buff[500];
MYSQL *con = mysql_init(NULL);
if (!con)
{
fprintf(stderr, "mysql_init() failed\n");
finish_with_error(con);
}
if (mysql_real_connect(con, th->conf->server_ip, th->conf->user, th->conf->password, th->conf->database, (unsigned int)th->conf->port, NULL, 0) == NULL)
finish_with_error(con);
mysql_set_character_set(con, "utf8");
mysql_real_escape_string(con, buff, th->name, strlen(th->name));
sprintf(query, "SELECT Id, DomainName FROM domains where DomainName LIKE '%s';", buff);
// printf("Thread #%u working on the query = %s\n" (int)pthread_self(), query);
if (mysql_query(con, query))
finish_with_error(con);
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
finish_with_error(con);
MYSQL_ROW row;
if ((row = mysql_fetch_row(result)))
{
printf("Domain name is found : %s %s \n", row[0], row[1]);
}
...
mysql_thread_end();
mysql_free_result(result);
mysql_close(con);
return ();
}
如果要处理的域名数量非常合理(最多500,000),这部分代码效果很好。但是,如果我必须处理大量数据(例如&gt; 2,092,900 names
),则Mysql服务器似乎要求太多。
它拒绝我的客户,我收到错误&#34; #1040 - 连接太多&#34;,然后&#34;无法在&#39; ip&#39;&#34;上连接到MySQL服务器。
usleep(200)
只会延迟错误。
我的猜测是:
names
一样多。所以,我的问题是如何重用相同的连接,考虑到1个连接将等于1个线程?我如何调整我的代码以限制连接?
提前致谢。