bind9+dlz+mysql连接断开问题

前言

关于bind-dlz介绍:http://bind-dlz.sourceforge.net/

DLZ(Dynamically Loadable Zones)与传统的BIND9不同,BIND的不足之处:

  1. BIND从文本文件中获取数据,这样容易因为编辑错误出现问题。
  2. BIND需要将数据加载到内存中,如果域或者记录较多,会消耗大量的内存。
  3. BIND启动时解析Zone文件,对于一个记录较多的DNS来说,会耽误更多的时间。
  4. 如果近修改一条记录,那么要重新加载或者重启BIND 才能生效,那么需要时间,可能会影响客户端查询。

而Bind-dlz 即将帮你解决这些问题,对Zone文件操作也更方便了,直接对数据库操作,可以很方便扩充及开发管理程序。

bind-dlz的相关配置就不说了,网上一大堆,推荐两个:

问题描述

bind9+dlz+mysql配置好正常使用没什么问题,但是当使用了一段时间(都是隔夜)之后再次解析之前的域名发现解析不了,查看日志/var/log/messages,发现如下错误信息:

localhost named[42406]: mysql driver unable to return result set for findzone query

经查询资料得知是因为dlz在连接mysql之后,由于连接的空闲时间达到mysql的最大空闲时间,被mysql强行断开导致无法再从mysql获取数据。关键是DLZ在断开之后不会重连,这就不得不重启named服务重新与mysql建立连接了。

但明显这个办法不靠谱,想到的解决方案大概有下面几种:

  • 1.更换成其他数据库
  • 2.修改wait_timeout为更大值,24天左右
  • 3.重启named服务
  • 4.保持连接的使用,定期进行查询
  • 5.修改dlz源码,加入数据库重连功能

更换数据库暂时不考虑;修改mysql的wait_timeout也不能解决根本问题;第3个就不说了;第四个我试了下,写了一个脚本定时请求bind解析域名,想让连接不超时,但是最后证明这种办法不行,不知道是不是方式不对;最后一种是实在没有办法了,硬着头皮打开了源码。。。

解决方案

。。。好吧,没有想象中的那么难,找到bind-9.6.0-P1/contrib/dlz/drivers/dlz_mysql_driver.c,大致读了下,配合资料 C中MySQL自动重新连接(部分zz),在dlz_mysql_driver.c的mysql_create函数中加入了重连的代码,完整函数内容:

/*%
 * create an instance of the driver.  Remember, only 1 copy of the driver's
 * code is ever loaded, the driver has to remember which context it's
 * operating in.  This is done via use of the dbdata argument which is
 * passed into all query functions.
 */
static isc_result_t
mysql_create(const char *dlzname, unsigned int argc, char *argv[],
         void *driverarg, void **dbdata)
{
    isc_result_t result;
    dbinstance_t *dbi = NULL;
    char *tmp = NULL;
    char *dbname = NULL;
    char *host = NULL;
    char *user = NULL;
    char *pass = NULL;
    char *socket = NULL;
    int port;
    MYSQL *dbc;
    char *endp;
    int j;
    unsigned int flags = 0;
    //新增部分:定义了一个value
    char value = 1;

    UNUSED(driverarg);
    UNUSED(dlzname);

    ...

    tmp = getParameterValue(argv[1], "space=");
    if (tmp != NULL) {
        if (strcasecmp(tmp, "ignore") == 0)
            flags = flags | CLIENT_IGNORE_SPACE;
        isc_mem_free(ns_g_mctx, tmp);
    }

    //新增部分:重连的代码
    /* reconnect to mysql */
    result = mysql_options((MYSQL *)dbi->dbconn, MYSQL_OPT_RECONNECT, (char *)&value);
    if( result != 0 )
    {
        isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
                  DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
                  "mysql_options reconnect failed!");
        result = ISC_R_FAILURE;
        goto full_cleanup;
    }

    dbc = NULL;
    host = getParameterValue(argv[1], "host=");
    user = getParameterValue(argv[1], "user=");
    pass = getParameterValue(argv[1], "pass=");
    socket = getParameterValue(argv[1], "socket=");

    for (j=0; dbc == NULL && j < 4; j++)
        dbc = mysql_real_connect((MYSQL *) dbi->dbconn, host,
                     user, pass, dbname, port, socket,
                     flags);

    /* let user know if we couldn't connect. */
    if (dbc == NULL) {
        isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
                  DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
                  "mysql driver failed to create "
                  "database connection after 4 attempts");
        result = ISC_R_FAILURE;
        goto full_cleanup;
    }

    ...
}

附上mysql关于c语言的官方文档: https://dev.mysql.com/doc/refman/5.6/en/mysql-real-connect.html

改完之后重新编译安装就好了,经过测试,第二天来发现域名仍然可以正常解析。问题暂时解决,后面再观察一下。

