| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #!/usr/bin/env python3
- """
- 查找并杀掉数据库端的僵尸连接,释放 knowledge 表的锁
- """
- import os, psycopg2
- from dotenv import load_dotenv
- _dir = os.path.dirname(os.path.abspath(__file__))
- _root = os.path.normpath(os.path.join(_dir, '..', '..'))
- load_dotenv(os.path.join(_root, '.env'))
- conn = psycopg2.connect(
- host=os.getenv('KNOWHUB_DB'),
- port=int(os.getenv('KNOWHUB_PORT', 5432)),
- user=os.getenv('KNOWHUB_USER'),
- password=os.getenv('KNOWHUB_PASSWORD'),
- database=os.getenv('KNOWHUB_DB_NAME'),
- connect_timeout=10
- )
- conn.autocommit = True
- cur = conn.cursor()
- print("Connected.\n")
- # 1. 查所有非 idle 的活跃连接
- print("=== Active connections (non-idle) ===")
- cur.execute("""
- SELECT pid, state, now() - query_start as duration, query
- FROM pg_stat_activity
- WHERE state != 'idle' AND pid != pg_backend_pid()
- ORDER BY query_start
- """)
- rows = cur.fetchall()
- print(f"Found {len(rows)} active connections.\n")
- for r in rows:
- print(f" PID={r[0]} state={r[1]} duration={r[2]}")
- print(f" query: {str(r[3])[:150]}")
- print()
- # 2. 查所有 idle in transaction 的连接(这些最可能持有锁)
- print("=== Idle-in-transaction connections ===")
- cur.execute("""
- SELECT pid, state, now() - query_start as duration, query
- FROM pg_stat_activity
- WHERE state = 'idle in transaction' AND pid != pg_backend_pid()
- ORDER BY query_start
- """)
- idle_tx = cur.fetchall()
- print(f"Found {len(idle_tx)} idle-in-transaction connections.\n")
- for r in idle_tx:
- print(f" PID={r[0]} duration={r[2]}")
- print(f" last query: {str(r[3])[:150]}")
- print()
- # 3. 杀掉所有非当前的 非idle 和 idle-in-transaction 连接
- cur.execute("""
- SELECT pid FROM pg_stat_activity
- WHERE pid != pg_backend_pid()
- AND (state != 'idle' OR state = 'idle in transaction')
- """)
- pids = [r[0] for r in cur.fetchall()]
- print(f"=== Terminating {len(pids)} backend connections ===")
- for pid in pids:
- try:
- cur.execute("SELECT pg_terminate_backend(%s)", (pid,))
- print(f" Killed PID {pid}")
- except Exception as e:
- print(f" Failed PID {pid}: {e}")
- print("\nDone. Try opening knowledge table in Navicat now.")
- cur.close()
- conn.close()
|