-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
14.0.4: PostgreSQL Duplicate key value violates unique constraint lock_key_index #12729
Comments
GitMate.io thinks possibly related issues are #12586 (14.0.4), #366 (PostgreSQL: violation of constraints), #6343 (PostgreSQL : duplicate key value violates unique constraint error message), #12204 (Resolve ERROR: duplicate key value violates unique constraint "oc_credentials_pkey"), and #11779 (SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry * for key 'lock_key_index'). |
Caused by #12413 and it is on purpose: We actually changed how the detection works, because there was a race condition in the old approach leading to real deadlocks and broken locks. Thus we changed the way from "INSERT INTO ... WHEN (SUBSELECT TO CHECK IF THIS EXISTS)". The old way had the problem that when a concurrent request also inserted right between the end of the subselect and the actual insert then the error was happening. So we now changed to trigger an insert and check if an exception is thrown. In this way we ignore it (because the code had the logic "only insert if it does not exist yet"). Long story short: if there is no such message in your nextcloud log then you can ignore the error. We tried to not cause this but unfortunately there was no clean way to solve this on all supported platforms except like this. |
Nearly a thousand of these each day. Postgres supports INSERT... ON CONFLICT [DO NOTHING | DO UPDATE] starting in 9.5. Current release is 11. Debian stable has 9.6. I think you can require 9.5 or later by now. |
Unfortunately we also support SQLite, MySQL, MariaDB and Oracle as well. Then the combined SQL syntax is not that impressive. 😢 |
So obviously you have a translation layer that takes a high-level "let me do an INSERT" and turns it into the right variant for each of your supported databases. That's where this goes. If you're writing SQL by hand and hoping that it works on all of those DBs... well, this is a case where it isn't working. |
We are happy to get PRs that head into this direction obviously. For the correct location have a look at the linked PR. We can also give you further guidance on this topic if you need help. |
Sadly, I am not proficient at PHP. It looks like Sqlite also implements ON CONFLICT (value) DO NOTHING, as of 3.24.0. Debian stable (which I'm using as a benchmark for "can we expect a year-old distro to have this") does not use a sufficiently new sqlite, but it is available in backports (3.25.3-2~bpo9+1). Meanwhile, over in MySQL, changing the INSERT to INSERT IGNORE should do the same thing; that's been supported for at least 8 years. The existing logic appears to be the best possible in oracle, although MERGE is suitable if you had a whole temporary table you wanted to bring in -- not the case here. These changes will require updating documentation to require minimum versions of I hope that's helpful. |
@MorrisJobke I would like to contribute. And I think this issue would be a good place to start. To me it seems like @dashdsrdash's proposal is quite reasonable. I moved the query from server/lib/private/Lock/DBLockingProvider.php Line 135 in cff89c2
@MorrisJobke I would be happy to hear some feedback, whether this coincides with what you had in mind? |
That makes most sense and maybe helps with the problems of log spam that was reported by Postgres users. Do you have the code already available and want to send a pull request? Because then we can check it better. |
I created a PR here. I got a little distracted last week, so that took a bit longer. I would be happy to get some feedback! |
Just wanted to leave this out here in case anyone is facing similar issues with a docker-compose setup. It was not immediately obvious to me how to prevent these messages from being logged (while waiting for an actual fix). If you are already using a custom postgresql.conf file, then you can just set the config there, but if you are just running with the default config, the easiest way to prevent logging all of these errors is just to add this line to the docker-compose.yml config for your postgresql container: This will, of course, prevent other actual errors from being logged, but it is better than filling up the logs with these errors. See this page for more info on Postgresql's logging settings: https://www.postgresql.org/docs/9.1/runtime-config-logging.html |
Steps to reproduce
Expected behaviour
No error messages.
Actual behaviour
Too many error messages:
$ sudo egrep '2018-11-29.*duplicate key value violates unique constraint "lock_key_index"'
/var/log/postgresql/postgresql-11-main.log | wc -l
15484
Those error messages look like this:
nextcloud@nextcloud ERROR: duplicate key value violates unique constraint "lock_key_index"
nextcloud@nextcloud DETAIL: Key (key)=(files/5f46d7639d8049fc652b79286a38d339) already exists.
nextcloud@nextcloud STATEMENT: INSERT INTO "oc_file_locks" ("key", "lock", "ttl") VALUES($1, $2, $3)
Server configuration
Operating system: Debian/Buster
Web server: nginx-1.14.1-1
Database: PostgreSQL-11
PHP version: 7.3
Nextcloud version: 14.0.4
Updated from an older Nextcloud/ownCloud or fresh install: Updates vom 13.x
Where did you install Nextcloud from: Official package. No docker.
List of activated apps:
Enabled:
Disabled:
Nextcloud configuration:
{
"system": {
"instanceid": "REMOVED SENSITIVE VALUE",
"passwordsalt": "REMOVED SENSITIVE VALUE",
"secret": "REMOVED SENSITIVE VALUE",
"trusted_domains": [
"foo.torrentkino.de"
],
"datadirectory": "REMOVED SENSITIVE VALUE",
"overwrite.cli.url": "https://foo.torrentkino.de",
"memcache.local": "\OC\Memcache\APCu",
"dbtype": "pgsql",
"version": "14.0.4.2",
"dbname": "REMOVED SENSITIVE VALUE",
"dbhost": "REMOVED SENSITIVE VALUE",
"dbport": "",
"dbtableprefix": "oc_",
"dbuser": "REMOVED SENSITIVE VALUE",
"dbpassword": "REMOVED SENSITIVE VALUE",
"installed": true,
"maintenance": false,
"theme": "",
"loglevel": 2,
"mail_smtpmode": "smtp",
"mail_smtpauthtype": "LOGIN",
"mail_smtpsecure": "tls",
"mail_from_address": "REMOVED SENSITIVE VALUE",
"mail_domain": "REMOVED SENSITIVE VALUE",
"mail_smtpauth": 1,
"mail_smtphost": "REMOVED SENSITIVE VALUE",
"mail_smtpport": "587",
"mail_smtpname": "REMOVED SENSITIVE VALUE",
"mail_smtppassword": "REMOVED SENSITIVE VALUE",
"updater.release.channel": "stable"
}
}
Are you using external storage, if yes which one: No
Are you using encryption: No
Are you using an external user-backend, if yes which one: No
The text was updated successfully, but these errors were encountered: