前言
动态绑定器(dlz )与传统绑定器9不同,绑定器的缺点是:
由于BIND从文本文件中检索数据,因此容易因编辑错误而出现问题。
BIND需要将数据加载到内存中,域和记录过多会占用大量内存。
在BIND启动时解析Zone文件对于记录较多的DNS来说,会延迟更多的时间。
如果最近修改了一条记录,则重新加载或重新启动BIND以使其生效可能需要时间,并且可能会影响客户端查询。
Bind-dlz即将解决这些问题,也便于Zone文件的操作,可以直接对应数据库的操作,轻松扩展开发管理程序。
关于bind-dlz的结构自不必说,网上有很多,推荐两个:
问题的说明
bind9 dlz mysql配置为可以正常使用,但使用一段时间后,再次解析以前的域名时,发现无法解析。 查看日志/var/log/messages时,将显示类似于以下内容的错误消息:
localhost named [ 42406 ] : mysqldriverunabletoreturnresultsetforfindzonequery
经过调查,我们发现dlz连接到mysql后,由于连接的空闲时间达到了mysql的最大空闲时间,因此被强制断开与mysql的连接,无法从mysql中检索数据。 重要的是,DLZ在断开连接后不会重新连接。 必须重新启动named服务以重新建立与mysql的连接。
但是,显然这种方法不可靠。 可能的解决方案如下。
1 .更换为另一个数据库
将wait_timeout修改为更大的值,24天左右
重新启动名称服务
4 .保持连接使用,定期进行咨询
5 .修改dlz源代码并添加数据库重新连接功能
暂时不考虑数据库交换修改mysql的wait_timeout并不能解决根本问题; 第三个不说,第四个试了一下。 我想编写一个脚本,请求bind解析域名,以防止连接超时,但最后证明这种方法不行。 我不知道方法有没有错。 最后一个是无可救药,硬打开了源代码。
解决方案。 好了,没想象中那么难。 找到bind-9.6.0-P1/contrib/dlz/drivers/dlz _ MySQL _ driver.c,大致阅读,然后根据资料c中的MySQL自动重新连接()
/*%
* createaninstanceofthedriver.remember,only 1 copy of the driver's
* code is ever loaded,thedriverhastorememberwhichcontextit ' s
* operating in.thisisdoneviauseofthedbdataargumentwhichis
* passed into all query functions。
*/
static isc_result_t
MySQL_create(constchar*dlzname,unsigned int argc,char *argv[] ),
void *驱动程序arg,void * * db数据)
{
isc_result_t result;
db instance _ t * DBI=空值;
char *tmp=NULL;
char *dbname=NULL;
char *host=NULL;
char *user=NULL;
char *pass=NULL;
char *socket=NULL;
输入端口;
MYSQL *dbc;
char *endp;
int j;
未指定的int flags=0;
//新部分: value已定义
char value=1;
未使用(驱动程序arg );
unused(dlzname;
.
tmp=getparametervalue(argv[1],' space=';
if(tmp!=空) {
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 (结果!=0)
{
isc_log_write(DNS_lctx,DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ,ISC_LOG_ERROR,
' MySQL _ options连接失败!' );
result=ISC_R_FAILURE;
goto full_cleanup;
}
DBC=空;
host=getparametervalue(argv[1],' host=';
user=getparametervalue(argv[1],' user=' );
pass=getparametervalue(argv[1],' pass=';
socket=getparameter value (argv [1],' socket=';
for(j=0; dbc==NULL j 4; j )
DBC=MySQL_real_connect () MySQL* ) dbi-dbconn,host,
用户、pass、dbname、port、socket、
flags;
/* letuserknowifwecouldn ' t connect.* /
if(DBC==null ) {
isc_log_write(DNS_lctx,DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ,ISC_LOG_ERROR,
' MySQL驱动程序故障to create '
' databaseconnectionafter4attempts ';
result=ISC_R_FAILURE;
goto full_cleanup;
}
.
}
更改后,重新编译安装就可以了。 经过测试,第二天发现域名还可以正常解析。 问题暂时解决一下,以后再观察一下吧。