Commit 72d5248
fix: handle duplicate key on trash unique constraint during concurrent 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>1 parent de5b16b commit 72d5248
2 files changed
+78
-10
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
263 | 278 | | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
264 | 292 | | |
265 | 293 | | |
266 | 294 | | |
267 | 295 | | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | 296 | | |
279 | 297 | | |
280 | 298 | | |
| |||
285 | 303 | | |
286 | 304 | | |
287 | 305 | | |
| 306 | + | |
| 307 | + | |
288 | 308 | | |
289 | 309 | | |
290 | 310 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| 40 | + | |
39 | 41 | | |
40 | 42 | | |
41 | 43 | | |
| |||
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
| 64 | + | |
62 | 65 | | |
63 | 66 | | |
64 | 67 | | |
| |||
284 | 287 | | |
285 | 288 | | |
286 | 289 | | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
287 | 335 | | |
0 commit comments