MK-LOG-PLAYER(1)
π mk-log-player π
okay bestie, so this is a page from the User Contributed Perl Documentation (that's the (1) bit, it's giving very "one of many, but iconic") and it's all about mk-log-player, which β as the NAME says β is here to replay MySQL query logs. π
β¨ NAME β¨
mk-log-player β replay MySQL query logs. fr fr that's the whole vibe. π¦
πΈ SYNOPSIS πΈ
Usage: mk-log-player [OPTION...] [DSN]
mk-log-player splits and plays slow log files. (yes, both. multitasking queen. π)
Split slow.log on Thread_id into 16 session files, save in ./sessions:
mk-log-player --split Thread_id --session-files 16 --base-dir ./sessions slow.log
Play all those sessions on host1, save results in ./results:
mk-log-player --play ./sessions --base-dir ./results h=host1
Use mk-query-digest to summarize the results:
mk-query-digest ./results/*
π RISKS π
okay so this section exists to tell you the potential risks β whether known or unknown β of using this tool. The two main categories of risk are:
- risks created by the nature of the tool (like, read-only tools vs. read-write tools, you know?), and
- risks created by bugs.
This tool is literally meant to load a server as much as possible, for stress-testing purposes. It is not designed to be used on production servers. not even a little. π
At the time of this release there is a bug which causesmk-log-playerto exceed max open files during--split. π
The authoritative source for updated info is always the online issue tracking system. Issues that affect this tool will be marked as such. You can see a list of such issues at the following URL:
http://www.maatkit.org/bugs/mk-log-player
See also "BUGS" for more on filing bugs and getting help. π«Ά
π¦ DESCRIPTION π¦
mk-log-player does two things, bestie: it splits MySQL query logs into session files, and it plays (executes) queries in session files on a MySQL server. Only session files can be played β slow logs cannot be played directly without being split. periodt.
A session is a group of queries from the slow log that all share a common attribute, usually Thread_id. The common attribute is specified with --split. Multiple sessions are saved into a single session file. See --session-files, --max-sessions, --base-file-name and --base-dir. These session files are played with --play. π
mk-log-player will --play session files in parallel using N number of --threads. (they're not technically threads, but we call them that anyway, iykyk π) Each thread will play all the sessions in its given session files. The sessions are played as fast as possible β there are no delays β because the goal is to stress-test and load-test the server. So be careful using this script on a production server! like genuinely.
Each --play thread writes its results to a separate file. These result files are in slow log format so they can be aggregated and summarized with mk-query-digest. See "OUTPUT". β¨
π OUTPUT π
Both --split and --play have two outputs:
- status messages printed to STDOUT to let you know what the script is doing, and
- session or result files written to separate files saved in
--base-dir.
You can suppress all output to STDOUT for each with --quiet, or increase output with --verbose. π
The session files written by --split are simple text files containing queries grouped into sessions. For example:
-- START SESSION 10
use foo
SELECT col FROM foo_tbl
The format of these session files is important: each query must be a single line separated by a single blank line. And the -- START SESSION comment tells mk-log-player where individual sessions begin and end so that --play can correctly fake Thread_id in its result files. no cap.
The result files written by --play are in slow log format with a minimal header: the only attributes printed are Thread_id, Query_time and Schema. π
π OPTIONS π
Specify at least one of --play, --split or --split-random.
--play and --split are mutually exclusive. (they cannot both be the main character at once, sorry. π)
This tool accepts additional command-line arguments. Refer to the "SYNOPSIS" and usage information for details.
--ask-passβ group: Play. Prompt for a password when connecting to MySQL. π--base-dirβ type: string; default:./. Base directory for--splitsession files and--playresult file.--base-file-nameβ type: string; default:session. Base file name for--splitsession files and--playresult file.
Each --split session file will be saved as <base-file-name>-N.txt, where N is a four digit, zero-padded session ID. For example: session-0003.txt. π
Each --play result file will be saved as <base-file-name>-results-PID.txt, where PID is the process ID of the executing thread.
All files are saved in --base-dir.
--charsetβ short form:-A; type: string; group: Play. Default character set. If the value isutf8, sets Perl'sbinmodeon STDOUT toutf8, passes themysql_enable_utf8option toDBD::mysql, and runsSET NAMES UTF8after connecting to MySQL. Any other value setsbinmodeon STDOUT without the utf8 layer, and runsSET NAMESafter connecting to MySQL. π--configβ type: Array. Read this comma-separated list of config files; if specified, this must be the first option on the command line.--defaults-fileβ short form:-F; type: string. Only read mysql options from the given file.--dry-runβ Print which processes play which session files then exit. π΅οΈ--filterβ type: string; group: Split. Discard--splitevents for which this Perl code doesn't return true.
This option only works with --split.
This option allows you to inject Perl code into the tool to affect how the tool runs. Usually your code should examine $event to decided whether or not to allow the event. $event is a hashref of attributes and values of the event being filtered. Or, your code could add new attribute-value pairs to $event for use by other options that accept event attributes as their value. You can find an explanation of the structure of $event at http://code.google.com/p/maatkit/wiki/EventAttributes. π
There are two ways to supply your code: on the command line or in a file. If you supply your code on the command line, it is injected into the following subroutine where $filter is your code:
sub {
MKDEBUG && _d('callback: filter');
my( $event ) = shift;
( $filter ) && return $event;
}
Therefore you must ensure two things: first, that you correctly escape any special characters that need to be escaped on the command line for your shell, and two, that your code is syntactically valid when injected into the subroutine above. (two things bestie, don't skip one π)
Here's an example filter supplied on the command line that discards events that are not SELECT statements:
--filter '$event->{arg} =~ m/^select/i'
The second way to supply your code is in a file. If your code is too complex to be expressed on the command line that results in valid syntax in the subroutine above, then you need to put the code in a file and give the file name as the value to --filter. The file should not contain a shebang (#!/usr/bin/perl) line. The entire contents of the file is injected into the following subroutine:
sub {
MKDEBUG && _d('callback: filter');
my( $event ) = shift;
$filter && return $event;
}
That subroutine is almost identical to the one above except your code is not wrapped in parentheses. This allows you to write multi-line code like:
my $event_ok;
if (...) {
$event_ok = 1;
}
else {
$event_ok = 0;
}
$event_ok
Notice that the last line is not syntactically valid by itself, but it becomes syntactically valid when injected into the subroutine because it becomes:
$event_ok && return $event;
If your code doesn't compile, the tool will die with an error. Even if your code compiles, it may crash to tool during runtime if, for example, it tries a pattern match an undefined value. No safeguards of any kind of provided so code carefully! π
--helpβ Show help and exit. π«Ά--hostβ short form:-h; type: string; group: Play. Connect to host.--iterationsβ type: int; default:1; group: Play. How many times each thread should play all its session files. π--max-sessionsβ type: int; default:5000000; group: Split. Maximum number of sessions to--split.
By default, mk-log-player tries to split every session from the log file. For huge logs, however, this can result in millions of sessions. This option causes only the first N number of sessions to be saved. All sessions after this number are ignored, but sessions split before this number will continue to have their queries split even if those queries appear near the end of the log and after this number has been reached. β¨
--only-selectβ group: Play. Play onlySELECTandUSEqueries; ignore all others.--passwordβ short form:-p; type: string; group: Play. Password to use when connecting. π--pidβ type: string. Create the given PID file. The file contains the process ID of the script. The PID file is removed when the script exits. Before starting, the script checks if the PID file already exists. If it does not, then the script creates and writes its own PID to it. If it does, then the script checks the following: if the file contains a PID and a process is running with that PID, then the script dies; or, if there is no process running with that PID, then the script overwrites the file with its own PID and starts; else, if the file contains no PID, then the script dies. π--playβ type: string; group: Play. Play (execute) session files created by--split.
The argument to play must be a comma-separated list of session files created by --split or a directory. If the argument is a directory, ALL files in that directory will be played. π
--portβ short form:-P; type: int; group: Play. Port number to use for connection.--printβ group: Play. Print queries instead of playing them; requires--play.
You must also specify --play with --print. Although the queries will not be executed, --play is required to specify which session files to read. π¨οΈ
--quietβ short form:-q. Do not print anything; disables--verbose. π€«--[no]resultsβ default:yes. Print--playresults to files in--base-dir.--session-filesβ type: int; default:8; group: Split. Number of session files to create with--split. π
...and bestie, we're not even done β more of this page is coming, so don't go anywhere π
...so the number of session files should either match the number of --threads you're gonna --play with, or be an even multiple of --threads. Why do we care? Because it's the whole key to max performance, babes, and here's the receipts:
- it lets every thread have roughly the same amount of sessions to play π«Ά
- it avoids having to open/close a million session files
- it avoids disk IO overhead by doing big ol' sequential reads β¨
You might wanna bump this number past --threads if each session file ends up being a chonky girl. Like, splitting a 20G log into 8 session files gives you roughly eight 2G session files. π
See also --max-sessions.
--set-varsβ type: string; group: Play; default:wait_timeout=10000
Sets these MySQL variables. The literal instant you connect to MySQL, this string gets appended to SET and executed. no cap.
--socketβ short form:-S; type: string; group: Play
The socket file to use for the connection. π
--splitβ type: string; group: Split
Split the log by the given attribute to create session files.
Valid attributes are literally anything that shows up in the log: Thread_id, Schema, etc.
--split-randomβ group: Split
Split the log without an attribute, writing queries round-robin into session files.
If you specify this, it overrides --split and makes the log split query-by-query, dropping each query into the next session file in round-robin style. So if you do not care about "sessions" at all and just wanna blast a lot into N many session files and the relation or order of the queries means nothing to you? This is your girl. π
--threadsβ type: int; default:2; group: Play
Number of threads used to play sessions concurrently.
This sets how many parallel processes run. Default is 2. On GNU/Linux machines, the default is however many times 'processor' shows up in /proc/cpuinfo. On Windows, the default is read from the environment. Either way, the default is at least 2, even if there's only a single processor in there.
See also --session-files.
--typeβ type: string; group: Split
The type of log you want to --split (default is slowlog). The permitted types are:
binlogβ Split the output of runningmysqlbinlogagainst a binary log file. Ngl, splitting binary logs does not always work well depending on what's inside them. Be sure to check the session files after splitting to make sure theOUTPUTis proper.
If the binary log contains row-based replication data, you need to run mysqlbinlog with the options --base64-output=decode-rows --verbose, otherwise invalid statements get written into the session files. π
genlogβ Split a general log file.slowlogβ Split a log file in any variation of MySQL slow-log format.
--userβ short form:-u; type: string; group: Play
User for login, if you're not the current user.
--verboseβ short form:-v; cumulative: yes; default:0
Increase verbosity; you can stack it multiple times. π£οΈ
This option is disabled by --quiet.
--versionβ Show version and exit.--wait-between-sessionsβ type: array; default:0; group: Play
Not implemented yet. π
The wait time is given in seconds with microsecond precision, and it can be either a single value or a range. A single value = an exact wait; example: 0.010 = wait 10 milliseconds. A range = a random wait somewhere between the given value times; example: 0.001,1 = random wait from 1 millisecond to 1 second.
--[no]warningsβ default:no; group: Play
Print warnings about SQL errors, like invalid queries, to STDERR. π
π DSN OPTIONS π
These DSN options are used to build a DSN. Each option goes in like "option=value". Heads up bestie: these options are case-sensitive, so P and p are not the same option, okay? There can't be any whitespace before or after the =, and if the value has whitespace in it, it's gotta be quoted. DSN options are comma-separated. See the maatkit manpage for the full details. π
A- dsn:
charset; copy:yes - Default character set.
- dsn:
D- dsn:
database; copy:yes - Default database.
- dsn:
F- dsn:
mysql_read_default_file; copy:yes - Only read default options from the given file.
- dsn:
h- dsn:
host; copy:yes - Connect to host.
- dsn:
p- dsn:
password; copy:yes - Password to use when connecting.
- dsn:
P- dsn:
port; copy:yes - Port number to use for connection.
- dsn:
S- dsn:
mysql_socket; copy:yes - Socket file to use for connection.
- dsn:
u- dsn:
user; copy:yes - User for login if not current user.
- dsn:
β¬οΈ DOWNLOADING β¬οΈ
You can download Maatkit from Google Code at <http://code.google.com/p/maatkit/>, or you can grab any of the tools super easily with a command like this:
wget http://www.maatkit.org/get/toolname
or
wget http://www.maatkit.org/trunk/toolname
Where toolname gets swapped out for the name (or even just a fragment of a name) of any of the Maatkit tools. Once it's downloaded, it's ready to run β no installation needed, periodt. The first URL gets you the latest released version of the tool, and the second one gets the latest trunk code from Subversion. β¨
π± ENVIRONMENT π±
The environment variable MKDEBUG enables verbose debugging output in all of the Maatkit tools:
MKDEBUG=1 mk-....
π₯οΈ SYSTEM REQUIREMENTS π₯οΈ
You need Perl, plus some core packages that honestly oughta already be installed in any reasonably new version of Perl. πͺ
π BUGS π
For a list of known bugs, go look at <http://www.maatkit.org/bugs/mk-log-player>.
Please use Google Code Issues and Groups to report bugs or request support: <http://code.google.com/p/maatkit/>. You can also hop into #maatkit on Freenode to chat Maatkit with us. π«Ά
When you report, please include the complete command-line you used to reproduce the problem, the version of all MySQL servers involved, the complete output of the tool when it's run with --version, and if you can, the debugging output produced by running with the MKDEBUG=1 environment variable. The more deets the better, fr fr. π
π COPYRIGHT, LICENSE AND WARRANTY π
This program is copyright 2008-2011 Percona Inc. Feedback and improvements are welcome. π
THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
That's the all-caps legal bit and it means business β no warranty, bestie.
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, version 2; OR the Perl Artistic License. On UNIX and similar systems, you can issue man perlgpl or man perlartistic to read these licenses.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
π AUTHOR π
Daniel Nichter
π ABOUT MAATKIT π
This tool is part of Maatkit, a toolkit for power users of MySQL. Maatkit was created by Baron Schwartz; Baron and Daniel Nichter are the primary code contributors. Both are employed by Percona. Financial support for Maatkit development is primarily provided by Percona and its clients. π
π·οΈ VERSION π·οΈ
This manual page documents Ver 1.0.9 Distrib 7540 $Revision: 7531 $.
And that's the whole thing, bestie β this page documents Ver 1.0.9 Distrib 7540 (revision 7531), rendered for perl v5.42.0 and dated 2025-07-24. Go forth and split those logs, you absolute icon. π
β¨π¦
π¦ where this page comes from
- fedora 43: maatkit 7540-39.fc43 Β· GPL-2.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms