We run Unbound on Debian Trixie (13.5) on two servers as resolvers for the internal network. We also use Unbound to serve RPZs. Recently, Debian upgraded Unbound from 1.22 to 1.26 and since then we intermittently get freezes for 20-30 seconds, during which Unbound does not respond to any requests. I could trace back the freezes to certain RPZ updates. While Investigating the issue more, I found that Version 1.25.2 introduced a change in RPZ update behaviour. Up until 1.22, the internal policy structure for RPZs was built during start of the server. Subsequent IXFR were applied quickly without any noticable side-effects. With 1.26, it appears that Unbound forces an AXFR after four IXFR, which leads to a rebuild of the internal policy structure. During this rebuild Unbound does not answer any requests. One of the RPZs in question has ~2 million records and it takes ~24 seconds to rebuild during which any requests stay unanswered.
The change that introduced the new behavior is 1354624b. It seems that number of IXFR before an AXFR happens cannot be changed in the configuration and is hard-coded in:
#define NUM_IXFR_BEFORE_AXFR 5
We reverted to 1.22.
Is there a way we can upgrade to the most recent version without experiencing intermittent freezes?
I see how the mentioned change addresses an issue with growing memory usage. For us, however, memory usage is of much less concern than responsiveness of the resolver.
There is a more involved workaround that you can use now if you are interested, via the fast_reload feature (i.e., unbound-control fast_reload).
For this you would have to:
Configure the rpz zone with only a zonefile, no primary servers,
Fetch the zone file outside of the running Unbound (e.g., dig @<server> AXFR <zone>), and
Issue the fast_reload command when the file is updated.
Thanks to the new unbound-control fast_reload we were able to upgrade to 1.26.1 without fearing stalls due to RPZ reloading.
Here some observations I made. The size of all RPZs we use is 409 MB (in BIND text format). When loaded into memory with Unbound through the command unbound-control fast_reload, the size expands to 5.6 GB in memory. On the second unbound-control fast_reload memory consumption of Unbound doubles to 11.3 GB - which is probably expected since the internal policy structure needs to be set up a second time for a seamless transition.
Now comes the hairy part. When Unbound is restarted with systemctl restart unbound.service or the server is rebooted, it creates the internal policy structure directly at startup from the available zone files and Unbound memory consumption is at 5.6 GB after the restart. A subsequent unbound-control fast_reload increases memory usage to 11.3 GB. Now, another run of unbound-control fast_reload again increases the memory to 16.9 GB.
In other words: When I let Unbound the read the complete RPZ files at startup, the memory consumption is three times the internal policy structure. In order to save the third copy, I need to make sure that RPZ files are empty at Unbound start and that I only load RPZ policies with unbound-control fast_reload.
Why does Unbound not release memory for internal policy structures that it apparently does not use anymore?