Fix race condition in backfill_version_column()

Fixes a race condition in backfill_version_column(). It was fetching
the objects whose version==None. Then it did an update to set the
value of those object versions. However, it is possible for one of
the object versionss to have been updated after the fetch but before
the update operation, in which case the update operation might set
the version to be an older version.

Change-Id: I882fdd3e83582a4d7110c68b0d84f243234ea7dd
Closes-Bug: #1715190
This commit is contained in:
Ruby Loo 2017-09-05 14:34:46 -04:00
parent 3dfc17a2eb
commit d44a210a50
2 changed files with 19 additions and 5 deletions

View File

@ -1218,11 +1218,18 @@ class Connection(api.Connection):
ids = []
for obj in query.slice(0, max_to_migrate):
ids.append(obj['id'])
query = model_query(model).filter(model.id.in_(ids))
num_migrated = query.update(
{model.version: mapping[model.__name__][0]},
synchronize_session=False)
num_migrated = (
model_query(model).
filter(sql.and_(model.id.in_(ids),
model.version.is_(None))).
update({model.version: mapping[model.__name__][0]},
synchronize_session=False))
else:
num_migrated = (
model_query(model).
filter(model.version.is_(None)).
update({model.version: mapping[model.__name__][0]},
synchronize_session=False))
total_migrated += num_migrated
max_to_migrate -= num_migrated

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Fixes an issue when running ``ironic-dbsync online_data_migrations``. The
value of an object's new ``version`` column might have been incorrectly
changed from a newer object version to an older object version, due to a
race condition. This is no longer the case.