Review round for the cross-thread close fix:
- cursor() now records its cursor under the lock _close_now copies the
cursor set under, and refuses once the connection is retired; a cursor
opened while the connection closed raised "Set changed size during
iteration" out of retire() on Python 3.10-3.12. retire() never raises,
retire_connections keeps going when one connection fails, and the mover
never reports a completed switch as failed because retiring or awaiting
old connections did.
- The restore's backup target is marked in use (ManagedConnection.using),
and in_transaction and create_function are guarded.
- Iterating a cursor marks the connection in use once per fetchmany(128)
chunk instead of once per row: a 1000-row scan costs 1.10x a plain
cursor instead of 2.7x (3.14) / 3.8x (3.10).
- Document what an interrupt does not end, the statements a retired
connection cannot hold back, close() from another thread returning
before the file is closed, and the await timeout ending as old-in-use.