惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
Google Developers Blog
J
Java Code Geeks
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
人人都是产品经理
人人都是产品经理
Martin Fowler
Martin Fowler
IT之家
IT之家
博客园_首页
B
Blog RSS Feed
Google DeepMind News
Google DeepMind News
B
Blog
U
Unit 42
Apple Machine Learning Research
Apple Machine Learning Research
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
N
Netflix TechBlog - Medium
T
Tailwind CSS Blog
博客园 - 聂微东
腾讯CDC
A
About on SuperTechFans

Hacker News: Show HN

PurrrrrFocus: Pomodoro Timer App - App Store Workflow Engine — Multi-Step Orchestration for Bun RapidPhoto: Pro Photo Editor App - App Store GitHub - DheerG/swarms: Achieve extraordinary results with claude code across a variety of tasks SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Show HN: VCoding – A 5 MB native Windows IDE with no dynamic dependencies Show HN: LLMs don't hallucinate because they're bad at math, it's the format GitHub - Agent-FM/agentfm-core: AgentFM is a peer-to-peer network that turns everyday computers into a decentralized AI supercomputer. AgentFM lets you run massive AI workloads directly across a global mesh of idle CPUs and GPUs. Show HN: Tracking Top US Science Olympiad Alumni over Last 25 Years GitHub - Potarix/agent-hub: One place to talk to all your agents Show HN: Runtime security for AI agents(injection,tool abuse, data exfiltration) GitHub - dubeyKartikay/lazyspotify: Terminal Spotify client for macOS and Linux GitHub - the-banana-tool/king-louie: Easy to use GUI Personal AI Assistant. Win/Linux/Mac. Show HN I made my vacation rental bookable by AI agents–no Airbnb, 0% commission GitHub - basteez/jsf-autoreload: maven plugin to enable hot reload on jsf projects uvm32/hosts/host-gdbstub at main · ringtailsoftware/uvm32 GitHub - labsai/EDDI: Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus. GitHub - glitchnsec/fortyone-oss: AI Executive Assistant Platform Quickstart | Alien GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. GitHub - ocrbase-hq/ocrbase: 📄 PDF/IMG ->.MD/JSON Document OCR API for PaddleOCR and GLMOCR. Self-hostable. GitHub - impactjo/home-memory: MCP server that lets your AI assistant remember everything about your home. GitHub - Sets88/dbcls: DbCls is a powerful terminal database client that supports various databases GitHub - neptun2000/heor-agent-mcp GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh RollQuation: Math Puzzles - Apps on Google Play GitHub - dropbox/witchcraft Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis GitHub - opentalon/opentalon: OpenTalon is an open-source platform built from the ground up in Go as a robust alternative to OpenClaw LinkedIn™ 职位抓取工具 - Chrome 应用商店
PostgreSQL Deadlock ShareLock Transaction Audit
gwei · 2026-06-16 · via Hacker News: Show HN

Initializing Enclave...

How to Fix PostgreSQL Deadlock Detected on ShareLock Transaction (With Root Cause Analysis)

Threat/Impact Level: HIGH | Downtime Risk: HIGH | Time to Fix: 15–45 mins


TL;DR

  • What broke: Two concurrent transactions acquired locks in inverse order — PostgreSQL's deadlock detector killed one to break the cycle, rolling back that transaction entirely.
  • How to fix it: Enforce a consistent lock acquisition order across all transactions touching the same rows; use SELECT FOR UPDATE with explicit ordering or SKIP LOCKED for queue-style workloads.
  • Use our Client-Side Sandbox below to paste your transaction logic and auto-refactor the lock ordering with zero data leaving your browser.

The Incident (What Does the Error Mean?)

ERROR:  deadlock detected
DETAIL:  Process 12345 waits for ShareLock on transaction 67890;
         blocked by process 67890.
         Process 67890 waits for ShareLock on transaction 12345;
         blocked by process 12345.
HINT:  See server log for query details.
CONTEXT:  while updating tuple (0,42) in relation "orders"

PostgreSQL's deadlock detector runs every deadlock_timeout (default: 1 second). When it fires, it picks one transaction as the victim and issues a hard rollback. The application receives this error on the next query execution. The rolled-back transaction's work is entirely lost — your application must detect this error code (40P01) and retry, or the operation silently fails.

ShareLocks in this context are row-level locks held by in-progress transactions, not table-level shared locks. The deadlock occurs when Transaction A holds a lock on Row 1 and wants Row 2, while Transaction B holds Row 2 and wants Row 1.


The Attack Vector / Blast Radius

This is not a one-off failure. In high-concurrency environments this is a recurring production degradation pattern:

  • Connection pool exhaustion: Threads waiting on locks pile up. If deadlock_timeout is 1s and you have 50 concurrent conflicting transactions, your connection pool saturates before the detector clears them.
  • Cascading retry storms: Naive retry logic without exponential backoff causes the same transactions to immediately re-conflict, worsening throughput under load.
  • Silent data loss: Applications that catch the error without retrying lose writes permanently — especially dangerous in financial ledgers, inventory systems, and order management where the rolled-back transaction updated multiple tables.
  • Replication lag amplification: On streaming replicas, the lock contention on primary causes WAL write spikes. Under sustained deadlock storms, replica lag can exceed your RTO.
  • ORM blind spots: Hibernate, SQLAlchemy, and ActiveRecord often wrap operations in implicit transactions with non-deterministic lock ordering based on object graph traversal order — making this nearly impossible to debug without query-level logging.

How to Fix It

