You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

xk6-sql扩展问题:setup()阶段无法传递数据库连接

问题原因及解决方案

直接错误原因

你的代码存在两个核心问题:

  1. 访问路径错误:setup()返回的是数据库连接对象db本身,但场景函数runtest1/runtest2中尝试访问data.db——这里的data就是setup返回的db对象,所以data.db是undefined,直接触发Cannot read property 'exec' of undefined报错。
  2. 连接无法跨进程复用:k6的setup函数运行在主进程,而虚拟用户(VU)的场景函数运行在独立子进程中。xk6-sql的数据库连接是底层原生对象,无法被序列化传递到子进程,即便修正访问路径,直接使用data.exec()也会因连接失效报错。

修复方案

方案1:每次迭代创建/关闭连接(简单直观)

将数据库连接逻辑移到场景函数内部,确保每个VU进程使用独立连接:

修改main.js

提取连接字符串为全局常量,移除setup中返回连接的逻辑:

import sql from "k6/x/sql";
export { runtest1 } from "./runtest1.js";
export { runtest2 } from "./runtest2.js";

const testConfig = JSON.parse(open("./conf.json"));
export const options = Object.assign(
  {
    insecureSkipTLSVerify: false,
  },
  testConfig
);

// 全局复用数据库连接字符串
export const DB_CONN_STR = "root:@tcp(127.0.0.1:3306)/testing";

export function setup() {
  // 如需初始化操作(如建表),可临时创建连接执行后关闭
  const tempDb = sql.open("mysql", DB_CONN_STR);
  // 示例:检查cats1表是否存在(按需添加)
  // tempDb.exec(`CREATE TABLE IF NOT EXISTS cats1 (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), breed VARCHAR(255), age INT)`);
  tempDb.close();
}

export default function () {
  console.log("running test cases...");
}

修改runtest1.js

import sql from "k6/x/sql";
import { DB_CONN_STR } from "./main.js";

export function runtest1() {
  const db = sql.open("mysql", DB_CONN_STR);
  try {
    db.exec(`INSERT INTO cats1 (name, breed, age) VALUES ('test1-2', 'Doodle', 1)`);
  } finally {
    // 确保无论是否报错都关闭连接
    db.close();
  }
}

修改runtest2.js

import sql from "k6/x/sql";
import { DB_CONN_STR } from "./main.js";

export function runtest2() {
  const db = sql.open("mysql", DB_CONN_STR);
  try {
    db.exec(`INSERT INTO cats1 (name, breed, age) VALUES ('test2-2', 'Doodle', 2)`);
  } finally {
    db.close();
  }
}

方案2:每个VU复用单个连接(性能更优)

如果希望每个VU在生命周期内只创建一次连接,可将连接逻辑放在模块级别(每个VU初始化时执行一次):

修改runtest1.js

import sql from "k6/x/sql";
import { DB_CONN_STR } from "./main.js";

// 每个VU初始化时创建一次连接
const db = sql.open("mysql", DB_CONN_STR);

export function runtest1() {
  db.exec(`INSERT INTO cats1 (name, breed, age) VALUES ('test1-2', 'Doodle', 1)`);
}

// VU结束时关闭连接
export function teardown() {
  db.close();
}

runtest2.js做相同修改即可。

额外说明

  • k6的setup/teardown仅用于全局初始化/清理,不能传递不可序列化的对象(如数据库连接)。
  • 每个VU拥有独立运行环境,必须使用自身的数据库连接,避免跨VU的资源竞争。

内容的提问来源于stack exchange,提问作者Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:08:17