I'm having a strange error:

user warning: Duplicate entry '4372' for key 1 query: INSERT INTO i18n_strings (lid, type, oid, property) VALUES(4372, 'empty', 0, '0') in /sites/all/modules/i18n/i18nstrings/i18nstrings.module on line 247.

This error appears on different pages when administering content, such as editing a node, but I've seen it appearing on different places. Also the entry value (here 4372) varies, but the rest of the message is always the same. It does not limit functionality, when I refresh the page the error appears on everything works, but it annoys me. Any ideas how to fix this, and where it's coming from?

Comments

ar-jan’s picture

Status: Active » Fixed

Hm, in the end the solution was quite simple. With phpmyadmin I just dropped all records in the i18n_strings table. That solved all errors. (I had been getting more and more of such errors, when just editing a node or something that had nothing to do with any translated string). No idea where all this came from.

Strange side-effect was that for one content type I have, the selected taxonomy term was unselected for some posts.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

eMPee584’s picture

Status: Closed (fixed) » Postponed (maintainer needs more info)

I have had the same issue.. this definitly should have a line in the documentation, never would have suspected that emptying that table might fix it... but this obviously would drop any customized stings IIUC.. should there not be a different fix for this?
And what exactly is going on, the troubling field is deleted in the previous line but then it complains about a duplicate entry?

eMPee584’s picture

Status: Postponed (maintainer needs more info) » Postponed

AHA... it's a
race condition

that is occuring here.... mmhhh .... so there's no quick fix other than regularily running
DELETE FROM `watchdog` WHERE `variables` REGEXP 'Duplicate.*INSERT.*i18n'...

jose reyero’s picture

Category: support » bug
Status: Postponed » Active

Not for the handbook, this is a bug, to do more research...

eMPee584’s picture

it is not a bug, it happens when the same page is accessed by multiple users at the same time. To prevent this from happening, the table has to be locked. I believe this is planned for D7.

jose reyero’s picture

Status: Active » Fixed

True, it's some race condition, which seems to be all around Drupal.

Anyway, implemented some workaround, this should avoid more error logs

quicksketch’s picture

Priority: Minor » Normal
Status: Fixed » Needs review
StatusFileSize
new999 bytes

I don't understand why this problem can't be fixed. If it's a race condition (which I agree, this does look like the case), the solution is to fix the race condition, not clear the table! This simple patch removes the race condition and doesn't increase the number queries. Instead of doing a DELETE/INSERT it does a SELECT/UPDATE. This problem was flooding our site's watchdog with thousands of entries per hour.

eMPee584’s picture

Status: Needs review » Reviewed & tested by the community

the patch didn't apply to the head version but it was not overly complicated to do it manually. It works and looks like the right way to do it, good job quicksketch. (Cool, now i know how to fix an SQL race condition ;)

neclimdul’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.52 KB

Alternate version of the patch based on the solution used by cache_set and variable_get in d6

eMPee584’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1.21 KB

Even better, one less SQL query. You're the dudes folks. Here's the patch rerolled for HEAD.

nedjo’s picture

Agreed, this is the correct fix.

quicksketch’s picture

Status: Reviewed & tested by the community » Needs review

There's no need for the @ symbol before the call to db_query(), this could obscure problems in the future if the query does cause errors, they shouldn't be suppressed. Was there are reason for adding this neclimdul?

nedjo’s picture

neclimdul was following the code in variable_set() and cache_set(), which both use the @.

This was introduced in #55516: Remove database locking.

quicksketch’s picture

Seems like David Strauss added the @ in #130 though the reason was never stated. I'll ask him about this need, but my guess is that it is unwarranted, just the result of following a pattern that existed before the locking was fixed (perhaps the @ was necessary at one point if a race condition were causing errors).

eMPee584’s picture

Status: Needs review » Reviewed & tested by the community

Well whatever the @ means, the fix is ready to be committed.

neclimdul’s picture

quicksketch’s picture

I agree we can go ahead and commit this. When I satisfy my curiosity about the @ sign, I'll make a patch for core first if it can be safely removed (my feeling is that it can), though as nedjo points out, all this code is gone anyway in Drupal 7 thanks to the new database layer.

nedjo’s picture

Status: Reviewed & tested by the community » Needs work

This issue indeed is worth fixing; but it suggests incorrect calls elsewhere to the tt() function.

tt() can be called in two ways--to add or update a string to be translated or to fetch an existing translation (if there is one).

The fact that we're getting high volume write operations suggests that insert/update operations are being called inappropriately.

It would help to know just what queries are failing, so we can track these issues to their source.

I had a look around and found this issue in i18nmenu: #339057: Performance: menu translations continuously updated, which was one instance of updating instead of fetching. The patch there may help reduce these errors.

All of which suggests that we shouldn't suppress error messages--they're indicators for where we need to fix other code. So let's leave out the @.

nedjo’s picture

Likely we are indeed getting race condition errors. But looking again at the original error message above, it seems noteworthy that the particular string being inserted is 0. A possible cause is:

* for whatever reason, we have a 0 being passed to tt().
* the first time this happens, a record is created
* the next and all subsequent times, the query to find an existing translation returns 0, which is interpreted as not finding a translation, so a new insert is attempted
* the new insert fails, because there is an existing record.

Probably we should bail early when an empty value is passed to tt(). We may also need handling of this case elsewhere.

catch’s picture

I have a feeling the @ might be to help with replication, but that's only half-remembered. Will be interested to see what the answer actually is.

nedjo’s picture

Status: Needs work » Postponed (maintainer needs more info)

I committed a version of the patch without @ and left a code comment.

Setting to needs more info pending more information on the @ question.

I looked further at the code and concluded we can't suppress empty values, since they're used to trigger deletes.

jose reyero’s picture

Status: Postponed (maintainer needs more info) » Fixed

Thanks nedjo, this looks much better now. Also committed a related patch which may avoid unneeded updates, #339057: Performance: menu translations continuously updated

About the @db_query(), I've added it back, reasons commented on the code. Otherwise we'd need an extra select statement to check if the value is already there. This will allow people to use the module while we (developers) can look for better options here.

The weird values passed around may come from other modules using i18nstrings, for further investigation....

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

helloanshul’s picture

m having similar problem on my website