mirror of https://github.com/postgres/postgres
This also adds a slighly modified sysbench to the repository, which creates encrypted tables, and modifies the debug message default to 0.pull/209/head
parent
7f8974bd56
commit
e53fc3e276
@ -0,0 +1,121 @@ |
||||
name: Perf test |
||||
on: [pull_request] |
||||
permissions: |
||||
contents: write |
||||
pull-requests: write |
||||
repository-projects: write |
||||
|
||||
jobs: |
||||
build: |
||||
runs-on: ubuntu-22.04 |
||||
steps: |
||||
|
||||
|
||||
- name: Remove old postgres |
||||
run: | |
||||
sudo apt purge postgresql-client-common postgresql-common \ |
||||
postgresql postgresql* |
||||
sudo rm -rf /var/lib/postgresql /var/log/postgresql /etc/postgresql \ |
||||
/usr/lib/postgresql /usr/include/postgresql /usr/share/postgresql \ |
||||
/etc/postgresql |
||||
sudo rm -f /usr/bin/pg_config |
||||
|
||||
- name: Install dependencies |
||||
run: | |
||||
sudo apt-get update |
||||
sudo apt-get install -y libreadline6-dev systemtap-sdt-dev \ |
||||
zlib1g-dev libssl-dev libpam0g-dev bison flex \ |
||||
libipc-run-perl -y docbook-xsl docbook-xsl libxml2 libxml2-utils \ |
||||
libxml2-dev libxslt-dev xsltproc libkrb5-dev libldap2-dev \ |
||||
libsystemd-dev gettext tcl-dev libperl-dev pkg-config clang-11 \ |
||||
llvm-11 llvm-11-dev libselinux1-dev python3-dev \ |
||||
uuid-dev liblz4-dev meson ninja-build libjson-c-dev \ |
||||
sysbench |
||||
sudo /usr/bin/perl -MCPAN -e 'install IPC::RUN' |
||||
sudo /usr/bin/perl -MCPAN -e 'install Text::Trim' |
||||
|
||||
- name: Clone postgres repository |
||||
uses: actions/checkout@v2 |
||||
with: |
||||
repository: 'postgres/postgres' |
||||
ref: 'a81e5516fa4bc53e332cb35eefe231147c0e1749' |
||||
path: 'src' |
||||
|
||||
- name: Clone postgres-tde-ext repository |
||||
uses: actions/checkout@v2 |
||||
with: |
||||
path: 'src/contrib/postgres-tde-ext' |
||||
|
||||
- name: Include postgres-tde-ext in meson build |
||||
run: | |
||||
echo "subdir('postgres-tde-ext')" >> src/contrib/meson.build |
||||
|
||||
- name: Build postgres |
||||
run: | |
||||
meson setup build --prefix `pwd`/../inst --buildtype=release |
||||
cd build && ninja && ninja install |
||||
working-directory: src |
||||
|
||||
- name: Test postgres-tde-ext |
||||
run: | |
||||
cp ../contrib/postgres-tde-ext/keyring.json /tmp/keyring.json |
||||
meson test --suite setup -v |
||||
meson test --suite postgres-tde-ext -v --num-processes 1 |
||||
working-directory: src/build |
||||
|
||||
- name: Report on test fail |
||||
uses: actions/upload-artifact@v2 |
||||
if: ${{ failure() }} |
||||
with: |
||||
name: Regressions diff and postgresql log |
||||
path: | |
||||
src/build/testrun/postgres-tde-ext/regress/ |
||||
retention-days: 3 |
||||
|
||||
- name: Setup test environment |
||||
run: | |
||||
bin/initdb -D data |
||||
echo "shared_preload_libraries = 'pg_tde'" >> data/postgresql.conf |
||||
echo "pg_tde.keyringConfigFile = '/tmp/keyring.json'" >> data/postgresql.conf |
||||
bin/pg_ctl -D data start |
||||
bin/createdb sbtest |
||||
bin/createdb sbtest2 |
||||
bin/createuser sbtest -s |
||||
bin/psql sbtest2 <<< "CREATE EXTENSION pg_tde;" |
||||
cp -r ../src/contrib/postgres-tde-ext/sysbench . |
||||
working-directory: inst |
||||
|
||||
- name: Run baseline performance tests |
||||
run: | |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_insert.lua --tables=1 --table-size=10000 --pgsql-db=sbtest prepare |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_read_only.lua --tables=1 --table-size=10000 --pgsql-db=sbtest run |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_read_only.lua --tables=1 --table-size=10000 --pgsql-db=sbtest run | tee perf_norm |
||||
working-directory: inst |
||||
|
||||
- name: Run TDE performance tests |
||||
run: | |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_common_tde.lua --tables=1 --table-size=10000 --pgsql-db=sbtest2 prepare |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_read_only.lua --tables=1 --table-size=10000 --pgsql-db=sbtest2 run |
||||
sysbench --db-driver=pgsql --threads=1 sysbench/oltp_read_only.lua --tables=1 --table-size=10000 --pgsql-db=sbtest2 run | tee perf_tde |
||||
working-directory: inst |
||||
|
||||
- name: Print results |
||||
run: | |
||||
NORM_Q=$(cat perf_norm | grep 'total number of events' | cut -d ':' -f 2 | sed 's/ //g') |
||||
TDE_Q=$(cat perf_tde | grep 'total number of events' | cut -d ':' -f 2 | sed 's/ //g') |
||||
echo "Norm queries: $NORM_Q" |
||||
echo "TDE queries: $TDE_Q" |
||||
echo "Performance test results:" >> pr_perf_results |
||||
echo "Normal queries: $(cat perf_norm | grep 'total number of events' | cut -d ':' -f 2 | sed 's/ //g')" >> pr_perf_results |
||||
echo "TDE queries: $(cat perf_tde | grep 'total number of events' | cut -d ':' -f 2 | sed 's/ //g')" >> pr_perf_results |
||||
echo "Percentage: $(($TDE_Q*100/$NORM_Q))%" >> pr_perf_results |
||||
PERF_RESULT=$(cat pr_perf_results) |
||||
echo "PERF_RESULT<<EOF" >> $GITHUB_ENV |
||||
echo "$PERF_RESULT" >> $GITHUB_ENV |
||||
echo "EOF" >> $GITHUB_ENV |
||||
working-directory: inst |
||||
|
||||
- uses: actions/upload-artifact@v3 |
||||
with: |
||||
name: pr_perf_results |
||||
path: inst/pr_perf_results |
@ -0,0 +1,51 @@ |
||||
name: Perf test results |
||||
|
||||
on: |
||||
workflow_run: |
||||
workflows: [Perf test] |
||||
types: |
||||
- completed |
||||
|
||||
jobs: |
||||
download: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: 'Download artifact' |
||||
uses: actions/github-script@v5 |
||||
with: |
||||
script: | |
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ |
||||
owner: context.repo.owner, |
||||
repo: context.repo.repo, |
||||
run_id: context.payload.workflow_run.id, |
||||
}); |
||||
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { |
||||
return artifact.name == "pr_perf_results" |
||||
})[0]; |
||||
let download = await github.rest.actions.downloadArtifact({ |
||||
owner: context.repo.owner, |
||||
repo: context.repo.repo, |
||||
artifact_id: matchArtifact.id, |
||||
archive_format: 'zip', |
||||
}); |
||||
let fs = require('fs'); |
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_perf_results.zip`, Buffer.from(download.data)); |
||||
|
||||
- name: 'Unzip artifact' |
||||
run: | |
||||
unzip pr_perf_results.zip |
||||
|
||||
- name: Clone postgres-tde-ext repository |
||||
uses: actions/checkout@v2 |
||||
with: |
||||
path: 'src' |
||||
ref: ${{ github.event.workflow_run.head_branch }} |
||||
|
||||
- name: 'Create comment' |
||||
run: | |
||||
gh pr comment ${PR_NUMBER} -F ../pr_perf_results --edit-last || \ |
||||
gh pr comment ${PR_NUMBER} -F ../pr_perf_results |
||||
env: |
||||
PR_NUMBER: ${{ github.event.number }} |
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
working-directory: src |
@ -0,0 +1,56 @@ |
||||
#!/usr/bin/sysbench |
||||
-- -------------------------------------------------------------------------- -- |
||||
-- Bulk insert benchmark: do multi-row INSERTs concurrently in --threads |
||||
-- threads with each thread inserting into its own table. The number of INSERTs |
||||
-- executed by each thread is controlled by either --time or --events. |
||||
-- -------------------------------------------------------------------------- -- |
||||
|
||||
cursize=0 |
||||
|
||||
function thread_init() |
||||
drv = sysbench.sql.driver() |
||||
con = drv:connect() |
||||
end |
||||
|
||||
function prepare() |
||||
local i |
||||
|
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = 1, sysbench.opt.threads do |
||||
print("Creating table 'sbtest" .. i .. "'...") |
||||
con:query(string.format([[ |
||||
CREATE TABLE IF NOT EXISTS sbtest%d ( |
||||
id INTEGER NOT NULL, |
||||
k INTEGER DEFAULT '0' NOT NULL, |
||||
PRIMARY KEY (id))]], i)) |
||||
end |
||||
end |
||||
|
||||
function event() |
||||
if (cursize == 0) then |
||||
con:bulk_insert_init("INSERT INTO sbtest" .. thread_id+1 .. " VALUES") |
||||
end |
||||
|
||||
cursize = cursize + 1 |
||||
|
||||
con:bulk_insert_next("(" .. cursize .. "," .. cursize .. ")") |
||||
end |
||||
|
||||
function thread_done(thread_9d) |
||||
con:bulk_insert_done() |
||||
con:disconnect() |
||||
end |
||||
|
||||
function cleanup() |
||||
local i |
||||
|
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = 1, sysbench.opt.threads do |
||||
print("Dropping table 'sbtest" .. i .. "'...") |
||||
con:query("DROP TABLE IF EXISTS sbtest" .. i ) |
||||
end |
||||
end |
@ -0,0 +1,503 @@ |
||||
-- Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ----------------------------------------------------------------------------- |
||||
-- Common code for OLTP benchmarks. |
||||
-- ----------------------------------------------------------------------------- |
||||
|
||||
function init() |
||||
assert(event ~= nil, |
||||
"this script is meant to be included by other OLTP scripts and " .. |
||||
"should not be called directly.") |
||||
end |
||||
|
||||
if sysbench.cmdline.command == nil then |
||||
error("Command is required. Supported commands: prepare, prewarm, run, " .. |
||||
"cleanup, help") |
||||
end |
||||
|
||||
-- Command line options |
||||
sysbench.cmdline.options = { |
||||
table_size = |
||||
{"Number of rows per table", 10000}, |
||||
range_size = |
||||
{"Range size for range SELECT queries", 100}, |
||||
tables = |
||||
{"Number of tables", 1}, |
||||
point_selects = |
||||
{"Number of point SELECT queries per transaction", 10}, |
||||
simple_ranges = |
||||
{"Number of simple range SELECT queries per transaction", 1}, |
||||
sum_ranges = |
||||
{"Number of SELECT SUM() queries per transaction", 1}, |
||||
order_ranges = |
||||
{"Number of SELECT ORDER BY queries per transaction", 1}, |
||||
distinct_ranges = |
||||
{"Number of SELECT DISTINCT queries per transaction", 1}, |
||||
index_updates = |
||||
{"Number of UPDATE index queries per transaction", 1}, |
||||
non_index_updates = |
||||
{"Number of UPDATE non-index queries per transaction", 1}, |
||||
delete_inserts = |
||||
{"Number of DELETE/INSERT combinations per transaction", 1}, |
||||
range_selects = |
||||
{"Enable/disable all range SELECT queries", true}, |
||||
auto_inc = |
||||
{"Use AUTO_INCREMENT column as Primary Key (for MySQL), " .. |
||||
"or its alternatives in other DBMS. When disabled, use " .. |
||||
"client-generated IDs", true}, |
||||
skip_trx = |
||||
{"Don't start explicit transactions and execute all queries " .. |
||||
"in the AUTOCOMMIT mode", false}, |
||||
secondary = |
||||
{"Use a secondary index in place of the PRIMARY KEY", false}, |
||||
create_secondary = |
||||
{"Create a secondary index in addition to the PRIMARY KEY", true}, |
||||
mysql_storage_engine = |
||||
{"Storage engine, if MySQL is used", "innodb"}, |
||||
pgsql_variant = |
||||
{"Use this PostgreSQL variant when running with the " .. |
||||
"PostgreSQL driver. The only currently supported " .. |
||||
"variant is 'redshift'. When enabled, " .. |
||||
"create_secondary is automatically disabled, and " .. |
||||
"delete_inserts is set to 0"} |
||||
} |
||||
|
||||
-- Prepare the dataset. This command supports parallel execution, i.e. will |
||||
-- benefit from executing with --threads > 1 as long as --tables > 1 |
||||
function cmd_prepare() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, |
||||
sysbench.opt.threads do |
||||
create_table(drv, con, i) |
||||
end |
||||
end |
||||
|
||||
-- Preload the dataset into the server cache. This command supports parallel |
||||
-- execution, i.e. will benefit from executing with --threads > 1 as long as |
||||
-- --tables > 1 |
||||
-- |
||||
-- PS. Currently, this command is only meaningful for MySQL/InnoDB benchmarks |
||||
function cmd_prewarm() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
assert(drv:name() == "mysql", "prewarm is currently MySQL only") |
||||
|
||||
-- Do not create on disk tables for subsequent queries |
||||
con:query("SET tmp_table_size=2*1024*1024*1024") |
||||
con:query("SET max_heap_table_size=2*1024*1024*1024") |
||||
|
||||
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, |
||||
sysbench.opt.threads do |
||||
local t = "sbtest" .. i |
||||
print("Prewarming table " .. t) |
||||
con:query("ANALYZE TABLE sbtest" .. i) |
||||
con:query(string.format( |
||||
"SELECT AVG(id) FROM " .. |
||||
"(SELECT * FROM %s FORCE KEY (PRIMARY) " .. |
||||
"LIMIT %u) t", |
||||
t, sysbench.opt.table_size)) |
||||
con:query(string.format( |
||||
"SELECT COUNT(*) FROM " .. |
||||
"(SELECT * FROM %s WHERE k LIKE '%%0%%' LIMIT %u) t", |
||||
t, sysbench.opt.table_size)) |
||||
end |
||||
end |
||||
|
||||
-- Implement parallel prepare and prewarm commands |
||||
sysbench.cmdline.commands = { |
||||
prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND}, |
||||
prewarm = {cmd_prewarm, sysbench.cmdline.PARALLEL_COMMAND} |
||||
} |
||||
|
||||
|
||||
-- Template strings of random digits with 11-digit groups separated by dashes |
||||
|
||||
-- 10 groups, 119 characters |
||||
local c_value_template = "###########-###########-###########-" .. |
||||
"###########-###########-###########-" .. |
||||
"###########-###########-###########-" .. |
||||
"###########" |
||||
|
||||
-- 5 groups, 59 characters |
||||
local pad_value_template = "###########-###########-###########-" .. |
||||
"###########-###########" |
||||
|
||||
function get_c_value() |
||||
return sysbench.rand.string(c_value_template) |
||||
end |
||||
|
||||
function get_pad_value() |
||||
return sysbench.rand.string(pad_value_template) |
||||
end |
||||
|
||||
function create_table(drv, con, table_num) |
||||
local id_index_def, id_def |
||||
local engine_def = "" |
||||
local extra_table_options = "" |
||||
local query |
||||
|
||||
if sysbench.opt.secondary then |
||||
id_index_def = "KEY xid" |
||||
else |
||||
id_index_def = "PRIMARY KEY" |
||||
end |
||||
|
||||
if drv:name() == "mysql" or drv:name() == "attachsql" or |
||||
drv:name() == "drizzle" |
||||
then |
||||
if sysbench.opt.auto_inc then |
||||
id_def = "INTEGER NOT NULL AUTO_INCREMENT" |
||||
else |
||||
id_def = "INTEGER NOT NULL" |
||||
end |
||||
engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */" |
||||
extra_table_options = mysql_table_options or "" |
||||
elseif drv:name() == "pgsql" |
||||
then |
||||
if not sysbench.opt.auto_inc then |
||||
id_def = "INTEGER NOT NULL" |
||||
elseif pgsql_variant == 'redshift' then |
||||
id_def = "INTEGER IDENTITY(1,1)" |
||||
else |
||||
id_def = "SERIAL" |
||||
end |
||||
else |
||||
error("Unsupported database driver:" .. drv:name()) |
||||
end |
||||
|
||||
print(string.format("Creating table 'sbtest%d'...", table_num)) |
||||
|
||||
query = string.format([[ |
||||
CREATE TABLE sbtest%d( |
||||
id %s, |
||||
k INTEGER DEFAULT '0' NOT NULL, |
||||
c CHAR(120) DEFAULT '' NOT NULL, |
||||
pad CHAR(60) DEFAULT '' NOT NULL, |
||||
%s (id) |
||||
), |
||||
table_num, id_def, id_index_def, engine_def, extra_table_options) |
||||
|
||||
con:query(query) |
||||
|
||||
if (sysbench.opt.table_size > 0) then |
||||
print(string.format("Inserting %d records into 'sbtest%d'", |
||||
sysbench.opt.table_size, table_num)) |
||||
end |
||||
|
||||
if sysbench.opt.auto_inc then |
||||
query = "INSERT INTO sbtest" .. table_num .. "(k, c, pad) VALUES" |
||||
else |
||||
query = "INSERT INTO sbtest" .. table_num .. "(id, k, c, pad) VALUES" |
||||
end |
||||
|
||||
con:bulk_insert_init(query) |
||||
|
||||
local c_val |
||||
local pad_val |
||||
|
||||
for i = 1, sysbench.opt.table_size do |
||||
|
||||
c_val = get_c_value() |
||||
pad_val = get_pad_value() |
||||
|
||||
if (sysbench.opt.auto_inc) then |
||||
query = string.format("(%d, '%s', '%s')", |
||||
sb_rand(1, sysbench.opt.table_size), c_val, |
||||
pad_val) |
||||
else |
||||
query = string.format("(%d, %d, '%s', '%s')", |
||||
i, sb_rand(1, sysbench.opt.table_size), c_val, |
||||
pad_val) |
||||
end |
||||
|
||||
con:bulk_insert_next(query) |
||||
end |
||||
|
||||
con:bulk_insert_done() |
||||
|
||||
if sysbench.opt.create_secondary then |
||||
print(string.format("Creating a secondary index on 'sbtest%d'...", |
||||
table_num)) |
||||
con:query(string.format("CREATE INDEX k_%d ON sbtest%d(k)", |
||||
table_num, table_num)) |
||||
end |
||||
end |
||||
|
||||
local t = sysbench.sql.type |
||||
local stmt_defs = { |
||||
point_selects = { |
||||
"SELECT c FROM sbtest%u WHERE id=?", |
||||
t.INT}, |
||||
simple_ranges = { |
||||
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?", |
||||
t.INT, t.INT}, |
||||
sum_ranges = { |
||||
"SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?", |
||||
t.INT, t.INT}, |
||||
order_ranges = { |
||||
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", |
||||
t.INT, t.INT}, |
||||
distinct_ranges = { |
||||
"SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", |
||||
t.INT, t.INT}, |
||||
index_updates = { |
||||
"UPDATE sbtest%u SET k=k+1 WHERE id=?", |
||||
t.INT}, |
||||
non_index_updates = { |
||||
"UPDATE sbtest%u SET c=? WHERE id=?", |
||||
{t.CHAR, 120}, t.INT}, |
||||
deletes = { |
||||
"DELETE FROM sbtest%u WHERE id=?", |
||||
t.INT}, |
||||
inserts = { |
||||
"INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)", |
||||
t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}}, |
||||
} |
||||
|
||||
function prepare_begin() |
||||
stmt.begin = con:prepare("BEGIN") |
||||
end |
||||
|
||||
function prepare_commit() |
||||
stmt.commit = con:prepare("COMMIT") |
||||
end |
||||
|
||||
function prepare_for_each_table(key) |
||||
for t = 1, sysbench.opt.tables do |
||||
stmt[t][key] = con:prepare(string.format(stmt_defs[key][1], t)) |
||||
|
||||
local nparam = #stmt_defs[key] - 1 |
||||
|
||||
if nparam > 0 then |
||||
param[t][key] = {} |
||||
end |
||||
|
||||
for p = 1, nparam do |
||||
local btype = stmt_defs[key][p+1] |
||||
local len |
||||
|
||||
if type(btype) == "table" then |
||||
len = btype[2] |
||||
btype = btype[1] |
||||
end |
||||
if btype == sysbench.sql.type.VARCHAR or |
||||
btype == sysbench.sql.type.CHAR then |
||||
param[t][key][p] = stmt[t][key]:bind_create(btype, len) |
||||
else |
||||
param[t][key][p] = stmt[t][key]:bind_create(btype) |
||||
end |
||||
end |
||||
|
||||
if nparam > 0 then |
||||
stmt[t][key]:bind_param(unpack(param[t][key])) |
||||
end |
||||
end |
||||
end |
||||
|
||||
function prepare_point_selects() |
||||
prepare_for_each_table("point_selects") |
||||
end |
||||
|
||||
function prepare_simple_ranges() |
||||
prepare_for_each_table("simple_ranges") |
||||
end |
||||
|
||||
function prepare_sum_ranges() |
||||
prepare_for_each_table("sum_ranges") |
||||
end |
||||
|
||||
function prepare_order_ranges() |
||||
prepare_for_each_table("order_ranges") |
||||
end |
||||
|
||||
function prepare_distinct_ranges() |
||||
prepare_for_each_table("distinct_ranges") |
||||
end |
||||
|
||||
function prepare_index_updates() |
||||
prepare_for_each_table("index_updates") |
||||
end |
||||
|
||||
function prepare_non_index_updates() |
||||
prepare_for_each_table("non_index_updates") |
||||
end |
||||
|
||||
function prepare_delete_inserts() |
||||
prepare_for_each_table("deletes") |
||||
prepare_for_each_table("inserts") |
||||
end |
||||
|
||||
function thread_init() |
||||
drv = sysbench.sql.driver() |
||||
con = drv:connect() |
||||
|
||||
-- Create global nested tables for prepared statements and their |
||||
-- parameters. We need a statement and a parameter set for each combination |
||||
-- of connection/table/query |
||||
stmt = {} |
||||
param = {} |
||||
|
||||
for t = 1, sysbench.opt.tables do |
||||
stmt[t] = {} |
||||
param[t] = {} |
||||
end |
||||
|
||||
-- This function is a 'callback' defined by individual benchmark scripts |
||||
prepare_statements() |
||||
end |
||||
|
||||
-- Close prepared statements |
||||
function close_statements() |
||||
for t = 1, sysbench.opt.tables do |
||||
for k, s in pairs(stmt[t]) do |
||||
stmt[t][k]:close() |
||||
end |
||||
end |
||||
if (stmt.begin ~= nil) then |
||||
stmt.begin:close() |
||||
end |
||||
if (stmt.commit ~= nil) then |
||||
stmt.commit:close() |
||||
end |
||||
end |
||||
|
||||
function thread_done() |
||||
close_statements() |
||||
con:disconnect() |
||||
end |
||||
|
||||
function cleanup() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = 1, sysbench.opt.tables do |
||||
print(string.format("Dropping table 'sbtest%d'...", i)) |
||||
con:query("DROP TABLE IF EXISTS sbtest" .. i ) |
||||
end |
||||
end |
||||
|
||||
local function get_table_num() |
||||
return sysbench.rand.uniform(1, sysbench.opt.tables) |
||||
end |
||||
|
||||
local function get_id() |
||||
return sysbench.rand.default(1, sysbench.opt.table_size) |
||||
end |
||||
|
||||
function begin() |
||||
stmt.begin:execute() |
||||
end |
||||
|
||||
function commit() |
||||
stmt.commit:execute() |
||||
end |
||||
|
||||
function execute_point_selects() |
||||
local tnum = get_table_num() |
||||
local i |
||||
|
||||
for i = 1, sysbench.opt.point_selects do |
||||
param[tnum].point_selects[1]:set(get_id()) |
||||
|
||||
stmt[tnum].point_selects:execute() |
||||
end |
||||
end |
||||
|
||||
local function execute_range(key) |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt[key] do |
||||
local id = get_id() |
||||
|
||||
param[tnum][key][1]:set(id) |
||||
param[tnum][key][2]:set(id + sysbench.opt.range_size - 1) |
||||
|
||||
stmt[tnum][key]:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_simple_ranges() |
||||
execute_range("simple_ranges") |
||||
end |
||||
|
||||
function execute_sum_ranges() |
||||
execute_range("sum_ranges") |
||||
end |
||||
|
||||
function execute_order_ranges() |
||||
execute_range("order_ranges") |
||||
end |
||||
|
||||
function execute_distinct_ranges() |
||||
execute_range("distinct_ranges") |
||||
end |
||||
|
||||
function execute_index_updates() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.index_updates do |
||||
param[tnum].index_updates[1]:set(get_id()) |
||||
|
||||
stmt[tnum].index_updates:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_non_index_updates() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.non_index_updates do |
||||
param[tnum].non_index_updates[1]:set_rand_str(c_value_template) |
||||
param[tnum].non_index_updates[2]:set(get_id()) |
||||
|
||||
stmt[tnum].non_index_updates:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_delete_inserts() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.delete_inserts do |
||||
local id = get_id() |
||||
local k = get_id() |
||||
|
||||
param[tnum].deletes[1]:set(id) |
||||
|
||||
param[tnum].inserts[1]:set(id) |
||||
param[tnum].inserts[2]:set(k) |
||||
param[tnum].inserts[3]:set_rand_str(c_value_template) |
||||
param[tnum].inserts[4]:set_rand_str(pad_value_template) |
||||
|
||||
stmt[tnum].deletes:execute() |
||||
stmt[tnum].inserts:execute() |
||||
end |
||||
end |
||||
|
||||
-- Re-prepare statements if we have reconnected, which is possible when some of |
||||
-- the listed error codes are in the --mysql-ignore-errors list |
||||
function sysbench.hooks.before_restart_event(errdesc) |
||||
if errdesc.sql_errno == 2013 or -- CR_SERVER_LOST |
||||
errdesc.sql_errno == 2055 or -- CR_SERVER_LOST_EXTENDED |
||||
errdesc.sql_errno == 2006 or -- CR_SERVER_GONE_ERROR |
||||
errdesc.sql_errno == 2011 -- CR_TCP_CONNECTION |
||||
then |
||||
close_statements() |
||||
prepare_statements() |
||||
end |
||||
end |
@ -0,0 +1,503 @@ |
||||
-- Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ----------------------------------------------------------------------------- |
||||
-- Common code for OLTP benchmarks. |
||||
-- ----------------------------------------------------------------------------- |
||||
|
||||
function init() |
||||
assert(event ~= nil, |
||||
"this script is meant to be included by other OLTP scripts and " .. |
||||
"should not be called directly.") |
||||
end |
||||
|
||||
if sysbench.cmdline.command == nil then |
||||
error("Command is required. Supported commands: prepare, prewarm, run, " .. |
||||
"cleanup, help") |
||||
end |
||||
|
||||
-- Command line options |
||||
sysbench.cmdline.options = { |
||||
table_size = |
||||
{"Number of rows per table", 10000}, |
||||
range_size = |
||||
{"Range size for range SELECT queries", 100}, |
||||
tables = |
||||
{"Number of tables", 1}, |
||||
point_selects = |
||||
{"Number of point SELECT queries per transaction", 10}, |
||||
simple_ranges = |
||||
{"Number of simple range SELECT queries per transaction", 1}, |
||||
sum_ranges = |
||||
{"Number of SELECT SUM() queries per transaction", 1}, |
||||
order_ranges = |
||||
{"Number of SELECT ORDER BY queries per transaction", 1}, |
||||
distinct_ranges = |
||||
{"Number of SELECT DISTINCT queries per transaction", 1}, |
||||
index_updates = |
||||
{"Number of UPDATE index queries per transaction", 1}, |
||||
non_index_updates = |
||||
{"Number of UPDATE non-index queries per transaction", 1}, |
||||
delete_inserts = |
||||
{"Number of DELETE/INSERT combinations per transaction", 1}, |
||||
range_selects = |
||||
{"Enable/disable all range SELECT queries", true}, |
||||
auto_inc = |
||||
{"Use AUTO_INCREMENT column as Primary Key (for MySQL), " .. |
||||
"or its alternatives in other DBMS. When disabled, use " .. |
||||
"client-generated IDs", true}, |
||||
skip_trx = |
||||
{"Don't start explicit transactions and execute all queries " .. |
||||
"in the AUTOCOMMIT mode", false}, |
||||
secondary = |
||||
{"Use a secondary index in place of the PRIMARY KEY", false}, |
||||
create_secondary = |
||||
{"Create a secondary index in addition to the PRIMARY KEY", true}, |
||||
mysql_storage_engine = |
||||
{"Storage engine, if MySQL is used", "innodb"}, |
||||
pgsql_variant = |
||||
{"Use this PostgreSQL variant when running with the " .. |
||||
"PostgreSQL driver. The only currently supported " .. |
||||
"variant is 'redshift'. When enabled, " .. |
||||
"create_secondary is automatically disabled, and " .. |
||||
"delete_inserts is set to 0"} |
||||
} |
||||
|
||||
-- Prepare the dataset. This command supports parallel execution, i.e. will |
||||
-- benefit from executing with --threads > 1 as long as --tables > 1 |
||||
function cmd_prepare() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, |
||||
sysbench.opt.threads do |
||||
create_table(drv, con, i) |
||||
end |
||||
end |
||||
|
||||
-- Preload the dataset into the server cache. This command supports parallel |
||||
-- execution, i.e. will benefit from executing with --threads > 1 as long as |
||||
-- --tables > 1 |
||||
-- |
||||
-- PS. Currently, this command is only meaningful for MySQL/InnoDB benchmarks |
||||
function cmd_prewarm() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
assert(drv:name() == "mysql", "prewarm is currently MySQL only") |
||||
|
||||
-- Do not create on disk tables for subsequent queries |
||||
con:query("SET tmp_table_size=2*1024*1024*1024") |
||||
con:query("SET max_heap_table_size=2*1024*1024*1024") |
||||
|
||||
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, |
||||
sysbench.opt.threads do |
||||
local t = "sbtest" .. i |
||||
print("Prewarming table " .. t) |
||||
con:query("ANALYZE TABLE sbtest" .. i) |
||||
con:query(string.format( |
||||
"SELECT AVG(id) FROM " .. |
||||
"(SELECT * FROM %s FORCE KEY (PRIMARY) " .. |
||||
"LIMIT %u) t", |
||||
t, sysbench.opt.table_size)) |
||||
con:query(string.format( |
||||
"SELECT COUNT(*) FROM " .. |
||||
"(SELECT * FROM %s WHERE k LIKE '%%0%%' LIMIT %u) t", |
||||
t, sysbench.opt.table_size)) |
||||
end |
||||
end |
||||
|
||||
-- Implement parallel prepare and prewarm commands |
||||
sysbench.cmdline.commands = { |
||||
prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND}, |
||||
prewarm = {cmd_prewarm, sysbench.cmdline.PARALLEL_COMMAND} |
||||
} |
||||
|
||||
|
||||
-- Template strings of random digits with 11-digit groups separated by dashes |
||||
|
||||
-- 10 groups, 119 characters |
||||
local c_value_template = "###########-###########-###########-" .. |
||||
"###########-###########-###########-" .. |
||||
"###########-###########-###########-" .. |
||||
"###########" |
||||
|
||||
-- 5 groups, 59 characters |
||||
local pad_value_template = "###########-###########-###########-" .. |
||||
"###########-###########" |
||||
|
||||
function get_c_value() |
||||
return sysbench.rand.string(c_value_template) |
||||
end |
||||
|
||||
function get_pad_value() |
||||
return sysbench.rand.string(pad_value_template) |
||||
end |
||||
|
||||
function create_table(drv, con, table_num) |
||||
local id_index_def, id_def |
||||
local engine_def = "" |
||||
local extra_table_options = "" |
||||
local query |
||||
|
||||
if sysbench.opt.secondary then |
||||
id_index_def = "KEY xid" |
||||
else |
||||
id_index_def = "PRIMARY KEY" |
||||
end |
||||
|
||||
if drv:name() == "mysql" or drv:name() == "attachsql" or |
||||
drv:name() == "drizzle" |
||||
then |
||||
if sysbench.opt.auto_inc then |
||||
id_def = "INTEGER NOT NULL AUTO_INCREMENT" |
||||
else |
||||
id_def = "INTEGER NOT NULL" |
||||
end |
||||
engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */" |
||||
extra_table_options = mysql_table_options or "" |
||||
elseif drv:name() == "pgsql" |
||||
then |
||||
if not sysbench.opt.auto_inc then |
||||
id_def = "INTEGER NOT NULL" |
||||
elseif pgsql_variant == 'redshift' then |
||||
id_def = "INTEGER IDENTITY(1,1)" |
||||
else |
||||
id_def = "SERIAL" |
||||
end |
||||
else |
||||
error("Unsupported database driver:" .. drv:name()) |
||||
end |
||||
|
||||
print(string.format("Creating table 'sbtest%d'...", table_num)) |
||||
|
||||
query = string.format([[ |
||||
CREATE TABLE sbtest%d( |
||||
id %s, |
||||
k INTEGER DEFAULT '0' NOT NULL, |
||||
c CHAR(120) DEFAULT '' NOT NULL, |
||||
pad CHAR(60) DEFAULT '' NOT NULL, |
||||
%s (id) |
||||
) USING pg_tde %s %s]], |
||||
table_num, id_def, id_index_def, engine_def, extra_table_options) |
||||
|
||||
con:query(query) |
||||
|
||||
if (sysbench.opt.table_size > 0) then |
||||
print(string.format("Inserting %d records into 'sbtest%d'", |
||||
sysbench.opt.table_size, table_num)) |
||||
end |
||||
|
||||
if sysbench.opt.auto_inc then |
||||
query = "INSERT INTO sbtest" .. table_num .. "(k, c, pad) VALUES" |
||||
else |
||||
query = "INSERT INTO sbtest" .. table_num .. "(id, k, c, pad) VALUES" |
||||
end |
||||
|
||||
con:bulk_insert_init(query) |
||||
|
||||
local c_val |
||||
local pad_val |
||||
|
||||
for i = 1, sysbench.opt.table_size do |
||||
|
||||
c_val = get_c_value() |
||||
pad_val = get_pad_value() |
||||
|
||||
if (sysbench.opt.auto_inc) then |
||||
query = string.format("(%d, '%s', '%s')", |
||||
sb_rand(1, sysbench.opt.table_size), c_val, |
||||
pad_val) |
||||
else |
||||
query = string.format("(%d, %d, '%s', '%s')", |
||||
i, sb_rand(1, sysbench.opt.table_size), c_val, |
||||
pad_val) |
||||
end |
||||
|
||||
con:bulk_insert_next(query) |
||||
end |
||||
|
||||
con:bulk_insert_done() |
||||
|
||||
if sysbench.opt.create_secondary then |
||||
print(string.format("Creating a secondary index on 'sbtest%d'...", |
||||
table_num)) |
||||
con:query(string.format("CREATE INDEX k_%d ON sbtest%d(k)", |
||||
table_num, table_num)) |
||||
end |
||||
end |
||||
|
||||
local t = sysbench.sql.type |
||||
local stmt_defs = { |
||||
point_selects = { |
||||
"SELECT c FROM sbtest%u WHERE id=?", |
||||
t.INT}, |
||||
simple_ranges = { |
||||
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?", |
||||
t.INT, t.INT}, |
||||
sum_ranges = { |
||||
"SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?", |
||||
t.INT, t.INT}, |
||||
order_ranges = { |
||||
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", |
||||
t.INT, t.INT}, |
||||
distinct_ranges = { |
||||
"SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", |
||||
t.INT, t.INT}, |
||||
index_updates = { |
||||
"UPDATE sbtest%u SET k=k+1 WHERE id=?", |
||||
t.INT}, |
||||
non_index_updates = { |
||||
"UPDATE sbtest%u SET c=? WHERE id=?", |
||||
{t.CHAR, 120}, t.INT}, |
||||
deletes = { |
||||
"DELETE FROM sbtest%u WHERE id=?", |
||||
t.INT}, |
||||
inserts = { |
||||
"INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)", |
||||
t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}}, |
||||
} |
||||
|
||||
function prepare_begin() |
||||
stmt.begin = con:prepare("BEGIN") |
||||
end |
||||
|
||||
function prepare_commit() |
||||
stmt.commit = con:prepare("COMMIT") |
||||
end |
||||
|
||||
function prepare_for_each_table(key) |
||||
for t = 1, sysbench.opt.tables do |
||||
stmt[t][key] = con:prepare(string.format(stmt_defs[key][1], t)) |
||||
|
||||
local nparam = #stmt_defs[key] - 1 |
||||
|
||||
if nparam > 0 then |
||||
param[t][key] = {} |
||||
end |
||||
|
||||
for p = 1, nparam do |
||||
local btype = stmt_defs[key][p+1] |
||||
local len |
||||
|
||||
if type(btype) == "table" then |
||||
len = btype[2] |
||||
btype = btype[1] |
||||
end |
||||
if btype == sysbench.sql.type.VARCHAR or |
||||
btype == sysbench.sql.type.CHAR then |
||||
param[t][key][p] = stmt[t][key]:bind_create(btype, len) |
||||
else |
||||
param[t][key][p] = stmt[t][key]:bind_create(btype) |
||||
end |
||||
end |
||||
|
||||
if nparam > 0 then |
||||
stmt[t][key]:bind_param(unpack(param[t][key])) |
||||
end |
||||
end |
||||
end |
||||
|
||||
function prepare_point_selects() |
||||
prepare_for_each_table("point_selects") |
||||
end |
||||
|
||||
function prepare_simple_ranges() |
||||
prepare_for_each_table("simple_ranges") |
||||
end |
||||
|
||||
function prepare_sum_ranges() |
||||
prepare_for_each_table("sum_ranges") |
||||
end |
||||
|
||||
function prepare_order_ranges() |
||||
prepare_for_each_table("order_ranges") |
||||
end |
||||
|
||||
function prepare_distinct_ranges() |
||||
prepare_for_each_table("distinct_ranges") |
||||
end |
||||
|
||||
function prepare_index_updates() |
||||
prepare_for_each_table("index_updates") |
||||
end |
||||
|
||||
function prepare_non_index_updates() |
||||
prepare_for_each_table("non_index_updates") |
||||
end |
||||
|
||||
function prepare_delete_inserts() |
||||
prepare_for_each_table("deletes") |
||||
prepare_for_each_table("inserts") |
||||
end |
||||
|
||||
function thread_init() |
||||
drv = sysbench.sql.driver() |
||||
con = drv:connect() |
||||
|
||||
-- Create global nested tables for prepared statements and their |
||||
-- parameters. We need a statement and a parameter set for each combination |
||||
-- of connection/table/query |
||||
stmt = {} |
||||
param = {} |
||||
|
||||
for t = 1, sysbench.opt.tables do |
||||
stmt[t] = {} |
||||
param[t] = {} |
||||
end |
||||
|
||||
-- This function is a 'callback' defined by individual benchmark scripts |
||||
prepare_statements() |
||||
end |
||||
|
||||
-- Close prepared statements |
||||
function close_statements() |
||||
for t = 1, sysbench.opt.tables do |
||||
for k, s in pairs(stmt[t]) do |
||||
stmt[t][k]:close() |
||||
end |
||||
end |
||||
if (stmt.begin ~= nil) then |
||||
stmt.begin:close() |
||||
end |
||||
if (stmt.commit ~= nil) then |
||||
stmt.commit:close() |
||||
end |
||||
end |
||||
|
||||
function thread_done() |
||||
close_statements() |
||||
con:disconnect() |
||||
end |
||||
|
||||
function cleanup() |
||||
local drv = sysbench.sql.driver() |
||||
local con = drv:connect() |
||||
|
||||
for i = 1, sysbench.opt.tables do |
||||
print(string.format("Dropping table 'sbtest%d'...", i)) |
||||
con:query("DROP TABLE IF EXISTS sbtest" .. i ) |
||||
end |
||||
end |
||||
|
||||
local function get_table_num() |
||||
return sysbench.rand.uniform(1, sysbench.opt.tables) |
||||
end |
||||
|
||||
local function get_id() |
||||
return sysbench.rand.default(1, sysbench.opt.table_size) |
||||
end |
||||
|
||||
function begin() |
||||
stmt.begin:execute() |
||||
end |
||||
|
||||
function commit() |
||||
stmt.commit:execute() |
||||
end |
||||
|
||||
function execute_point_selects() |
||||
local tnum = get_table_num() |
||||
local i |
||||
|
||||
for i = 1, sysbench.opt.point_selects do |
||||
param[tnum].point_selects[1]:set(get_id()) |
||||
|
||||
stmt[tnum].point_selects:execute() |
||||
end |
||||
end |
||||
|
||||
local function execute_range(key) |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt[key] do |
||||
local id = get_id() |
||||
|
||||
param[tnum][key][1]:set(id) |
||||
param[tnum][key][2]:set(id + sysbench.opt.range_size - 1) |
||||
|
||||
stmt[tnum][key]:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_simple_ranges() |
||||
execute_range("simple_ranges") |
||||
end |
||||
|
||||
function execute_sum_ranges() |
||||
execute_range("sum_ranges") |
||||
end |
||||
|
||||
function execute_order_ranges() |
||||
execute_range("order_ranges") |
||||
end |
||||
|
||||
function execute_distinct_ranges() |
||||
execute_range("distinct_ranges") |
||||
end |
||||
|
||||
function execute_index_updates() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.index_updates do |
||||
param[tnum].index_updates[1]:set(get_id()) |
||||
|
||||
stmt[tnum].index_updates:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_non_index_updates() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.non_index_updates do |
||||
param[tnum].non_index_updates[1]:set_rand_str(c_value_template) |
||||
param[tnum].non_index_updates[2]:set(get_id()) |
||||
|
||||
stmt[tnum].non_index_updates:execute() |
||||
end |
||||
end |
||||
|
||||
function execute_delete_inserts() |
||||
local tnum = get_table_num() |
||||
|
||||
for i = 1, sysbench.opt.delete_inserts do |
||||
local id = get_id() |
||||
local k = get_id() |
||||
|
||||
param[tnum].deletes[1]:set(id) |
||||
|
||||
param[tnum].inserts[1]:set(id) |
||||
param[tnum].inserts[2]:set(k) |
||||
param[tnum].inserts[3]:set_rand_str(c_value_template) |
||||
param[tnum].inserts[4]:set_rand_str(pad_value_template) |
||||
|
||||
stmt[tnum].deletes:execute() |
||||
stmt[tnum].inserts:execute() |
||||
end |
||||
end |
||||
|
||||
-- Re-prepare statements if we have reconnected, which is possible when some of |
||||
-- the listed error codes are in the --mysql-ignore-errors list |
||||
function sysbench.hooks.before_restart_event(errdesc) |
||||
if errdesc.sql_errno == 2013 or -- CR_SERVER_LOST |
||||
errdesc.sql_errno == 2055 or -- CR_SERVER_LOST_EXTENDED |
||||
errdesc.sql_errno == 2006 or -- CR_SERVER_GONE_ERROR |
||||
errdesc.sql_errno == 2011 -- CR_TCP_CONNECTION |
||||
then |
||||
close_statements() |
||||
prepare_statements() |
||||
end |
||||
end |
@ -0,0 +1,34 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Delete-Only OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
prepare_for_each_table("deletes") |
||||
end |
||||
|
||||
function event() |
||||
local tnum = sysbench.rand.uniform(1, sysbench.opt.tables) |
||||
local id = sysbench.rand.default(1, sysbench.opt.table_size) |
||||
|
||||
param[tnum].deletes[1]:set(id) |
||||
stmt[tnum].deletes:execute() |
||||
end |
@ -0,0 +1,65 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Insert-Only OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require(".oltp_common") |
||||
|
||||
sysbench.cmdline.commands.prepare = { |
||||
function () |
||||
if (not sysbench.opt.auto_inc) then |
||||
-- Create empty tables on prepare when --auto-inc is off, since IDs |
||||
-- generated on prepare may collide later with values generated by |
||||
-- sysbench.rand.unique() |
||||
sysbench.opt.table_size=0 |
||||
end |
||||
|
||||
cmd_prepare() |
||||
end, |
||||
sysbench.cmdline.PARALLEL_COMMAND |
||||
} |
||||
|
||||
function prepare_statements() |
||||
-- We do not use prepared statements here, but oltp_common.sh expects this |
||||
-- function to be defined |
||||
end |
||||
|
||||
function event() |
||||
local table_name = "sbtest" .. sysbench.rand.uniform(1, sysbench.opt.tables) |
||||
local k_val = sysbench.rand.default(1, sysbench.opt.table_size) |
||||
local c_val = get_c_value() |
||||
local pad_val = get_pad_value() |
||||
|
||||
if (drv:name() == "pgsql" and sysbench.opt.auto_inc) then |
||||
con:query(string.format("INSERT INTO %s (k, c, pad) VALUES " .. |
||||
"(%d, '%s', '%s')", |
||||
table_name, k_val, c_val, pad_val)) |
||||
else |
||||
if (sysbench.opt.auto_inc) then |
||||
i = 0 |
||||
else |
||||
-- Convert a uint32_t value to SQL INT |
||||
i = sysbench.rand.unique() - 2147483648 |
||||
end |
||||
|
||||
con:query(string.format("INSERT INTO %s (id, k, c, pad) VALUES " .. |
||||
"(%d, %d, '%s', '%s')", |
||||
table_name, i, k_val, c_val, pad_val)) |
||||
end |
||||
end |
@ -0,0 +1,34 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- OLTP Point Select benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
-- use 1 query per event, rather than sysbench.opt.point_selects which |
||||
-- defaults to 10 in other OLTP scripts |
||||
sysbench.opt.point_selects=1 |
||||
|
||||
prepare_point_selects() |
||||
end |
||||
|
||||
function event() |
||||
execute_point_selects() |
||||
end |
@ -0,0 +1,57 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Read-Only OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
prepare_point_selects() |
||||
|
||||
if not sysbench.opt.skip_trx then |
||||
prepare_begin() |
||||
prepare_commit() |
||||
end |
||||
|
||||
if sysbench.opt.range_selects then |
||||
prepare_simple_ranges() |
||||
prepare_sum_ranges() |
||||
prepare_order_ranges() |
||||
prepare_distinct_ranges() |
||||
end |
||||
end |
||||
|
||||
function event() |
||||
if not sysbench.opt.skip_trx then |
||||
begin() |
||||
end |
||||
|
||||
execute_point_selects() |
||||
|
||||
if sysbench.opt.range_selects then |
||||
execute_simple_ranges() |
||||
execute_sum_ranges() |
||||
execute_order_ranges() |
||||
execute_distinct_ranges() |
||||
end |
||||
|
||||
if not sysbench.opt.skip_trx then |
||||
commit() |
||||
end |
||||
end |
@ -0,0 +1,65 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Read/Write OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
if not sysbench.opt.skip_trx then |
||||
prepare_begin() |
||||
prepare_commit() |
||||
end |
||||
|
||||
prepare_point_selects() |
||||
|
||||
if sysbench.opt.range_selects then |
||||
prepare_simple_ranges() |
||||
prepare_sum_ranges() |
||||
prepare_order_ranges() |
||||
prepare_distinct_ranges() |
||||
end |
||||
|
||||
prepare_index_updates() |
||||
prepare_non_index_updates() |
||||
prepare_delete_inserts() |
||||
end |
||||
|
||||
function event() |
||||
if not sysbench.opt.skip_trx then |
||||
begin() |
||||
end |
||||
|
||||
execute_point_selects() |
||||
|
||||
if sysbench.opt.range_selects then |
||||
execute_simple_ranges() |
||||
execute_sum_ranges() |
||||
execute_order_ranges() |
||||
execute_distinct_ranges() |
||||
end |
||||
|
||||
execute_index_updates() |
||||
execute_non_index_updates() |
||||
execute_delete_inserts() |
||||
|
||||
if not sysbench.opt.skip_trx then |
||||
commit() |
||||
end |
||||
end |
@ -0,0 +1,30 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Update-Index OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
prepare_index_updates() |
||||
end |
||||
|
||||
function event() |
||||
execute_index_updates(con) |
||||
end |
@ -0,0 +1,30 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Update-Non-Index OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
prepare_non_index_updates() |
||||
end |
||||
|
||||
function event() |
||||
execute_non_index_updates() |
||||
end |
@ -0,0 +1,47 @@ |
||||
#!/usr/bin/sysbench |
||||
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com> |
||||
|
||||
-- This program is free software; you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation; either version 2 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program; if not, write to the Free Software |
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
||||
-- ---------------------------------------------------------------------- |
||||
-- Write-Only OLTP benchmark |
||||
-- ---------------------------------------------------------------------- |
||||
|
||||
require("oltp_common") |
||||
|
||||
function prepare_statements() |
||||
if not sysbench.opt.skip_trx then |
||||
prepare_begin() |
||||
prepare_commit() |
||||
end |
||||
|
||||
prepare_index_updates() |
||||
prepare_non_index_updates() |
||||
prepare_delete_inserts() |
||||
end |
||||
|
||||
function event() |
||||
if not sysbench.opt.skip_trx then |
||||
begin() |
||||
end |
||||
|
||||
execute_index_updates() |
||||
execute_non_index_updates() |
||||
execute_delete_inserts() |
||||
|
||||
if not sysbench.opt.skip_trx then |
||||
commit() |
||||
end |
||||
end |
@ -0,0 +1,72 @@ |
||||
#!/usr/bin/sysbench |
||||
-- This test is designed for testing MariaDB's key_cache_segments for MyISAM, |
||||
-- and should work with other storage engines as well. |
||||
-- |
||||
-- For details about key_cache_segments please refer to: |
||||
-- http://kb.askmonty.org/v/segmented-key-cache |
||||
-- |
||||
|
||||
require("oltp_common") |
||||
|
||||
-- Add random_points to the list of standard OLTP options |
||||
sysbench.cmdline.options.random_points = |
||||
{"Number of random points in the IN() clause in generated SELECTs", 10} |
||||
|
||||
-- Override standard prepare/cleanup OLTP functions, as this benchmark does not |
||||
-- support multiple tables |
||||
oltp_prepare = prepare |
||||
oltp_cleanup = cleanup |
||||
|
||||
function prepare() |
||||
assert(sysbench.opt.tables == 1, "this benchmark does not support " .. |
||||
"--tables > 1") |
||||
oltp_prepare() |
||||
end |
||||
|
||||
function cleanup() |
||||
assert(sysbench.opt.tables == 1, "this benchmark does not support " .. |
||||
"--tables > 1") |
||||
oltp_cleanup() |
||||
end |
||||
|
||||
function thread_init() |
||||
drv = sysbench.sql.driver() |
||||
con = drv:connect() |
||||
|
||||
local points = string.rep("?, ", sysbench.opt.random_points - 1) .. "?" |
||||
|
||||
stmt = con:prepare(string.format([[ |
||||
SELECT id, k, c, pad |
||||
FROM sbtest1 |
||||
WHERE k IN (%s) |
||||
]], points)) |
||||
|
||||
params = {} |
||||
for j = 1, sysbench.opt.random_points do |
||||
params[j] = stmt:bind_create(sysbench.sql.type.INT) |
||||
end |
||||
|
||||
stmt:bind_param(unpack(params)) |
||||
|
||||
rlen = sysbench.opt.table_size / sysbench.opt.threads |
||||
|
||||
thread_id = sysbench.tid % sysbench.opt.threads |
||||
end |
||||
|
||||
function thread_done() |
||||
stmt:close() |
||||
con:disconnect() |
||||
end |
||||
|
||||
function event() |
||||
-- To prevent overlapping of our range queries we need to partition the whole |
||||
-- table into 'threads' segments and then make each thread work with its |
||||
-- own segment. |
||||
for i = 1, sysbench.opt.random_points do |
||||
local rmin = rlen * thread_id |
||||
local rmax = rmin + rlen |
||||
params[i]:set(sb_rand(rmin, rmax)) |
||||
end |
||||
|
||||
stmt:execute() |
||||
end |
@ -0,0 +1,77 @@ |
||||
#!/usr/bin/sysbench |
||||
-- This test is designed for testing MariaDB's key_cache_segments for MyISAM, |
||||
-- and should work with other storage engines as well. |
||||
-- |
||||
-- For details about key_cache_segments please refer to: |
||||
-- http://kb.askmonty.org/v/segmented-key-cache |
||||
-- |
||||
|
||||
require("oltp_common") |
||||
|
||||
-- Add --number-of-ranges and --delta to the list of standard OLTP options |
||||
sysbench.cmdline.options.number_of_ranges = |
||||
{"Number of random BETWEEN ranges per SELECT", 10} |
||||
sysbench.cmdline.options.delta = |
||||
{"Size of BETWEEN ranges", 5} |
||||
|
||||
-- Override standard prepare/cleanup OLTP functions, as this benchmark does not |
||||
-- support multiple tables |
||||
oltp_prepare = prepare |
||||
oltp_cleanup = cleanup |
||||
|
||||
function prepare() |
||||
assert(sysbench.opt.tables == 1, "this benchmark does not support " .. |
||||
"--tables > 1") |
||||
oltp_prepare() |
||||
end |
||||
|
||||
function cleanup() |
||||
assert(sysbench.opt.tables == 1, "this benchmark does not support " .. |
||||
"--tables > 1") |
||||
oltp_cleanup() |
||||
end |
||||
|
||||
function thread_init() |
||||
drv = sysbench.sql.driver() |
||||
con = drv:connect() |
||||
|
||||
local ranges = string.rep("k BETWEEN ? AND ? OR ", |
||||
sysbench.opt.number_of_ranges - 1) .. |
||||
"k BETWEEN ? AND ?" |
||||
|
||||
stmt = con:prepare(string.format([[ |
||||
SELECT count(k) |
||||
FROM sbtest1 |
||||
WHERE %s]], ranges)) |
||||
|
||||
params = {} |
||||
for j = 1, sysbench.opt.number_of_ranges*2 do |
||||
params[j] = stmt:bind_create(sysbench.sql.type.INT) |
||||
end |
||||
|
||||
stmt:bind_param(unpack(params)) |
||||
|
||||
rlen = sysbench.opt.table_size / sysbench.opt.threads |
||||
|
||||
thread_id = sysbench.tid % sysbench.opt.threads |
||||
end |
||||
|
||||
function thread_done() |
||||
stmt:close() |
||||
con:disconnect() |
||||
end |
||||
|
||||
function event() |
||||
-- To prevent overlapping of our range queries we need to partition the whole |
||||
-- table into 'threads' segments and then make each thread work with its |
||||
-- own segment. |
||||
for i = 1, sysbench.opt.number_of_ranges*2, 2 do |
||||
local rmin = rlen * thread_id |
||||
local rmax = rmin + rlen |
||||
local val = sb_rand(rmin, rmax) |
||||
params[i]:set(val) |
||||
params[i+1]:set(val + sysbench.opt.delta) |
||||
end |
||||
|
||||
stmt:execute() |
||||
end |
Loading…
Reference in new issue