<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[box crashes with "Lock wait timeout exceeded" from eventlog.upsertLoginEvent()]]></title><description><![CDATA[<h2>Environment:</h2>
<p dir="auto">Cloudron 10.0.5, Ubuntu 26.04.1, MySQL 8.4.11 (also seen before<br />
the OS upgrade on 22.04 / MySQL 8.0.46), ~100 apps, mail enabled,  eventlog <br />
table ~38k rows.</p>
<h2>Symptom</h2>
<p dir="auto">The box service exits through the uncaughtException handler and is restarted<br />
by systemd. 3 times in 23 minutes today ( NRestarts=3 ), and 3 times on<br />
2026-09-24:</p>
<pre><code>From uncaughtException handler.                                           
BoxError: Lock wait timeout exceeded; try restarting transaction          
    at Object.transaction (box/src/database.js:58:15)                     
    at upsertLoginEvent (box/src/eventlog.js:57)                          
</code></pre>
<p dir="auto">While box restarts, the dashboard, LDAP/OIDC and mail authentication are<br />
briefly unavailable.</p>
<h2>What I found</h2>
<p dir="auto">The stack points at the  UPDATE  in  upsertLoginEvent() . Because of<br />
 DATE(creationTime)  in the WHERE clause, MySQL doesn't use<br />
 creationTime_index  and scans the whole table:</p>
<pre><code>EXPLAIN UPDATE eventlog SET dataJson='{}' WHERE action='user.login' AND   sourceJson LIKE '%x%' AND DATE(creationTime)=CURDATE();                     
type: index | possible_keys: NULL | key: PRIMARY | rows: 32747 | Extra: Using where                                                                 
</code></pre>
<p dir="auto">On a test MySQL I could reproduce the lock wait: with that UPDATE open in<br />
one transaction, a write to an unrelated  eventlog  row from a second<br />
session times out.</p>
<p dir="auto">Some callers (the mail auth paths in  app-bridge.js  and  ldapserver.js )<br />
call  upsertLoginEvent()  without  await , which would explain why the error<br />
ends up in the uncaughtException handler.</p>
<p dir="auto">Happy to provide more logs if useful.</p>
]]></description><link>https://forum.cloudron.io/topic/16106/box-crashes-with-lock-wait-timeout-exceeded-from-eventlog.upsertloginevent</link><generator>RSS for Node</generator><lastBuildDate>Wed, 14 Oct 2026 18:06:41 GMT</lastBuildDate><atom:link href="https://forum.cloudron.io/topic/16106.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 10 Oct 2026 15:57:19 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to box crashes with "Lock wait timeout exceeded" from eventlog.upsertLoginEvent() on Mon, 12 Oct 2026 16:16:03 GMT]]></title><description><![CDATA[<p dir="auto">I have fixed the crash itself. I think the 38k rows is causing the timeout. Maybe your disk or CPU is slow? But the default transaction lock is 50 seconds, and I can't think why reading 38k rows will take that long. I have changed the transaction's isolation level that should at least make it faster. Let's see how it is in the next release.</p>
]]></description><link>https://forum.cloudron.io/post/130896</link><guid isPermaLink="true">https://forum.cloudron.io/post/130896</guid><dc:creator><![CDATA[girish]]></dc:creator><pubDate>Mon, 12 Oct 2026 16:16:03 GMT</pubDate></item></channel></rss>