Basic Fix — Enforce Consistent Lock Ordering

The root cause is always lock acquisition order inversion. Fix it by sorting the rows you intend to lock before acquiring locks.

-- Transaction A and B both update accounts: sender and receiver
-- BAD: Each transaction locks in application-determined order (non-deterministic)
- BEGIN;
- UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- locks row 1
- UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- waits for row 2
- COMMIT;

-- (Concurrent Transaction B)
- BEGIN;
- UPDATE accounts SET balance = balance - 50 WHERE id = 2;  -- locks row 2
- UPDATE accounts SET balance = balance + 50 WHERE id = 1;  -- DEADLOCK
- COMMIT;

-- GOOD: Always lock in ascending ID order regardless of transaction direction
+ BEGIN;
+ -- Pre-sort: always lock lower ID first
+ SELECT id FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
+ UPDATE accounts SET balance = balance - 100 WHERE id = 1;
+ UPDATE accounts SET balance = balance + 100 WHERE id = 2;
+ COMMIT;

Enterprise Best Practice — SKIP LOCKED + Advisory Locks + Retry Logic

-- BAD: Blocking SELECT FOR UPDATE with no timeout, no retry handling
- SELECT * FROM job_queue WHERE status = 'pending' FOR UPDATE;

-- GOOD: Non-blocking queue consumption with SKIP LOCKED
+ SELECT * FROM job_queue
+   WHERE status = 'pending'
+   ORDER BY created_at ASC
+   LIMIT 1
+   FOR UPDATE SKIP LOCKED;

-- GOOD: Application-level retry with 40P01 detection (Python/psycopg2 example)
+ import psycopg2
+ from psycopg2 import errors
+ import time, random
+
+ def execute_with_retry(conn, fn, max_retries=5):
+     for attempt in range(max_retries):
+         try:
+             with conn.cursor() as cur:
+                 fn(cur)
+                 conn.commit()
+                 return
+         except errors.DeadlockDetected:
+             conn.rollback()
+             wait = (2 ** attempt) + random.uniform(0, 0.5)
+             time.sleep(wait)
+     raise Exception("Max retries exceeded on deadlock")

-- GOOD: PostgreSQL advisory locks for application-level mutex (no row lock needed)
+ SELECT pg_advisory_xact_lock(hashtext('transfer:' || LEAST(1,2)::text || ':' || GREATEST(1,2)::text));

Key postgresql.conf tuning:

- deadlock_timeout = 1s       # Default — too slow for high-concurrency OLTP
+ deadlock_timeout = 100ms    # Detect and resolve faster under load
+ lock_timeout = 5000         # Kill queries waiting >5s for a lock (per session or globally)
+ idle_in_transaction_session_timeout = 30000  # Kill abandoned open transactions

💡 Tired of pasting proprietary configs into ChatGPT? Generic AI tools log your company's ARNs, DB strings, and private keys. StackEngine is a zero-backend, pure Client-Side WASM utility. Drop your failing config into the sandbox above. We redact your secrets locally in the browser and auto-generate the refactored code using your own API key.


Prevention in CI/CD

1. Enable log_lock_waits in PostgreSQL — Non-Negotiable

-- postgresql.conf or per-session
log_lock_waits = on
deadlock_timeout = 100ms

This logs every lock wait exceeding deadlock_timeout to pg_log. Feed this into your observability stack (Datadog, Grafana Loki) and alert on deadlock detected log lines.

2. Query-Level Lock Analysis in Staging

-- Run during load tests to catch lock contention before production
SELECT
  pid, wait_event_type, wait_event, state,
  left(query, 80) AS query_snippet
FROM pg_stat_activity
WHERE wait_event_type = 'Lock'
ORDER BY state_change;

3. pgBadger / auto_explain in CI

  • pgBadger: Parse PostgreSQL logs in your CI pipeline and fail the build if deadlock frequency exceeds threshold.
  • auto_explain: Log execution plans for slow/blocked queries automatically.
- # No query plan logging
+ shared_preload_libraries = 'auto_explain'
+ auto_explain.log_min_duration = 500
+ auto_explain.log_analyze = on

4. Integration Test Lock Order Enforcement

For ORMs, write integration tests that run the same transaction concurrently using threading and assert no 40P01 errors are raised. This catches ORM-level lock order inversion before deployment.

# pytest example — run two conflicting transactions concurrently
import threading, pytest

def test_no_deadlock_on_concurrent_transfer():
    errors = []
    def transfer(from_id, to_id):
        try:
            do_transfer(from_id, to_id)  # your application function
        except DeadlockDetected as e:
            errors.append(e)
    t1 = threading.Thread(target=transfer, args=(1, 2))
    t2 = threading.Thread(target=transfer, args=(2, 1))
    t1.start(); t2.start()
    t1.join(); t2.join()
    assert len(errors) == 0, f"Deadlock detected in concurrent transfer test: {errors}"

5. Checkov / Terraform — Enforce lock_timeout at Infrastructure Level

- # RDS parameter group — no lock timeout set
- resource "aws_db_parameter_group" "pg" {
-   # empty
- }

+ resource "aws_db_parameter_group" "pg" {
+   parameter {
+     name  = "lock_timeout"
+     value = "5000"
+   }
+   parameter {
+     name  = "deadlock_timeout"
+     value = "100"
+   }
+   parameter {
+     name  = "idle_in_transaction_session_timeout"
+     value = "30000"
+   }
+ }

Related Diagnostics

"Part of the Performance Utility Matrix."

View all 219 Performance Tools →