Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-01-15 03:08:28 +0300
committerStan Hu <stanhu@gmail.com>2019-01-15 08:17:40 +0300
commitbcdb5a0a2d62caa685c32c5d1a4453bd5926b5b1 (patch)
tree73053901d8d0d565d949e8359c2d03f1de65bffc
parent0e510780a15955b06445fb4c440230151da9ae93 (diff)
Fix failing MySQL spec due to deadlock condition
`spec/features/uploads/user_uploads_file_to_note_spec.rb` was failing in master because MySQL detected a deadlock when a DELETE and INSERT for the same indexed item occurred within a transaction in the `uploads` table. Due to InnoDB's next-key locking algorithm (innodb_locks_unsafe_for_binlog in https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html), InnoDB sets an exclusive lock for any of the indexed records it encounters, so the INSERT will fail until the DELETE is committed. To fix this, we just disable the transaction for MySQL and keep it for PostgreSQL. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/55161
-rw-r--r--app/uploaders/records_uploads.rb20
1 files changed, 15 insertions, 5 deletions
diff --git a/app/uploaders/records_uploads.rb b/app/uploaders/records_uploads.rb
index 0efca895a50..9a243e07936 100644
--- a/app/uploaders/records_uploads.rb
+++ b/app/uploaders/records_uploads.rb
@@ -23,13 +23,23 @@ module RecordsUploads
return unless model
return unless file && file.exists?
- Upload.transaction do
- uploads.where(path: upload_path).delete_all
- upload.delete if upload
-
- self.upload = build_upload.tap(&:save!)
+ # MySQL InnoDB may encounter a deadlock if a deletion and an
+ # insert is in the same transaction due to its next-key locking
+ # algorithm, so we need to skip the transaction.
+ # https://gitlab.com/gitlab-org/gitlab-ce/issues/55161#note_131556351
+ if Gitlab::Database.mysql?
+ readd_upload
+ else
+ Upload.transaction { readd_upload }
end
end
+
+ def readd_upload
+ uploads.where(path: upload_path).delete_all
+ upload.delete if upload
+
+ self.upload = build_upload.tap(&:save!)
+ end
# rubocop: enable CodeReuse/ActiveRecord
def upload_path