소스 정보
- 저장소
- tools-only/X-Skills
- 최근 소스 활동
- 2026년 2월 9일 04:32
- 감지된 SKILL.md 언어
- 영어
- 스타
- 7
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tools-only/X-Skills --skill transactions명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | transactions |
| description | Monitor database transactions with real-time alerting for performance and... |
| shortcut | txnm |
Monitor database transaction performance, detect long-running transactions, identify lock contention, track rollback rates, and automatically alert on transaction anomalies for production database health.
Use /txn-monitor when you need to:
DON'T use this when:
This command implements real-time transaction monitoring with automated alerting because:
Alternative considered: Periodic manual checks
Alternative considered: Database log parsing
Before running this command:
Configure database to track transaction statistics.
Create monitoring script that polls transaction statistics every 5-10 seconds.
Set thresholds for long-running transactions, lock waits, and rollback rates.
Auto-kill transactions exceeding thresholds or alert operators.
Build Grafana dashboards for transaction metrics visualization.
The command generates:
monitoring/transaction_monitor.py - Real-time transaction monitoring daemonqueries/transaction_analysis.sql - Transaction health diagnostic queriesalerts/transaction_alerts.yml - Prometheus alerting rulesdashboards/transaction_dashboard.json - Grafana dashboard configurationdocs/transaction_runbook.md - Incident response procedures# monitoring/postgres_transaction_monitor.py
import psycopg2
from psycopg2.extras import Dict Cursor
import time
import logging
from typing import List, Dict, Optional
from dataclasses import dataclass, asdict
from datetime import datetime, timedelta
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@dataclass
class TransactionInfo:
"""Represents an active transaction."""
pid: int
username: str
database: str
application_name: str
client_addr: str
state: str
query: str
transaction_start: datetime
query_start: datetime
wait_event: Optional[str]
blocking_pids: List[int]
def duration_seconds(self) -> float:
return (datetime.now() - self.transaction_start).total_seconds()
def to_dict(self) -> dict:
result = asdict(self)
result['transaction_start'] = self.transaction_start.isoformat()
result['query_start'] = self.query_start.isoformat()
result[] = .duration_seconds()
result
:
():
.conn_string = connection_string
.long_transaction_threshold = long_transaction_threshold
.check_interval = check_interval
.stats = {
: ,
: ,
: ,
:
}
():
psycopg2.connect(.conn_string, cursor_factory=DictCursor)
() -> [TransactionInfo]:
query =
conn = .connect()
:
conn.cursor() cur:
cur.execute(query)
rows = cur.fetchall()
transactions = []
row rows:
txn = TransactionInfo(
pid=row[],
username=row[],
database=row[],
application_name=row[] ,
client_addr=row[] ,
state=row[],
query=row[][:],
transaction_start=row[],
query_start=row[],
wait_event=row[],
blocking_pids=row[] []
)
transactions.append(txn)
transactions
:
conn.close()
() -> [TransactionInfo]:
[
txn txn transactions
txn.duration_seconds() > .long_transaction_threshold
]
() -> [TransactionInfo]:
[
txn txn transactions
txn.blocking_pids (txn.blocking_pids) >
]
() -> [TransactionInfo]:
[
txn txn transactions
txn.state ==
txn.duration_seconds() >
]
() -> :
conn = .connect()
:
conn.cursor() cur:
cur.execute(, (pid,))
success = cur.fetchone()[]
success:
logger.warning()
:
logger.error()
success
:
conn.close()
() -> [, ]:
conn = .connect()
:
conn.cursor() cur:
cur.execute()
row = cur.fetchone()
total_txns = row[] + row[]
rollback_rate = (row[] / total_txns * ) total_txns >
{
: row[],
: row[],
: row[],
: row[],
: (rollback_rate, ),
: row[]
}
:
conn.close()
():
log_func = {
: logger.critical,
: logger.warning,
: logger.info
}.get(severity, logger.info)
log_func()
details:
logger.info()
():
logger.info()
:
:
transactions = .get_active_transactions()
.stats[] = (transactions)
long_running = .find_long_running_transactions(transactions)
long_running:
.stats[] = (long_running)
txn long_running:
.alert(
,
,
{
: txn.duration_seconds(),
: txn.database,
: txn.username,
: txn.query
}
)
txn.duration_seconds() > :
.kill_transaction(
txn.pid,
)
blocked = .find_blocked_transactions(transactions)
blocked:
.stats[] = (blocked)
txn blocked:
.alert(
,
,
{
: txn.blocking_pids,
: txn.wait_event,
: txn.duration_seconds()
}
)
idle_txns = .find_idle_in_transaction(transactions)
idle_txns:
.stats[] = (idle_txns)
txn idle_txns:
.alert(
,
,
{
: txn.duration_seconds(),
: txn.application_name
}
)
txn.duration_seconds() > :
.kill_transaction(txn.pid, )
stats = .get_transaction_stats()
stats[] > :
.alert(
,
,
stats
)
logger.info(
)
time.sleep(.check_interval)
KeyboardInterrupt:
logger.info()
Exception e:
logger.error()
time.sleep(.check_interval)
__name__ == :
monitor = PostgreSQLTransactionMonitor(
connection_string=,
long_transaction_threshold=,
check_interval=
)
monitor.run_monitoring_loop()
-- PostgreSQL transaction health diagnostic queries
-- 1. Long-running transactions
SELECT
pid,
usename,
application_name,
client_addr,
NOW() - xact_start AS transaction_duration,
NOW() - query_start AS query_duration,
state,
LEFT(query, 100) AS query_snippet
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
AND state != 'idle'
AND pid != pg_backend_pid()
ORDER BY xact_start;
-- 2. Blocking tree (which transactions are blocking others)
WITH RECURSIVE blocking_tree AS (
SELECT
a.pid,
a.usename,
a.query AS blocked_query,
NULL::integer AS blocking_pid,
NULL::text AS blocking_query,
1 AS level
FROM pg_stat_activity a
WHERE NOT EXISTS (
SELECT 1 FROM pg_stat_activity b
WHERE b.pid = ANY(pg_blocking_pids(a.pid))
)
AND a.pid IN (
SELECT unnest(pg_blocking_pids(c.pid))
pg_stat_activity c
)
a.pid,
a.usename,
a.query,
b.pid,
b.query,
bt.level
blocking_tree bt
pg_stat_activity a a.pid (
(pg_blocking_pids(x.pid))
pg_stat_activity x
x.pid bt.pid
)
pg_stat_activity b b.pid (pg_blocking_pids(a.pid))
)
level,
pid,
usename,
blocking_pid,
(blocked_query, ) blocked_query,
(blocking_query, ) blocking_query
blocking_tree
level, pid;
datname,
xact_commit commits,
xact_rollback rollbacks,
ROUND( xact_rollback (xact_commit xact_rollback, ), ) rollback_rate_percent
pg_stat_database
datname (, , )
rollback_rate_percent ;
pid,
usename,
application_name,
client_addr,
NOW() state_change idle_duration,
state,
query
pg_stat_activity
state
pid pg_backend_pid()
state_change;
wait_event_type,
wait_event,
() waiting_count,
( pid) waiting_pids
pg_stat_activity
wait_event
state
wait_event_type, wait_event
waiting_count ;
| Error | Cause | Solution |
|---|---|---|
| "Permission denied for pg_stat_activity" | Insufficient monitoring privileges | Grant pg_monitor role or SELECT on pg_stat_activity |
| "Cannot terminate backend" | Trying to kill superuser connection | Use pg_cancel_backend or kill from OS level |
| "Connection pool exhausted" | Too many idle connections | Kill idle in transaction connections, increase pool size |
| "High rollback rate" | Application errors or constraint violations | Review application logs and fix bugs |
| "Lock wait timeout exceeded" | Deadlock or very long lock hold | Analyze blocking queries, implement timeouts |
Monitoring Intervals
check_interval: 5-10 seconds for real-time alertinglong_transaction_threshold: 30-60 seconds (production), 300s (analytics)idle_in_transaction_timeout: 600 seconds (10 minutes)Auto-Kill Thresholds
Alert Thresholds
DO:
DON'T:
/database-deadlock-detector - Detailed deadlock analysis/database-health-monitor - Overall database health metrics/sql-query-optimizer - Optimize slow queries causing lock contention/database-connection-pooler - Manage connection pool sizingSOC 직업 분류 기준