原文地址:https://www.cnblogs.com/nickhan/p/9849687.html

时间: 2024-11-05 13:38:27

bind9+dlz+mysql连接断开问题的相关文章

Mysql网络断开重连问题

最近做一个项目的后台守护程序,需要多线程对mysql数据库服务进行操作,为了加强守护撑的健壮性,特地连接成功后拔掉网线,然后测试守护程序断开重新连接的健壮性,可是发现网络断开后,重新插上网线,用mysql_real_conncet进行重新连接返回的永远是假,也就是重新连接失败,之后我想断开网络后重新将mysql连接释放(mysql_close(MYSQL )),并重新初始化mysql_init((MYSQL )),然后再用mysql_real_conncet()函数进行连接,但是这样做的后果是m

mysql连接的空闲时间超过8小时后 MySQL自动断开该连接解决方案 详细出处参考:http://www.jb51.net/article/32284.htm

MySQL 的默认设置下,当一个连接的空闲时间超过8小时后,MySQL 就会断开该连接,而 c3p0 连接池则以为该被断开的连接依然有效.在这种情况下,如果客户端代码向 c3p0 连接池请求连接的话,连接池就会把已经失效的连接返回给客户端,客户端在使用该失效连接的时候即抛出异常 解决这个问题的办法有三种: 1. 增加 MySQL 的 wait_timeout 属性的值. 修改 /etc/mysql/my.cnf文件,在 [mysqld] 节中设置: # Set a connection to w

MySql连接空闲8小时自动断开引起的问题

一.问题描述 ? 最近遇到了一个奇怪的MySql数据库问题,好几次前一天晚上历史数据还正常存储,第二天早上来了看实时数据存储还正常,历史数据不存储了.找了好久也没找到问题.后来仔细想了想,历史数据设置了变化才存储,是不是数据一直不变,就一直没有往数据库写数据,导致MySql的连接太久不用自动断开了.然后就百度了一下,Mysql空闲连接有效时长,一看都说是8个小时就自动断开了.嗯,有点感觉了,应该就是这个原因. 二.问题排查 根据查到的资料查看MySql 有两个参数,可以设定空闲连接的有效时长,分

如何解决MySQL连接超时关闭

最近做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到MySQL的时候,发现MySQL的连接超时关闭了,于是就出现了"MySQL server has gone away"这样的错误提示,解决这个问题,我的经验有以下两点,或许对大家有用处: 第一种方法: 当然是增加你的 wait-timeout值,这个参数是在my.cnf(在Windows下台

nodejs使用MYSQL连接池,断线重连

两种方式解决1.你可以配置mysql的连接池 var mysql = require('mysql'); var pool = mysql.createPool({ host: 'localhost', user: 'nodejs', password: 'nodejs', database: 'nodejs', port: 3306 }); var selectSQL = 'select * from t_user limit 10'; pool.getConnection(function

bind+dlz+mysql实现区域记录动态更新

BIND-DLZ实验:http://bind-dlz.sourceforge.net/ 实验环境:RHEL4,BIND-9.5.0-P2.tar.gz(9.4.0以上版本都已含DLZ补丁),Mysql-5.0.56.tar.gz 1.安装mysql(先安装gcc等相关软件包) #tar zxvf mysql-5.0.56.tar.gz    #cd mysql-5.0.56   #./configure --prefix=/usr/local/mysql --localstatedir=/usr

mysql连接超时问题

前几天使用个脚本不停的查看redis队列中的事件.如果有则把事件取出来,然后进行一些数据库操作. 后来发现,每天的第一次有事件时都会到导致,找不到数据. 后来定位到问题,是mysql在连接长时间无活动的情况下,将连接断开.php在有事件,准备从数据库中获取数据时,捕获到mysql已断开的错误. 解决方案有两个: 修改mysql配置文件,my.cnf [mysqld] interactive_timeout=600 wait_timeout=600 两个参数都要同时设置. 相关参考:http://

MySql连接异常解决

这两天遇到一个mysql连接的问题,找人弄了好几天也没弄好,先看一下报错信息: ==================================================================== org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.h

一则线上MySql连接异常的排查过程

Mysql作为一个常用数据库,在互联网系统应用很多.有些故障是其自身的bug,有些则不是,这里以前段时间遇到的问题举例. 问题 当时遇到的症状是这样的,我们的应用在线上测试环境,JMeter测试过程中,发现每次压力测试开始时访问低前几个http request请求会超时,而之后的请求持续测试中都不会.最后一点是Tomcat的log并没有报什么错误. 压测的内容就是起200线程不停的向这个http页面发送请求,这个页面逻辑也比较简单,会在后端向数据库插入一条数据,连接池采用阿里的Druid(这个坑