Skip to content
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

Lock acquisition concurrency issue #107

Open
denyskonakhevych opened this issue Oct 15, 2021 · 2 comments
Open

Lock acquisition concurrency issue #107

denyskonakhevych opened this issue Oct 15, 2021 · 2 comments

Comments

@denyskonakhevych
Copy link

denyskonakhevych commented Oct 15, 2021

In order to apply changes correctly, liquibase first need to acquire lock to insure only single active upgrader is now working.
This brings us to cases where multiple nodes try to acquire lock simultaneously.
Let's look at the case with 2 nodes

1							2

check -> released				check -> released
 ...  							...
acquire						acquire
process		   				process
release 						release
 ...		  		 			...

On the first line, both check is that lock occupied or not with query
SELECT COUNT(*) FROM <table_name> where LOCKED = TRUE ALLOW FILTERING

After that both execute following query to acquire lock:
UPDATE <table_name> SET LOCKED = TRUE, LOCKEDBY = '<lockedBy>', LOCKGRANTED = <ts> WHERE ID = 1

And result in both cases is -1

I suggest to change query to following
UPDATE <table_name> SET LOCKED = TRUE, LOCKEDBY = '<lockedBy>', LOCKGRANTED = <ts> WHERE ID = 1 IF LOCKED = FALSE
The result of this operation would still be -1, but record would not be changed because of IF condition

After that we can check whether current host managed to occupy lock:
SELECT COUNT(*) FROM <table_name> where LOCKED = TRUE AND LOCKEDBY = '<lockedBy>' ALLOW FILTERING

So, if result is bigger then 0 - current process successfully occupied lock, otherwise - another was faster this time.
Now we will see following situation

1							2

check -> released				check -> released
 ...  							...
try acquire					try acquire
check -> acquired				check -> acquired by another process
process		   				wait
release 						...
 ...		  		 			check -> released
 ...		  		 			try acquire
 ...		  		 			check -> acquired
 ...		  		 			...

┆Issue is synchronized with this Jira Bug by Unito

@denyskonakhevych denyskonakhevych changed the title Lock acquiring concurrency issue Lock acquisition concurrency issue Oct 15, 2021
@recampbell
Copy link

@denyskonakhevych - Thanks for raising this problem. If I understand correctly - the risk of not fixing is that this bug may allow concurrent updates of a schema from two different Liquibase clients. Is that correct?

@denyskonakhevych
Copy link
Author

@denyskonakhevych - Thanks for raising this problem. If I understand correctly - the risk of not fixing is that this bug may allow concurrent updates of a schema from two different Liquibase clients. Is that correct?

That's correct. Typically, if you have liquibase as part of start up sequence and now you are redeploying/scaling your app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants