Critical bugfix for invalidations during ZEO cache verification.
ClientCache.invalidate(): - This was written not to expect tid=None, which is what happens during cache verification, although it didn't catch the tid=None case and went on doing really strange things then. Rewrote so that tid=None means "forget everything I think I know about the oid". It was kind-of performing an invalidation wrt the in-memory data structures in this case, but leaving the invalidated data for oid looking as if it were still current on disk. That was accidental, depending on what various other parts of the code thought "None" meant (primarily, an end_tid of None is generally taken here to mean "the data is current"). - Also changed the "and we already have version data for oid" case to a "forget everything I think I know about the oid" case. The comments seemed to say that's what it thought it was doing, but the code actually left non-current revisions sitting around. I really don't want to spend time trying to figure out what versions are supposed to do in all cases here, and nuking everything in this case is an obviously *safe* thing to do. - Added more asserts, because the pre- and post-conditions here are delicate and non-obvious (indeed, that a new assert failed is how I stumbled into the invalidation problem to begin with). FileCache.remove(): Changed to remove the key from self.key2entry. While self.filemap keeps an in-memory map of the entire disk file, there's no need to keep info in key2entry for keys that no longer exist in the disk file. I'm not sure a visible bug followed from this (but not sure one didn't either!), but it at best wasted memory, and violated a documented invariant. ConnectionTests.py: New test checkVerificationInvalidationPersists(). Before the patch, this provokes a persistent ZEO cache into delivering stale object state. Of course the test passes after this patch. stats.py: Added a trace code meaning "invalidation hit, and the object state was discarded". This is what happens now for invalidations produced by verification. Because of MVCC, that's really not needed *except* for the invalidations produced by startup verification (invalidations normally just set a new ending tid on the validity range for what was current data; but validity-range info isn't available from verification invalidations).
Showing
Please register or sign in to comment