Lua sysbench – 速成课

这是对我之前关于使用启用 Lua 的 sysbench 的博客文章的后续。今天我将深入探讨如何为 sysbench 编写 Lua 脚本。 请看这个简单的例子

function prepare ()
  local i
  print("creating table sbtest.t1 ...")
  db_query("create table t1 (c1 int unsigned primary key, c2 int)")
  db_query("begin")
  for i= 1, 1000 do
    db_query("insert into t1 values (" .. i .. "," .. i .. ")")
  end
  db_query("commit")
end

function cleanup()
  db_query("drop table t1")
end

function help()
  print("sysbench Lua demo; no special command line options available")
end

function thread_init(thread_id)
end

function thread_done(thread_id)
  db_disconnect()
end

function event(thread_id)
  db_query("select c2 from t1 where c1=" .. sb_rand(1, 1000))
end

有 3 个函数 prepare()cleanup()help()。当要求 sysbench 执行相应的操作时(例如 sysbench … help),这些函数就会被执行。

如果你运行 sysbench ... run,情况就不同了。首先 sysbench 启动所需数量的线程,并为每个线程执行 thread_init() 函数。在此之前,每个线程都会连接到数据库服务器(使用 sbtest 数据库)。因此,你不需要(实际上是:禁止)从 thread_init() 中调用 db_connect()。参数 thread_id 的值从 1 到所需的线程数。

之后 sysbench 会暂停片刻,让所有线程有机会完成初始化。然后每个线程都会在一个循环中执行 event() 函数,直到达到请求数限制(–max-requests)或执行时间限制(–max-time)。

最后,每个线程执行 thread_done() 函数。注意:当 sysbench 线程退出时,db_disconnect() 不会自动调用。如果 sysbench 直接连接到 MySQL 服务器,这不是问题,因为当 sysbench 退出时,所有 socket 都会关闭,MySQL 会终止相关的会话。如果你通过某个代理连接,你可能需要明确关闭连接,就像我上面做的那样。

如果提到的任何 Lua 函数为空,你可以从 Lua 脚本中省略它。上面我添加 thread_init() 函数只是为了完整起见。

这是使用上述 Lua 代码的示例会话

sysbench-trunk/sysbench$ ./sysbench --test=tests/db/demo.lua help
sysbench 0.5:  multi-threaded system evaluation benchmark

sysbench Lua demo; no special command line options available

sysbench-trunk/sysbench$ ./sysbench --test=tests/db/demo.lua 
  --mysql-socket=/tmp/mysql.sock --mysql-user=root prepare
sysbench 0.5:  multi-threaded system evaluation benchmark

creating table sbtest.t1 ...

sysbench-trunk/sysbench$ ./sysbench --test=tests/db/demo.lua 
  --mysql-socket=/tmp/mysql.sock --mysql-user=root --num-threads=4 
  --max-requests=0 --max-time=30 --report-interval=5 run
sysbench 0.5:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 4
Report intermediate results every 5 second(s)
Random number generator seed is 0 and will be ignored

Threads started!

[   5s] threads: 4, tps: 0.00, reads/s: 37499.12, writes/s: 0.00, response time: 0.19ms (95%)
[  10s] threads: 4, tps: 0.00, reads/s: 37041.45, writes/s: 0.00, response time: 0.19ms (95%)
[  15s] threads: 4, tps: 0.00, reads/s: 37358.99, writes/s: 0.00, response time: 0.19ms (95%)
[  20s] threads: 4, tps: 0.00, reads/s: 36109.20, writes/s: 0.00, response time: 0.20ms (95%)
[  25s] threads: 4, tps: 0.00, reads/s: 35841.39, writes/s: 0.00, response time: 0.20ms (95%)
OLTP test statistics:
    queries performed:
        read:                            1096527
        write:                           0
        other:                           0
        total:                           1096527
    transactions:                        0      (0.00 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 1096527 (36550.85 per sec.)
    other operations:                    0      (0.00 per sec.)

General statistics:
    total time:                          30.0000s
    total number of events:              1096527
    total time taken by event execution: 118.0536s
    response time:
         min:                                  0.07ms
         avg:                                  0.11ms
         max:                                 16.98ms
         approx.  95 percentile:               0.19ms

Threads fairness:
    events (avg/stddev):           274131.7500/5125.89
    execution time (avg/stddev):   29.5134/0.01

如果你了解 Lua,你可能已经注意到 demo.lua 使用了一些非标准的 Lua 函数。Sysbench 为 Lua 解释器添加了几个新函数。最重要的可能是 db_query()sb_rand()。还有更多。请查看 sysbench 源代码中 script_lua.c 文件中的 C 函数 sb_lua_new_state(),以获取完整列表。

你也应该查看附带的 Lua 代码,了解如何使用这些函数。

接下来:扩展 oltp.lua …