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