I suspect it is the very same issue am working on right now.
Thanks for letting us know.
I'll keep you posted when a solution is found.
PS: In the mean time - use "Modified Nodes" method to minimise the impact (especially if you are NOT modifying an MQTT node) because "Full" causes all nodes (even ones you havent touched) to be re-created.
QOS value and retain will change the behaviour. Upon losing the connection with a client the broker will maintain the connection for a while so that the same client reconnects it will find the messages waiting for him.
When using the same client_id you force reusing the same "queue" hence the same TCP connection on the broker.
I would say that "Clean session" is key
I'm using either one of those 2 combinations:
empty (automatic) client_id and "Clean session" checked : the broker clear the client context in case of disconnection
fixed client_id and "Clean session" unchecked : the broker keeps the client context in case of temporary disconnection. If a new connection comes with the same client_id, the older one is closed by the broker.
I don't say that other combinations are useless, just that I have no use-case for them.
So from your description it looks like the combination of "automatic client_id" and "Clean session unchecked" leaves MQTT connection in the background that are neither closed by Node-RED nor the broker.