这是我第 14 篇技术复盘。这一次主角是数据库:PostgreSQL 15 → 16 + Citus 12.1 + pgvector 0.7 + Patroni 4.0 + pgBouncer 1.23 + Debezium 2.6 + 分库分表 + 主从 + 逻辑复制 + 向量检索全套现代化。27 天,52 名 SRE + DBA + 后端工程师,17 个数据集群,4.8TB 单库 + 11 个 Citus 分片,踩出了 10 个反模式,触发了 6 次回滚 + 1 次 P0 + 3 次 P1,沉淀出 12 套修法 + 28 个 PostgreSQL / Citus / pgvector 工程化议题。本文是这 27 天的完整复盘。
一、升级清单与背景
升级前后对比:
| 组件 | 升级前 | 升级后 |
|---|---|---|
| PostgreSQL | 15.6 | 16.4 |
| Citus(分布式 PG) | 11.3 | 12.1 |
| pgvector(向量插件) | 0.5.1 | 0.7.4 |
| Patroni(HA) | 3.2 | 4.0.4 |
| pgBouncer(连接池) | 1.21 | 1.23.1 |
| Debezium(CDC) | 2.4 | 2.6.2 |
| WAL-G(备份) | 2.0.1 | 3.0.3 |
| pg_stat_statements | 启用 | 启用 + sample_rate=0.1 |
| jit(query JIT) | off | on(分析查询) |
| OS | Ubuntu 22.04 | Ubuntu 24.04 LTS |
背景:17 个集群,2 个 OLTP(4.8TB + 1.2TB)分别支撑订单 / 用户域,3 个 Citus 分布式集群支撑日志 + 行为分析(11 + 7 + 5 worker),5 个 OLAP(pg + 物化视图)支撑报表,7 个小集群支撑微服务领域数据。日 QPS 峰值 42 万,P99 写 30ms / 读 18ms 是基线 SLA。这次升级目标:启用 pgvector 0.7 HNSW 加速 AI 检索 + Citus 12 子查询下推 + PG 16 增量排序 + Patroni 4 配置热加载。
二、10 个反模式:写在最前面
这 27 天最坑的 10 个反模式,先列出来:
每一个反模式都对应一个具体故障。本文会逐一展开。
三、反模式 1:SELECT * + OFFSET 分页慢成噩梦
升级前,订单分页接口 P99 = 2.1s。EXPLAIN ANALYZE 一看,SELECT * FROM orders ORDER BY id OFFSET 10000 LIMIT 20 走的是全索引扫描 + 10020 行排序丢弃 1 万行。改成 keyset 分页(WHERE id < $last_id ORDER BY id DESC LIMIT 20)后,P99 = 18ms。
-- 反模式:OFFSET 分页(随着页数增大线性变慢)
SELECT * FROM orders ORDER BY id OFFSET 10000 LIMIT 20;
-- 第 500 页:扫描 + 丢弃 10020 行,P99 = 2.1s
-- 修法 1:keyset 分页 + 联合索引
CREATE INDEX CONCURRENTLY idx_orders_created_id ON orders(created_at DESC, id DESC);
SELECT id, user_id, amount, status, created_at
FROM orders
WHERE (created_at, id) < ($last_created_at, $last_id)
ORDER BY created_at DESC, id DESC
LIMIT 20;
-- P99 = 18ms,稳定
-- 修法 2:SELECT 具体列(不要 *)
SELECT id, user_id, amount FROM orders WHERE id = $1;
-- 避免大字段(JSON/text)无谓 IO
-- 修法 3:COUNT(*) 避免精确计数
SELECT reltuples::bigint AS estimated_count FROM pg_class WHERE relname='orders';
-- 4.8TB 单表精确 COUNT 需 35 分钟,估算值毫秒返回
结论:OFFSET 分页是 OLTP 的反模式,keyset 分页是工业级标配。任何 PG 接口大于 100ms 都要 EXPLAIN ANALYZE 一次,不要凭感觉调优。
四、反模式 2:11 个索引压垮一张表
orders 表 11 个索引,写性能崩了。每次 INSERT 都要更新 11 个 B-tree + 1 个 GIN(JSON),写 RPS 从 8500 跌到 2300。删除 4 个低使用索引,RPS 恢复到 7900。诊断索引使用率必看 pg_stat_user_indexes。
-- 1. 查找未使用的索引(idx_scan=0 即从未被使用)
SELECT schemaname, relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch,
pg_size_pretty(pg_relation_size(indexrelid)) AS index_size
FROM pg_stat_user_indexes
WHERE schemaname NOT IN ('pg_catalog','information_schema')
ORDER BY idx_scan ASC, pg_relation_size(indexrelid) DESC
LIMIT 30;
-- 2. 查找冗余索引(前缀重复)
WITH idx AS (
SELECT indrelid::regclass AS tbl, indkey::text AS cols, indexrelid::regclass AS idx
FROM pg_index
)
SELECT a.idx AS redundant, b.idx AS covered_by
FROM idx a JOIN idx b ON a.tbl=b.tbl AND a.idx<>b.idx
WHERE b.cols LIKE a.cols || ' %';
-- 3. 删除未使用索引(必须 CONCURRENTLY,避免锁)
DROP INDEX CONCURRENTLY idx_orders_legacy_xxx;
-- 4. 监控:每周自动报表 + 阈值告警(idx_scan < 100/week 标记审查)
4.8TB 单表删除 4 个索引腾出 280GB 磁盘,vacuum 时间从 7 小时降到 3.2 小时,写 RPS 从 2300 恢复到 7900。
五、反模式 3:长事务 + SELECT FOR UPDATE 全表锁
支付回调里写了一个"先锁全部待支付订单"的事务,持有锁 8 秒。同时 6000 个并发 transaction 全部阻塞,数据库 CPU 直接 100%。修法:
-- 反模式:长事务 + 大范围 FOR UPDATE
BEGIN;
SELECT * FROM orders WHERE status='pending' FOR UPDATE; -- 锁住 4.2 万行 8 秒
UPDATE orders SET status='processing' WHERE id IN (...);
-- 后续业务逻辑 7 秒
COMMIT;
-- 修法 1:SKIP LOCKED + 小批量(Job/Queue 模式工业标配)
BEGIN;
SELECT id FROM orders
WHERE status='pending'
ORDER BY created_at
LIMIT 50 FOR UPDATE SKIP LOCKED;
UPDATE orders SET status='processing' WHERE id = ANY($1::bigint[]);
COMMIT;
-- 修法 2:事务保持 < 100ms,业务逻辑挪到事务外
BEGIN;
UPDATE orders SET status='processing' WHERE id=$1 AND status='pending'; -- 单行
COMMIT;
-- 7 秒业务逻辑在事务外执行
-- 修法 3:超长事务监控
SELECT pid, now()-xact_start AS xact_age, state, query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL AND now()-xact_start > interval '5 seconds';
SKIP LOCKED 是 PG 9.5+ 老特性,但在工业级 Job/Queue 场景的使用率不到 30%,这是巨大的认知缺口。
六、反模式 4:autovacuum 关闭 + bloat 60%
有个老 DBA 留下的设置:对 orders 表 autovacuum_enabled = false,理由是"避免高峰期 IO 抖动"。半年后 bloat 60%,4.8TB 实际只有 1.8TB 数据,2.6TB 是死元组。pg_repack 跑了 11 小时才整理完。修法:
; postgresql.conf:autovacuum 永远开,通过参数调节频率
autovacuum = on
autovacuum_max_workers = 6
autovacuum_naptime = 30s
autovacuum_vacuum_scale_factor = 0.05 ; 默认 0.2,大表降低
autovacuum_vacuum_threshold = 50
autovacuum_analyze_scale_factor = 0.02
autovacuum_vacuum_cost_limit = 4000 ; 默认 200,提升 IO 配额
autovacuum_vacuum_cost_delay = 2ms ; 默认 20ms,降低 sleep
; 大表单独覆盖(超过 100GB 都覆盖)
ALTER TABLE orders SET (
autovacuum_vacuum_scale_factor = 0.02,
autovacuum_analyze_scale_factor = 0.01,
autovacuum_vacuum_cost_limit = 8000
);
; 监控 bloat
CREATE EXTENSION pgstattuple;
SELECT relname, pg_size_pretty(pg_table_size(c.oid)) AS size,
(pgstattuple(c.oid)).dead_tuple_percent
FROM pg_class c WHERE relkind='r' AND pg_table_size(c.oid) > 1e9
ORDER BY 3 DESC LIMIT 20;
autovacuum 不该关,该调。bloat > 20% 报警,> 40% 触发 pg_repack 排程。
七、反模式 5:同步复制全部从节点,leader 写抖动
Patroni 配的 synchronous_standby_names = '*',3 个从节点全部同步。任何一个 standby 网络抖动,主库写延迟暴涨 200ms+。改成 ANY 1 (replica_a, replica_b, replica_c),写延迟稳定在 8ms 以内。
; postgresql.conf:写一致性与可用性的平衡
synchronous_commit = on ; 同步等待 WAL 写到 standby
synchronous_standby_names = 'ANY 1 (replica_a, replica_b, replica_c)'
; 等任意 1 个 standby ACK 即可继续,容忍单节点抖动
; 监控同步状态
SELECT application_name, state, sync_state, sync_priority,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes,
pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn) AS write_lag_bytes
FROM pg_stat_replication;
; 故障演练:cd Patroni,手动切主必须 < 30s 完成
patronictl switchover --master pg-leader --candidate pg-replica-b
同步复制是数据一致性保险,但全部同步是反模式。ANY N 才是工业级合理配置。
八、反模式 6:pgBouncer transaction mode 错配 prepared statements
Java 应用用 PreparedStatement,pgBouncer 配的是 transaction 模式。每个事务结束 prepared statement 失效,客户端重新 PREPARE,反而比直连慢 2 倍。修法:
; pgbouncer.ini:transaction mode + PG 14+ server-side prepared statements
[databases]
orders = host=pg-leader port=5432 dbname=orders
[pgbouncer]
pool_mode = transaction
default_pool_size = 80
reserve_pool_size = 20
reserve_pool_timeout = 5
max_client_conn = 5000
server_idle_timeout = 600
; PG 14+ + pgBouncer 1.21+ 已支持 transaction mode prepared statements
; 但需要客户端走 PG protocol-level prepare(JDBC reWriteBatchedInserts=true)
; 监控 pgBouncer
SHOW POOLS;
SHOW STATS;
SHOW SERVERS;
JDBC 端配合:prepareThreshold=5 + preparedStatementCacheQueries=1024 + reWriteBatchedInserts=true。这三个参数让 prepared statements 在 transaction mode 下也能工作。
九、反模式 7:Citus colocation 漏配,跨分片 JOIN 慢成性
Citus 11 上线时,11 个 shard,users 表用 id 分片,orders 表也用 user_id 分片,但 没有配 colocation_id,导致 user JOIN orders 在每对 worker 间做 broadcast,4 万次 JOIN 平均 800ms。修法:
-- 反模式:两表分片但 colocation_id 不同
SELECT create_distributed_table('users', 'id');
SELECT create_distributed_table('orders', 'user_id'); -- colocation_id 不同!
-- 跨 shard JOIN 触发 broadcast,慢
-- 修法:明确指定 colocate_with
SELECT create_distributed_table('users', 'id');
SELECT create_distributed_table('orders', 'user_id', colocate_with => 'users');
-- 同一 user_id 的 orders 与 users 落在同一 shard,JOIN 本地完成
-- 检查 colocation
SELECT logicalrelid, colocationid FROM pg_dist_partition ORDER BY colocationid;
-- reference table(小维表)避免广播
SELECT create_reference_table('regions'); -- 100 行,所有 worker 复制一份
SELECT create_reference_table('categories'); -- 大于 10 万行就不要 reference
-- 监控跨 shard 查询
SELECT query, count(*), sum(execution_time) FROM citus_stat_statements
WHERE shard_count > 1 GROUP BY query ORDER BY sum DESC LIMIT 20;
Citus 性能 80% 取决于 colocation 设计,20% 才是 SQL 调优。这是 Citus 工程化第一课。
十、反模式 8:ALTER TABLE 长锁卡住整个业务
一次 ALTER TABLE orders ADD COLUMN tax NUMERIC NOT NULL DEFAULT 0 锁了 3 分钟,期间所有读写都阻塞,直接 P0。PG 11+ 之后 NOT NULL DEFAULT 已经是 metadata-only,但 NOT NULL CHECK 仍然全表扫描。修法:
-- 反模式:一条语句搞定(锁全表)
ALTER TABLE orders ADD COLUMN tax NUMERIC NOT NULL DEFAULT 0;
-- 修法:分 3 步(每步都是短锁)
-- 1. 加列,允许 NULL(metadata-only,瞬间完成)
ALTER TABLE orders ADD COLUMN tax NUMERIC;
-- 2. 后台批量 backfill(分批 5000 行,每批 sleep 50ms)
DO $$
DECLARE batch_size int := 5000;
BEGIN
LOOP
UPDATE orders SET tax = 0 WHERE tax IS NULL AND id IN (
SELECT id FROM orders WHERE tax IS NULL LIMIT batch_size FOR UPDATE SKIP LOCKED
);
EXIT WHEN NOT FOUND;
PERFORM pg_sleep(0.05);
END LOOP;
END $$;
-- 3. 加 NOT NULL 约束(PG 12+ 通过 NOT VALID + VALIDATE 分两步)
ALTER TABLE orders ADD CONSTRAINT orders_tax_not_null CHECK (tax IS NOT NULL) NOT VALID;
ALTER TABLE orders VALIDATE CONSTRAINT orders_tax_not_null;
ALTER TABLE orders ALTER COLUMN tax SET NOT NULL;
ALTER TABLE orders DROP CONSTRAINT orders_tax_not_null;
-- 索引:必须 CONCURRENTLY
CREATE INDEX CONCURRENTLY idx_orders_tax ON orders(tax);
-- DROP COLUMN:PG 仅标记不立即释放,需 VACUUM FULL 或 pg_repack 才回收
4.8TB 单表 ADD COLUMN 安全做法分 3 步,总耗时 14 小时(后台批),零业务阻塞。一条 ALTER 干完是 P0 温床。
十一、反模式 9:pgvector ivfflat 召回低 + HNSW 内存爆
升级 pgvector 0.7 启用 HNSW 之前,用的是 0.5 的 ivfflat 索引。2 千万 768 维 embedding,ivfflat lists=1000 召回率仅 78%,top-10 实际只有 6 个正确。换 HNSW 后召回 96%,但内存暴涨。修法:
-- 启用 pgvector 0.7
CREATE EXTENSION vector;
ALTER TABLE docs ADD COLUMN embedding vector(768);
-- 反模式 1:ivfflat lists 太少(召回低)
CREATE INDEX docs_embedding_ivf ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists=100);
-- lists=100 对 2 千万行严重不足,召回 78%
-- 修法 1:lists = sqrt(rows) 经验值
CREATE INDEX docs_embedding_ivf ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists=4500);
SET ivfflat.probes = 50; -- 查询时探针数,trade-off 召回 vs 延迟
-- 修法 2:HNSW(召回高,内存换性能)
CREATE INDEX docs_embedding_hnsw ON docs USING hnsw (embedding vector_cosine_ops)
WITH (m=16, ef_construction=64);
SET hnsw.ef_search = 80; -- 查询时候选集大小
-- 内存监控:HNSW 索引会驻留 shared_buffers
-- 2 千万 768 维 ≈ 60GB 索引,shared_buffers 必须 ≥ 32GB
-- 维度限制:pgvector ≤ 2000 维(0.7),超过用 halfvec(float16)或 sparsevec
ALTER TABLE docs ADD COLUMN embedding_half halfvec(1536);
CREATE INDEX docs_embedding_half_hnsw ON docs USING hnsw (embedding_half halfvec_cosine_ops);
-- 查询:cosine / l2 / inner product 三种距离
SELECT id, content FROM docs
ORDER BY embedding <=> $1::vector -- <=> cosine, <-> l2, <#> inner
LIMIT 10;
pgvector 工业级使用 HNSW 优于 ivfflat 80% 场景,但必须保证 shared_buffers ≥ 索引大小 * 0.6。2 千万 768 维 HNSW 索引需 60GB 共享内存,这是 RAG 系统的隐藏成本。
十二、反模式 10:pg_dump 备份压垮主库
每天凌晨 3 点 cron 调 pg_dump -Fc 备份,4.8TB 跑 9 小时。期间 IO util 90%,导致接 IO 的接口 P99 抖到 400ms。改用 pg_basebackup + WAL-G 增量备份,主库 IO 几乎无感。
# 反模式:pg_dump 在主库逻辑备份
pg_dump -Fc -h pg-leader orders > orders.dump # 9 小时 + IO 90%
# 修法 1:pg_basebackup 物理备份 + WAL-G 增量(主流)
# 配置 WAL-G 推送 S3
wal-g backup-push /var/lib/postgresql/16/main # 增量,30 分钟完成
# WAL 流式归档(连续备份)
# postgresql.conf:
# archive_mode = on
# archive_command = 'wal-g wal-push %p'
# wal_level = replica
# PITR(point-in-time recovery)恢复
wal-g backup-fetch /var/lib/postgresql/16/main LATEST
echo "restore_command = 'wal-g wal-fetch %f %p'" >> postgresql.auto.conf
echo "recovery_target_time = '2026-05-15 14:30:00'" >> postgresql.auto.conf
touch /var/lib/postgresql/16/main/recovery.signal
systemctl restart postgresql
# 修法 2:逻辑备份从 standby 库做(不影响主库)
pg_dump -h pg-replica-b -Fc orders > orders.dump
# 验证演练:每周一次,从备份恢复到测试集群,跑核心 SQL 验证
# 没有验证的备份不是备份
备份策略 = 物理(WAL-G 增量)+ 逻辑(从 standby)+ 每周演练。三者缺一不可。
十三、Patroni 4.0 升级:配置热加载与 raft 改进
Patroni 4.0 相比 3.x 最大改进:(1) DCS 配置热加载,patronictl edit-config 后无需重启 Patroni 进程;(2) etcdv3 + raft 通信优化,leader 选举从 12s 降到 4s;(3) RBAC 支持,运维权限分级。
scope: orders-cluster
namespace: /db/
name: pg-leader
restapi:
listen: 0.0.0.0:8008
connect_address: pg-leader.internal:8008
etcd3:
hosts:
- etcd-1.internal:2379
- etcd-2.internal:2379
- etcd-3.internal:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 5
retry_timeout: 10
maximum_lag_on_failover: 33554432 # 32MB,超过 lag 拒绝 failover
synchronous_mode: true
synchronous_mode_strict: false # strict 时无 sync standby 会拒绝写,生产慎用
postgresql:
use_pg_rewind: true
use_slots: true
parameters:
max_connections: 800
shared_buffers: 32GB
effective_cache_size: 96GB
wal_level: replica
max_wal_size: 16GB
min_wal_size: 4GB
checkpoint_timeout: 15min
checkpoint_completion_target: 0.9
random_page_cost: 1.1 # SSD/NVMe 必调
effective_io_concurrency: 200 # NVMe
max_worker_processes: 32
max_parallel_workers_per_gather: 4
max_parallel_workers: 16
max_parallel_maintenance_workers: 4
postgresql:
listen: 0.0.0.0:5432
data_dir: /var/lib/postgresql/16/main
authentication:
replication:
username: replicator
password: ${REPLICATION_PASSWORD}
superuser:
username: postgres
password: ${POSTGRES_PASSWORD}
watchdog:
mode: required # 强制 watchdog,防止 split-brain
device: /dev/watchdog
safety_margin: 5
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
十四、JIT 启用与基准
PG 16 默认 jit = on,但生产长期关闭。这次升级测试:OLAP 查询(大量聚合 + 表达式)开 JIT 平均快 35%;OLTP 短查询开 JIT 反而慢 8%(JIT 编译开销 > 收益)。结论:按 workload 区分。
; postgresql.conf:JIT 按 cost 阈值开启
jit = on
jit_above_cost = 100000 ; cost >= 100k 才编译,OLTP 跳过
jit_optimize_above_cost = 500000
jit_inline_above_cost = 500000
jit_provider = 'llvmjit'
; 验证:EXPLAIN ANALYZE 查看 JIT 字段
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT user_id, SUM(amount) FROM orders WHERE created_at > now() - interval '7 days'
GROUP BY user_id;
; 输出末尾:
; JIT:
; Functions: 6
; Options: Inlining true, Optimization true, Expressions true, Deforming true
; Timing: Generation 4.2 ms, Inlining 12.1 ms, Optimization 87.3 ms, Total 105.6 ms
十五、读写分离与连接路由
升级期间确定的连接路由层架构:
App → pgBouncer (transaction mode, per-service pool)
↓
┌──┴──┐
↓ ↓
Primary Read-only(haproxy / Patroni REST)
↓ ↓
WAL Replica × 3 (sync ANY 1, async × 2)
↓
WAL-G → S3 (15s WAL push)
规则:(1) 写、强一致读、SELECT FOR UPDATE 走 primary;(2) 报表 / 归档 / 大查询走 async replica;(3) 实时风控查询走 sync replica(0 延迟);(4) 跨服务查询禁止,走 API 或 CDC。
十六、Debezium 2.6 CDC:订阅 PostgreSQL WAL
升级 Debezium 2.6 + Kafka Connect,订阅 PG WAL,实时同步到下游数据湖与搜索引擎。
{
"name": "orders-cdc-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "pg-replica-b.internal",
"database.port": "5432",
"database.user": "debezium",
"database.password": "${vault:secret/debezium/password}",
"database.dbname": "orders",
"topic.prefix": "cdc.orders",
"plugin.name": "pgoutput",
"slot.name": "debezium_orders_slot",
"publication.name": "debezium_pub",
"publication.autocreate.mode": "filtered",
"table.include.list": "public.orders,public.payments,public.refunds",
"snapshot.mode": "initial",
"heartbeat.interval.ms": "10000",
"heartbeat.action.query": "UPDATE debezium_heartbeat SET ts=now() WHERE id=1;",
"decimal.handling.mode": "double",
"time.precision.mode": "connect",
"tombstones.on.delete": "true",
"key.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter.schemas.enable": "true",
"transforms": "unwrap,route",
"transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState",
"transforms.unwrap.drop.tombstones": "false",
"transforms.route.type": "org.apache.kafka.connect.transforms.RegexRouter",
"transforms.route.regex": "cdc.orders.public.(.*)",
"transforms.route.replacement": "cdc.orders.$1"
}
}
关键坑:(1) replication slot 不清理会持续占用 WAL,磁盘爆;(2) 大表初次 snapshot 锁表,必须用 snapshot.mode=initial_only 然后切换;(3) heartbeat 必须配,否则 idle 表 WAL 不释放;(4) 从 replica 订阅减少主库压力(PG 16+ 支持)。
十七、监控:pg_stat_statements + Prometheus + Grafana
慢查询全靠 pg_stat_statements。PG 16 引入 pg_stat_statements.sample_rate,可以采样降低 overhead。
; postgresql.conf:监控基础
shared_preload_libraries = 'pg_stat_statements, auto_explain, pg_cron'
pg_stat_statements.max = 10000
pg_stat_statements.track = top
pg_stat_statements.track_utility = off
pg_stat_statements.save = on
; auto_explain:慢查询自动 EXPLAIN(必开)
auto_explain.log_min_duration = 1s
auto_explain.log_analyze = on
auto_explain.log_buffers = on
auto_explain.log_timing = on
auto_explain.log_triggers = on
auto_explain.log_verbose = off
auto_explain.log_nested_statements = on
auto_explain.sample_rate = 0.1 ; 10% 采样,降低 overhead
; pg_stat_statements 查询:Top 10 总耗时
SELECT substring(query, 1, 120) AS short_query,
calls, total_exec_time::numeric(20,2) AS total_ms,
mean_exec_time::numeric(20,3) AS avg_ms,
(100 * total_exec_time / sum(total_exec_time) OVER ())::numeric(5,2) AS pct
FROM pg_stat_statements
ORDER BY total_exec_time DESC LIMIT 10;
Prometheus + Grafana + postgres_exporter,8 张面板:Connections / TPS / Cache hit / Replication lag / Lock / Vacuum / Bloat / Top SQL。这套监控让 P99 抖动定位平均 6 分钟内完成,以前是 40 分钟。
十八、安全:row-level security + 审计
27 天升级附带启用了 RLS(行级安全)与审计扩展 pgaudit。
-- RLS:多租户场景
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY orders_tenant_isolation ON orders
USING (tenant_id = current_setting('app.current_tenant')::int);
-- 应用层每请求设置:
SET app.current_tenant = '$tenant_id';
-- pgaudit:审计 DDL + DML
CREATE EXTENSION pgaudit;
ALTER SYSTEM SET pgaudit.log = 'ddl, role, write';
ALTER SYSTEM SET pgaudit.log_catalog = off;
ALTER SYSTEM SET pgaudit.log_parameter = on;
ALTER SYSTEM SET pgaudit.log_relation = on;
SELECT pg_reload_conf();
-- 密码策略
ALTER ROLE app_user PASSWORD 'xxx' VALID UNTIL '2026-08-01';
CREATE EXTENSION passwordcheck;
十九、备份验证演练 SOP
每周一次的备份验证 SOP:
| 步骤 | 动作 | 耗时 | SLA |
|---|---|---|---|
| 1 | 从 S3 拉最新 base backup | 22 分钟 | < 30 分钟 |
| 2 | WAL replay 到最近 1 小时 | 14 分钟 | < 20 分钟 |
| 3 | 启动测试集群 | 3 分钟 | < 5 分钟 |
| 4 | 跑 12 条核心业务 SQL | 8 分钟 | < 10 分钟 |
| 5 | 对比主库 row count(抽样 20 张表) | 5 分钟 | < 10 分钟 |
| 6 | 清理测试集群 | 2 分钟 | — |
| 7 | 报告归档 | 5 分钟 | — |
这套演练让 27 天升级期间发现 1 次 WAL 链断裂(WAL-G 升级时配置错误),提前修复。
二十、回滚剧本:5 次回滚的 SOP
27 天 5 次回滚:1 次 Patroni 配置写错触发 split-brain 风险,2 次 Citus colocation 改完跑迁移失败,1 次 pgvector HNSW 索引构建内存爆,1 次 Debezium snapshot 锁表。每次回滚平均 11 分钟,业务感知 < 8 分钟。
# 1. Patroni 配置回滚
patronictl edit-config --pg-config /etc/patroni/patroni.yml.backup
patronictl restart orders-cluster --pg-leader
# 2. Citus 元数据回滚(undo_distribute_table)
SELECT undistribute_table('orders_v2', cascade_via_foreign_keys => true);
# 3. pgvector 索引回滚(DROP + 重建 ivfflat)
DROP INDEX CONCURRENTLY docs_embedding_hnsw;
CREATE INDEX CONCURRENTLY docs_embedding_ivf ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists=4500);
# 4. Debezium connector 回滚
curl -X DELETE http://kafka-connect:8083/connectors/orders-cdc-connector
# slot 必须手动清理,否则 WAL 占用
SELECT pg_drop_replication_slot('debezium_orders_slot');
二十一、容量规划与硬件选型
升级期间重新审视硬件:
| 角色 | CPU | RAM | 磁盘 | 网络 |
|---|---|---|---|---|
| OLTP primary(4.8TB) | 64C | 256GB | NVMe 8TB × 2 RAID10 | 25Gbps × 2 |
| OLTP replica × 3 | 48C | 192GB | NVMe 8TB | 10Gbps |
| Citus coordinator | 32C | 128GB | NVMe 2TB | 10Gbps |
| Citus worker × 11 | 32C | 128GB | NVMe 4TB | 10Gbps |
| OLAP / 报表 | 64C | 512GB | NVMe 16TB | 10Gbps |
shared_buffers 永远配物理内存的 25%,不要超过 40GB(超过会触发 PG 内部锁竞争)。effective_cache_size 配 75%。
二十二、扩展生态:必装 12 个
所有 17 个集群必装的 PG 扩展:
| 扩展 | 用途 |
|---|---|
| pg_stat_statements | 慢查询统计 |
| auto_explain | 慢查询自动 EXPLAIN |
| pgaudit | 审计 |
| pg_repack | 在线整理 bloat |
| pgstattuple | bloat 测量 |
| pg_cron | 数据库内定时任务 |
| pg_partman | 分区表自动管理 |
| citus | 水平分片 |
| vector(pgvector) | 向量检索 |
| pg_trgm | 模糊搜索 + GIN |
| btree_gin / btree_gist | 多列复合索引 |
| postgres_fdw | 跨库联邦查询 |
二十三、分区表 + pg_partman 自动管理
logs / events 大表都用范围分区。pg_partman 自动建分区 + 自动归档。
CREATE TABLE events (
id bigserial,
user_id bigint NOT NULL,
event_type text NOT NULL,
payload jsonb,
created_at timestamptz NOT NULL DEFAULT now()
) PARTITION BY RANGE (created_at);
-- 默认分区(兜底)
CREATE TABLE events_default PARTITION OF events DEFAULT;
-- pg_partman 自动:每天一个分区,保留 90 天
SELECT create_parent(
p_parent_table => 'public.events',
p_control => 'created_at',
p_type => 'native',
p_interval => '1 day',
p_premake => 7
);
UPDATE part_config SET retention='90 days', retention_keep_table=false
WHERE parent_table='public.events';
-- 每天调度
SELECT cron.schedule('partman-maintenance', '0 2 * * *',
$$SELECT partman.run_maintenance(p_analyze => true)$$);
二十四、连接管理与防雪崩
PG 连接成本高(每连接 ~10MB + fork)。策略:(1) max_connections = 500 上限;(2) pgBouncer transaction mode,server_pool 100;(3) 应用 HikariCP 池子 ≤ 20;(4) 任何 service 超 100 连接报警;(5) idle 连接 > 60s 主动断。
二十五、PG 16 新特性盘点
PG 16 新特性 6 项工程价值:(1) 增量排序(incremental sort)优化 ORDER BY + LIMIT;(2) 并行 hash full outer join;(3) logical replication 支持从 standby 订阅;(4) pg_stat_io 新视图(IO 分析);(5) SQL/JSON 增强(JSON_TABLE 等 SQL 标准);(6) libpq load balancing(连接级别)。
二十六、Citus 12 升级亮点
Citus 12 相比 11 的 5 个工程价值:(1) 子查询下推优化,跨分片复杂查询快 40%;(2) shard pruning 改进,等值过滤精确路由;(3) reference table 写性能提升;(4) columnar 表(列存)支持更新;(5) 与 PG 16 增量排序协同。
二十七、AI 时代数据库的位置
2026 年 PostgreSQL 在 AI 栈的位置:(1) 业务数据 + 向量混存(pgvector);(2) AI Feature Store 底层(Hopsworks / Tecton 都基于 PG);(3) RAG 主流向量库(替代 Pinecone / Weaviate 的低成本方案);(4) Agent 状态持久化;(5) 训练数据 ETL 中转。
二十八、写在最后
27 天 PostgreSQL 16 + Citus 12 + pgvector 0.7 + Patroni 4 + Debezium 2.6 全栈现代化,52 工程师 + 6 次回滚 + 1 次 P0 + 3 次 P1,沉淀出 10 个反模式 + 12 套修法 + 28 个引申话题。核心结论:数据库工程化 = 索引 + 锁 + 事务 + Vacuum + 复制 + 分布式 + 备份 + 监控 + 安全 + 容量 9 个维度的综合工程能力,任何一个维度的缺失都会成为生产 P0 温床。
愿 2026 年每位 DBA + SRE + 后端工程师都能在 AI 数据浪潮中继续保持工程态度,做出真正可靠、高性能、易维护的数据库系统。我们下一个 27 天再见。
二十九、引申一:OLTP 与 OLAP 的分裂与统一
2026 年数据库领域的核心矛盾仍然是 OLTP 与 OLAP 的分裂。OLTP 主战场是 PostgreSQL / MySQL 8 / TiDB / CockroachDB,关心写入吞吐 + 短查询 + ACID;OLAP 主战场是 ClickHouse / Doris / DuckDB / Snowflake,关心列存 + 向量化 + 大批量聚合。我们 27 天升级期间的现实路径:(1) 业务核心走 PG OLTP;(2) 报表分析走 ClickHouse(从 PG CDC 同步);(3) 实时分析走 Citus columnar 表;(4) 大数据仓库走 Snowflake。这种 4 层架构是 2026 年中大型企业的事实标准。
三十、引申二:HTAP 现实主义
HTAP(混合事务分析)在 2022-2024 年被吹得很高,2026 年回归现实。实战观察:(1) TiDB HTAP 在中小型分析有效,但 2TB 以上数据 ClickHouse 仍然性能领先 5 倍以上;(2) PostgreSQL + Citus columnar 是渐进式 HTAP,适合从 OLTP 平滑过渡;(3) 真正大数据仍需独立 OLAP 引擎。结论:HTAP 是过渡解法,不是终极方案。明确读写分离 + CDC 同步仍是工业级标配。
三十一、引申三:NoSQL 的 2026 年现实
2026 年 NoSQL 各家位置:(1) MongoDB:文档数据库主流,适合半结构化;(2) Redis 7:缓存 + Stream + Search + Vector 全栈;(3) Cassandra / ScyllaDB:超大规模写入,IoT / 时序;(4) DynamoDB:AWS 全托管,Serverless 友好;(5) Elasticsearch / OpenSearch:全文搜索 + 日志分析。我们的策略:核心数据 PostgreSQL,缓存 Redis,日志 OpenSearch,半结构化少量场景 MongoDB。
三十二、引申四:Time-series 数据库选型
时序数据库选型 4 种:(1) TimescaleDB(PG 插件):平滑过渡,适合中型时序;(2) InfluxDB 3.0:DataFusion 重写,Rust 实现,性能跃迁;(3) VictoriaMetrics:Prometheus 兼容,运维简单;(4) ClickHouse + MergeTree:超大规模,聚合极快。我们的策略:监控指标用 VictoriaMetrics + Prometheus;业务时序用 TimescaleDB(与 PG 同栈);超大日志走 ClickHouse。
三十三、引申五:NewSQL 的位置
NewSQL(分布式 SQL)2026 年代表:(1) TiDB:MySQL 协议,PingCAP 主导,中国主流;(2) CockroachDB:Postgres 协议,全球分布式;(3) YugabyteDB:Postgres 协议,K8s 原生;(4) Spanner:Google 全托管,价格高昂。评估标准:(a) 协议兼容性;(b) 一致性级别(线性 vs 快照);(c) 跨区域延迟;(d) 运维复杂度;(e) 价格。我们的结论:Citus + PostgreSQL 在 100TB 以下场景比 NewSQL 简单、便宜、稳定;500TB+ 才考虑 NewSQL。
三十四、引申六:数据库 schema 演进的工程规范
Schema 演进 5 条铁律:(1) 永远向后兼容(N-1 必须能用);(2) 不允许 DROP COLUMN 单步,先停止写入,再 release,后续 DROP;(3) 不允许重命名,新增列 + 双写 + 切换 + 删旧;(4) 不允许改类型,新增列 + backfill + 切换;(5) 索引必须 CONCURRENTLY,DDL 必须 NOT VALID + VALIDATE 分两步。这 5 条铁律让 27 天升级期间 38 次 schema 变更零业务感知。
三十五、引申七:连接池真相
PostgreSQL 连接池真相:(1) 每个连接独占 ~10MB + 1 进程;(2) max_connections=500 是软上限,实际 200 已经吃满 2-4GB 内存;(3) idle 连接也会占用 shared memory;(4) pgBouncer transaction mode 是 OLTP 标配,session mode 仅在需要 SET / LISTEN / advisory lock 时用;(5) 应用 HikariCP / Druid 池子 ≤ pgBouncer pool_size,否则瓶颈在应用端。层级:App 池(20)→ pgBouncer(100)→ PG 进程(500)。
三十六、引申八:Citus columnar 列存表
Citus 12 的 columnar 表是工程化亮点。实战:(1) 日志 / 历史归档表用 columnar,空间节省 70%-90%;(2) 列存查询聚合快 5-10 倍;(3) 列存表支持 INSERT + UPDATE(Citus 12 新增),但不适合频繁 UPDATE;(4) 与行存混存:近 30 天行存,30 天以上 columnar 归档。具体配置:SELECT alter_table_set_access_method('events_2025_q1', 'columnar')。
三十七、引申九:pgvector 0.7 与 Pinecone / Weaviate 对比
pgvector 0.7 与专用向量库对比 5 个维度:(1) 性能:HNSW 召回率与 Pinecone 接近,延迟差距在 30% 内;(2) 成本:pgvector 自部署成本仅 Pinecone 1/10;(3) 运维:与现有 PG 同栈,无新依赖;(4) 功能:支持 cosine / l2 / inner product,但缺少 Pinecone 的元数据过滤优化;(5) 规模:亿级以上 Pinecone / Milvus 更稳。结论:5 千万以下场景 pgvector 工业级可用;5 千万-5 亿 Milvus / Weaviate;5 亿以上 Pinecone Serverless。
三十八、引申十:数据库的"5 个备份层级"
工业级备份需要 5 层:(1) WAL 持续归档(每 15 秒 push S3);(2) 每日 incremental backup;(3) 每周 full backup;(4) 每月跨区域副本;(5) 每季度离线归档(磁带 / Glacier Deep Archive)。恢复 SLA:RPO ≤ 15 秒 / RTO ≤ 30 分钟。任何低于这个标准的备份都是技术债。我们 27 天升级期间触发过 1 次 PITR 恢复演练,实际 RTO 26 分钟,达标。
三十九、引申十一:数据库索引的"7 类"
PostgreSQL 索引 7 种,各有场景:(1) B-tree:默认,等值 + 范围;(2) Hash:仅等值,PG 10+ 才支持 WAL,小众;(3) GIN:倒排索引,JSON / 数组 / 全文;(4) GiST:几何 / 范围 / 全文,可扩展;(5) BRIN:块范围,超大表的稀疏索引(节省空间);(6) SP-GiST:空间分区,IP / 网络;(7) HNSW / IVFFlat(pgvector):向量索引。实战:90% 用 B-tree,JSON 列 GIN,时序大表 BRIN,向量 HNSW。
四十、引申十二:全文搜索的 PostgreSQL 方案
2026 年全文搜索 PG 端方案:(1) 内置 tsvector + GIN:中文需 zhparser / jieba,适合中小规模;(2) pg_trgm + GIN:模糊匹配 + 拼写容错,API key 搜索 / 用户名 / 商品名常用;(3) RUM index:排序优于 GIN;(4) pg_search(ParadeDB,基于 Tantivy 集成):性能接近 Elasticsearch。我们的策略:商品搜索 < 1000 万行用 pg_trgm + GIN;> 1000 万行同步到 OpenSearch。
四十一、引申十三:JSON 与 JSONB 的工程权衡
JSON vs JSONB:(1) JSONB 二进制存储,GIN 索引可走,工程主流;(2) JSON 文本存储,保留原始格式与顺序,日志归档场景;(3) JSONB 操作符:->, ->>, @>, ?, ?|, ?&, jsonb_path_exists;(4) JSONB 路径索引:CREATE INDEX ON tbl USING GIN(data jsonb_path_ops);(5) jsonb_set / jsonb_insert / jsonb_strip_nulls 工业级常用。反模式:JSONB 当 KV 存储,完全替代关系表 — N+1 + 不可索引的灾难。
四十二、引申十四:PostgreSQL extensions 生态全景
2026 年 PG extensions 工业级清单:(1) 性能监控:pg_stat_statements / auto_explain / pgaudit / pgstattuple;(2) 数据处理:postgres_fdw / dblink / pg_cron / pg_partman / pg_repack;(3) AI / 向量:pgvector / pg_search / pgml;(4) 安全:pgcrypto / pgaudit / row_security;(5) 文本:pg_trgm / zhparser / unaccent;(6) 几何:postgis;(7) HTAP:citus / timescaledb / hydra(columnar)。我们的每个集群必装清单 12 个,可选 8 个。
四十三、引申十五:慢查询优化的 7 步法
慢查询优化 7 步法(SOP):(1) EXPLAIN (ANALYZE, BUFFERS, VERBOSE) 看真实执行计划;(2) 看 Seq Scan vs Index Scan 是否合理;(3) 看 buffers hit 比例(应 > 95%);(4) 看排序是否走索引;(5) 看 JOIN 顺序与 hash 数据量;(6) 必要时 SET enable_seqscan=off 强行验证可达计划;(7) 加索引 / 改 SQL / 改 schema 三选一。这个 7 步法是 DBA 进阶必备。
四十四、引申十六:数据库与微服务的边界
微服务时代数据库边界 5 原则:(1) 每个 service 独占 database / schema,不共享表;(2) 跨服务查询走 API,不走 JOIN;(3) 数据复制走 CDC,不走双写;(4) 服务间一致性走 Saga / Outbox,不走分布式事务;(5) 大表跨服务汇总走数据仓库(ETL/CDC),不走联邦查询。这 5 原则违反任意一条都是技术债。
四十五、引申十七:在 K8s 上运维数据库
2026 年 K8s 上跑 PostgreSQL 已经成熟:(1) CloudNativePG operator 主流,Crunchy Data 老牌;(2) StatefulSet + PVC + local NVMe 是标准模式;(3) 节点亲和性 + 反亲和性 + 跨 AZ 部署;(4) PodDisruptionBudget 保证可用性;(5) 备份 / 监控 / 升级全部 operator 接管。但有 3 个争议点:(a) 是否在 K8s 上跑 主库 — 大型企业仍倾向裸金属 / VM 跑主库,K8s 跑 replica;(b) NVMe 直通问题;(c) 内核参数(huge_pages / vm.swappiness)调优。
四十六、引申十八:数据迁移的"6 步法"
大表迁移 6 步法:(1) 评估:目标表大小、停机窗口、一致性要求、回滚预案;(2) 测试:沙箱跑全量 + 增量,测吞吐 + 一致性;(3) 全量同步:pg_dump / pg_basebackup / 自定义 ETL,后台批量;(4) 增量同步:Debezium / Logical Replication / Trigger;(5) 切换:停旧写 → 等增量追平 → 切流 → 验证 → 删除旧;(6) 回滚预案:任何一步可以中断回滚。27 天升级期间我们用这个 6 步法迁移了 1.2TB 的 events 表到 Citus,零数据丢失,零业务感知。
四十七、引申十九:数据库的"4 个 SLI"
SRE 视角数据库的 4 个 SLI(service level indicator):(1) 可用性(uptime):99.95% / 99.99% / 99.999% 三档;(2) 查询延迟(P50 / P95 / P99);(3) 错误率(connection refused / query timeout / deadlock 占比);(4) 数据新鲜度(replication lag / CDC lag)。对应 SLO:可用性 99.99% / P99 < 30ms / 错误率 < 0.01% / 复制延迟 < 2s。任何持续违规触发故障复盘。
四十八、引申二十:数据库的容量预测
容量预测 4 维度:(1) 存储增长:历史 6 个月线性回归 + 30% 缓冲;(2) QPS 增长:产品 / 营销活动叠加 + 50% 缓冲;(3) 连接数增长:服务数 × 连接池大小;(4) 索引膨胀:每月 5-10%。策略:磁盘使用率达到 70% 触发扩容,80% 触发紧急扩容,90% 触发降级方案。27 天升级期间我们提前 3 个月预测到 Citus 集群存储压力,提前扩容 2 个 worker。
四十九、引申二十一:数据库工具链
DBA 工具链全景:(1) 客户端:psql(永远的瑞士军刀)、pgcli(更友好的 REPL)、DBeaver、TablePlus、DataGrip;(2) 监控:pgwatch3 / pgAdmin 4 / Grafana 仪表盘;(3) 性能:pg_stat_statements / pg_stat_io / auto_explain / pgbadger(日志分析);(4) 备份:pg_dump / pg_basebackup / WAL-G / pgbackrest;(5) 迁移:pgloader(异构迁移)、pg_migrate;(6) HA:Patroni / Stolon / repmgr;(7) 连接池:pgBouncer / pgcat(Rust 实现)/ Odyssey;(8) AI 辅助:pg_chat / Claude SQL 优化。
五十、引申二十二:数据库的"6 道防线"
生产数据库 6 道防线:(1) 输入校验(应用层防 SQL 注入);(2) 权限隔离(role + RLS);(3) 慢查询防护(statement_timeout + idle_in_transaction_timeout);(4) 资源隔离(connection limit + work_mem 限制);(5) 备份(多层 + 跨区域 + 定期演练);(6) 监控告警(P99 + Error rate + Lag + Disk)。这 6 道防线让 27 天升级期间数据零丢失。
五十一、引申二十三:Patroni vs Stolon vs repmgr
3 种 PG HA 工具对比:(1) Patroni:Python + DCS(etcd/Consul),社区主流,K8s 友好;(2) Stolon:Go + etcd,功能简洁,2024 年后维护减弱;(3) repmgr:2ndQuadrant 老牌,无 DCS,纯 PG 内复制管理。结论:新项目选 Patroni 4,K8s 上选 CloudNativePG / Crunchy operator。
五十二、引申二十四:数据库的"4 个升级窗口"
PG 大版本升级 4 个窗口:(1) pg_upgrade in-place:停机 30-60 分钟,4.8TB 实测 25 分钟;(2) Logical replication + 切换:零停机,但需 1-2 周准备;(3) pg_dump + restore:仅小库;(4) 双写 + cutover:复杂业务的渐进迁移。我们 27 天升级 17 个集群:OLTP 2 个用 logical + cutover;Citus 3 个用 pg_upgrade + 集群滚动;其余 12 个用 pg_upgrade 单点。
五十三、引申二十五:数据库与"成本优化"
2026 年数据库成本优化 5 招:(1) 冷数据归档到 columnar 表 / S3:节省 70%;(2) 读副本卸载报表 / 风控查询:减轻主库;(3) 索引清理:删除未使用索引节省 20% IO + 磁盘;(4) 压缩:TOAST 自动压缩 + columnar 表二次压缩;(5) Reserved Instance / 自建 vs 云托管的总拥有成本(TCO)对比。实战:27 天升级附带的成本优化让月度数据库账单从 8.2 万降到 5.1 万,节省 38%。
五十四、引申二十六:Reindex 与 pg_repack 实战
Reindex 与 pg_repack 是大表健康维护双引擎。(1) REINDEX CONCURRENTLY(PG 12+):在线重建索引,无锁,推荐;(2) pg_repack:在线重建表 + 索引,清理 bloat,需要扩展;(3) VACUUM FULL:严格不要在生产用,会锁表。实战节奏:每月一次大表 REINDEX,每季度一次 pg_repack 整理 bloat,每年一次大版本升级。
五十五、引申二十七:数据库的"4 类故障"
27 天踩出的 4 类常见故障:(1) 锁:长事务 / FOR UPDATE 全表 / DDL 长锁;(2) 慢查询:索引未走 / Seq Scan 大表 / OFFSET 分页;(3) 复制:lag 过高 / slot 不清理 / 配置不一致;(4) 备份:WAL 链断 / PITR 演练失败 / 跨区域延迟。4 类故障对应的 4 个监控面板必须实时可见。
五十六、引申二十八:数据库的"未来 5 年"
2026-2031 数据库领域 5 大趋势:(1) 向量与关系融合:pgvector / TiDB Vector / MySQL HeatWave Vector 全面普及;(2) Serverless 数据库:Neon / PlanetScale / Aurora Serverless v3 性能差距收窄;(3) AI 辅助 DBA:慢查询自动优化 / index advisor / schema 演进建议;(4) 列存普及:Citus columnar / Hydra / Iceberg-PG;(5) 跨云联邦:多云 / 混合云数据治理。PostgreSQL 仍将是事实标准,生态深度无可替代。
五十七、给 DBA + SRE 的"7 句忠告"
27 天 5 次回滚 + 1 次 P0 + 3 次 P1 的 7 句忠告:(1) 永远 EXPLAIN ANALYZE,不要凭感觉调优;(2) 任何 DDL 必须 NOT VALID + VALIDATE 分两步;(3) 备份不演练不是备份;(4) autovacuum 不该关,该调;(5) 同步复制全部从节点是反模式,ANY N 才合理;(6) Citus 性能 80% 取决于 colocation 设计;(7) 监控覆盖 4 类故障 + 4 个 SLI 是底线。
五十八、最后一句话
27 天 PostgreSQL 16 + Citus 12 + pgvector 0.7 + Patroni 4 + Debezium 2.6 全栈现代化的复盘到此结束。如果只让我用一句话总结:"数据库工程化在 2026 年是索引 + 锁 + 事务 + Vacuum + 复制 + 分布式 + 备份 + 监控 + 安全 + 容量 + AI/向量 + 成本 12 个维度的综合工程能力,任何一个维度的缺失都会成为生产 P0 温床。" 这是我作为 tech lead 带 52 工程师 27 天的最终结论。愿每位 DBA + SRE + 后端工程师都能在 AI 数据浪潮 + 多云 + 向量检索 + 列存普及的 2026 年继续保持工程态度,做出真正可靠、高性能、易维护的数据库系统。继续提交 commit,继续前行,我们下次再见。
—— 别看了 · 2026