Re: nsd name server generates high load during zone update on slave
On 2012-05-29, Imre Oolberg i...@auul.pri.ee wrote: Hi! Thank you very much for quick answer! Tried it on 5.1 stable in the spirit on applying bind patch i.e. saying # cd /usr/src # patch -p0 /usr/src/nsd.patch # cd usr.sbin/nsd # make -f Makefile.bsd-wrapper obj # make -f Makefile.bsd-wrapper depend # make -f Makefile.bsd-wrapper # make -f Makefile.bsd-wrapper install And restarting nsd. I specifically copied zone before and after several times and got respectivele load and no load. Also checked that zone content is all right after copying. At the same time i realize that my testing is not thorough. Do you think it is safe for me to start using this patch in production or your people do some more testing and eventually publish this patch as 002_nsd.patch for OpenBSD v. 5.1? I think it's safe and would be a good candidate for the 5.1-stable tree, but it's not in the class of bugs for which we usually release separate patches (typically these are just for security/crash fixes).
Re: nsd name server generates high load during zone update on slave
Hi! Thank you very much for quick answer! Tried it on 5.1 stable in the spirit on applying bind patch i.e. saying # cd /usr/src # patch -p0 /usr/src/nsd.patch # cd usr.sbin/nsd # make -f Makefile.bsd-wrapper obj # make -f Makefile.bsd-wrapper depend # make -f Makefile.bsd-wrapper # make -f Makefile.bsd-wrapper install And restarting nsd. I specifically copied zone before and after several times and got respectivele load and no load. Also checked that zone content is all right after copying. At the same time i realize that my testing is not thorough. Do you think it is safe for me to start using this patch in production or your people do some more testing and eventually publish this patch as 002_nsd.patch for OpenBSD v. 5.1? Best regards, Imre On 05/28/12 23:12, Stuart Henderson wrote: On 2012-05-28, Imre Oolbergi...@auul.pri.ee wrote: Hi! I am having trouble on OpenBSD v. 5.1 using NSD nameserver. When slave NSD name server receives zone update and reloads it into its database high and sustained user load (about 1-2) is generated on cpu depending on hardware from 3 minutes to 10 minutes. Also this kind on load is observed when doing nsdc patch. It seems to happen only when zone has many RRs, say 100k NS lines; using NSD with OpenBSD v. 4.8 from packages does not have this issue, also not 5.1-current, but 5.1 does; i have tried and got similar results on amd64 and i386, happens on both; Normally this kind of reload and patch takes several seconds only. I would be very thankful if somebody could have a look at it and confirm this behaviour. And if really nsd on 5.1 is to blame may i add that patch would be very much welcomed! :) This is due to a bug introduced with NSD 3.2.9 and fixed shortly afterwards. The _untested_ diff against -stable below may fix it. Index: difffile.c === RCS file: /cvs/src/usr.sbin/nsd/difffile.c,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 difffile.c --- difffile.c 29 Jan 2012 11:15:31 - 1.1.1.5 +++ difffile.c 28 May 2012 20:10:31 - @@ -261,14 +261,43 @@ has_data_below(domain_type* top) /* in the canonical ordering subdomains are after this name */ d = domain_next(d); while(d != NULL dname_is_subdomain(domain_dname(d), domain_dname(top))) { - if(d-is_existing) + if(d-is_existing) { return 1; + } d = domain_next(d); } return 0; } -static void + +/* this routine makes empty terminals non-existent. + * @domain the lowest empty terminal + * @ce the closest encloser + */ +static domain_type* +rrset_delete_empty_terminals(domain_type* domain, domain_type* ce) +{ + assert(domain); + if (domain-rrsets == 0) { + /* if there is no data below it, it becomes non existing. + also empty nonterminals above it become nonexisting */ + /* check for data below this node. */ + if(!has_data_below(domain)) { + /* nonexist this domain and all parent empty nonterminals */ + domain_type* p = domain; + while(p != NULL p-rrsets == 0) { + if(p == ce || has_data_below(p)) + return p; + p-is_existing = 0; + p = p-parent; + } + } + } + return NULL; +} + + +static domain_type* rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) { int i; @@ -279,7 +308,7 @@ rrset_delete(namedb_type* db, domain_typ } if(!*pp) { /* rrset does not exist for domain */ - return; + return NULL; } *pp = rrset-next; @@ -320,23 +349,13 @@ rrset_delete(namedb_type* db, domain_typ sizeof(rr_type) * rrset-rr_count); region_recycle(db-region, rrset, sizeof(rrset_type)); + rrset-rr_count = 0; + /* is the node now an empty node (completely deleted) */ - if(domain-rrsets == 0) { - /* if there is no data below it, it becomes non existing. - also empty nonterminals above it become nonexisting */ - /* check for data below this node. */ - if(!has_data_below(domain)) { - /* nonexist this domain and all parent empty nonterminals */ - domain_type* p = domain; - while(p != NULL p-rrsets == 0) { - if(has_data_below(p)) - break; - p-is_existing = 0; - p = p-parent; - } - } + if (domain-rrsets == 0) { + return domain; } - rrset-rr_count = 0;
Re: nsd name server generates high load during zone update on slave
On 2012-05-28, Imre Oolberg i...@auul.pri.ee wrote: Hi! I am having trouble on OpenBSD v. 5.1 using NSD nameserver. When slave NSD name server receives zone update and reloads it into its database high and sustained user load (about 1-2) is generated on cpu depending on hardware from 3 minutes to 10 minutes. Also this kind on load is observed when doing nsdc patch. It seems to happen only when zone has many RRs, say 100k NS lines; using NSD with OpenBSD v. 4.8 from packages does not have this issue, also not 5.1-current, but 5.1 does; i have tried and got similar results on amd64 and i386, happens on both; Normally this kind of reload and patch takes several seconds only. I would be very thankful if somebody could have a look at it and confirm this behaviour. And if really nsd on 5.1 is to blame may i add that patch would be very much welcomed! :) This is due to a bug introduced with NSD 3.2.9 and fixed shortly afterwards. The _untested_ diff against -stable below may fix it. Index: difffile.c === RCS file: /cvs/src/usr.sbin/nsd/difffile.c,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 difffile.c --- difffile.c 29 Jan 2012 11:15:31 - 1.1.1.5 +++ difffile.c 28 May 2012 20:10:31 - @@ -261,14 +261,43 @@ has_data_below(domain_type* top) /* in the canonical ordering subdomains are after this name */ d = domain_next(d); while(d != NULL dname_is_subdomain(domain_dname(d), domain_dname(top))) { - if(d-is_existing) + if(d-is_existing) { return 1; + } d = domain_next(d); } return 0; } -static void + +/* this routine makes empty terminals non-existent. + * @domain the lowest empty terminal + * @ce the closest encloser + */ +static domain_type* +rrset_delete_empty_terminals(domain_type* domain, domain_type* ce) +{ + assert(domain); + if (domain-rrsets == 0) { + /* if there is no data below it, it becomes non existing. + also empty nonterminals above it become nonexisting */ + /* check for data below this node. */ + if(!has_data_below(domain)) { + /* nonexist this domain and all parent empty nonterminals */ + domain_type* p = domain; + while(p != NULL p-rrsets == 0) { + if(p == ce || has_data_below(p)) + return p; + p-is_existing = 0; + p = p-parent; + } + } + } + return NULL; +} + + +static domain_type* rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) { int i; @@ -279,7 +308,7 @@ rrset_delete(namedb_type* db, domain_typ } if(!*pp) { /* rrset does not exist for domain */ - return; + return NULL; } *pp = rrset-next; @@ -320,23 +349,13 @@ rrset_delete(namedb_type* db, domain_typ sizeof(rr_type) * rrset-rr_count); region_recycle(db-region, rrset, sizeof(rrset_type)); + rrset-rr_count = 0; + /* is the node now an empty node (completely deleted) */ - if(domain-rrsets == 0) { - /* if there is no data below it, it becomes non existing. - also empty nonterminals above it become nonexisting */ - /* check for data below this node. */ - if(!has_data_below(domain)) { - /* nonexist this domain and all parent empty nonterminals */ - domain_type* p = domain; - while(p != NULL p-rrsets == 0) { - if(has_data_below(p)) - break; - p-is_existing = 0; - p = p-parent; - } - } + if (domain-rrsets == 0) { + return domain; } - rrset-rr_count = 0; + return NULL; } static int @@ -384,6 +403,7 @@ find_rr_num(rrset_type* rrset, static int delete_RR(namedb_type* db, const dname_type* dname, uint16_t type, uint16_t klass, + domain_type* prevdomain, buffer_type* packet, size_t rdatalen, zone_type *zone, region_type* temp_region, int is_axfr) { @@ -442,7 +462,11 @@ delete_RR(namedb_type* db, const dname_t if(rrset-rr_count == 1) { /* delete entire rrset */ - rrset_delete(db, domain, rrset); + domain = rrset_delete(db, domain, rrset); + if (domain !domain-nextdiff) { + /* this domain is not yet in the diff chain */ +