On Wed, Sep 09, 2026 at 08:09:30AM +0200, Andras Korn wrote:

> I'll try to dig deeper into what sanity_problem() does/calls, but am sharing 
> these preliminary results in the hope someone will find them useful.

The expensive operation seems to be apt.cache.get_changes(). It consistently 
took hundreds to low thousands of ms per invocation, while sanity_problem() 
itself had essentially no self time; for example:

sanity_problem() [total=1.141s self=0.005s]
  apt.cache.get_changes() [total=1.136s self=1.136s]

apt.cache.get_changes() seems to be implemented in Python by iterating over the 
APT cache and testing each package's marked state, with the actual 
package/dependency-cache operations performed through the APT bindings (making 
them invisible to the Python tracer).

I believe that's where all the observed newfstatat() calls are made (making 
them a symptom, not the actual problem).

unattended-upgrade calls get_changes() repeatedly (potentially tens of 
thousands of times) while evaluating and adjusting candidate changes, which 
contributed substantially to my observed 11-hour runtime.

The result of get_changes() reflects the current mutable marked state of the 
APT dependency cache, and unattended-upgrade modifies that state while 
considering candidates, so that the result of get_changes() can't be trivially 
cached; but maybe there are cases where it's called several times without 
intervening state changes, and those calls could be optimized out, at least.

(There is at least one redundant call in the sanity-check failure path: 
sanity_problem() obtains the change set, and check_changes_for_sanity() 
subsequently calls cache.get_changes() again to construct the debug message. 
However, this is only relevant to --debug runs.)

It seems to me the performance issue can only be fixed by refactoring 
unattended-upgrades and/or python3-apt so that get_changes() is called less 
often, or performs less work each time it's called.

AndrĂ¡s

-- 
                   I'd give my right arm to be ambidextrous.

Reply via email to