<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Locking Concurrency on Netdata</title><link>https://www.netdata.cloud/tags/locking-concurrency/</link><description>Recent content in Locking Concurrency on Netdata</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 22 Aug 2026 05:09:03 +0300</lastBuildDate><atom:link href="https://www.netdata.cloud/tags/locking-concurrency/index.xml" rel="self" type="application/rss+xml"/><item><title>Using FOR UPDATE SKIP LOCKED For Queue Workflows</title><link>https://www.netdata.cloud/academy/update-skip-locked/</link><pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/academy/update-skip-locked/</guid><description>&lt;p&gt;One of the most common and powerful patterns in modern application development is the job queue. Whether you&amp;rsquo;re sending emails, processing images, or running complex calculations, offloading tasks to background workers is essential for building responsive and scalable systems. Many developers reach for dedicated queueing software like RabbitMQ or Redis, but for many use cases, your primary PostgreSQL database already has all the tools you need to build a robust, transactional, and incredibly performant &lt;code&gt;job_queue_postgres&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>How Autovacuum Causes PostgreSQL Deadlocks</title><link>https://www.netdata.cloud/academy/autovaccum-vs-deadlock/</link><pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/academy/autovaccum-vs-deadlock/</guid><description>&lt;p&gt;You&amp;rsquo;ve meticulously optimized your application queries. Your transaction logic is sound. Yet, under heavy load, your system seizes up, logging the dreaded &amp;ldquo;deadlock detected&amp;rdquo; error. You dig into the logs, expecting to find two application transactions locked in a deadly embrace, but instead, you find a surprising culprit: one of the participants is the PostgreSQL &lt;code&gt;autovacuum&lt;/code&gt; process. How can a routine maintenance task, designed to keep the database healthy, be the cause of a production-stopping &lt;code&gt;postgres_deadlock&lt;/code&gt;?&lt;/p&gt;</description></item><item><title>Real-World PostgreSQL Deadlock Examples &amp; Fixes</title><link>https://www.netdata.cloud/academy/10-real-world-postgresql-deadlock/</link><pubDate>Mon, 25 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/academy/10-real-world-postgresql-deadlock/</guid><description>&lt;p&gt;It’s 3 AM. The pager screams. Your application is throwing a cascade of errors, and users are reporting that the system is completely frozen. You dive into the logs and see the same ominous message repeating over and over: &lt;code&gt;ERROR: deadlock detected&lt;/code&gt;. A PostgreSQL deadlock is one of the most abrupt and disruptive failures a database can experience. It&amp;rsquo;s not a performance degradation; it&amp;rsquo;s a hard stop where two or more transactions are locked in a fatal embrace, each waiting for a resource the other holds.&lt;/p&gt;</description></item><item><title>Early Deadlock Detection With pg_stat_kcache &amp; eBPF</title><link>https://www.netdata.cloud/academy/early-deadlock-detection/</link><pubDate>Sat, 09 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/academy/early-deadlock-detection/</guid><description>&lt;p&gt;The dreaded deadlock. For anyone managing a high-traffic PostgreSQL database, it&amp;rsquo;s a familiar nemesis. The database logs a &amp;ldquo;deadlock detected&amp;rdquo; message, a transaction is unceremoniously aborted, and your application has to handle the fallout. This reactive cycle is frustrating; by the time you&amp;rsquo;re alerted, the damage is already done. Traditional &lt;code&gt;postgres_metrics&lt;/code&gt; and monitoring tools are excellent at telling you &lt;em&gt;that&lt;/em&gt; a deadlock occurred, but they fall short of explaining the subtle conditions that led to it.&lt;/p&gt;</description></item><item><title>What Is Database Concurrency? Problems &amp; Control Techniques</title><link>https://www.netdata.cloud/academy/what-is-database-concurrency/</link><pubDate>Sun, 04 May 2025 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/academy/what-is-database-concurrency/</guid><description>&lt;p&gt;Imagine trying to book the very last seat on a popular flight online. At the exact same moment, another person clicks &amp;ldquo;confirm&amp;rdquo; for the same seat. How does the system ensure only one booking goes through and the database remains accurate? This scenario highlights the core challenge of &lt;strong&gt;database concurrency&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;In today&amp;rsquo;s world, &lt;a href="https://www.netdata.cloud/academy/what-is-application-performance-monitoring-apm/"&gt;almost every application interacts with databases&lt;/a&gt; accessed by multiple users or processes simultaneously. &lt;strong&gt;Database concurrency&lt;/strong&gt; is the ability of a Database Management System (DBMS) to handle these simultaneous operations efficiently while maintaining data integrity and consistency. For developers, DevOps engineers, and SREs, understanding concurrency is vital for building reliable and performant applications. Let&amp;rsquo;s explore what concurrency entails, the problems it can cause if unmanaged, and the techniques used to control it.&lt;/p&gt;</description></item><item><title>MySQL ERROR 1205: Lock wait timeout exceeded; try restarting transaction</title><link>https://www.netdata.cloud/guides/mysql/mysql-lock-wait-timeout-exceeded/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-lock-wait-timeout-exceeded/</guid><description>&lt;p&gt;&lt;code&gt;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction&lt;/code&gt; appears when one transaction holds an InnoDB row lock so long that another transaction exhausts &lt;code&gt;innodb_lock_wait_timeout&lt;/code&gt; (default 50 seconds). Unlike a deadlock, which InnoDB resolves automatically, a timeout means a blocker is still active. The root cause is almost always a long-running transaction or hot row contention. Find it before it cascades into a wider outage.&lt;/p&gt;&#10;&lt;p&gt;This error applies only to InnoDB row-level locks. Metadata lock waits from DDL operations show &lt;code&gt;Waiting for table metadata lock&lt;/code&gt; in &lt;code&gt;SHOW PROCESSLIST&lt;/code&gt; and are governed by &lt;code&gt;lock_wait_timeout&lt;/code&gt;, not &lt;code&gt;innodb_lock_wait_timeout&lt;/code&gt;. Table-level locks are also separate. If you see ERROR 1205, you are dealing with row-level contention inside InnoDB.&lt;/p&gt;</description></item><item><title>MySQL ERROR 1213: Deadlock found when trying to get lock; try restarting transaction</title><link>https://www.netdata.cloud/guides/mysql/mysql-deadlock-found/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-deadlock-found/</guid><description>&lt;p&gt;Your application logs show &lt;code&gt;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction&lt;/code&gt;. One transaction was rolled back; the other completed normally. InnoDB broke a circular lock wait by selecting the cheaper transaction as the victim. Occasional deadlocks (less than one per hour) in high-concurrency OLTP are normal. A sustained storm is not: it means transactions are colliding under load.&lt;/p&gt;&#10;&lt;p&gt;The error is raised instantly. There is no timeout. InnoDB detects the cycle in the wait-for graph and rolls back the victim before either transaction waits. Without retry logic, users see failures. With retry logic, a high deadlock rate burns CPU and latency on repeated attempts.&lt;/p&gt;</description></item><item><title>MySQL FLUSH TABLES WITH READ LOCK stall: backups that freeze the server</title><link>https://www.netdata.cloud/guides/mysql/mysql-flush-tables-with-read-lock-stall/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-flush-tables-with-read-lock-stall/</guid><description>&lt;p&gt;Your application suddenly cannot write. &lt;code&gt;Threads_connected&lt;/code&gt; climbs toward &lt;code&gt;max_connections&lt;/code&gt;, but &lt;code&gt;Questions&lt;/code&gt; flatlines. The last change was a backup job that started ten minutes ago. The culprit is almost always &lt;code&gt;FLUSH TABLES WITH READ LOCK&lt;/code&gt; (FTWRL), and the damage is caused not by the lock itself but by what happens while the server waits to acquire it.&lt;/p&gt;&#10;&lt;p&gt;FTWRL is triggered by &lt;code&gt;mysqldump --master-data&lt;/code&gt;, &lt;code&gt;mysqldump --lock-tables&lt;/code&gt;, and similar tools that need a consistent logical backup. It attempts to close all open tables and acquire a global read lock. While it waits for a long-running query to finish, new writes are already blocked. The result is a whole-server freeze: the query rate drops to zero, connections pile up, and the application sees cascading timeouts.&lt;/p&gt;</description></item><item><title>MySQL InnoDB row lock contention: finding who blocks whom</title><link>https://www.netdata.cloud/guides/mysql/mysql-row-lock-contention/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-row-lock-contention/</guid><description>&lt;p&gt;Queries that normally finish in milliseconds take seconds. &lt;code&gt;Threads_running&lt;/code&gt; climbs while &lt;code&gt;Questions&lt;/code&gt; stalls. &lt;code&gt;SHOW PROCESSLIST&lt;/code&gt; shows active threads, yet the database is frozen. That is the shape of InnoDB row lock contention: transactions are waiting to release row-level locks, and the queue is growing.&lt;/p&gt;&#10;&lt;p&gt;Row lock contention differs from a metadata lock cascade. Metadata locks block DDL and DML at the table level and live in &lt;code&gt;performance_schema.metadata_locks&lt;/code&gt;. Row locks are held by open InnoDB transactions and block at the row, gap, or next-key level. Rising &lt;code&gt;Innodb_row_lock_current_waits&lt;/code&gt; alongside rising &lt;code&gt;Threads_running&lt;/code&gt; signals a live contention crisis. The goal is to identify the blocker, the waiter, and the lock footprint so you can break the chain without guessing.&lt;/p&gt;</description></item><item><title>MySQL metadata lock cascade: how one ALTER TABLE freezes a whole table</title><link>https://www.netdata.cloud/guides/mysql/mysql-metadata-lock-cascade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-metadata-lock-cascade/</guid><description>&lt;p&gt;You run an &lt;code&gt;ALTER TABLE&lt;/code&gt; to add an index. Seconds later, health checks fail for queries that touch only that table. Other tables work fine. CPU and disk are idle. The connection pool fills. &lt;code&gt;SHOW ENGINE INNODB STATUS&lt;/code&gt; shows no row lock waits. The culprit is a metadata lock cascade, not InnoDB contention.&lt;/p&gt;&#10;&lt;p&gt;This happens when DDL requests an exclusive metadata lock (MDL) on a table already protected by a shared MDL held by a long-running or idle transaction. The DDL waits. Subsequent DML on that table queues behind it. The queue grows until the connection pool exhausts and the application times out. Because the outage is isolated to one table and leaves no trace in InnoDB lock metrics, it is easy to misdiagnose as a network blip or a runaway query.&lt;/p&gt;</description></item><item><title>MySQL online DDL still blocking: ALGORITHM, LOCK, and the copy phase</title><link>https://www.netdata.cloud/guides/mysql/mysql-online-ddl-blocking/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-online-ddl-blocking/</guid><description>&lt;p&gt;Online DDL in MySQL is not lock-free. Even with &lt;code&gt;ALGORITHM=INPLACE&lt;/code&gt; or &lt;code&gt;ALGORITHM=INSTANT&lt;/code&gt;, and even with &lt;code&gt;LOCK=NONE&lt;/code&gt;, every online DDL operation passes through a brief window where it upgrades its metadata lock (MDL) to exclusive. That window is short, but it is real, and it is the single most common reason an &amp;ldquo;online&amp;rdquo; schema change still stalls a busy production table.&lt;/p&gt;&#10;&lt;p&gt;This article explains the three-phase MDL model that online DDL uses, why &lt;code&gt;ALGORITHM=INPLACE&lt;/code&gt; with &lt;code&gt;LOCK=NONE&lt;/code&gt; can still block, what the copy phase actually does, and how third-party tools such as &lt;code&gt;pt-online-schema-change&lt;/code&gt; and &lt;code&gt;gh-ost&lt;/code&gt; change the picture. It assumes you already understand the broader MySQL mental model. See the hub page for the failure-pattern catalogue that frames metadata lock stalls as one of MySQL&amp;rsquo;s characteristic outage archetypes.&lt;/p&gt;</description></item><item><title>MySQL Waiting for table metadata lock: diagnosing the DDL stall</title><link>https://www.netdata.cloud/guides/mysql/mysql-waiting-for-table-metadata-lock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/mysql/mysql-waiting-for-table-metadata-lock/</guid><description>&lt;p&gt;You run &lt;code&gt;SHOW PROCESSLIST&lt;/code&gt; and see a wall of threads in &lt;code&gt;Waiting for table metadata lock&lt;/code&gt;. An &lt;code&gt;ALTER TABLE&lt;/code&gt; that should finish in seconds hangs for minutes. Queries against one table stop returning, the application connection pool drains, and CPU and disk look calm. This is a metadata lock (MDL) stall. It is a queueing failure, not resource exhaustion. Left alone, it cascades into connection exhaustion and a partial outage where every other table continues to work normally.&lt;/p&gt;</description></item><item><title>PostgreSQL ALTER TABLE blocked: zero-downtime DDL patterns</title><link>https://www.netdata.cloud/guides/postgres/postgres-alter-table-blocked/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/postgres/postgres-alter-table-blocked/</guid><description>&lt;p&gt;An &lt;code&gt;ALTER TABLE&lt;/code&gt; to add a column or change a type hangs. Application queries time out. Connection pools saturate. What looked like a simple schema change becomes a production incident.&lt;/p&gt;&#10;&lt;p&gt;By default, &lt;code&gt;ALTER TABLE&lt;/code&gt; acquires an &lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt; lock. It conflicts with every other lock mode, including &lt;code&gt;ACCESS SHARE&lt;/code&gt; held by a plain &lt;code&gt;SELECT&lt;/code&gt;. Once the DDL statement queues behind a blocker, every subsequent read and write on that table queues behind the waiting DDL. The table goes offline before the &lt;code&gt;ALTER TABLE&lt;/code&gt; executes any work.&lt;/p&gt;</description></item><item><title>PostgreSQL Blocking Queries: Finding The Root Blocker In A Lock Cascade</title><link>https://www.netdata.cloud/guides/postgres/postgres-blocking-queries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/postgres/postgres-blocking-queries/</guid><description>&lt;p&gt;A query that normally finishes in milliseconds is now running for minutes. &lt;code&gt;pg_stat_activity&lt;/code&gt; shows a queue of sessions with &lt;code&gt;wait_event_type = 'Lock'&lt;/code&gt;. You identify one session holding the contested lock, but terminating it does not clear the queue. That session was itself blocked by another, which was blocked by another. Until you find the session at the head of the chain, the cascade continues.&lt;/p&gt;&#10;&lt;p&gt;Use this guide to traverse the lock graph, distinguish direct blockers from the root blocker, and decide whether to terminate or wait. It applies to self-managed PostgreSQL, RDS, Aurora, and containerized deployments where you have access to &lt;code&gt;pg_stat_activity&lt;/code&gt; and &lt;code&gt;pg_locks&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>PostgreSQL deadlock detected: how to diagnose and prevent deadlocks</title><link>https://www.netdata.cloud/guides/postgres/postgres-deadlock-detected/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/postgres/postgres-deadlock-detected/</guid><description>&lt;p&gt;&lt;code&gt;ERROR: deadlock detected&lt;/code&gt; means PostgreSQL aborted one transaction to break a circular wait-for graph. The victim returns SQLSTATE &lt;code&gt;40P01&lt;/code&gt;; the application must retry it. Deadlocks are a safety mechanism, not a bug: they fire when concurrent transactions acquire locks in incompatible orders. Even a few per minute degrade user experience, burn retry budget, and mask deeper contention. This guide shows how to read the deadlock output, find the root cause, and stop the cycle.&lt;/p&gt;</description></item><item><title>PostgreSQL ERROR: Could Not Obtain Lock — Diagnosis &amp; Recovery</title><link>https://www.netdata.cloud/guides/postgres/postgres-lock-not-available/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/postgres/postgres-lock-not-available/</guid><description>&lt;p&gt;&lt;code&gt;ERROR: could not obtain lock on row in relation&lt;/code&gt; and &lt;code&gt;ERROR: canceling statement due to lock timeout&lt;/code&gt; mean a query requested a lock but PostgreSQL refused to wait. The database is not down; a session is holding a resource another transaction needs.&lt;/p&gt;&#10;&lt;p&gt;Three variants produce these errors:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;SELECT ... FOR UPDATE NOWAIT&lt;/code&gt; fails immediately if the row is locked.&lt;/li&gt;&#10;&lt;li&gt;A statement that exceeds &lt;code&gt;lock_timeout&lt;/code&gt; fails after waiting.&lt;/li&gt;&#10;&lt;li&gt;DDL such as &lt;code&gt;ALTER TABLE&lt;/code&gt; or &lt;code&gt;TRUNCATE&lt;/code&gt; requires &lt;code&gt;AccessExclusiveLock&lt;/code&gt; and will wait or fail depending on session configuration.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;These often cascade: one long-running query blocks a schema change, the schema change queues behind it, and subsequent queries queue behind the DDL until the &lt;a &gt;connection pool exhausts&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>