做 n8n 工作流开发的同行,大概率都逃不过一件事:把 PostgreSQL 或者 MySQL 接进来。这两个关系型数据库在自动化场景里的出镜率实在太高,从单据同步、报表汇总到数据清洗,几乎每个项目都会碰到。我发现一个普遍现象:大家写 SQL 都没问题,增删改查、JOIN 子查询信手拈来,可一旦工作流真的跑起来,数据库端就开始闹脾气——连接稍微一多就报错、事务明明写在里面就是不回滚、一个循环跑完业务库直接卡到爆。这篇文章不绕圈子,直接把我用 n8n 深度对接 PostgreSQL/MySQL 过程中验证过的配置、踩过的坑、以及稳定运行的方案一次说清楚。无论你是刚装好 n8n 准备接第一个库,还是已经在生产环境为性能和稳定性挠头,这篇都值得看完。
1. 先把连接这件事弄明白:环境准备与凭据配置
1.1 分清 n8n 主库和业务库,别搅在一起
很多人不清楚 n8n 自身也是要库存数据的。默认情况下,它用 SQLite 保存用户、工作流、凭证这些元数据。单机小规模玩无所谓,但你如果打算把它当生产工具用,我的建议是第一次部署就把主库换成 PostgreSQL。原因很直接:n8n 运行时有大量并发读写元数据的场景,SQLite 的锁竞争在这个负载下会明显拖慢节点执行速度,甚至导致 “database is locked” 之类的报错。MySQL、MariaDB 也可以,但我个人更偏向 PostgreSQL,毕竟 n8n 官方对这个组合的测试覆盖最全,社区踩坑记录也最少。
这里有个概念必须掰开:n8n 主库存的是 n8n 自己的元数据,业务库则是你工作流里要操作的数据。两者可以部署在同一个数据库实例上,只是用不同的 database 名做隔离。连接池、索引、参数调优要分别对待,别把调业务库的参数套到主库上,也不要反过来。后面讲到的连接池和事务,很多问题都出在这个混淆上。举个真实例子,有次我在部署时图省事,把 n8n 主库和业务库放在同一个 PostgreSQL 实例,结果业务库的慢查询直接把主库的进程打满,n8n 整个控制台跟着卡死。分库分实例虽然多花一点运维成本,但能避免这类互相拖累的事故。
1.2 凭据逐字段解读:为什么填 localhost 会翻车
在 n8n 里添加 PostgreSQL 或 MySQL 凭证时,字段无非是 host、port、database、user、password,顶多加个 SSL 开关。但就是这几个简单字段,藏着不少坑。
第一,host 填 localhost 和 127.0.0.1 的行为完全不同。n8n 的 MySQL 节点底层用的是 mysql2 驱动,写成 localhost 时驱动会优先尝试 Unix socket 文件而不是 TCP 端口。在 Docker 容器或者远程执行环境里,socket 文件路径对不上,就会报出 “Can't connect to local MySQL server through socket '/tmp/mysql.sock'” 这种让新手摸不着头脑的错误。我的习惯是凡是跨主机或容器环境,一律填 127.0.0.1 或内网 IP,强制走 TCP。本地开发连本机 MySQL 时,如果刻意要用 socket,那另说,但生产环境统一走 TCP 最省心。
第二,PostgreSQL 的默认库名不要搞错。n8n 的 PostgreSQL 节点里 database 字段填的是连接目标库名,而 schema 是另一个字段,默认 public。如果你的业务表建在某个非 public 的 schema 下,记得在节点配置里把 schema 指过去。很多人在 PostgreSQL 里建了业务表,却忘了在 n8n 节点里指定 schema,结果一直报 “relation does not exist”,排查半天才发现是默认 schema 不对。
第三,SSL 选项。数据库服务器如果没开 SSL,别勾 enableSSL,否则握手直接失败;反过来服务器强制 SSL 而你没勾,也会报 SSL 协商错误。这个通常在配置阶段会立刻暴露,属于一眼能看出的问题。但还有一个隐蔽场景:数据库前面挂着代理或负载均衡,代理终止了 SSL,n8n 这端反而要关掉 SSL 才能连上。所以遇到 SSL 报错,先确认整条链路每段的 SSL 状态,不要只盯着数据库本身。
1.3 连接验证:点 Test 之前先做这三步
n8n 编辑器里那个 Test connection 按钮很友好,但错误提示往往被包装得比较圆润,反而不利于排查。我在配置阶段通常先绕开 n8n,直接在数据库服务器所在机器上做三件事:
用 psql 或 mysql 命令行客户端手动连一次:
bash复制psql -h 127.0.0.1 -p 5432 -U your_user -d your_db
mysql -h 127.0.0.1 -P 3306 -u your_user -p your_db
能连上,再进 n8n 配凭证。连不上,错误信息在命令行里会更直白。这一步能过滤掉绝大多数账号权限、密码错误、端口不通的问题。
检查数据库监听地址。PostgreSQL 默认 listen_addresses 是 localhost,如果 n8n 和数据库不在同一台机器,必须把它改成实际监听地址并配置 pg_hba.conf 放行;MySQL 同样有 bind-address 限制。比如你在服务器上装好了 PostgreSQL,本机能连,但 n8n 在另一台机器上就是连不上,十有八九是 listen_addresses 没改。
检查防火墙和安全组。端口 5432、3306 有没有对外放行,这个虽然基础,但在云环境里是报错高发区。我每次都提醒一句:云厂商的安全组和服务器本机的 iptables/firewalld 是两层过滤,任何一层没放行都会导致连接超时,而且这两层报错的方式还不一样,安全组通常表现为连接一直卡住然后超时,本机防火墙有时候会直接拒绝。
这三步走完,Test connection 基本能一次过。如果还失败,把具体报错原文记下来,第五章有对应的排查思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 连接池机制拆解:并发下的第一道防线
2.1 连接池在帮你解决什么问题
数据库连接不是免费的午餐。每一次连接都要经历 TCP 握手、认证、可能的 SSL 协商,最便宜的 MySQL 连接建立也要几十毫秒,PostgreSQL 走 TLS 就更慢。如果 n8n 的每个工作流节点都现建现抛连接,那高并发时性能会非常难看。连接池的本质就是预先建好一批连接,调用方申请、使用、归还,循环复用。这就好比自助餐厅备好的餐盘,客人随手拿,用完放回去,而不是每次吃饭都从工厂现烧一个新的盘子。
这个看起来简单的机制,恰恰是 n8n 数据库集成里最容易出问题的一环。很多人遇到 “偶尔报错,重启 n8n 就好” 的诡异现象,十有八九和连接池配置不当有关。比如连接池里积累了坏连接,或者池子太小导致高并发时取连接超时,重启只是把池子清空重来,治标不治本。
2.2 n8n 底层驱动怎么管理连接池
n8n 的 PostgreSQL 节点底层基于 pg / pg-promise 系列驱动,MySQL 节点基于 mysql2。这两个驱动都有自己默认的连接池行为。n8n 在执行一个数据库节点时,会从连接池里取一条连接,跑完 SQL 再归还。注意:同一个工作流的不同节点,甚至同一个节点在循环中多次执行,拿到的都不一定是同一条连接。你可以把连接池理解成一批共享的工人,谁有空谁来接活,不保证每次都是同一个工人。
这个特性极其重要。它决定了 n8n 不能像你在 psql 客户端里那样,随手写个 BEGIN、再写几条 SQL、最后 COMMIT 完事——因为后两条 SQL 很可能落到另一条连接上,而事务是绑定在单条连接上的。n8n 里很多人以为把 SQL 拆到多个 Execute Query 节点就能组成事务,这是个经典误区。后面第三章会专门讲正确的做法,这里先记住一个结论:n8n 的连接池是给并发服务的,不是给事务服务的。
2.3 连接数到底配多少:一个能直接套用的计算方法
连接池大小不是越大越好。每一条连接在数据库端都占用内存会话资源,连接数过多反而拖垮数据库。我的参考公式是:
text复制连接池 max ≈ 预估最大并发工作流数 × 单个工作流最大并行数据库节点数 × 1.5
打个比方。假设你的 n8n 生产环境最多同时跑 10 个工作流,每个工作流内最多有 3 个数据库节点处于并行执行(n8n 支持无依赖节点并行,这个第四章会细说),那峰值连接数大概是 30。乘个 1.5 的余量系数,连接池 max 设在 45 左右比较稳妥。
这还没完,数据库端的 max_connections 也要跟着核对。PostgreSQL 默认 100,MySQL 默认 151。如果你一个数据库实例同时服务 n8n 主库、业务库和运维工具,这些连接数要整体排兵布阵。数据库端连接数是全局配额,连接池只是其中的消费者之一。忘了这层,就会在并发高峰期看到 “Too many connections” 或者 PostgreSQL 的 “remaining connection slots are reserved for superuser” 报错。
我这里整理了一张连接池参数速查表,方便你直接对照着调:
| 参数 | 作用 | 我的建议 |
|---|---|---|
| max | 连接池最大连接数 | 按公式估算,留 1.5 倍余量 |
| min | 最小空闲连接数 | 2~5 即可,没必要太高 |
| idleTimeoutMillis | 空闲连接回收时间 | 必须小于数据库 wait_timeout |
| connectionTimeoutMillis | 取连接的最长等待时间 | 10 秒左右比较合适 |
3. 事务处理实战:工作流里的原子性难题
3.1 先认清 n8n 的事务边界在哪
事务在数据库里是绑定在一条连接上的。BEGIN 开启一个事务块,后续所有 SQL 都必须在同一条连接上执行,直到 COMMIT 或 ROLLBACK。回到 n8n 的机制:每个数据库节点执行时都从连接池取连接,用完归还。那么问题来了——你在节点 A 里执行 BEGIN,节点 B 里执行 INSERT,节点 C 里执行 COMMIT,这三个节点拿到的很可能不是同一条连接。B 里的 INSERT 到了一个没有事务的普通连接上,就是裸执行,没有任何原子性保障,甚至可能报错。
我在项目里看到过不少把多节点事务当宝的写法,最后都是表面能跑,一到真正需要回滚的场景就露馅。比如订单创建工作流,节点 A 插入订单、节点 B 扣库存,节点 B 失败后你以为数据能回滚,结果订单已经留在库里成了脏数据。所以在 n8n 里谈事务,必须先接受一个前提:事务边界只能放在一个节点内部,或者干脆下推到数据库端。跨节点的 “事务” 想都不要想,那是分布式事务的范畴,3.4 会单独说。
3.2 单节点多语句事务的正确姿势
需要事务保护的几条 SQL 之间没有复杂逻辑的话,最简单的方式是写成一个 Execute Query 节点的多语句 SQL:
sql复制BEGIN;
INSERT INTO orders (order_no, amount, status) VALUES ('20240001', 99.00, 'PENDING');
UPDATE inventory SET stock = stock - 1 WHERE sku = 'A001' AND stock > 0;
COMMIT;
PostgreSQL 驱动对多语句支持比较自然,这类写法在 n8n 里能跑通。需要注意的是,如果中间某条 SQL 报错,PostgreSQL 会把事务置于 aborted 状态,后续所有语句都会报 “current transaction is aborted”,相当于事务被 “冻结” 了。正确做法是给整个事务块套上异常处理。PL/pgSQL 的 DO 块是个好选择:
sql复制DO $$
BEGIN
INSERT INTO orders (order_no, amount, status) VALUES ('20240001', 99.00, 'PENDING');
UPDATE inventory SET stock = stock - 1 WHERE sku = 'A001';
EXCEPTION WHEN OTHERS THEN
ROLLBACK;
RAISE;
END $$;
MySQL 节点处理多语句麻烦一些,mysql2 驱动默认不开启 multiStatements。如果非要这么做,还得看驱动配置,我更推荐下面存储过程的方案。MySQL 下正确做法是在存储过程里处理事务逻辑,原因很简单:驱动层面的多语句开关有安全隐患,开启后如果拼接不当很容易被注入。
3.3 存储过程方案:让数据库自己管事务
复杂事务,尤其是包含条件判断、循环、多表更新的逻辑,强烈建议封装成存储过程或函数。n8n 只发一次调用,事务的开启、提交、回滚全部在数据库端完成。这样有几层好处:首先,事务边界和连接归属问题直接消失;其次,逻辑在数据库里可以做单测;再者,n8n 工作流本身保持简单,可读性也更好。
一个 MySQL 存储过程的例子:
sql复制CREATE PROCEDURE sp_create_order_with_inventory(
IN p_order_no VARCHAR(64),
IN p_sku VARCHAR(32),
IN p_amount DECIMAL(10,2)
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
INSERT INTO orders (order_no, amount, status) VALUES (p_order_no, p_amount, 'PENDING');
UPDATE inventory SET stock = stock - 1 WHERE sku = p_sku AND stock > 0;
IF ROW_COUNT() = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'insufficient stock';
END IF;
COMMIT;
END;
n8n 节点里写一行 CALL sp_create_order_with_inventory('20240001', 'A001', 99.00) 就完事。如果库存不足,存储过程会主动抛错,n8n 节点直接失败,之前的事务已经回滚,不会产生脏数据。这个模式我在生产环境用了很久,稳。另外一个加速技巧:存储过程在 MySQL 8.0 和 PostgreSQL 11+ 都已经做过大量优化,预编译效果比每条 SQL 现解释要好,所以从性能角度来看,用存储过程也不亏。
3.4 失败重试、幂等与补偿设计
n8n 工作流有个 “Retry On Fail” 功能,节点失败后可以自动重试。听起来省心,但把它和数据库操作一组合,就诞生了经典的脏数据来源:重试导致重复插入。
解决方案有几个层次。第一层是数据库约束兜底:给业务表加上唯一键或唯一索引,INSERT 时带上业务唯一编号。第二层是 SQL 层面用幂等写法。PostgreSQL 的 INSERT ... ON CONFLICT DO NOTHING 和 MySQL 的 INSERT IGNORE / ON DUPLICATE KEY UPDATE 都能让重复执行变得无害:
sql复制INSERT INTO orders (order_no, amount) VALUES ('20240001', 99.00)
ON CONFLICT (order_no) DO NOTHING;
注意,ON CONFLICT 需要表上有对应的唯一约束或唯一索引,否则语法会直接报错。建表时就把业务唯一键设计好,比事后补强多了。我见过太多表没有业务唯一键,导致幂等方案无从下手,只能在工作流里加一堆判断逻辑,最后还是漏。
至于跨系统的场景,比如 n8n 编排订单创建和扣库存两个独立系统,数据库本地事务根本管不了这种分布式问题。n8n 在这里只能当编排器,用 Saga 的思想:每个步骤配一个正向操作和一个补偿操作,一旦后续步骤失败,在 Error Workflow 里逐一对已成功的步骤执行补偿。比如订单创建成功,但扣库存失败,那就执行一个补偿操作把订单标记为已取消。这套设计没有银弹,但 n8n 的 Error Workflow 机制恰好适合落地,值得好好利用。我自己实现的补偿表很简单:记录每次补偿操作的执行状态和次数,防止补偿动作本身失败后无人接手。
4. 性能调优实录:从工作流到数据库的全链路优化
4.1 Loop 节点逐行写库是头号反模式
在全职做 n8n 项目的这些年里,我见过最多的性能灾难,就是 Loop 节点配合数据库写操作。很多人从别的平台带过来的习惯是用循环逐条处理数据,每次迭代跑一条 INSERT 或 UPDATE。数据量少时没啥感觉,一到几百上千行,每行都是一次网络往返、一次 SQL 解析、一次事务提交,整体耗时直线上升,数据库连接也被占得满满的。更坑的是,如果循环体里还用了事务节点,那就是把锁粒度拉满,数据库直接动弹不得。
正确做法是批量。先把数据在内存里聚合好,然后一条 SQL 插入多行:
sql复制INSERT INTO orders (order_no, amount) VALUES
('20240001', 99.00),
('20240002', 88.00),
('20240003', 77.00);
在 n8n 里可以用 Code 节点(JavaScript)把数组处理成批量 SQL 的参数,或者用数据库节点的批量能力。批大小我一般控制在 500 到 1000 行之间,太大容易把事务锁范围拉得太宽,反而引发锁等待和死锁。实际跑下来,1000 行以内的批量插入在普通配置的 PostgreSQL 上都是毫秒级完成,比循环 1000 次快了不止一个量级。
4.2 节点并行执行与并发窗口:白拿的吞吐量
n8n 工作流里,如果几个数据库节点之间没有依赖关系,它们其实是可以并行执行的。很多人习惯把所有节点串成一条长链,明明是两个独立查询,非得等一个跑完再跑另一个,消耗的时间白白翻倍。把无依赖的节点摆在同一层级,再配合并发配置,整个工作流的数据库处理时间能明显下降。比如一个同步工作流里要分别读订单表和读库存表,两边没有先后依赖,并行读比串行读省将近一半时间。
但并行意味着连接峰值上升。这正好呼应第二章的连接池计算:单个工作流内并行 DB 节点数这个参数,会直接影响连接池 max 的估算。调并行度之前,先看看连接池和数据库 max_connections 有没有余量。一上来就把并行度拉满,而连接池没跟着调,大概率会在高峰期出问题。
另外一个隐藏的并发杠杆是 n8n 的并发窗口配置。生产环境里可以限制同时执行的工作流数量,比如设为 5。这个数字比盲目加大连接池更有效——它从源头限制了数据库压力,也给其他业务系统留出了空间。调并发窗口本质上是 “节流”,而调大连接池是 “扩路”,两者方向不同,但后者很容易被用成偷懒的手段。真正合理的做法是:先节流,确认业务峰值并发是多少,再按需扩路,两边配合着调。
4.3 数据库侧的关键参数:共享缓冲、排序内存与检查点
工作流设计和 SQL 写法优化完了,接下来看数据库本身的参数。这一步往往是最容易被忽视的,因为 n8n 能连上库、能跑通 SQL,大家就觉得数据库没问题了。其实默认参数只是保证能用,离好用还有距离。
对于 PostgreSQL,三个参数值得先动:shared_buffers 通常设为物理内存的 25% 左右;work_mem 控制单次排序、哈希操作能用的内存,不能设得太大,因为每个连接都可能分到一份,并发高时内存会被吃穿;effective_cache_size 给优化器一个参考值,设成总内存的 50% 到 75% 比较合理。另外一个大家容易忽略的是 checkpoint 相关参数,热词里有人提到 checkpointer,其实就是在排查这类问题。如果系统日志频繁出现 checkpoint 导致的 IO 抖动,多半是 checkpoint 间隔设置得太短,脏页刷盘太过频繁,需要拉长间隔并配合 checkpoint_completion_target 平滑刷盘。
MySQL 这边,最常见的调整是 innodb_buffer_pool_size,一般建议物理内存的 70% 左右。max_connections 默认 151,对稍有些并发的 n8n 场景是不够的,但改它之前先想清楚是不是真的要那么多连接——很多时候是连接池和慢查询的问题,而不是连接配额不够。另外建议把慢查询日志开起来,long_query_time 设为 1 秒,跑一段业务后再去分析。数据库参数调优不是照抄网上的模板,而是针对你的工作流特点去配。
4.4 部署模式与连接压力的关系
n8n 的部署方式对数据库连接压力有直接影响。默认的单进程模式把工作流执行、节点调度全放在一个进程里,数据库连接也全部由这一个进程管理。并发上来后,这个进程成为瓶颈,连接池分配、事件循环都会吃紧。我在压测时发现,单进程模式下连接池达到上限后,即使数据库本身还很闲,n8n 也会因为进程内资源争用而响应变慢。
生产环境推荐接入 Queue Mode:主进程负责调度和 API,真正执行工作流的 worker 进程可以开多个,彼此通过 Redis 通信。这样数据库连接池就分布到多个 worker 进程里,整体连接容量和吞吐都线性扩展。但要留意,每个 worker 都有自己的连接池,最大连接数是 “单个池 × worker 数”,计算总体规划时别漏乘。我有次就是忘了这个乘法,按单 worker 规划了连接配额,结果扩容到 3 个 worker 后直接把数据库连接数顶爆。
我在一个数据同步项目里,就是从单进程模式切到 3 个 worker 的 Queue Mode,数据库节点从每分钟百来次操作提升到每分钟六百多次,连接数规划好后没有任何报错。这个收益几乎是白拿的,前提是愿意多部署一个 Redis。如果你已经有 Redis 基础设施,Queue Mode 的迁移成本很低,强烈建议生产环境一步到位。
5. 常见问题与排查速查
5.1 MySQL socket 连接失败:localhost 惹的祸
这个报错太经典了:“Can't connect to local MySQL server through socket '/tmp/mysql.sock'”。原因前面说过,mysql2 驱动看到 host 是 localhost 就尝试 Unix socket,而容器或远程环境里 socket 文件路径不存在。解决办法很简单:n8n 的 MySQL 凭证里,host 改成 127.0.0.1,强迫走 TCP。顺手看看 MySQL 配置文件里的 socket 路径和 bind-address,确认服务端监听正常。
5.2 Too many connections 与连接池耗尽
数据库报连接数超限,第一反应先看现状,不要急着调大参数。在 MySQL 上执行:
sql复制SELECT COUNT(*) FROM information_schema.processlist;
SHOW STATUS LIKE 'Threads_connected';
PostgreSQL 上执行:
sql复制SELECT count(*) FROM pg_stat_activity;
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
如果连接数长期贴近上限但有大量空闲,说明连接池生命周期没管好,连接被占着不还。如果大量连接都卡在某个 SQL 上,那问题是慢查询而不是连接配额。如果确实是工作流并发太高,再考虑调大 max_connections 或者降低 n8n 并发窗口。顺序不能反,先确认原因再动手。我遇到过最典型的案例:业务方直接说连接不够,让我调大 max_connections,结果查出来是一个 Loop 节点在逐行更新几千条数据,每条都占着连接跑好几秒,把池子全占满了。改成了批量更新之后,连接数压力瞬间消失。
5.3 连接被数据库悄然断开
日志里偶尔出现 “connection terminated” 或者 “Lost connection to MySQL server”,但工作流并不是每次必现。这个通常是数据库端的 wait_timeout 把空闲连接回收了,而连接池不知道,还在用这条 “已死” 的连接。
处理方法是让连接池的空闲回收时间小于数据库的 wait_timeout。比如 MySQL 的 wait_timeout 是 8 小时,连接池的 idleTimeoutMillis 就该远小于 8 小时,我一般设 10 到 15 分钟。PostgreSQL 同理,还要检查 idle_in_transaction_session_timeout,防止事务挂起太久把连接拖死。这个参数是我后期才加上的,起因是一个工作流里事务开启了但一直没提交,连接被挂住,数据库端把这个连接杀了,然后工作流里后续的 SQL 全部报错。加上超时限制之后,隐患自动消除。
5.4 死锁:更新顺序不一致引发的冲突
并发工作流同时更新同一批数据时,死锁经常出现。最典型的是订单和库存:工作流 A 先更新订单再更新库存,工作流 B 先更新库存再更新订单,大家在等对方释放锁,数据库检测到死锁后回滚其中一个事务,n8n 节点直接报错。
解决办法是约定一个全局的锁顺序,比如所有工作流都先更新订单表再更新库存表。同时尽量缩小事务范围,一次事务别更新太多行。数据库死锁日志能帮你快速定位:PostgreSQL 看 postgresql.log 里的 deadlock detected 段,MySQL 看 innodb_print_all_deadlocks 开关打开后的记录。我习惯在新上线的数据库集成前,先开一个小时的死锁日志监控,跑一轮压测,把所有死锁场景在正式上线前都打出来。
5.5 n8n 用户账号与数据库的边角关系
最后说个容易被忽略的边角话题。n8n 自身的用户、工作流、凭证元数据都存在主数据库里,所以 “n8n 忘记密码” 这类问题本质上也是一个数据库问题。不过 n8n 的密码是 bcrypt 哈希存储,直接 SQL 改密码是不可行的。正确做法是命令行运行 n8n user-management:reset-password,把忘记的账号找回来。这个小细节提醒我们:你在 n8n 里做的每一项数据库集成,最终都跑在同一个数据库生态里,理解库的结构,很多 “平台问题” 其实就是数据库问题。同理,n8n 的凭证信息也是加密存在主库里的,备份主库就是备份了所有集成凭证,这个备份策略一定不能漏。
说了这么多,最后分享两个我自己的操作习惯。第一,每次新接一个数据库集成,我都会先跑一周的连接监控,用脚本每小时记录 pg_stat_activity 或 processlist 的连接曲线,确认工作流峰值时段到底需要多少连接。连接池参数不是一次配好就完事的,它是根据真实负载迭代出来的。第二,所有需要原子性保护的复杂逻辑,我尽量下沉到数据库的存储过程或函数里,n8n 只负责编排调用。这个原则让我后续维护省掉了大量 “为什么数据对不上” 的排查时间。也希望这篇里的方案,能帮你在 n8n 和 PostgreSQL/MySQL 集成的路上少走几个弯路。
