-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CBL-6131: Race creating the expiration
column in a collection table
#2160
Conversation
@jianminzhao |
The fix looks good, I just disagree with the test. |
The new version is okay with me: doing an extra mayHaveExpiration inside the transaction, since the positive return is always good to omit the following transaction. |
EDIT: Sorry, just saw the code comment above. |
Code Coverage Results:
|
LiteCore/Storage/SQLiteDataFile.hh
Outdated
WithDeletedTable = 500, // Added 'deleted' KeyStore for deleted docs (CBL 3.0?) | ||
WithIndexesLastSeq = 501, // Added 'lastSeq' column to 'indexes' table (CBL 3.2) | ||
MaxReadable = 599, // Cannot open versions newer than this | ||
WithExpirationColumn = 490, // Added 'expiration' column to KeyStore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you insert a new version before existing versions? How would a version at 500 or 501 get upgraded? There should be a test, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any database at version >=500 already has the expiration column, because addExpiration
was added to KeyStore::reopen
in the same commit that WithDeletedTable (500)
migration was added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you actually try to retrofit into current upgrade path. This relies on very precise understanding of other part of code and the schema.
Recognizing this fact, we can also treat it as a new version, but because of the above fact, do
ALTER TABLE ..... IF NOT EXISTS
I am little concerned of retrofitting a new version into the history
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ALTER TABLE ..... IF NOT EXISTS
There is no such syntax. We need to check the existence of the column manually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you check the existence, do we still need to insert a new version into past history? This is the new version, after this new version, we will know schema has the expiration table at the time of creation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the code path that supports your statement? Is it in the same transaction of the upgrade transaction? Is it possible that some failure occurs outside the upgrade transaction that arrives following state:
- version bumped 500
- some keystore not opened successfully and expiration not added successfully.
Since you removed the addExpiration completely, there is no way to have the column.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SQLiteKeyStore::reopen calls addExpiration
(on the main branch).
So if a database is version >=500, every collection which has been used since it upgraded to version 500 has the expiration column.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"which has been used since ..." -- what if not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not used then I'm not sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's worth trying to optimize. Seems like you need to make WithExpiration = 502 and always do it (once) for every database, just to make sure.
Fixed by surrounding the column check with the same file lock used when adding the column.
One can verify that the test
Create collection concurrently
fails if you revert the lock change.