Repository navigation
Conversation
|
There's a followup patch that should land with this, I'll update momentarily. |
|
Added the migration from 20 => 21 to clean up any existing orphans that should be deleted, and recalculates |
bendk
left a comment
There was a problem hiding this comment.
This looks right to me, with the possible exception of the comment I left about SyncStatus::normal. Mark should also take a look though, since he knows this code better than me.
|
|
||
| DELETE FROM moz_places | ||
| WHERE foreign_count = 0 AND last_visit_date_local = 0 AND last_visit_date_remote = 0;", | ||
| normal = SyncStatus::Normal as u8, |
There was a problem hiding this comment.
Why only SyncStatus::Normal? I think this bug could also happen for SyncStatus::new
There was a problem hiding this comment.
Could you have a new one that's an existing orphan due to its grandparent being deleted?
There was a problem hiding this comment.
This is where we need Mark, but I thought SyncStatus::New just meant that it hasn't been synced yet.
There was a problem hiding this comment.
Oh. If that's what it means, it's probably ok since it should've been deleted?
There was a problem hiding this comment.
Couldn't it have hit the same bug you're fixing now? I didn't think it was sync only, just that we only observed it during sync.
There was a problem hiding this comment.
I misunderstood the question: so yeah, this could affect non-Sync bookmark trees, and since only Sync (iiuc) complains about it, we -- and the user -- would never know about it.
There was a problem hiding this comment.
Yeah, agree that second check should not check Normal. The tombstone check for Normal is correct though.
There was a problem hiding this comment.
I'm confused: the second check is the tombstone check? I thought Ben is suggesting removing line 377, and Mark is saying leave line 411?
There was a problem hiding this comment.
(And now these are in different places)
There was a problem hiding this comment.
Ah nevermind. I think you meant the constraint in the insertion to moz_bookmarks_deleted. Leaving this open so you can double-check.
| let mut child_guids_by_parent_guid: HashMap<SyncGuid, Vec<dogear::Guid>> = HashMap::new(); | ||
| // Items whose parent is missing can't be placed in the tree, so leave | ||
| // them and their descendants out rather than failing the merge. | ||
| let orphan_guids = self.fetch_local_orphan_guids()?; |
There was a problem hiding this comment.
IIUC, this patch should also be arranging for this to never actually be hit, right? If so, I wonder if this is valuable, and whether just allowing the same error we see today to continue is fine? While it could be argued this is a kind of defense-in-depth, I'm fairly sure there are other places where we also assume sqlite is enforcing our model and will fail where it does not?
(IOW, I'm wondering if paying the cost of the orphan check is actually worthwhile, and whether we will be able to deduce it working from existing telemetry in the same we we found this?)
There was a problem hiding this comment.
This is only there in case something slips through (that way the error reported shows us that it's happening).
Given that we should see the "nonexistent parent" errors and places-sync-bookmarks-orphaned errors go to zero. So we could just watch those and see if they tick up again.
I'd include this check, because it's a safety net -- but if it's a performance drag and we think we'd see the signs of a similar thing happening again, I'm fine losing it.
There was a problem hiding this comment.
Maybe we could put this in run_maintenance, where performance doesn't matter that much.
|
|
||
| DELETE FROM moz_places | ||
| WHERE foreign_count = 0 AND last_visit_date_local = 0 AND last_visit_date_remote = 0;", | ||
| normal = SyncStatus::Normal as u8, |
There was a problem hiding this comment.
Yeah, agree that second check should not check Normal. The tombstone check for Normal is correct though.
|
Sorry, another migration 20 beat this last week, so I had to update this to account for that. |
…an up after orphan bookmarks mitigation
bendk
left a comment
There was a problem hiding this comment.
This is good from my POV. I left a couple questions/suggestions, but however you want to deal with those is fine with me.
| let mut child_guids_by_parent_guid: HashMap<SyncGuid, Vec<dogear::Guid>> = HashMap::new(); | ||
| // Items whose parent is missing can't be placed in the tree, so leave | ||
| // them and their descendants out rather than failing the merge. | ||
| let orphan_guids = self.fetch_local_orphan_guids()?; |
There was a problem hiding this comment.
Maybe we could put this in run_maintenance, where performance doesn't matter that much.
| WHERE foreign_count > 0 | ||
| AND id NOT IN (SELECT place_id FROM placeForeignCounts) | ||
| AND last_visit_date_local = 0 AND last_visit_date_remote = 0 | ||
| AND NOT EXISTS (SELECT 1 FROM moz_places_metadata m WHERE m.place_id = moz_places.id)", |
There was a problem hiding this comment.
This is probably me not understanding places, but it seems like placesForeignCounts is all we need to know if a bookmark should be garbage collected or not.
What would it mean for id NOT IN (SELECT place_id FROM placeForeignCounts) to be true, but either of the following clauses to be false?
There was a problem hiding this comment.
The way I understand it, placesForeignCounts is all of the references to a places id (from bookmarks, keywords, or tags) -- so a history entry that has none of those things should have a foreign_count of 0. But one of the reasons to recalculate foreign_count is because the REPLACE INTO moz_bookmarks_synced statement while recursive triggers were off could've contributed to the foreign_count drifting high because the decrements that should've happened didn't (because delete triggers weren't firing). So if something doesn't have any references (isn't in placeForeignCounts), it could still have a nonzero value for last_visit_date_local or last_visit_date_remote.
The metadata one is similar in that it's not a reference either, but technically could be created without an actual visit.
So these checks are here to ensure we don't delete something that legitimately could exist -- whereas anything that's in zeroedPlaces has an erroneous foreign_count and it's not about to be fixed by the recalculation that follows.
For bug 2084607, this adds an explicit
PRAGMA recursive_triggers = ON. Accordingly, also it adds the following:moz_bookmarks_parent_afterdelete_triggerinsql/create_shared_triggers.sqlforeign_countdecrement/increment insrc/db/schema.rssrc/storage/bookmarks.rsThis restores the behavior for cascading deletions that were present with the previous FK, which were assumed to still be in effect.
Two more changes will be needed, addressed separately (handling existing erroneous orphans, and recalculating the
moz_places.foreign_count).Pull Request checklist
[ci full]to the PR title.