[stable32] Handle duplicate key on trash unique constraint during concurrent deletes#4497
Merged
provokateurin merged 3 commits intostable32from Mar 12, 2026
Merged
[stable32] Handle duplicate key on trash unique constraint during concurrent deletes#4497provokateurin merged 3 commits intostable32from
provokateurin merged 3 commits intostable32from
Conversation
i2h3
approved these changes
Mar 10, 2026
Member
9e25d6c to
e6f352c
Compare
i2h3
added a commit
that referenced
this pull request
Mar 11, 2026
The original PR #4496 targeting **master** already includes the `private TrashManager $trashManager;` property declaration and the `use` import. The diff shows it properly adds both. The backport PR #4497 **lost the property declaration** during the backport process. The PR description even warns about this: "This backport's changes differ from the original and might be incomplete." What likely happened: the `master` branch and `stable32` branch have slightly different property orderings or surrounding context in `TrashBackendTest.php` (e.g., `master` doesn't have the `ACLManager` property, or they're in a different order). When the automated backport tool cherry-picked the changes, the hunk adding `private TrashManager $trashManager;` failed to apply cleanly and was silently dropped, while the code in `setUp()` and the new test method that *uses* `$this->trashManager` did apply — resulting in the mismatch. Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
…t deletes The unique constraint on oc_group_folders_trash (folder_id, name, deleted_time) uses second-granularity timestamps. When multiple files with the same base name inside the same group folder are deleted within the same second (e.g. by the desktop client issuing bulk DELETEs), the INSERT in TrashManager::addTrashItem() fails with a unique constraint violation. Because the file has already been physically moved to trash storage before the INSERT, the failed DB record leaves the file orphaned — resulting in data loss. Insert the trash record before moving the file, using a for-loop that retries with an incremented deleted_time on constraint collision. This way the on-disk trash name is constructed from the confirmed timestamp and no renames are needed. If the subsequent file move fails, the DB record is cleaned up. This follows the existing pattern in VersionsBackend.php for handling the same class of constraint violation. Fixes: #4014 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
- Wrap moveFromStorage() in try/catch to clean up the DB record when the move throws an exception (not just when it returns false) - Fix test: use assertCount on full trash list instead of filtering by getName() which returns the trash filename with .d suffix - Make test deterministic by waiting for a new-second boundary before both moveToTrash() calls so they always land in the same second Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
The original PR #4496 targeting **master** already includes the `private TrashManager $trashManager;` property declaration and the `use` import. The diff shows it properly adds both. The backport PR #4497 **lost the property declaration** during the backport process. The PR description even warns about this: "This backport's changes differ from the original and might be incomplete." What likely happened: the `master` branch and `stable32` branch have slightly different property orderings or surrounding context in `TrashBackendTest.php` (e.g., `master` doesn't have the `ACLManager` property, or they're in a different order). When the automated backport tool cherry-picked the changes, the hunk adding `private TrashManager $trashManager;` failed to apply cleanly and was silently dropped, while the code in `setUp()` and the new test method that *uses* `$this->trashManager` did apply — resulting in the mismatch. Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
dda3bcc to
4e17145
Compare
Contributor
|
@provokateurin I have no idea about these Cypress actions or how to fix it. Can you help? |
Member
|
Hi, one of them is always failing, we can ignore that. The other one is unexpected, so I just restarted it again. |
provokateurin
approved these changes
Mar 12, 2026
Contributor
|
@provokateurin Do they need to pass? |
Member
|
No, expected to fail unfortunately. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #4496
Warning, This backport's changes differ from the original and might be incomplete⚠️
Todo
Learn more about backports at https://docs.nextcloud.com/server/stable/go.php?to=developer-backports.