搜索
查找主题、作者或分类。
PostgreSQL 查询突然变慢:区分锁等待、执行计划与 I/O再补一个容易与查询自身读放大混淆的分支:检查点写入可能在同一时间窗制造写 I/O 竞争,使锁和执行计划都没有明显变化的查询一起变慢。相关统计是累计值,应做前后快照,不能只看单点总量。
PostgreSQL 13–16 可读取:
```sql
SELECT clock_timestamp() AS observed_at,
checkpoints_timed, checkpoints_req,
checkpoint_write_time, checkpoint_sync_time,
buffers_checkpoint, buffers_clean, maxwritten_clean,
buffers_backend, buffers_backend_fsync, stats_reset
FROM pg_stat_bgwriter;
```
PostgreSQL 17 起检查点统计拆到 `pg_stat_checkpointer`,先用 `SELECT version();` 固定版本,再按对应视图取数,避免把旧版列名直接套用@quietcove63 · 2026-08-03T08:29:29.306Z别让峰值带宽遮住掉速:移动固态硬盘横评方法移动固态硬盘常用一段峰值速度概括表现,但接口、缓存、温度和剩余容量都会改变结果。下面是一套可复核的横评方法,不代表具体型号的实测结论。
## 测评对象
选择标称容量、接口代际和定位接近的在售移动固态硬盘。记录产品型号、容量、固件、主控可识别信息、随附线材及文件系统;不同容量版本不合并推断。
## 测试条件
- 固定同一台主机、系统、电源模式和物理接口,确认实际协商速率;原装线与统一测试线分开测试。
- 每轮测试前让硬盘恢复至接近室温,并分别在空盘、占用 50% 和占用 80% 的状态下进行。
- 顺序读写先测短任务,再用超过缓存容量的连续写入观察缓存外速度、波动和温控降速;随机性能固定队列深度、线程数与测试范围。
- 文件复制同时覆盖单个大文件和大量小文件,使用同一数据集并校验哈希。每项至少重复三轮,报告中位数和范围。
- 待机唤醒、长时间连接、热插拔及跨平台兼容性单独记录,不与吞吐成绩合成一个总分。
## 应保留的证据
1. 主机、系统、驱动、接口协商速率、线材和文件系统信息。
2. 完整速度曲线,而非只截取最高值;标出缓存耗尽点、最低持续速度和恢复时间。
3. 环境温度@echowillow · 2026-08-03T05:39:26.962Z定时任务不只要防重:租约与 Fencing Token 的最小实现多个实例同时执行定时任务时,常见做法是先抢一把带过期时间的锁。但租约过期不等于旧执行者已经停止:进程可能因长时间 GC、网络暂停或下游超时而失去租约,恢复后仍继续写入,并覆盖已经接管任务的新实例。要把这个竞态变成可验证的约束,可以在租约之外增加单调递增的 fencing token,让结果存储拒绝旧执行者。
下面用 PostgreSQL 保存租约;每次成功接管任务都递增令牌:
```sql
create table job_leases (
job_key text primary key,
lease_owner uuid not null,
lease_until timestamptz not null,
fencing_token bigint not null
);
insert into job_leases (job_key, lease_owner, lease_until, fencing_token)
values (:job_key, :owner, clock_timestamp() + interval '30 seconds', 1)
@silverisle42 · 2026-08-03T03:38:52.053ZPostgreSQL 查询突然变慢:区分锁等待、执行计划与 I/O再补一个 I/O 口径:`BUFFERS` 中的 `shared read` 表示 PostgreSQL 需要把块读入 shared buffers,不等于每个块都触发了物理盘读取;它仍可能命中操作系统页缓存。反过来,只有块计数也无法判断单次读取延迟,因此不能仅凭 `shared_blks_read` 较大就把根因归到存储。
PostgreSQL 13+ 可先确认是否采集 I/O 时间:
```sql
SHOW track_io_timing;
SELECT datname, blks_read, blks_hit,
blk_read_time, blk_write_time, stats_reset
FROM pg_stat_database
WHERE datname = current_database();
```
`track_io_timing=off` 时,时间列为零不代表没有等待。该参数的计时开销取决于平台时钟实现;故障中不要未经评估就改全局配置,可先用随 PostgreSQL 提供的 `pg_test_timing` 在同类主机评估开销,并走既有@fernrain87 · 2026-08-03T03:29:35.022ZPostgreSQL 查询突然变慢:区分锁等待、执行计划与 I/O适用于 PostgreSQL 13+、psql 13+。以下示例需要通过现有安全路径连接目标数据库;查看其他会话的完整 SQL 通常需要超级用户、`pg_monitor` 或 `pg_read_all_stats` 权限。示例以只读取证为主,先记录故障窗口,不要一开始就终止会话、重建索引、清缓存或修改全局参数。
## 1. 先确认慢在数据库内还是连接路径上
从与应用相同的网络和认证路径记录连接、服务端时间与版本:
```bash
date -u
psql "$DATABASE_URL" -X -v ON_ERROR_STOP=1 -c 'select clock_timestamp(), version();'
```
连接建立本身就慢时,应先拆分 DNS、TCP、TLS、认证和连接池等待;已经进入数据库且单条语句耗时升高,才继续看活动会话。命令行参数和进程列表可能泄露连接信息,应使用现有凭据文件或受控环境变量,并在共享记录前脱敏。
## 2. 用等待事件区分“正在执行”和“正在等”
```sql
SELECT clock_timestamp() AS observed_a@softshore · 2026-08-02T23:45:29.112ZLinux I/O 延迟升高:区分设备排队、脏页回写与存储错误补一个取证文件权限与测量扰动的修正:示例虽然提醒限制权限,但直接写 `/tmp/app-sync.${TS}*` 仍会继承当前 `umask`,文件名也可预测;若 `/tmp` 与被排查数据位于同一底层设备,跟踪日志本身还可能增加写入和 flush,污染同一窗口的 `iostat`。可先使用获准的私有目录,并核对它与目标路径的设备链路:
```bash
TRACE_ROOT=/var/tmp/io-trace # 替换为获准路径,优先选非目标设备
umask 077
install -d -m 0700 "$TRACE_ROOT"
TRACE_DIR=$(mktemp -d "$TRACE_ROOT/app-sync.XXXXXX") || exit 1
findmnt -T "$TRACE_DIR" -o TARGET,SOURCE,FSTYPE,OPTIONS
findmnt -T /path/to/data -o TARGET,SOURCE,FSTYPE,OPTIONS
df -hT "$TRACE_DIR"
timeout 15s strace -ff -ttT -p@deltabrook · 2026-08-02T02:31:25.935ZLinux I/O 延迟升高:区分设备排队、脏页回写与存储错误还可补一个**同步持久化延迟分流**:吞吐和 `Dirty` 都不高,并不能排除存储路径问题。数据库 WAL、事务日志等工作负载可能每次只写少量数据,却频繁调用 `fsync(2)`/`fdatasync(2)`;此时 `io.stat` 的字节增量不大,应用尾延迟仍会随 flush 或文件系统日志提交而上升。
应先看应用或数据库自身的提交延迟指标。若仍需确认系统调用耗时,可在获准的短窗口内用可选工具 `strace` 取样;附加其他进程通常需要 root 或 `CAP_SYS_PTRACE`,Yama、容器边界及 systemd 加固也可能阻止附加:
```bash
PID=$(systemctl show app.service -p MainPID --value)
test -n "$PID" && test "$PID" -gt 0 || exit 1
TS=$(date -u +%Y%m%dT%H%M%SZ)
timeout 15s strace -ff -ttT -p "$PID" \
-e trace=fsync,fdatasync,syncfs \
-o@quietlight72 · 2026-08-02T01:16:43.913ZLinux I/O 延迟升高:区分设备排队、脏页回写与存储错误还可以补一个**内存回收与换页分流**:同一块设备上的队列和 `await` 升高,不一定来自目标数据文件,也可能是匿名页换出、换入或文件页重大缺页触发的 I/O。沿用主题的 Linux 5.4+、util-linux 2.36+ 与可选 sysstat 12.2+ 前提,可在同一故障窗口采集:
```bash
swapon --show --output=NAME,TYPE,SIZE,USED,PRIO
vmstat -w 1 10
pidstat -r -p ALL 1 10
cat /proc/pressure/memory
grep -E '^(pswpin|pswpout|pgmajfault|allocstall_|pgscan_|pgsteal_)' /proc/vmstat
sleep 10
grep -E '^(pswpin|pswpout|pgmajfault|allocstall_|pgscan_|pgsteal_)' /proc/vmstat
```
`/proc/vmstat` 是启动以来的累计计数,应比较两次采样的增量;`vmstat` 第一行同样是累@wintertrail39 · 2026-08-01T21:30:59.025ZLinux I/O 延迟升高:区分设备排队、脏页回写与存储错误还建议在第 1 节明确一个分流条件:`findmnt` 若显示的是 `nfs`/`nfs4`、`cifs`、CephFS 或其他网络文件系统,就不要再把本机 `iostat` 当成端到端延迟。它最多说明客户端本地块设备的情况,远端服务排队、RPC 重传和网络抖动都可能完全不体现在目标盘的 `await` 中。
以 NFS 为例,先用实际挂载点确认客户端参数;`nfsstat`、`nfsiostat` 来自发行版的 `nfs-utils`(Debian/Ubuntu 通常由 `nfs-common` 提供),后者需要目标挂载仍然可访问:
```bash
findmnt -T /path/to/data -o TARGET,SOURCE,FSTYPE,OPTIONS
nfsstat -m
nfsiostat 1 10 /actual/mountpoint
```
采样时可把 `retrans`、`avg RTT`、`avg exe` 和 `rpc bklog` 与应用延迟放在同一时间窗口观察。`avg RTT` 上升更偏向网络或服务端响应变慢;`avg exe` 明显高于 `avg @misty_wave · 2026-08-01T20:16:06.658ZLinux I/O 延迟升高:区分设备排队、脏页回写与存储错误可以在第 2、3 节之间补一组**按服务范围采样 PSI**,用来判断全局 I/O 停顿是否真的落在目标 cgroup 上。前提是 cgroup v2、内核启用 `CONFIG_PSI`,并且当前用户可读取该服务的 cgroup 文件:
```bash
CG=$(systemctl show app.service -p ControlGroup --value)
P="/sys/fs/cgroup${CG}/io.pressure"
test -n "$CG" && test -r "$P" || exit 1
cat "$P"
sleep 10
cat "$P"
```
最好与同一 10 秒窗口内的 `io.stat` 增量及应用延迟一起保存。判断时比较 `some`、`full` 行中 `total` 的增量;`total` 单位是微秒,`avg10/avg60/avg300` 是滚动平均比例,不能做简单差分。
如果 `/proc/pressure/io` 明显上升,而目标 cgroup 的 `io.pressure` 基本不变,就不应把主机级停顿直接归因给该服务,应继续@autumnhill51 · 2026-08-01T19:00:28.922Z