summaryrefslogtreecommitdiffstats
path: root/debian/additions/innotop/innotop.1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:42 +0000
commit15322b5e4bfa3f93637cb32bf9d45e2b4791a6e7 (patch)
treef146159c9472fd011940a5ed051deb835bbabf7c /debian/additions/innotop/innotop.1
parentAdding upstream version 1:10.11.6. (diff)
downloadmariadb-15322b5e4bfa3f93637cb32bf9d45e2b4791a6e7.tar.xz
mariadb-15322b5e4bfa3f93637cb32bf9d45e2b4791a6e7.zip
Adding debian version 1:10.11.6-0+deb12u1.debian/1%10.11.6-0+deb12u1debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/additions/innotop/innotop.1')
-rw-r--r--debian/additions/innotop/innotop.12200
1 files changed, 2200 insertions, 0 deletions
diff --git a/debian/additions/innotop/innotop.1 b/debian/additions/innotop/innotop.1
new file mode 100644
index 00000000..62a9aed6
--- /dev/null
+++ b/debian/additions/innotop/innotop.1
@@ -0,0 +1,2200 @@
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{
+. if \nF \{
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "INNOTOP 1"
+.TH INNOTOP 1 "2017-01-23" "perl v5.20.2" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+innotop \- MySQL and InnoDB transaction/status monitor.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+To monitor servers normally:
+.PP
+.Vb 1
+\& innotop
+.Ve
+.PP
+To monitor InnoDB status information from a file:
+.PP
+.Vb 1
+\& innotop /var/log/mysql/mysqld.err
+.Ve
+.PP
+To run innotop non-interactively in a pipe-and-filter configuration:
+.PP
+.Vb 1
+\& innotop \-\-count 5 \-d 1 \-n
+.Ve
+.PP
+To monitor a database on another system using a particular username and password:
+.PP
+.Vb 1
+\& innotop \-u <username> \-p <password> \-h <hostname>
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+innotop monitors MySQL servers. Each of its modes shows you a different aspect
+of what's happening in the server. For example, there's a mode for monitoring
+replication, one for queries, and one for transactions. innotop refreshes its
+data periodically, so you see an updating view.
+.PP
+innotop has lots of features for power users, but you can start and run it with
+virtually no configuration. If you're just getting started, see
+\&\*(L"QUICK-START\*(R". Press '?' at any time while running innotop for
+context-sensitive help.
+.SH "QUICK-START"
+.IX Header "QUICK-START"
+To start innotop, open a terminal or command prompt. If you have installed
+innotop on your system, you should be able to just type \*(L"innotop\*(R" and press
+Enter; otherwise, you will need to change to innotop's directory and type \*(L"perl
+innotop\*(R".
+.PP
+With no options specified, innotop will attempt to connect to a MySQL server on
+localhost using mariadb_read_default_group=client for other connection
+parameters. If you need to specify a different username and password, use the
+\&\-u and \-p options, respectively. To monitor a MySQL database on another
+host, use the \-h option.
+.PP
+After you've connected, innotop should show you something like the following:
+.PP
+.Vb 1
+\& [RO] Query List (? for help) localhost, 01:11:19, 449.44 QPS, 14/7/163 con/run
+\&
+\& CXN When Load QPS Slow QCacheHit KCacheHit BpsIn BpsOut
+\& localhost Total 0.00 1.07k 697 0.00% 98.17% 476.83k 242.83k
+\&
+\& CXN Cmd ID User Host DB Time Query
+\& localhost Query 766446598 test 10.0.0.1 foo 00:02 INSERT INTO table (
+.Ve
+.PP
+(This sample is truncated at the right so it will fit on a terminal when running
+\&'man innotop')
+.PP
+If your server is busy, you'll see more output. Notice the first line on the
+screen, which tells you that readonly is set to true ([\s-1RO\s0]), what mode you're
+in and what server you're connected to. You can change to other modes with
+keystrokes; press 'T' to switch to a list of InnoDB transactions, for example.
+.PP
+Press the '?' key to see what keys are active in the current mode. You can
+press any of these keys and innotop will either take the requested action or
+prompt you for more input. If your system has Term::ReadLine support, you can
+use \s-1TAB\s0 and other keys to auto-complete and edit input.
+.PP
+To quit innotop, press the 'q' key.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+innotop is mostly configured via its configuration file, but some of the
+configuration options can come from the command line. You can also specify a
+file to monitor for InnoDB status output; see \*(L"\s-1MONITORING A FILE\*(R"\s0 for more
+details.
+.PP
+You can negate some options by prefixing the option name with \-\-no. For
+example, \-\-noinc (or \-\-no\-inc) negates \*(L"\-\-inc\*(R".
+.IP "\-\-color" 4
+.IX Item "--color"
+Enable or disable terminal coloring. Corresponds to the \*(L"color\*(R" config file
+setting.
+.IP "\-\-config" 4
+.IX Item "--config"
+Specifies a configuration file to read. This option is non-sticky, that is to
+say it does not persist to the configuration file itself.
+.IP "\-\-count" 4
+.IX Item "--count"
+Refresh only the specified number of times (ticks) before exiting. Each refresh
+is a pause for \*(L"interval\*(R" seconds, followed by requesting data from MySQL
+connections and printing it to the terminal.
+.IP "\-\-delay" 4
+.IX Item "--delay"
+Specifies the amount of time to pause between ticks (refreshes). Corresponds to
+the configuration option \*(L"interval\*(R".
+.IP "\-\-help" 4
+.IX Item "--help"
+Print a summary of command-line usage and exit.
+.IP "\-\-host" 4
+.IX Item "--host"
+Host to connect to.
+.IP "\-\-inc" 4
+.IX Item "--inc"
+Specifies whether innotop should display absolute numbers or relative numbers
+(offsets from their previous values). Corresponds to the configuration option
+\&\*(L"status_inc\*(R".
+.IP "\-\-mode" 4
+.IX Item "--mode"
+Specifies the mode in which innotop should start. Corresponds to the
+configuration option \*(L"mode\*(R".
+.IP "\-\-nonint" 4
+.IX Item "--nonint"
+Enable non-interactive operation. See \*(L"NON-INTERACTIVE \s-1OPERATION\*(R"\s0 for more.
+.IP "\-\-password" 4
+.IX Item "--password"
+Password to use for connection.
+.IP "\-\-port" 4
+.IX Item "--port"
+Port to use for connection.
+.IP "\-\-skipcentral" 4
+.IX Item "--skipcentral"
+Don't read the central configuration file.
+.IP "\-\-timestamp" 4
+.IX Item "--timestamp"
+In \-n mode, write a timestamp either before every screenful of output, or if
+the option is given twice, at the start of every line. The format is controlled
+by the timeformat config variable.
+.IP "\-\-user" 4
+.IX Item "--user"
+User to use for connection.
+.IP "\-\-version" 4
+.IX Item "--version"
+Output version information and exit.
+.IP "\-\-write" 4
+.IX Item "--write"
+Sets the configuration option \*(L"readonly\*(R" to 0, making innotop write the
+running configuration to ~/.innotop/innotop.conf on exit, if no configuration
+file was loaded at start-up.
+.SH "HOTKEYS"
+.IX Header "HOTKEYS"
+innotop is interactive, and you control it with key-presses.
+.IP "\(bu" 4
+Uppercase keys switch between modes.
+.IP "\(bu" 4
+Lowercase keys initiate some action within the current mode.
+.IP "\(bu" 4
+Other keys do something special like change configuration or show the
+innotop license.
+.PP
+Press '?' at any time to see the currently active keys and what they do.
+.SH "MODES"
+.IX Header "MODES"
+Each of innotop's modes retrieves and displays a particular type of data from
+the servers you're monitoring. You switch between modes with uppercase keys.
+The following is a brief description of each mode, in alphabetical order. To
+switch to the mode, press the key listed in front of its heading in the
+following list:
+.IP "A: Health Dashboard" 4
+.IX Item "A: Health Dashboard"
+This mode displays a single table with one row per monitored server. The
+columns show essential overview information about the server's health, and
+coloration rules show whether replication is running or if there are any very
+long-running queries or excessive replication delay.
+.IP "B: InnoDB Buffers" 4
+.IX Item "B: InnoDB Buffers"
+This mode displays information about the InnoDB buffer pool, page statistics,
+insert buffer, and adaptive hash index. The data comes from \s-1SHOW INNODB STATUS.\s0
+.Sp
+This mode contains the \*(L"buffer_pool\*(R", \*(L"page_statistics\*(R",
+\&\*(L"insert_buffers\*(R", and \*(L"adaptive_hash_index\*(R" tables by default.
+.IP "C: Command Summary" 4
+.IX Item "C: Command Summary"
+This mode is similar to mytop's Command Summary mode. It shows the
+\&\*(L"cmd_summary\*(R" table, which looks something like the following:
+.Sp
+.Vb 8
+\& Command Summary (? for help) localhost, 25+07:16:43, 2.45 QPS, 3 thd, 5.0.40
+\& _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_ Command Summary _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_
+\& Name Value Pct Last Incr Pct
+\& Select_scan 3244858 69.89% 2 100.00%
+\& Select_range 1354177 29.17% 0 0.00%
+\& Select_full_join 39479 0.85% 0 0.00%
+\& Select_full_range_join 4097 0.09% 0 0.00%
+\& Select_range_check 0 0.00% 0 0.00%
+.Ve
+.Sp
+The command summary table is built by extracting variables from
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0. The variables must be numeric and must match the prefix
+given by the \*(L"cmd_filter\*(R" configuration variable. The variables are then
+sorted by value descending and compared to the last variable, as shown above.
+The percentage columns are percentage of the total of all variables in the
+table, so you can see the relative weight of the variables.
+.Sp
+The example shows what you see if the prefix is \*(L"Select_\*(R". The default
+prefix is \*(L"Com_\*(R". You can choose a prefix with the 's' key.
+.Sp
+It's rather like running \s-1SHOW VARIABLES LIKE \s0\*(L"prefix%\*(R" with memory and
+nice formatting.
+.Sp
+Values are aggregated across all servers. The Pct columns are not correctly
+aggregated across multiple servers. This is a known limitation of the grouping
+algorithm that may be fixed in the future.
+.IP "D: InnoDB Deadlocks" 4
+.IX Item "D: InnoDB Deadlocks"
+This mode shows the transactions involved in the last InnoDB deadlock. A second
+table shows the locks each transaction held and waited for. A deadlock is
+caused by a cycle in the waits-for graph, so there should be two locks held and
+one waited for unless the deadlock information is truncated.
+.Sp
+InnoDB puts deadlock information before some other information in the \s-1SHOW
+INNODB STATUS\s0 output. If there are a lot of locks, the deadlock information can
+grow very large, and there is a limit on the size of the \s-1SHOW INNODB
+STATUS\s0 output. A large deadlock can fill the entire output, or even be
+truncated, and prevent you from seeing other information at all. If you are
+running innotop in another mode, for example T mode, and suddenly you don't see
+anything, you might want to check and see if a deadlock has wiped out the data
+you need.
+.Sp
+If it has, you can create a small deadlock to replace the large one. Use the
+\&'w' key to 'wipe' the large deadlock with a small one. This will not work
+unless you have defined a deadlock table for the connection (see \*(L"\s-1SERVER
+CONNECTIONS\*(R"\s0).
+.Sp
+You can also configure innotop to automatically detect when a large deadlock
+needs to be replaced with a small one (see \*(L"auto_wipe_dl\*(R").
+.Sp
+This mode displays the \*(L"deadlock_transactions\*(R" and \*(L"deadlock_locks\*(R" tables
+by default.
+.IP "F: InnoDB Foreign Key Errors" 4
+.IX Item "F: InnoDB Foreign Key Errors"
+This mode shows the last InnoDB foreign key error information, such as the
+table where it happened, when and who and what query caused it, and so on.
+.Sp
+InnoDB has a huge variety of foreign key error messages, and many of them are
+just hard to parse. innotop doesn't always do the best job here, but there's
+so much code devoted to parsing this messy, unparseable output that innotop is
+likely never to be perfect in this regard. If innotop doesn't show you what
+you need to see, just look at the status text directly.
+.Sp
+This mode displays the \*(L"fk_error\*(R" table by default.
+.IP "I: InnoDB I/O Info" 4
+.IX Item "I: InnoDB I/O Info"
+This mode shows InnoDB's I/O statistics, including the I/O threads, pending I/O,
+file I/O miscellaneous, and log statistics. It displays the \*(L"io_threads\*(R",
+\&\*(L"pending_io\*(R", \*(L"file_io_misc\*(R", and \*(L"log_statistics\*(R" tables by default.
+.IP "K: InnoDB Lock Waits" 4
+.IX Item "K: InnoDB Lock Waits"
+This mode shows information from InnoDB plugin's transaction and locking tables.
+You can use it to find when a transaction is waiting for another, and kill the
+blocking transaction. It displays the "innodb_blocked_blocker" table.
+.IP "L: Locks" 4
+.IX Item "L: Locks"
+This mode shows information about current locks. At the moment only InnoDB
+locks are supported, and by default you'll only see locks for which transactions
+are waiting. This information comes from the \s-1TRANSACTIONS\s0 section of the InnoDB
+status text. If you have a very busy server, you may have frequent lock waits;
+it helps to be able to see which tables and indexes are the \*(L"hot spot\*(R" for
+locks. If your server is running pretty well, this mode should show nothing.
+.Sp
+You can configure MySQL and innotop to monitor not only locks for which a
+transaction is waiting, but those currently held, too. You can do this with the
+InnoDB Lock Monitor (<http://dev.mysql.com/doc/en/innodb\-monitor.html>). It's
+not documented in the MySQL manual, but creating the lock monitor with the
+following statement also affects the output of \s-1SHOW INNODB STATUS,\s0 which innotop
+uses:
+.Sp
+.Vb 1
+\& CREATE TABLE innodb_lock_monitor(a int) ENGINE=INNODB;
+.Ve
+.Sp
+This causes InnoDB to print its output to the MySQL file every 16 seconds or so,
+as stated in the manual, but it also makes the normal \s-1SHOW INNODB STATUS\s0 output
+include lock information, which innotop can parse and display (that's the
+undocumented feature).
+.Sp
+This means you can do what may have seemed impossible: to a limited extent
+(InnoDB truncates some information in the output), you can see which transaction
+holds the locks something else is waiting for. You can also enable and disable
+the InnoDB Lock Monitor with the key mappings in this mode.
+.Sp
+This mode displays the \*(L"innodb_locks\*(R" table by default. Here's a sample of
+the screen when one connection is waiting for locks another connection holds:
+.Sp
+.Vb 7
+\& _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_ InnoDB Locks _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_
+\& CXN ID Type Waiting Wait Active Mode DB Table Index
+\& localhost 12 RECORD 1 00:10 00:10 X test t1 PRIMARY
+\& localhost 12 TABLE 0 00:10 00:10 IX test t1
+\& localhost 12 RECORD 1 00:10 00:10 X test t1 PRIMARY
+\& localhost 11 TABLE 0 00:00 00:25 IX test t1
+\& localhost 11 RECORD 0 00:00 00:25 X test t1 PRIMARY
+.Ve
+.Sp
+You can see the first connection, \s-1ID 12,\s0 is waiting for a lock on the \s-1PRIMARY\s0
+key on test.t1, and has been waiting for 10 seconds. The second connection
+isn't waiting, because the Waiting column is 0, but it holds locks on the same
+index. That tells you connection 11 is blocking connection 12.
+.IP "M: Master/Slave Replication Status" 4
+.IX Item "M: Master/Slave Replication Status"
+This mode shows the output of \s-1SHOW SLAVE STATUS\s0 and \s-1SHOW MASTER STATUS\s0 in three
+tables. The first two divide the slave's status into \s-1SQL\s0 and I/O thread status,
+and the last shows master status. Filters are applied to eliminate non-slave
+servers from the slave tables, and non-master servers from the master table.
+.Sp
+This mode displays the \*(L"slave_sql_status\*(R", \*(L"slave_io_status\*(R", and
+\&\*(L"master_status\*(R" tables by default.
+.IP "O: Open Tables" 4
+.IX Item "O: Open Tables"
+This section comes from MySQL's \s-1SHOW OPEN TABLES\s0 command. By default it is
+filtered to show tables which are in use by one or more queries, so you can
+get a quick look at which tables are 'hot'. You can use this to guess which
+tables might be locked implicitly.
+.Sp
+This mode displays the \*(L"open_tables\*(R" mode by default.
+.IP "U: User Statistics" 4
+.IX Item "U: User Statistics"
+This mode displays data that's available in Percona's enhanced version of MySQL
+(also known as Percona Server with XtraDB). Specifically, it makes it easy to
+enable and disable the so-called \*(L"user statistics.\*(R" This feature gathers stats
+on clients, threads, users, tables, and indexes and makes them available as
+\&\s-1INFORMATION_SCHEMA\s0 tables. These are invaluable for understanding what your
+server is doing. They are also available in MariaDB.
+.Sp
+The statistics supported so far are only from the \s-1TABLE_STATISTICS\s0 and
+\&\s-1INDEX_STATISTICS\s0 tables added by Percona. There are three views: one of table stats,
+one of index stats (which can be aggregated with the = key), and one of both.
+.Sp
+The server doesn't gather these stats by default. You have to set the variable
+userstat_running to turn it on. You can do this easily with innotop from U mode,
+with the 's' key.
+.IP "Q: Query List" 4
+.IX Item "Q: Query List"
+This mode displays the output from \s-1SHOW FULL PROCESSLIST,\s0 much like \fBmytop\fR's
+query list mode. This mode does \fBnot\fR show InnoDB-related information. This
+is probably one of the most useful modes for general usage.
+.Sp
+There is an informative header that shows general status information about
+your server. You can toggle it on and off with the 'h' key. By default,
+innotop hides inactive processes and its own process. You can toggle these on
+and off with the 'i' and 'a' keys.
+.Sp
+You can \s-1EXPLAIN\s0 a query from this mode with the 'e' key. This displays the
+query's full text, the results of \s-1EXPLAIN,\s0 and in newer MySQL versions, even
+the optimized query resulting from \s-1EXPLAIN EXTENDED. \s0 innotop also tries to
+rewrite certain queries to make them EXPLAIN-able. For example, \s-1INSERT/SELECT\s0
+statements are rewritable.
+.Sp
+This mode displays the \*(L"q_header\*(R" and \*(L"processlist\*(R" tables by default.
+.IP "R: InnoDB Row Operations and Semaphores" 4
+.IX Item "R: InnoDB Row Operations and Semaphores"
+This mode shows InnoDB row operations, row operation miscellaneous, semaphores,
+and information from the wait array. It displays the \*(L"row_operations\*(R",
+\&\*(L"row_operation_misc\*(R", \*(L"semaphores\*(R", and \*(L"wait_array\*(R" tables by default.
+.IP "S: Variables & Status" 4
+.IX Item "S: Variables & Status"
+This mode calculates statistics, such as queries per second, and prints them out
+in several different styles. You can show absolute values, or incremental values
+between ticks.
+.Sp
+You can switch between the views by pressing a key. The 's' key prints a
+single line each time the screen updates, in the style of \fBvmstat\fR. The 'g'
+key changes the view to a graph of the same numbers, sort of like \fBtload\fR.
+The 'v' key changes the view to a pivoted table of variable names on the left,
+with successive updates scrolling across the screen from left to right. You can
+choose how many updates to put on the screen with the \*(L"num_status_sets\*(R"
+configuration variable.
+.Sp
+Headers may be abbreviated to fit on the screen in interactive operation. You
+choose which variables to display with the 'c' key, which selects from
+predefined sets, or lets you create your own sets. You can edit the current set
+with the 'e' key.
+.Sp
+This mode doesn't really display any tables like other modes. Instead, it uses
+a table definition to extract and format the data, but it then transforms the
+result in special ways before outputting it. It uses the \*(L"var_status\*(R" table
+definition for this.
+.IP "T: InnoDB Transactions" 4
+.IX Item "T: InnoDB Transactions"
+This mode shows transactions from the InnoDB monitor's output, in \fBtop\fR\-like
+format. This mode is the reason I wrote innotop.
+.Sp
+You can kill queries or processes with the 'k' and 'x' keys, and \s-1EXPLAIN\s0 a query
+with the 'e' or 'f' keys. InnoDB doesn't print the full query in transactions,
+so explaining may not work right if the query is truncated.
+.Sp
+The informational header can be toggled on and off with the 'h' key. By
+default, innotop hides inactive transactions and its own transaction. You can
+toggle this on and off with the 'i' and 'a' keys.
+.Sp
+This mode displays the \*(L"t_header\*(R" and \*(L"innodb_transactions\*(R" tables by
+default.
+.SH "INNOTOP STATUS"
+.IX Header "INNOTOP STATUS"
+The first line innotop displays is a \*(L"status bar\*(R" of sorts. What it contains
+depends on the mode you're in, and what servers you're monitoring. The first
+few words are always [\s-1RO\s0] (if readonly is set to 1), the innotop mode, such as
+\&\*(L"InnoDB Txns\*(R" for T mode, followed by a reminder to press '?' for help at any
+time.
+.SS "\s-1ONE SERVER\s0"
+.IX Subsection "ONE SERVER"
+The simplest case is when you're monitoring a single server. In this case, the
+name of the connection is next on the status line. This is the name you gave
+when you created the connection \*(-- most likely the MySQL server's hostname.
+This is followed by the server's uptime.
+.PP
+If you're in an InnoDB mode, such as T or B, the next word is \*(L"InnoDB\*(R" followed
+by some information about the \s-1SHOW INNODB STATUS\s0 output used to render the
+screen. The first word is the number of seconds since the last \s-1SHOW INNODB
+STATUS,\s0 which InnoDB uses to calculate some per-second statistics. The next is
+a smiley face indicating whether the InnoDB output is truncated. If the smiley
+face is a :\-), all is well; there is no truncation. A :^| means the transaction
+list is so long, InnoDB has only printed out some of the transactions. Finally,
+a frown :\-( means the output is incomplete, which is probably due to a deadlock
+printing too much lock information (see \*(L"D: InnoDB Deadlocks\*(R").
+.PP
+The next two words indicate the server's queries per second (\s-1QPS\s0) and how many
+threads (connections) exist. Finally, the server's version number is the last
+thing on the line.
+.SS "\s-1MULTIPLE SERVERS\s0"
+.IX Subsection "MULTIPLE SERVERS"
+If you are monitoring multiple servers (see \*(L"\s-1SERVER CONNECTIONS\*(R"\s0), the status
+line does not show any details about individual servers. Instead, it shows the
+names of the connections that are active. Again, these are connection names you
+specified, which are likely to be the server's hostname. A connection that has
+an error is prefixed with an exclamation point.
+.PP
+If you are monitoring a group of servers (see \*(L"\s-1SERVER GROUPS\*(R"\s0), the status
+line shows the name of the group. If any connection in the group has an
+error, the group's name is followed by the fraction of the connections that
+don't have errors.
+.PP
+See \*(L"\s-1ERROR HANDLING\*(R"\s0 for more details about innotop's error handling.
+.SS "\s-1MONITORING A FILE\s0"
+.IX Subsection "MONITORING A FILE"
+If you give a filename on the command line, innotop will not connect to \s-1ANY\s0
+servers at all. It will watch the specified file for InnoDB status output and
+use that as its data source. It will always show a single connection called
+\&'file'. And since it can't connect to a server, it can't determine how long the
+server it's monitoring has been up; so it calculates the server's uptime as time
+since innotop started running.
+.SH "SERVER ADMINISTRATION"
+.IX Header "SERVER ADMINISTRATION"
+While innotop is primarily a monitor that lets you watch and analyze your
+servers, it can also send commands to servers. The most frequently useful
+commands are killing queries and stopping or starting slaves.
+.PP
+You can kill a connection, or in newer versions of MySQL kill a query but not a
+connection, from \*(L"Q: Query List\*(R" and \*(L"T: InnoDB Transactions\*(R" modes.
+Press 'k' to issue a \s-1KILL\s0 command, or 'x' to issue a \s-1KILL QUERY\s0 command.
+innotop will prompt you for the server and/or connection \s-1ID\s0 to kill (innotop
+does not prompt you if there is only one possible choice for any input).
+innotop pre-selects the longest-running query, or the oldest connection.
+Confirm the command with 'y'.
+.PP
+In \*(L"Slave Replication Status\*(R"\*(L" in \*(R"M: Master mode, you can start and stop slaves
+with the 'a' and 'o' keys, respectively. You can send these commands to many
+slaves at once. innotop fills in a default command of \s-1START SLAVE\s0 or \s-1STOP SLAVE\s0
+for you, but you can actually edit the command and send anything you wish, such
+as \s-1SET GLOBAL\s0 SQL_SLAVE_SKIP_COUNTER=1 to make the slave skip one binlog event
+when it starts.
+.PP
+You can also ask innotop to calculate the earliest binlog in use by any slave
+and issue a \s-1PURGE MASTER LOGS\s0 on the master. Use the 'b' key for this. innotop
+will prompt you for a master to run the command on, then prompt you for the
+connection names of that master's slaves (there is no way for innotop to
+determine this reliably itself). innotop will find the minimum binlog in use by
+these slave connections and suggest it as the argument to \s-1PURGE MASTER LOGS.\s0
+.PP
+in \*(L"U: User Statistics\*(R" mode, you can use the 's' key to start and stop
+the collection of the statistics data for \s-1TABLE_STATISTICS\s0 and similar.
+.SH "SERVER CONNECTIONS"
+.IX Header "SERVER CONNECTIONS"
+When you create a server connection using '@', innotop asks you for a series of
+inputs, as follows:
+.IP "\s-1DSN\s0" 4
+.IX Item "DSN"
+A \s-1DSN\s0 is a Data Source Name, which is the initial argument passed to the \s-1DBI\s0
+module for connecting to a server. It is usually of the form
+.Sp
+.Vb 1
+\& DBI:MariaDB:;mariadb_read_default_group=mysql;host=HOSTNAME
+.Ve
+.Sp
+Since this \s-1DSN\s0 is passed to the DBD::MariaDB driver, you should read the driver's
+documentation at <https://metacpan.org/pod/DBD::MariaDB> for
+the exact details on all the options you can pass the driver in the \s-1DSN. \s0 You
+can read more about \s-1DBI\s0 at <http://dbi.perl.org/docs/>, and especially at
+<http://search.cpan.org/~timb/DBI/DBI.pm>.
+.Sp
+The mariadb_read_default_group=mysql option lets the \s-1DBD\s0 driver read your MySQL
+options files, such as ~/.my.cnf on UNIX-ish systems. You can use this to avoid
+specifying a username or password for the connection.
+.IP "InnoDB Deadlock Table" 4
+.IX Item "InnoDB Deadlock Table"
+This optional item tells innotop a table name it can use to deliberately create
+a small deadlock (see \*(L"D: InnoDB Deadlocks\*(R"). If you specify this option,
+you just need to be sure the table doesn't exist, and that innotop can create
+and drop the table with the InnoDB storage engine. You can safely omit or just
+accept the default if you don't intend to use this.
+.IP "Username" 4
+.IX Item "Username"
+innotop will ask you if you want to specify a username. If you say 'y', it will
+then prompt you for a user name. If you have a MySQL option file that specifies
+your username, you don't have to specify a username.
+.Sp
+The username defaults to your login name on the system you're running innotop on.
+.IP "Password" 4
+.IX Item "Password"
+innotop will ask you if you want to specify a password. Like the username, the
+password is optional, but there's an additional prompt that asks if you want to
+save the password in the innotop configuration file. If you don't save it in
+the configuration file, innotop will prompt you for a password each time it
+starts. Passwords in the innotop configuration file are saved in plain text,
+not encrypted in any way.
+.PP
+Once you finish answering these questions, you should be connected to a server.
+But innotop isn't limited to monitoring a single server; you can define many
+server connections and switch between them by pressing the '@' key. See
+\&\*(L"\s-1SWITCHING BETWEEN CONNECTIONS\*(R"\s0.
+.SH "SERVER GROUPS"
+.IX Header "SERVER GROUPS"
+If you have multiple MySQL instances, you can put them into named groups, such
+as 'all', 'masters', and 'slaves', which innotop can monitor all together.
+.PP
+You can choose which group to monitor with the '#' key, and you can press the
+\&\s-1TAB\s0 key to switch to the next group. If you're not currently monitoring a
+group, pressing \s-1TAB\s0 selects the first group.
+.PP
+To create a group, press the '#' key and type the name of your new group, then
+type the names of the connections you want the group to contain.
+.SH "SWITCHING BETWEEN CONNECTIONS"
+.IX Header "SWITCHING BETWEEN CONNECTIONS"
+innotop lets you quickly switch which servers you're monitoring. The most basic
+way is by pressing the '@' key and typing the name(s) of the connection(s) you
+want to use. This setting is per-mode, so you can monitor different connections
+in each mode, and innotop remembers which connections you choose.
+.PP
+You can quickly switch to the 'next' connection in alphabetical order with the
+\&'n' key. If you're monitoring a server group (see \*(L"\s-1SERVER GROUPS\*(R"\s0) this will
+switch to the first connection.
+.PP
+You can also type many connection names, and innotop will fetch and display data
+from them all. Just separate the connection names with spaces, for example
+\&\*(L"server1 server2.\*(R" Again, if you type the name of a connection that doesn't
+exist, innotop will prompt you for connection information and create the
+connection.
+.PP
+Another way to monitor multiple connections at once is with server groups. You
+can use the \s-1TAB\s0 key to switch to the 'next' group in alphabetical order, or if
+you're not monitoring any groups, \s-1TAB\s0 will switch to the first group.
+.PP
+innotop does not fetch data in parallel from connections, so if you are
+monitoring a large group or many connections, you may notice increased delay
+between ticks.
+.PP
+When you monitor more than one connection, innotop's status bar changes. See
+\&\*(L"\s-1INNOTOP STATUS\*(R"\s0.
+.SH "ERROR HANDLING"
+.IX Header "ERROR HANDLING"
+Error handling is not that important when monitoring a single connection, but is
+crucial when you have many active connections. A crashed server or lost
+connection should not crash innotop. As a result, innotop will continue to run
+even when there is an error; it just won't display any information from the
+connection that had an error. Because of this, innotop's behavior might confuse
+you. It's a feature, not a bug!
+.PP
+innotop does not continue to query connections that have errors, because they
+may slow innotop and make it hard to use, especially if the error is a problem
+connecting and causes a long time-out. Instead, innotop retries the connection
+occasionally to see if the error still exists. If so, it will wait until some
+point in the future. The wait time increases in ticks as the Fibonacci series,
+so it tries less frequently as time passes.
+.PP
+Since errors might only happen in certain modes because of the \s-1SQL\s0 commands
+issued in those modes, innotop keeps track of which mode caused the error. If
+you switch to a different mode, innotop will retry the connection instead of
+waiting.
+.PP
+By default innotop will display the problem in red text at the bottom of the
+first table on the screen. You can disable this behavior with the
+\&\*(L"show_cxn_errors_in_tbl\*(R" configuration option, which is enabled by default.
+If the \*(L"debug\*(R" option is enabled, innotop will display the error at the
+bottom of every table, not just the first. And if \*(L"show_cxn_errors\*(R" is
+enabled, innotop will print the error text to \s-1STDOUT\s0 as well. Error messages
+might only display in the mode that caused the error, depending on the mode and
+whether innotop is avoiding querying that connection.
+.SH "NON-INTERACTIVE OPERATION"
+.IX Header "NON-INTERACTIVE OPERATION"
+You can run innotop in non-interactive mode, in which case it is entirely
+controlled from the configuration file and command-line options. To start
+innotop in non-interactive mode, give the L\*(L"<\-\-nonint\*(R"> command-line option.
+This changes innotop's behavior in the following ways:
+.IP "\(bu" 4
+Certain Perl modules are not loaded. Term::Readline is not loaded, since
+innotop doesn't prompt interactively. Term::ANSIColor and Win32::Console::ANSI
+modules are not loaded. Term::ReadKey is still used, since innotop may have to
+prompt for connection passwords when starting up.
+.IP "\(bu" 4
+innotop does not clear the screen after each tick.
+.IP "\(bu" 4
+innotop does not persist any changes to the configuration file.
+.IP "\(bu" 4
+If \*(L"\-\-count\*(R" is given and innotop is in incremental mode (see \*(L"status_inc\*(R"
+and \*(L"\-\-inc\*(R"), innotop actually refreshes one more time than specified so it
+can print incremental statistics. This suppresses output during the first
+tick, so innotop may appear to hang.
+.IP "\(bu" 4
+innotop only displays the first table in each mode. This is so the output can
+be easily processed with other command-line utilities such as awk and sed. To
+change which tables display in each mode, see \*(L"\s-1TABLES\*(R"\s0. Since \*(L"Q: Query
+List\*(R" mode is so important, innotop automatically disables the \*(L"q_header\*(R"
+table. This ensures you'll see the \*(L"processlist\*(R" table, even if you have
+innotop configured to show the q_header table during interactive operation.
+Similarly, in \*(L"T: InnoDB Transactions\*(R" mode, the \*(L"t_header\*(R" table is
+suppressed so you see only the \*(L"innodb_transactions\*(R" table.
+.IP "\(bu" 4
+All output is tab-separated instead of being column-aligned with whitespace, and
+innotop prints the full contents of each table instead of only printing one
+screenful at a time.
+.IP "\(bu" 4
+innotop only prints column headers once instead of every tick (see
+\&\*(L"hide_hdr\*(R"). innotop does not print table captions (see
+\&\*(L"display_table_captions\*(R"). innotop ensures there are no empty lines in the
+output.
+.IP "\(bu" 4
+innotop does not honor the \*(L"shorten\*(R" transformation, which normally shortens
+some numbers to human-readable formats.
+.IP "\(bu" 4
+innotop does not print a status line (see \*(L"\s-1INNOTOP STATUS\*(R"\s0).
+.SH "CONFIGURING"
+.IX Header "CONFIGURING"
+Nearly everything about innotop is configurable. Most things are possible to
+change with built-in commands, but you can also edit the configuration file.
+.PP
+While running innotop, press the '$' key to bring up the configuration editing
+dialog. Press another key to select the type of data you want to edit:
+.IP "S: Statement Sleep Times" 4
+.IX Item "S: Statement Sleep Times"
+Edits \s-1SQL\s0 statement sleep delays, which make innotop pause for the specified
+amount of time after executing a statement. See \*(L"\s-1SQL STATEMENTS\*(R"\s0 for a
+definition of each statement and what it does. By default innotop does not
+delay after any statements.
+.Sp
+This feature is included so you can customize the side-effects caused by
+monitoring your server. You may not see any effects, but some innotop users
+have noticed that certain MySQL versions under very high load with InnoDB
+enabled take longer than usual to execute \s-1SHOW GLOBAL STATUS. \s0 If innotop calls
+\&\s-1SHOW FULL PROCESSLIST\s0 immediately afterward, the processlist contains more
+queries than the machine actually averages at any given moment. Configuring
+innotop to pause briefly after calling \s-1SHOW GLOBAL STATUS\s0 alleviates this
+effect.
+.Sp
+Sleep times are stored in the \*(L"stmt_sleep_times\*(R" section of the configuration
+file. Fractional-second sleeps are supported, subject to your hardware's
+limitations.
+.IP "c: Edit Columns" 4
+.IX Item "c: Edit Columns"
+Starts the table editor on one of the displayed tables. See \*(L"\s-1TABLE EDITOR\*(R"\s0.
+An alternative way to start the table editor without entering the configuration
+dialog is with the '^' key.
+.IP "g: General Configuration" 4
+.IX Item "g: General Configuration"
+Starts the configuration editor to edit global and mode-specific configuration
+variables (see \*(L"\s-1MODES\*(R"\s0). innotop prompts you to choose a variable from among
+the global and mode-specific ones depending on the current mode.
+.IP "k: Row-Coloring Rules" 4
+.IX Item "k: Row-Coloring Rules"
+Starts the row-coloring rules editor on one of the displayed table(s). See
+\&\*(L"\s-1COLORS\*(R"\s0 for details.
+.IP "p: Manage Plugins" 4
+.IX Item "p: Manage Plugins"
+Starts the plugin configuration editor. See \*(L"\s-1PLUGINS\*(R"\s0 for details.
+.IP "s: Server Groups" 4
+.IX Item "s: Server Groups"
+Lets you create and edit server groups. See \*(L"\s-1SERVER GROUPS\*(R"\s0.
+.IP "t: Choose Displayed Tables" 4
+.IX Item "t: Choose Displayed Tables"
+Lets you choose which tables to display in this mode. See \*(L"\s-1MODES\*(R"\s0 and
+\&\*(L"\s-1TABLES\*(R"\s0.
+.SH "CONFIGURATION FILE"
+.IX Header "CONFIGURATION FILE"
+innotop's default configuration file locations are \f(CW$HOME\fR/.innotop and
+/etc/innotop/innotop.conf, and they are looked for in that order. If the first
+configuration file exists, the second will not be processed. Those can be
+overridden with the \*(L"\-\-config\*(R" command-line option. You can edit it by hand
+safely, however innotop reads the configuration file when it starts, and, if
+readonly is set to 0, writes it out again when it exits. Thus, if readonly is
+set to 0, any changes you make by hand while innotop is running will be lost.
+.PP
+innotop doesn't store its entire configuration in the configuration file. It
+has a huge set of default configuration values that it holds only in memory,
+and the configuration file only overrides these defaults. When you customize a
+default setting, innotop notices, and then stores the customizations into the
+file. This keeps the file size down, makes it easier to edit, and makes
+upgrades easier.
+.PP
+A configuration file is read-only be default. You can override that with
+\&\*(L"\-\-write\*(R". See \*(L"readonly\*(R".
+.PP
+The configuration file is arranged into sections like an \s-1INI\s0 file. Each
+section begins with [section\-name] and ends with [/section\-name]. Each
+section's entries have a different syntax depending on the data they need to
+store. You can put comments in the file; any line that begins with a #
+character is a comment. innotop will not read the comments, so it won't write
+them back out to the file when it exits. Comments in read-only configuration
+files are still useful, though.
+.PP
+The first line in the file is innotop's version number. This lets innotop
+notice when the file format is not backwards-compatible, and upgrade smoothly
+without destroying your customized configuration.
+.PP
+The following list describes each section of the configuration file and the data
+it contains:
+.IP "general" 4
+.IX Item "general"
+The 'general' section contains global configuration variables and variables that
+may be mode-specific, but don't belong in any other section. The syntax is a
+simple key=value list. innotop writes a comment above each value to help you
+edit the file by hand.
+.RS 4
+.IP "S_func" 4
+.IX Item "S_func"
+Controls S mode presentation (see \*(L"S: Variables & Status\*(R"). If g, values are
+graphed; if s, values are like vmstat; if p, values are in a pivoted table.
+.IP "S_set" 4
+.IX Item "S_set"
+Specifies which set of variables to display in \*(L"S: Variables & Status\*(R" mode.
+See \*(L"\s-1VARIABLE SETS\*(R"\s0.
+.IP "auto_wipe_dl" 4
+.IX Item "auto_wipe_dl"
+Instructs innotop to automatically wipe large deadlocks when it notices them.
+When this happens you may notice a slight delay. At the next tick, you will
+usually see the information that was being truncated by the large deadlock.
+.IP "charset" 4
+.IX Item "charset"
+Specifies what kind of characters to allow through the \*(L"no_ctrl_char\*(R"
+transformation. This keeps non-printable characters from confusing a
+terminal when you monitor queries that contain binary data, such as images.
+.Sp
+The default is 'ascii', which considers anything outside normal \s-1ASCII\s0 to be a
+control character. The other allowable values are 'unicode' and 'none'. 'none'
+considers every character a control character, which can be useful for
+collapsing \s-1ALL\s0 text fields in queries.
+.IP "cmd_filter" 4
+.IX Item "cmd_filter"
+This is the prefix that filters variables in \*(L"C: Command Summary\*(R" mode.
+.IP "color" 4
+.IX Item "color"
+Whether terminal coloring is permitted.
+.IP "cxn_timeout" 4
+.IX Item "cxn_timeout"
+On MySQL versions 4.0.3 and newer, this variable is used to set the connection's
+timeout, so MySQL doesn't close the connection if it is not used for a while.
+This might happen because a connection isn't monitored in a particular mode, for
+example.
+.IP "debug" 4
+.IX Item "debug"
+This option enables more verbose errors and makes innotop more strict in some
+places. It can help in debugging filters and other user-defined code. It also
+makes innotop write a lot of information to \*(L"debugfile\*(R" when there is a
+crash.
+.IP "debugfile" 4
+.IX Item "debugfile"
+A file to which innotop will write information when there is a crash. See
+\&\*(L"\s-1FILES\*(R"\s0.
+.IP "display_table_captions" 4
+.IX Item "display_table_captions"
+innotop displays a table caption above most tables. This variable suppresses or
+shows captions on all tables globally. Some tables are configured with the
+hide_caption property, which overrides this.
+.IP "global" 4
+.IX Item "global"
+Whether to show \s-1GLOBAL\s0 variables and status. innotop only tries to do this on
+servers which support the \s-1GLOBAL\s0 option to \s-1SHOW VARIABLES\s0 and \s-1SHOW STATUS. \s0 In
+some MySQL versions, you need certain privileges to do this; if you don't have
+them, innotop will not be able to fetch any variable and status data. This
+configuration variable lets you run innotop and fetch what data you can even
+without the elevated privileges.
+.Sp
+I can no longer find or reproduce the situation where \s-1GLOBAL\s0 wasn't allowed, but
+I know there was one.
+.IP "graph_char" 4
+.IX Item "graph_char"
+Defines the character to use when drawing graphs in \*(L"S: Variables & Status\*(R"
+mode.
+.IP "header_highlight" 4
+.IX Item "header_highlight"
+Defines how to highlight column headers. This only works if Term::ANSIColor is
+available. Valid values are 'bold' and 'underline'.
+.IP "hide_hdr" 4
+.IX Item "hide_hdr"
+Hides column headers globally.
+.IP "interval" 4
+.IX Item "interval"
+The interval at which innotop will refresh its data (ticks). The interval is
+implemented as a sleep time between ticks, so the true interval will vary
+depending on how long it takes innotop to fetch and render data.
+.Sp
+This variable accepts fractions of a second.
+.IP "mode" 4
+.IX Item "mode"
+The mode in which innotop should start. Allowable arguments are the same as the
+key presses that select a mode interactively. See \*(L"\s-1MODES\*(R"\s0.
+.IP "num_digits" 4
+.IX Item "num_digits"
+How many digits to show in fractional numbers and percents. This variable's
+range is between 0 and 9 and can be set directly from \*(L"S: Variables & Status\*(R"
+mode with the '+' and '\-' keys. It is used in the \*(L"set_precision\*(R",
+\&\*(L"shorten\*(R", and \*(L"percent\*(R" transformations.
+.IP "num_status_sets" 4
+.IX Item "num_status_sets"
+Controls how many sets of status variables to display in pivoted \*(L"S: Variables
+& Status\*(R" mode. It also controls the number of old sets of variables innotop
+keeps in its memory, so the larger this variable is, the more memory innotop
+uses.
+.IP "plugin_dir" 4
+.IX Item "plugin_dir"
+Specifies where plugins can be found. By default, innotop stores plugins in the
+\&'plugins' subdirectory of your innotop configuration directory.
+.IP "readonly" 4
+.IX Item "readonly"
+Whether the configuration file is readonly. This cannot be set interactively.
+.IP "show_cxn_errors" 4
+.IX Item "show_cxn_errors"
+Makes innotop print connection errors to \s-1STDOUT. \s0 See \*(L"\s-1ERROR HANDLING\*(R"\s0.
+.IP "show_cxn_errors_in_tbl" 4
+.IX Item "show_cxn_errors_in_tbl"
+Makes innotop display connection errors as rows in the first table on screen.
+See \*(L"\s-1ERROR HANDLING\*(R"\s0.
+.IP "show_percent" 4
+.IX Item "show_percent"
+Adds a '%' character after the value returned by the \*(L"percent\*(R"
+transformation.
+.IP "show_statusbar" 4
+.IX Item "show_statusbar"
+Controls whether to show the status bar in the display. See \*(L"\s-1INNOTOP
+STATUS\*(R"\s0.
+.IP "skip_innodb" 4
+.IX Item "skip_innodb"
+Disables fetching \s-1SHOW INNODB STATUS,\s0 in case your server(s) do not have InnoDB
+enabled and you don't want innotop to try to fetch it. This can also be useful
+when you don't have the \s-1SUPER\s0 privilege, required to run \s-1SHOW INNODB STATUS.\s0
+.IP "spark" 4
+.IX Item "spark"
+Specifies how wide a spark chart is. There are two \s-1ASCII\s0 spark charts in A
+mode, showing \s-1QPS\s0 and User_threads_running.
+.IP "status_inc" 4
+.IX Item "status_inc"
+Whether to show absolute or incremental values for status variables.
+Incremental values are calculated as an offset from the last value innotop saw
+for that variable. This is a global setting, but will probably become
+mode-specific at some point. Right now it is honored a bit inconsistently; some
+modes don't pay attention to it.
+.IP "timeformat" 4
+.IX Item "timeformat"
+The C\-style \fIstrftime()\fR\-compatible format for the timestamp line to be printed
+in \-n mode when \-t is set.
+.RE
+.RS 4
+.RE
+.IP "plugins" 4
+.IX Item "plugins"
+This section holds a list of package names of active plugins. If the plugin
+exists, innotop will activate it. See \*(L"\s-1PLUGINS\*(R"\s0 for more information.
+.IP "filters" 4
+.IX Item "filters"
+This section holds user-defined filters (see \*(L"\s-1FILTERS\*(R"\s0). Each line is in the
+format filter_name=text='filter text' tbls='table list'.
+.Sp
+The filter text is the text of the subroutine's code. The table list is a list
+of tables to which the filter can apply. By default, user-defined filters apply
+to the table for which they were created, but you can manually override that by
+editing the definition in the configuration file.
+.IP "active_filters" 4
+.IX Item "active_filters"
+This section stores which filters are active on each table. Each line is in the
+format table_name=filter_list.
+.IP "tbl_meta" 4
+.IX Item "tbl_meta"
+This section stores user-defined or user-customized columns (see \*(L"\s-1COLUMNS\*(R"\s0).
+Each line is in the format col_name=properties, where the properties are a
+name=quoted\-value list.
+.IP "connections" 4
+.IX Item "connections"
+This section holds the server connections you have defined. Each line is in
+the format name=properties, where the properties are a name=value list. The
+properties are self-explanatory, and the only one that is treated specially is
+\&'pass' which is only present if 'savepass' is set. This section of the
+configuration file will be skipped if any \s-1DSN,\s0 username, or password
+command-line options are used. See \*(L"\s-1SERVER CONNECTIONS\*(R"\s0.
+.IP "active_connections" 4
+.IX Item "active_connections"
+This section holds a list of which connections are active in each mode. Each
+line is in the format mode_name=connection_list.
+.IP "server_groups" 4
+.IX Item "server_groups"
+This section holds server groups. Each line is in the format
+name=connection_list. See \*(L"\s-1SERVER GROUPS\*(R"\s0.
+.IP "active_server_groups" 4
+.IX Item "active_server_groups"
+This section holds a list of which server group is active in each mode. Each
+line is in the format mode_name=server_group.
+.IP "max_values_seen" 4
+.IX Item "max_values_seen"
+This section holds the maximum values seen for variables. This is used to scale
+the graphs in \*(L"S: Variables & Status\*(R" mode. Each line is in the format
+name=value.
+.IP "active_columns" 4
+.IX Item "active_columns"
+This section holds table column lists. Each line is in the format
+tbl_name=column_list. See \*(L"\s-1COLUMNS\*(R"\s0.
+.IP "sort_cols" 4
+.IX Item "sort_cols"
+This section holds the sort definition. Each line is in the format
+tbl_name=column_list. If a column is prefixed with '\-', that column sorts
+descending. See \*(L"\s-1SORTING\*(R"\s0.
+.IP "visible_tables" 4
+.IX Item "visible_tables"
+This section defines which tables are visible in each mode. Each line is in the
+format mode_name=table_list. See \*(L"\s-1TABLES\*(R"\s0.
+.IP "varsets" 4
+.IX Item "varsets"
+This section defines variable sets for use in \*(L"S: Status & Variables\*(R" mode.
+Each line is in the format name=variable_list. See \*(L"\s-1VARIABLE SETS\*(R"\s0.
+.IP "colors" 4
+.IX Item "colors"
+This section defines colorization rules. Each line is in the format
+tbl_name=property_list. See \*(L"\s-1COLORS\*(R"\s0.
+.IP "stmt_sleep_times" 4
+.IX Item "stmt_sleep_times"
+This section contains statement sleep times. Each line is in the format
+statement_name=sleep_time. See \*(L"S: Statement Sleep Times\*(R".
+.IP "group_by" 4
+.IX Item "group_by"
+This section contains column lists for table group_by expressions. Each line is
+in the format tbl_name=column_list. See \*(L"\s-1GROUPING\*(R"\s0.
+.SH "CUSTOMIZING"
+.IX Header "CUSTOMIZING"
+You can customize innotop a great deal. For example, you can:
+.IP "\(bu" 4
+Choose which tables to display, and in what order.
+.IP "\(bu" 4
+Choose which columns are in those tables, and create new columns.
+.IP "\(bu" 4
+Filter which rows display with built-in filters, user-defined filters, and
+quick-filters.
+.IP "\(bu" 4
+Sort the rows to put important data first or group together related rows.
+.IP "\(bu" 4
+Highlight rows with color.
+.IP "\(bu" 4
+Customize the alignment, width, and formatting of columns, and apply
+transformations to columns to extract parts of their values or format the values
+as you wish (for example, shortening large numbers to familiar units).
+.IP "\(bu" 4
+Design your own expressions to extract and combine data as you need. This gives
+you unlimited flexibility.
+.PP
+All these and more are explained in the following sections.
+.SS "\s-1TABLES\s0"
+.IX Subsection "TABLES"
+A table is what you'd expect: a collection of columns. It also has some other
+properties, such as a caption. Filters, sorting rules, and colorization rules
+belong to tables and are covered in later sections.
+.PP
+Internally, table meta-data is defined in a data structure called \f(CW%tbl_meta\fR.
+This hash holds all built-in table definitions, which contain a lot of default
+instructions to innotop. The meta-data includes the caption, a list of columns
+the user has customized, a list of columns, a list of visible columns, a list of
+filters, color rules, a sort-column list, sort direction, and some information
+about the table's data sources. Most of this is customizable via the table
+editor (see \*(L"\s-1TABLE EDITOR\*(R"\s0).
+.PP
+You can choose which tables to show by pressing the '$' key. See \*(L"\s-1MODES\*(R"\s0 and
+\&\*(L"\s-1TABLES\*(R"\s0.
+.PP
+The table life-cycle is as follows:
+.IP "\(bu" 4
+Each table begins with a data source, which is an array of hashes. See below
+for details on data sources.
+.IP "\(bu" 4
+Each element of the data source becomes a row in the final table.
+.IP "\(bu" 4
+For each element in the data source, innotop extracts values from the source and
+creates a row. This row is another hash, which later steps will refer to as
+\&\f(CW$set\fR. The values innotop extracts are determined by the table's columns. Each
+column has an extraction subroutine, compiled from an expression (see
+\&\*(L"\s-1EXPRESSIONS\*(R"\s0). The resulting row is a hash whose keys are named the same as
+the column name.
+.IP "\(bu" 4
+innotop filters the rows, removing those that don't need to be displayed. See
+\&\*(L"\s-1FILTERS\*(R"\s0.
+.IP "\(bu" 4
+innotop sorts the rows. See \*(L"\s-1SORTING\*(R"\s0.
+.IP "\(bu" 4
+innotop groups the rows together, if specified. See \*(L"\s-1GROUPING\*(R"\s0.
+.IP "\(bu" 4
+innotop colorizes the rows. See \*(L"\s-1COLORS\*(R"\s0.
+.IP "\(bu" 4
+innotop transforms the column values in each row. See \*(L"\s-1TRANSFORMATIONS\*(R"\s0.
+.IP "\(bu" 4
+innotop optionally pivots the rows (see \*(L"\s-1PIVOTING\*(R"\s0), then filters and sorts
+them.
+.IP "\(bu" 4
+innotop formats and justifies the rows as a table. During this step, innotop
+applies further formatting to the column values, including alignment, maximum
+and minimum widths. innotop also does final error checking to ensure there are
+no crashes due to undefined values. innotop then adds a caption if specified,
+and the table is ready to print.
+.PP
+The lifecycle is slightly different if the table is pivoted, as noted above. To
+clarify, if the table is pivoted, the process is extract, group, transform,
+pivot, filter, sort, create. If it's not pivoted, the process is extract,
+filter, sort, group, color, transform, create. This slightly convoluted process
+doesn't map all that well to \s-1SQL,\s0 but pivoting complicates things pretty
+thoroughly. Roughly speaking, filtering and sorting happen as late as needed to
+effect the final result as you might expect, but as early as possible for
+efficiency.
+.PP
+Each built-in table is described below:
+.IP "adaptive_hash_index" 4
+.IX Item "adaptive_hash_index"
+Displays data about InnoDB's adaptive hash index. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "buffer_pool" 4
+.IX Item "buffer_pool"
+Displays data about InnoDB's buffer pool. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "cmd_summary" 4
+.IX Item "cmd_summary"
+Displays weighted status variables. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "deadlock_locks" 4
+.IX Item "deadlock_locks"
+Shows which locks were held and waited for by the last detected deadlock. Data
+source: \*(L"\s-1DEADLOCK_LOCKS\*(R"\s0.
+.IP "deadlock_transactions" 4
+.IX Item "deadlock_transactions"
+Shows transactions involved in the last detected deadlock. Data source:
+\&\*(L"\s-1DEADLOCK_TRANSACTIONS\*(R"\s0.
+.IP "explain" 4
+.IX Item "explain"
+Shows the output of \s-1EXPLAIN. \s0 Data source: \*(L"\s-1EXPLAIN\*(R"\s0.
+.IP "file_io_misc" 4
+.IX Item "file_io_misc"
+Displays data about InnoDB's file and I/O operations. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "fk_error" 4
+.IX Item "fk_error"
+Displays various data about InnoDB's last foreign key error. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "health_dashboard" 4
+.IX Item "health_dashboard"
+Displays an overall summary of servers, one server per line, for monitoring.
+Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0, \*(L"\s-1MASTER_SLAVE\*(R"\s0, \*(L"\s-1PROCESSLIST_STATS\*(R"\s0.
+.IP "index_statistics" 4
+.IX Item "index_statistics"
+Displays data from the \s-1INDEX_STATISTICS\s0 table in Percona-enhanced servers.
+.IP "index_table_statistics" 4
+.IX Item "index_table_statistics"
+Displays data from the \s-1INDEX_STATISTICS\s0 and \s-1TABLE_STATISTICS\s0 tables in
+Percona-enhanced servers. It joins the two together, grouped by the database
+and table name. It is the default view in \*(L"U: User Statistics\*(R" mode,
+and makes it easy to see what tables are hot, how many rows are read from indexes,
+how many changes are made, and how many changes are made to indexes.
+.IP "innodb_blocked_blocker" 4
+.IX Item "innodb_blocked_blocker"
+Displays InnoDB locks and lock waits. Data source: \*(L"\s-1INNODB_BLOCKED_BLOCKER\*(R"\s0.
+.IP "innodb_locks" 4
+.IX Item "innodb_locks"
+Displays InnoDB locks. Data source: \*(L"\s-1INNODB_LOCKS\*(R"\s0.
+.IP "innodb_transactions" 4
+.IX Item "innodb_transactions"
+Displays data about InnoDB's current transactions. Data source:
+\&\*(L"\s-1INNODB_TRANSACTIONS\*(R"\s0.
+.IP "insert_buffers" 4
+.IX Item "insert_buffers"
+Displays data about InnoDB's insert buffer. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "io_threads" 4
+.IX Item "io_threads"
+Displays data about InnoDB's I/O threads. Data source: \*(L"\s-1IO_THREADS\*(R"\s0.
+.IP "log_statistics" 4
+.IX Item "log_statistics"
+Displays data about InnoDB's logging system. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "master_status" 4
+.IX Item "master_status"
+Displays replication master status. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "open_tables" 4
+.IX Item "open_tables"
+Displays open tables. Data source: \*(L"\s-1OPEN_TABLES\*(R"\s0.
+.IP "page_statistics" 4
+.IX Item "page_statistics"
+Displays InnoDB page statistics. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "pending_io" 4
+.IX Item "pending_io"
+Displays InnoDB pending I/O operations. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "processlist" 4
+.IX Item "processlist"
+Displays current MySQL processes (threads/connections). Data source:
+\&\*(L"\s-1PROCESSLIST\*(R"\s0.
+.IP "q_header" 4
+.IX Item "q_header"
+Displays various status values. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "row_operation_misc" 4
+.IX Item "row_operation_misc"
+Displays data about InnoDB's row operations. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "row_operations" 4
+.IX Item "row_operations"
+Displays data about InnoDB's row operations. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "semaphores" 4
+.IX Item "semaphores"
+Displays data about InnoDB's semaphores and mutexes. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "slave_io_status" 4
+.IX Item "slave_io_status"
+Displays data about the slave I/O thread. Data source:
+\&\*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "slave_sql_status" 4
+.IX Item "slave_sql_status"
+Displays data about the slave \s-1SQL\s0 thread. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "table_statistics" 4
+.IX Item "table_statistics"
+Displays data from the \s-1TABLE_STATISTICS\s0 table in Percona-enhanced servers.
+.IP "t_header" 4
+.IX Item "t_header"
+Displays various InnoDB status values. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "var_status" 4
+.IX Item "var_status"
+Displays user-configurable data. Data source: \*(L"\s-1STATUS_VARIABLES\*(R"\s0.
+.IP "wait_array" 4
+.IX Item "wait_array"
+Displays data about InnoDB's \s-1OS\s0 wait array. Data source: \*(L"\s-1OS_WAIT_ARRAY\*(R"\s0.
+.SS "\s-1COLUMNS\s0"
+.IX Subsection "COLUMNS"
+Columns belong to tables. You can choose a table's columns by pressing the '^'
+key, which starts the \*(L"\s-1TABLE EDITOR\*(R"\s0 and lets you choose and edit columns.
+Pressing 'e' from within the table editor lets you edit the column's properties:
+.IP "\(bu" 4
+hdr: a column header. This appears in the first row of the table.
+.IP "\(bu" 4
+just: justification. '\-' means left-justified and '' means right-justified,
+just as with printf formatting codes (not a coincidence).
+.IP "\(bu" 4
+dec: whether to further align the column on the decimal point.
+.IP "\(bu" 4
+num: whether the column is numeric. This affects how values are sorted
+(lexically or numerically).
+.IP "\(bu" 4
+label: a small note about the column, which appears in dialogs that help the
+user choose columns.
+.IP "\(bu" 4
+src: an expression that innotop uses to extract the column's data from its
+source (see \*(L"\s-1DATA SOURCES\*(R"\s0). See \*(L"\s-1EXPRESSIONS\*(R"\s0 for more on expressions.
+.IP "\(bu" 4
+minw: specifies a minimum display width. This helps stabilize the display,
+which makes it easier to read if the data is changing frequently.
+.IP "\(bu" 4
+maxw: similar to minw.
+.IP "\(bu" 4
+trans: a list of column transformations. See \*(L"\s-1TRANSFORMATIONS\*(R"\s0.
+.IP "\(bu" 4
+agg: an aggregate function. See \*(L"\s-1GROUPING\*(R"\s0. The default is \*(L"first\*(R".
+.IP "\(bu" 4
+aggonly: controls whether the column only shows when grouping is enabled on the
+table (see \*(L"\s-1GROUPING\*(R"\s0). By default, this is disabled. This means columns
+will always be shown by default, whether grouping is enabled or not. If a
+column's aggonly is set true, the column will appear when you toggle grouping on
+the table. Several columns are set this way, such as the count column on
+\&\*(L"processlist\*(R" and \*(L"innodb_transactions\*(R", so you don't see a count when the
+grouping isn't enabled, but you do when it is.
+.IP "\(bu" 4
+agghide: the reverse of aggonly. The column is hidden when grouping is enabled.
+.SS "\s-1FILTERS\s0"
+.IX Subsection "FILTERS"
+Filters remove rows from the display. They behave much like a \s-1WHERE\s0 clause in
+\&\s-1SQL. \s0 innotop has several built-in filters, which remove irrelevant information
+like inactive queries, but you can define your own as well. innotop also lets
+you create quick-filters, which do not get saved to the configuration file, and
+are just an easy way to quickly view only some rows.
+.PP
+You can enable or disable a filter on any table. Press the '%' key (mnemonic: %
+looks kind of like a line being filtered between two circles) and choose which
+table you want to filter, if asked. You'll then see a list of possible filters
+and a list of filters currently enabled for that table. Type the names of
+filters you want to apply and press Enter.
+.PP
+\fIUSER-DEFINED \s-1FILTERS\s0\fR
+.IX Subsection "USER-DEFINED FILTERS"
+.PP
+If you type a name that doesn't exist, innotop will prompt you to create the
+filter. Filters are easy to create if you know Perl, and not hard if you don't.
+What you're doing is creating a subroutine that returns true if the row should
+be displayed. The row is a hash reference passed to your subroutine as \f(CW$set\fR.
+.PP
+For example, imagine you want to filter the processlist table so you only see
+queries that have been running more than five minutes. Type a new name for your
+filter, and when prompted for the subroutine body, press \s-1TAB\s0 to initiate your
+terminal's auto-completion. You'll see the names of the columns in the
+\&\*(L"processlist\*(R" table (innotop generally tries to help you with auto-completion
+lists). You want to filter on the 'time' column. Type the text \*(L"$set\->{time} >
+300\*(R" to return true when the query is more than five minutes old. That's all
+you need to do.
+.PP
+In other words, the code you're typing is surrounded by an implicit context,
+which looks like this:
+.PP
+.Vb 4
+\& sub filter {
+\& my ( $set ) = @_;
+\& # YOUR CODE HERE
+\& }
+.Ve
+.PP
+If your filter doesn't work, or if something else suddenly behaves differently,
+you might have made an error in your filter, and innotop is silently catching
+the error. Try enabling \*(L"debug\*(R" to make innotop throw an error instead.
+.PP
+\fIQUICK-FILTERS\fR
+.IX Subsection "QUICK-FILTERS"
+.PP
+innotop's quick-filters are a shortcut to create a temporary filter that doesn't
+persist when you restart innotop. To create a quick-filter, press the '/' key.
+innotop will prompt you for the column name and filter text. Again, you can use
+auto-completion on column names. The filter text can be just the text you want
+to \*(L"search for.\*(R" For example, to filter the \*(L"processlist\*(R" table on queries
+that refer to the products table, type '/' and then 'info product'. Internally,
+the filter is compiled into a subroutine like this:
+.PP
+.Vb 4
+\& sub filter {
+\& my ( $set ) = @_;
+\& $set\->{info} =~ m/product/;
+\& }
+.Ve
+.PP
+The filter text can actually be any Perl regular expression, but of course a
+literal string like 'product' works fine as a regular expression.
+.PP
+What if you want the filter to discard matching rows, rather than showing
+matching rows? If you're familiar with Perl regular expressions, you might
+guess how to do this. You have to use a zero-width negative lookahead
+assertion. If you don't know what that means, don't worry. Let's filter out
+all rows where the command is Gandalf. Type the following:
+.PP
+.Vb 2
+\& 1. /
+\& 2. cmd ^(?!Gandalf)
+.Ve
+.PP
+Behind the scenes innotop compiles the quick-filter into a specially tagged
+filter that is otherwise like any other filter. It just isn't saved to the
+configuration file.
+.PP
+To clear quick-filters, press the '\e' key and innotop will clear them all at
+once.
+.SS "\s-1SORTING\s0"
+.IX Subsection "SORTING"
+innotop has sensible built-in defaults to sort the most important rows to the
+top of the table. Like anything else in innotop, you can customize how any
+table is sorted.
+.PP
+To start the sort dialog, start the \*(L"\s-1TABLE EDITOR\*(R"\s0 with the '^' key, choose a
+table if necessary, and press the 's' key. You'll see a list of columns you can
+use in the sort expression and the current sort expression, if any. Enter a
+list of columns by which you want to sort and press Enter. If you want to
+reverse sort, prefix the column name with a minus sign. For example, if you
+want to sort by column a ascending, then column b descending, type 'a \-b'. You
+can also explicitly add a + in front of columns you want to sort ascending, but
+it's not required.
+.PP
+Some modes have keys mapped to open this dialog directly, and to quickly reverse
+sort direction. Press '?' as usual to see which keys are mapped in any mode.
+.SS "\s-1GROUPING\s0"
+.IX Subsection "GROUPING"
+innotop can group, or aggregate, rows together (the terms are used
+interchangeably). This is quite similar to an \s-1SQL GROUP BY\s0 clause. You can
+specify to group on certain columns, or if you don't specify any, the entire set
+of rows is treated as one group. This is quite like \s-1SQL\s0 so far, but unlike \s-1SQL,\s0
+you can also select un-grouped columns. innotop actually aggregates every
+column. If you don't explicitly specify a grouping function, the default is
+\&'first'. This is basically a convenience so you don't have to specify an
+aggregate function for every column you want in the result.
+.PP
+You can quickly toggle grouping on a table with the '=' key, which toggles its
+aggregate property. This property doesn't persist to the config file.
+.PP
+The columns by which the table is grouped are specified in its group_by
+property. When you turn grouping on, innotop places the group_by columns at the
+far left of the table, even if they're not supposed to be visible. The rest of
+the visible columns appear in order after them.
+.PP
+Two tables have default group_by lists and a count column built in:
+\&\*(L"processlist\*(R" and \*(L"innodb_transactions\*(R". The grouping is by connection
+and status, so you can quickly see how many queries or transactions are in a
+given status on each server you're monitoring. The time columns are aggregated
+as a sum; other columns are left at the default 'first' aggregation.
+.PP
+By default, the table shown in \*(L"S: Variables & Status\*(R" mode also uses
+grouping so you can monitor variables and status across many servers. The
+default aggregation function in this mode is 'avg'.
+.PP
+Valid grouping functions are defined in the \f(CW%agg_funcs\fR hash. They include
+.IP "first" 4
+.IX Item "first"
+Returns the first element in the group.
+.IP "count" 4
+.IX Item "count"
+Returns the number of elements in the group, including undefined elements, much
+like \s-1SQL\s0's \s-1COUNT\s0(*).
+.IP "avg" 4
+.IX Item "avg"
+Returns the average of defined elements in the group.
+.IP "sum" 4
+.IX Item "sum"
+Returns the sum of elements in the group.
+.PP
+Here's an example of grouping at work. Suppose you have a very busy server with
+hundreds of open connections, and you want to see how many connections are in
+what status. Using the built-in grouping rules, you can press 'Q' to enter
+\&\*(L"Q: Query List\*(R" mode. Press '=' to toggle grouping (if necessary, select the
+\&\*(L"processlist\*(R" table when prompted).
+.PP
+Your display might now look like the following:
+.PP
+.Vb 1
+\& Query List (? for help) localhost, 32:33, 0.11 QPS, 1 thd, 5.0.38\-log
+\&
+\& CXN Cmd Cnt ID User Host Time Query
+\& localhost Query 49 12933 webusr localhost 19:38 SELECT * FROM
+\& localhost Sending Da 23 2383 webusr localhost 12:43 SELECT col1,
+\& localhost Sleep 120 140 webusr localhost 5:18:12
+\& localhost Statistics 12 19213 webusr localhost 01:19 SELECT * FROM
+.Ve
+.PP
+That's actually quite a worrisome picture. You've got a lot of idle connections
+(Sleep), and some connections executing queries (Query and Sending Data).
+That's okay, but you also have a lot in Statistics status, collectively spending
+over a minute. That means the query optimizer is having a really hard time
+generating execution plans for your statements. Something is wrong; it should
+normally take milliseconds to plan queries. You might not have seen this pattern if you
+didn't look at your connections in aggregate. (This is a made-up example, but
+it can happen in real life).
+.SS "\s-1PIVOTING\s0"
+.IX Subsection "PIVOTING"
+innotop can pivot a table for more compact display, similar to a Pivot Table in
+a spreadsheet (also known as a crosstab). Pivoting a table makes columns into
+rows. Assume you start with this table:
+.PP
+.Vb 4
+\& foo bar
+\& === ===
+\& 1 3
+\& 2 4
+.Ve
+.PP
+After pivoting, the table will look like this:
+.PP
+.Vb 4
+\& name set0 set1
+\& ==== ==== ====
+\& foo 1 2
+\& bar 3 4
+.Ve
+.PP
+To get reasonable results, you might need to group as well as pivoting.
+innotop currently does this for \*(L"S: Variables & Status\*(R" mode.
+.SS "\s-1COLORS\s0"
+.IX Subsection "COLORS"
+By default, innotop highlights rows with color so you can see at a glance which
+rows are more important. You can customize the colorization rules and add your
+own to any table. Open the table editor with the '^' key, choose a table if
+needed, and press 'o' to open the color editor dialog.
+.PP
+The color editor dialog displays the rules applied to the table, in the order
+they are evaluated. Each row is evaluated against each rule to see if the rule
+matches the row; if it does, the row gets the specified color, and no further
+rules are evaluated. The rules look like the following:
+.PP
+.Vb 9
+\& state eq Locked black on_red
+\& cmd eq Sleep white
+\& user eq system user white
+\& cmd eq Connect white
+\& cmd eq Binlog Dump white
+\& time > 600 red
+\& time > 120 yellow
+\& time > 60 green
+\& time > 30 cyan
+.Ve
+.PP
+This is the default rule set for the \*(L"processlist\*(R" table. In order of
+priority, these rules make locked queries black on a red background, \*(L"gray out\*(R"
+connections from replication and sleeping queries, and make queries turn from
+cyan to red as they run longer.
+.PP
+(For some reason, the \s-1ANSI\s0 color code \*(L"white\*(R" is actually a light gray. Your
+terminal's display may vary; experiment to find colors you like).
+.PP
+You can use keystrokes to move the rules up and down, which re-orders their
+priority. You can also delete rules and add new ones. If you add a new rule,
+innotop prompts you for the column, an operator for the comparison, a value
+against which to compare the column, and a color to assign if the rule matches.
+There is auto-completion and prompting at each step.
+.PP
+The value in the third step needs to be correctly quoted. innotop does not try
+to quote the value because it doesn't know whether it should treat the value as
+a string or a number. If you want to compare the column against a string, as
+for example in the first rule above, you should enter 'Locked' surrounded by
+quotes. If you get an error message about a bareword, you probably should have
+quoted something.
+.SS "\s-1EXPRESSIONS\s0"
+.IX Subsection "EXPRESSIONS"
+Expressions are at the core of how innotop works, and are what enables you to
+extend innotop as you wish. Recall the table lifecycle explained in
+\&\*(L"\s-1TABLES\*(R"\s0. Expressions are used in the earliest step, where it extracts
+values from a data source to form rows.
+.PP
+It does this by calling a subroutine for each column, passing it the source data
+set, a set of current values, and a set of previous values. These are all
+needed so the subroutine can calculate things like the difference between this
+tick and the previous tick.
+.PP
+The subroutines that extract the data from the set are compiled from
+expressions. This gives significantly more power than just naming the values to
+fill the columns, because it allows the column's value to be calculated from
+whatever data is necessary, but avoids the need to write complicated and lengthy
+Perl code.
+.PP
+innotop begins with a string of text that can look as simple as a value's name
+or as complicated as a full-fledged Perl expression. It looks at each
+\&'bareword' token in the string and decides whether it's supposed to be a key
+into the \f(CW$set\fR hash. A bareword is an unquoted value that isn't already
+surrounded by code-ish things like dollar signs or curly brackets. If innotop
+decides that the bareword isn't a function or other valid Perl code, it converts
+it into a hash access. After the whole string is processed, innotop compiles a
+subroutine, like this:
+.PP
+.Vb 5
+\& sub compute_column_value {
+\& my ( $set, $cur, $pre ) = @_;
+\& my $val = # EXPANDED STRING GOES HERE
+\& return $val;
+\& }
+.Ve
+.PP
+Here's a concrete example, taken from the header table \*(L"q_header\*(R" in \*(L"Q:
+Query List\*(R" mode. This expression calculates the qps, or Queries Per Second,
+column's values, from the values returned by \s-1SHOW STATUS:\s0
+.PP
+.Vb 1
+\& Questions/Uptime_hires
+.Ve
+.PP
+innotop decides both words are barewords, and transforms this expression into
+the following Perl code:
+.PP
+.Vb 1
+\& $set\->{Questions}/$set\->{Uptime_hires}
+.Ve
+.PP
+When surrounded by the rest of the subroutine's code, this is executable Perl
+that calculates a high-resolution queries-per-second value.
+.PP
+The arguments to the subroutine are named \f(CW$set\fR, \f(CW$cur\fR, and \f(CW$pre\fR. In most cases,
+\&\f(CW$set\fR and \f(CW$cur\fR will be the same values. However, if \*(L"status_inc\*(R" is set, \f(CW$cur\fR
+will not be the same as \f(CW$set\fR, because \f(CW$set\fR will already contain values that are
+the incremental difference between \f(CW$cur\fR and \f(CW$pre\fR.
+.PP
+Every column in innotop is computed by subroutines compiled in the same fashion.
+There is no difference between innotop's built-in columns and user-defined
+columns. This keeps things consistent and predictable.
+.SS "\s-1TRANSFORMATIONS\s0"
+.IX Subsection "TRANSFORMATIONS"
+Transformations change how a value is rendered. For example, they can take a
+number of seconds and display it in H:M:S format. The following transformations
+are defined:
+.IP "commify" 4
+.IX Item "commify"
+Adds commas to large numbers every three decimal places.
+.IP "distill" 4
+.IX Item "distill"
+Distills \s-1SQL\s0 into verb-noun-noun format for quick comprehension.
+.IP "dulint_to_int" 4
+.IX Item "dulint_to_int"
+Accepts two unsigned integers and converts them into a single longlong. This is
+useful for certain operations with InnoDB, which uses two integers as
+transaction identifiers, for example.
+.IP "fuzzy_time" 4
+.IX Item "fuzzy_time"
+Converts a number of seconds into a friendly, readable value like \*(L"1h35m\*(R".
+.IP "no_ctrl_char" 4
+.IX Item "no_ctrl_char"
+Removes quoted control characters from the value. This is affected by the
+\&\*(L"charset\*(R" configuration variable.
+.Sp
+This transformation only operates within quoted strings, for example, values to
+a \s-1SET\s0 clause in an \s-1UPDATE\s0 statement. It will not alter the \s-1UPDATE\s0 statement,
+but will collapse the quoted string to [\s-1BINARY\s0] or [\s-1TEXT\s0], depending on the
+charset.
+.IP "percent" 4
+.IX Item "percent"
+Converts a number to a percentage by multiplying it by two, formatting it with
+\&\*(L"num_digits\*(R" digits after the decimal point, and optionally adding a percent
+sign (see \*(L"show_percent\*(R").
+.IP "secs_to_time" 4
+.IX Item "secs_to_time"
+Formats a number of seconds as time in days+hours:minutes:seconds format.
+.IP "set_precision" 4
+.IX Item "set_precision"
+Formats numbers with \*(L"num_digits\*(R" number of digits after the decimal point.
+.IP "shorten" 4
+.IX Item "shorten"
+Formats a number as a unit of 1024 (k/M/G/T) and with \*(L"num_digits\*(R" number of
+digits after the decimal point.
+.SS "\s-1TABLE EDITOR\s0"
+.IX Subsection "TABLE EDITOR"
+The innotop table editor lets you customize tables with keystrokes. You start
+the table editor with the '^' key. If there's more than one table on the
+screen, it will prompt you to choose one of them. Once you do, innotop will
+show you something like this:
+.PP
+.Vb 1
+\& Editing table definition for Buffer Pool. Press ? for help, q to quit.
+\&
+\& name hdr label src
+\& cxn CXN Connection from which cxn
+\& buf_pool_size Size Buffer pool size IB_bp_buf_poo
+\& buf_free Free Bufs Buffers free in the b IB_bp_buf_fre
+\& pages_total Pages Pages total IB_bp_pages_t
+\& pages_modified Dirty Pages Pages modified (dirty IB_bp_pages_m
+\& buf_pool_hit_rate Hit Rate Buffer pool hit rate IB_bp_buf_poo
+\& total_mem_alloc Memory Total memory allocate IB_bp_total_m
+\& add_pool_alloc Add\*(Aql Pool Additional pool alloca IB_bp_add_poo
+.Ve
+.PP
+The first line shows which table you're editing, and reminds you again to press
+\&'?' for a list of key mappings. The rest is a tabular representation of the
+table's columns, because that's likely what you're trying to edit. However, you
+can edit more than just the table's columns; this screen can start the filter
+editor, color rule editor, and more.
+.PP
+Each row in the display shows a single column in the table you're editing, along
+with a couple of its properties such as its header and source expression (see
+\&\*(L"\s-1EXPRESSIONS\*(R"\s0).
+.PP
+The key mappings are Vim-style, as in many other places. Pressing 'j' and 'k'
+moves the highlight up or down. You can then (d)elete or (e)dit the highlighted
+column. You can also (a)dd a column to the table. This actually just activates
+one of the columns already defined for the table; it prompts you to choose from
+among the columns available but not currently displayed. Finally, you can
+re-order the columns with the '+' and '\-' keys.
+.PP
+You can do more than just edit the columns with the table editor, you can also
+edit other properties, such as the table's sort expression and group-by
+expression. Press '?' to see the full list, of course.
+.PP
+If you want to really customize and create your own column, as opposed to just
+activating a built-in one that's not currently displayed, press the (n)ew key,
+and innotop will prompt you for the information it needs:
+.IP "\(bu" 4
+The column name: this needs to be a word without any funny characters, e.g. just
+letters, numbers and underscores.
+.IP "\(bu" 4
+The column header: this is the label that appears at the top of the column, in
+the table header. This can have spaces and funny characters, but be careful not
+to make it too wide and waste space on-screen.
+.IP "\(bu" 4
+The column's data source: this is an expression that determines what data from
+the source (see \*(L"\s-1TABLES\*(R"\s0) innotop will put into the column. This can just be
+the name of an item in the source, or it can be a more complex expression, as
+described in \*(L"\s-1EXPRESSIONS\*(R"\s0.
+.PP
+Once you've entered the required data, your table has a new column. There is no
+difference between this column and the built-in ones; it can have all the same
+properties and behaviors. innotop will write the column's definition to the
+configuration file, so it will persist across sessions.
+.PP
+Here's an example: suppose you want to track how many times your slaves have
+retried transactions. According to the MySQL manual, the
+Slave_retried_transactions status variable gives you that data: \*(L"The total
+number of times since startup that the replication slave \s-1SQL\s0 thread has retried
+transactions. This variable was added in version 5.0.4.\*(R" This is appropriate to
+add to the \*(L"slave_sql_status\*(R" table.
+.PP
+To add the column, switch to the replication-monitoring mode with the 'M' key,
+and press the '^' key to start the table editor. When prompted, choose
+slave_sql_status as the table, then press 'n' to create the column. Type
+\&'retries' as the column name, 'Retries' as the column header, and
+\&'Slave_retried_transactions' as the source. Now the column is created, and you
+see the table editor screen again. Press 'q' to exit the table editor, and
+you'll see your column at the end of the table.
+.SH "VARIABLE SETS"
+.IX Header "VARIABLE SETS"
+Variable sets are used in \*(L"S: Variables & Status\*(R" mode to define more easily
+what variables you want to monitor. Behind the scenes they are compiled to a
+list of expressions, and then into a column list so they can be treated just
+like columns in any other table, in terms of data extraction and
+transformations. However, you're protected from the tedious details by a syntax
+that ought to feel very natural to you: a \s-1SQL SELECT\s0 list.
+.PP
+The data source for variable sets, and indeed the entire S mode, is the
+combination of \s-1SHOW STATUS, SHOW VARIABLES,\s0 and \s-1SHOW INNODB STATUS. \s0 Imagine
+that you had a huge table with one column per variable returned from those
+statements. That's the data source for variable sets. You can now query this
+data source just like you'd expect. For example:
+.PP
+.Vb 1
+\& Questions, Uptime, Questions/Uptime as QPS
+.Ve
+.PP
+Behind the scenes innotop will split that variable set into three expressions,
+compile them and turn them into a table definition, then extract as usual. This
+becomes a \*(L"variable set,\*(R" or a \*(L"list of variables you want to monitor.\*(R"
+.PP
+innotop lets you name and save your variable sets, and writes them to the
+configuration file. You can choose which variable set you want to see with the
+\&'c' key, or activate the next and previous sets with the '>' and '<' keys.
+There are many built-in variable sets as well, which should give you a good
+start for creating your own. Press 'e' to edit the current variable set, or
+just to see how it's defined. To create a new one, just press 'c' and type its
+name.
+.PP
+You may want to use some of the functions listed in \*(L"\s-1TRANSFORMATIONS\*(R"\s0 to help
+format the results. In particular, \*(L"set_precision\*(R" is often useful to limit
+the number of digits you see. Extending the above example, here's how:
+.PP
+.Vb 1
+\& Questions, Uptime, set_precision(Questions/Uptime) as QPS
+.Ve
+.PP
+Actually, this still needs a little more work. If your \*(L"interval\*(R" is less
+than one second, you might be dividing by zero because Uptime is incremental in
+this mode by default. Instead, use Uptime_hires:
+.PP
+.Vb 1
+\& Questions, Uptime, set_precision(Questions/Uptime_hires) as QPS
+.Ve
+.PP
+This example is simple, but it shows how easy it is to choose which variables
+you want to monitor.
+.SH "PLUGINS"
+.IX Header "PLUGINS"
+innotop has a simple but powerful plugin mechanism by which you can extend
+or modify its existing functionality, and add new functionality. innotop's
+plugin functionality is event-based: plugins register themselves to be called
+when events happen. They then have a chance to influence the event.
+.PP
+An innotop plugin is a Perl module (.pm) file placed in innotop's \*(L"plugin_dir\*(R"
+directory. On \s-1UNIX\s0 systems, you can place a symbolic link to the module instead
+of putting the actual file there. innotop automatically discovers files named \f(CW\*(C`*.pm\*(C'\fR. If
+there is a corresponding entry in the \*(L"plugins\*(R" configuration file section,
+innotop loads and activates the plugin.
+.PP
+The module must conform to innotop's plugin interface. Additionally, the source
+code of the module must be written in such a way that innotop can inspect the
+file and determine the package name and description.
+.SS "Package Source Convention"
+.IX Subsection "Package Source Convention"
+innotop inspects the plugin module's source to determine the Perl package name.
+It looks for a line of the form \*(L"package Foo;\*(R" and if found, considers the
+plugin's package name to be Foo. Of course the package name can be a valid Perl
+package name such as Foo::Bar, with double colons (::) and so on.
+.PP
+It also looks for a description in the source code, to make the plugin editor
+more human-friendly. The description is a comment line of the form \*(L"#
+description: Foo\*(R", where \*(L"Foo\*(R" is the text innotop will consider to be the
+plugin's description.
+.SS "Plugin Interface"
+.IX Subsection "Plugin Interface"
+The innotop plugin interface is quite simple: innotop expects the plugin to be
+an object-oriented module it can call certain methods on. The methods are
+.IP "new(%variables)" 4
+.IX Item "new(%variables)"
+This is the plugin's constructor. It is passed a hash of innotop's variables,
+which it can manipulate (see \*(L"Plugin Variables\*(R"). It must return a reference
+to the newly created plugin object.
+.Sp
+At construction time, innotop has only loaded the general configuration and
+created the default built-in variables with their default contents (which is
+quite a lot). Therefore, the state of the program is exactly as in the innotop
+source code, plus the configuration variables from the \*(L"general\*(R" section in
+the config file.
+.Sp
+If your plugin manipulates the variables, it is changing global data, which is
+shared by innotop and all plugins. Plugins are loaded in the order they're
+listed in the config file. Your plugin may load before or after another plugin,
+so there is a potential for conflict or interaction between plugins if they
+modify data other plugins use or modify.
+.IP "\fIregister_for_events()\fR" 4
+.IX Item "register_for_events()"
+This method must return a list of events in which the plugin is interested, if
+any. See \*(L"Plugin Events\*(R" for the defined events. If the plugin returns an
+event that's not defined, the event is ignored.
+.IP "event handlers" 4
+.IX Item "event handlers"
+The plugin must implement a method named the same as each event for which it has
+registered. In other words, if the plugin returns qw(foo bar) from
+\&\fIregister_for_events()\fR, it must have \fIfoo()\fR and \fIbar()\fR methods. These methods are
+callbacks for the events. See \*(L"Plugin Events\*(R" for more details about each
+event.
+.SS "Plugin Variables"
+.IX Subsection "Plugin Variables"
+The plugin's constructor is passed a hash of innotop's variables, which it can
+manipulate. It is probably a good idea if the plugin object saves a copy of it
+for later use. The variables are defined in the innotop variable
+\&\f(CW%pluggable_vars\fR, and are as follows:
+.IP "action_for" 4
+.IX Item "action_for"
+A hashref of key mappings. These are innotop's global hot-keys.
+.IP "agg_funcs" 4
+.IX Item "agg_funcs"
+A hashref of functions that can be used for grouping. See \*(L"\s-1GROUPING\*(R"\s0.
+.IP "config" 4
+.IX Item "config"
+The global configuration hash.
+.IP "connections" 4
+.IX Item "connections"
+A hashref of connection specifications. These are just specifications of how to
+connect to a server.
+.IP "dbhs" 4
+.IX Item "dbhs"
+A hashref of innotop's database connections. These are actual \s-1DBI\s0 connection
+objects.
+.IP "filters" 4
+.IX Item "filters"
+A hashref of filters applied to table rows. See \*(L"\s-1FILTERS\*(R"\s0 for more.
+.IP "modes" 4
+.IX Item "modes"
+A hashref of modes. See \*(L"\s-1MODES\*(R"\s0 for more.
+.IP "server_groups" 4
+.IX Item "server_groups"
+A hashref of server groups. See \*(L"\s-1SERVER GROUPS\*(R"\s0.
+.IP "tbl_meta" 4
+.IX Item "tbl_meta"
+A hashref of innotop's table meta-data, with one entry per table (see
+\&\*(L"\s-1TABLES\*(R"\s0 for more information).
+.IP "trans_funcs" 4
+.IX Item "trans_funcs"
+A hashref of transformation functions. See \*(L"\s-1TRANSFORMATIONS\*(R"\s0.
+.IP "var_sets" 4
+.IX Item "var_sets"
+A hashref of variable sets. See \*(L"\s-1VARIABLE SETS\*(R"\s0.
+.SS "Plugin Events"
+.IX Subsection "Plugin Events"
+Each event is defined somewhere in the innotop source code. When innotop runs
+that code, it executes the callback function for each plugin that expressed its
+interest in the event. innotop passes some data for each event. The events are
+defined in the \f(CW%event_listener_for\fR variable, and are as follows:
+.ie n .IP "extract_values($set, $cur, $pre, $tbl)" 4
+.el .IP "extract_values($set, \f(CW$cur\fR, \f(CW$pre\fR, \f(CW$tbl\fR)" 4
+.IX Item "extract_values($set, $cur, $pre, $tbl)"
+This event occurs inside the function that extracts values from a data source.
+The arguments are the set of values, the current values, the previous values,
+and the table name.
+.IP "set_to_tbl" 4
+.IX Item "set_to_tbl"
+Events are defined at many places in this subroutine, which is responsible for
+turning an arrayref of hashrefs into an arrayref of lines that can be printed to
+the screen. The events all pass the same data: an arrayref of rows and the name
+of the table being created. The events are set_to_tbl_pre_filter,
+set_to_tbl_pre_sort,set_to_tbl_pre_group, set_to_tbl_pre_colorize,
+set_to_tbl_pre_transform, set_to_tbl_pre_pivot, set_to_tbl_pre_create,
+set_to_tbl_post_create.
+.IP "draw_screen($lines)" 4
+.IX Item "draw_screen($lines)"
+This event occurs inside the subroutine that prints the lines to the screen.
+\&\f(CW$lines\fR is an arrayref of strings.
+.SS "Simple Plugin Example"
+.IX Subsection "Simple Plugin Example"
+The easiest way to explain the plugin functionality is probably with a simple
+example. The following module adds a column to the beginning of every table and
+sets its value to 1. (If you copy and paste this example code, be sure to remove
+the first space from each line; lines such as '# description' must not start with
+whitespace).
+.PP
+.Vb 2
+\& use strict;
+\& use warnings FATAL => \*(Aqall\*(Aq;
+\&
+\& package Innotop::Plugin::Example;
+\& # description: Adds an \*(Aqexample\*(Aq column to every table
+\&
+\& sub new {
+\& my ( $class, %vars ) = @_;
+\& # Store reference to innotop\*(Aqs variables in $self
+\& my $self = bless { %vars }, $class;
+\&
+\& # Design the example column
+\& my $col = {
+\& hdr => \*(AqExample\*(Aq,
+\& just => \*(Aq\*(Aq,
+\& dec => 0,
+\& num => 1,
+\& label => \*(AqExample\*(Aq,
+\& src => \*(Aqexample\*(Aq, # Get data from this column in the data source
+\& tbl => \*(Aq\*(Aq,
+\& trans => [],
+\& };
+\&
+\& # Add the column to every table.
+\& my $tbl_meta = $vars{tbl_meta};
+\& foreach my $tbl ( values %$tbl_meta ) {
+\& # Add the column to the list of defined columns
+\& $tbl\->{cols}\->{example} = $col;
+\& # Add the column to the list of visible columns
+\& unshift @{$tbl\->{visible}}, \*(Aqexample\*(Aq;
+\& }
+\&
+\& # Be sure to return a reference to the object.
+\& return $self;
+\& }
+\&
+\& # I\*(Aqd like to be called when a data set is being rendered into a table, please.
+\& sub register_for_events {
+\& my ( $self ) = @_;
+\& return qw(set_to_tbl_pre_filter);
+\& }
+\&
+\& # This method will be called when the event fires.
+\& sub set_to_tbl_pre_filter {
+\& my ( $self, $rows, $tbl ) = @_;
+\& # Set the example column\*(Aqs data source to the value 1.
+\& foreach my $row ( @$rows ) {
+\& $row\->{example} = 1;
+\& }
+\& }
+\&
+\& 1;
+.Ve
+.SS "Plugin Editor"
+.IX Subsection "Plugin Editor"
+The plugin editor lets you view the plugins innotop discovered and activate or
+deactivate them. Start the editor by pressing $ to start the configuration
+editor from any mode. Press the 'p' key to start the plugin editor. You'll see
+a list of plugins innotop discovered. You can use the 'j' and 'k' keys to move
+the highlight to the desired one, then press the * key to toggle it active or
+inactive. Exit the editor and restart innotop for the changes to take effect.
+.SH "SQL STATEMENTS"
+.IX Header "SQL STATEMENTS"
+innotop uses a limited set of \s-1SQL\s0 statements to retrieve data from MySQL for
+display. The statements are customized depending on the server version against
+which they are executed; for example, on MySQL 5 and newer, \s-1INNODB_STATUS\s0
+executes \*(L"\s-1SHOW ENGINE INNODB STATUS\*(R",\s0 while on earlier versions it executes
+\&\*(L"\s-1SHOW INNODB STATUS\*(R". \s0 The statements are as follows:
+.PP
+.Vb 10
+\& Statement SQL executed
+\& =================== ===============================
+\& INDEX_STATISTICS SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS
+\& INNODB_STATUS SHOW [ENGINE] INNODB STATUS
+\& KILL_CONNECTION KILL
+\& KILL_QUERY KILL QUERY
+\& OPEN_TABLES SHOW OPEN TABLES
+\& PROCESSLIST SHOW FULL PROCESSLIST
+\& SHOW_MASTER_LOGS SHOW MASTER LOGS
+\& SHOW_MASTER_STATUS SHOW MASTER STATUS
+\& SHOW_SLAVE_STATUS SHOW SLAVE STATUS
+\& SHOW_STATUS SHOW [GLOBAL] STATUS
+\& SHOW_VARIABLES SHOW [GLOBAL] VARIABLES
+\& TABLE_STATISTICS SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS
+.Ve
+.SH "DATA SOURCES"
+.IX Header "DATA SOURCES"
+Each time innotop extracts values to create a table (see \*(L"\s-1EXPRESSIONS\*(R"\s0 and
+\&\*(L"\s-1TABLES\*(R"\s0), it does so from a particular data source. Largely because of the
+complex data extracted from \s-1SHOW INNODB STATUS,\s0 this is slightly messy. \s-1SHOW
+INNODB STATUS\s0 contains a mixture of single values and repeated values that form
+nested data sets.
+.PP
+Whenever innotop fetches data from MySQL, it adds two extra bits to each set:
+cxn and Uptime_hires. cxn is the name of the connection from which the data
+came. Uptime_hires is a high-resolution version of the server's Uptime status
+variable, which is important if your \*(L"interval\*(R" setting is sub-second.
+.PP
+Here are the kinds of data sources from which data is extracted:
+.IP "\s-1STATUS_VARIABLES\s0" 4
+.IX Item "STATUS_VARIABLES"
+This is the broadest category, into which the most kinds of data fall. It
+begins with the combination of \s-1SHOW STATUS\s0 and \s-1SHOW VARIABLES,\s0 but other sources
+may be included as needed, for example, \s-1SHOW MASTER STATUS\s0 and \s-1SHOW SLAVE
+STATUS,\s0 as well as many of the non-repeated values from \s-1SHOW INNODB STATUS.\s0
+.IP "\s-1DEADLOCK_LOCKS\s0" 4
+.IX Item "DEADLOCK_LOCKS"
+This data is extracted from the transaction list in the \s-1LATEST DETECTED DEADLOCK\s0
+section of \s-1SHOW INNODB STATUS. \s0 It is nested two levels deep: transactions, then
+locks.
+.IP "\s-1DEADLOCK_TRANSACTIONS\s0" 4
+.IX Item "DEADLOCK_TRANSACTIONS"
+This data is from the transaction list in the \s-1LATEST DETECTED DEADLOCK\s0
+section of \s-1SHOW INNODB STATUS. \s0 It is nested one level deep.
+.IP "\s-1EXPLAIN\s0" 4
+.IX Item "EXPLAIN"
+This data is from the result set returned by \s-1EXPLAIN.\s0
+.IP "\s-1INNODB_BLOCKED_BLOCKER\s0" 4
+.IX Item "INNODB_BLOCKED_BLOCKER"
+This data is from the \s-1INFORMATION_SCHEMA\s0 tables related to InnoDB locks and
+the processlist.
+.IP "\s-1INNODB_TRANSACTIONS\s0" 4
+.IX Item "INNODB_TRANSACTIONS"
+This data is from the \s-1TRANSACTIONS\s0 section of \s-1SHOW INNODB STATUS.\s0
+.IP "\s-1IO_THREADS\s0" 4
+.IX Item "IO_THREADS"
+This data is from the list of threads in the \s-1FILE I/O\s0 section of \s-1SHOW INNODB
+STATUS.\s0
+.IP "\s-1INNODB_LOCKS\s0" 4
+.IX Item "INNODB_LOCKS"
+This data is from the \s-1TRANSACTIONS\s0 section of \s-1SHOW INNODB STATUS\s0 and is nested
+two levels deep.
+.IP "\s-1MASTER_SLAVE\s0" 4
+.IX Item "MASTER_SLAVE"
+This data is from the combination of \s-1SHOW MASTER STATUS\s0 and \s-1SHOW SLAVE STATUS.\s0
+.IP "\s-1OPEN_TABLES\s0" 4
+.IX Item "OPEN_TABLES"
+This data is from \s-1SHOW OPEN TABLES.\s0
+.IP "\s-1PROCESSLIST\s0" 4
+.IX Item "PROCESSLIST"
+This data is from \s-1SHOW FULL PROCESSLIST.\s0
+.IP "\s-1PROCESSLIST_STATS\s0" 4
+.IX Item "PROCESSLIST_STATS"
+This data is from \s-1SHOW FULL PROCESSLIST\s0 and computes stats such as the maximum time
+a user query has been running, and how many user queries are running. A \*(L"user
+query\*(R" excludes replication threads.
+.IP "\s-1OS_WAIT_ARRAY\s0" 4
+.IX Item "OS_WAIT_ARRAY"
+This data is from the \s-1SEMAPHORES\s0 section of \s-1SHOW INNODB STATUS\s0 and is nested one
+level deep. It comes from the lines that look like this:
+.Sp
+.Vb 1
+\& \-\-Thread 1568861104 has waited at btr0cur.c line 424 ....
+.Ve
+.SH "MYSQL PRIVILEGES"
+.IX Header "MYSQL PRIVILEGES"
+.IP "\(bu" 4
+You must connect to MySQL as a user who has the \s-1SUPER\s0 privilege for many of the
+functions.
+.IP "\(bu" 4
+If you don't have the \s-1SUPER\s0 privilege, you can still run some functions, but you
+won't necessarily see all the same data.
+.IP "\(bu" 4
+You need the \s-1PROCESS\s0 privilege to see the list of currently running queries in Q
+mode.
+.IP "\(bu" 4
+You need special privileges to start and stop slave servers.
+.IP "\(bu" 4
+You need appropriate privileges to create and drop the deadlock tables if needed
+(see \*(L"\s-1SERVER CONNECTIONS\*(R"\s0).
+.SH "SYSTEM REQUIREMENTS"
+.IX Header "SYSTEM REQUIREMENTS"
+You need Perl to run innotop, of course. You also need a few Perl modules: \s-1DBI,\s0
+DBD::MariaDB, Term::ReadKey, and Time::HiRes. These should be included with most
+Perl distributions, but in case they are not, I recommend using versions
+distributed with your operating system or Perl distribution, not from \s-1CPAN.\s0
+Term::ReadKey in particular has been known to cause problems if installed from
+\&\s-1CPAN.\s0
+.PP
+If you have Term::ANSIColor, innotop will use it to format headers more readably
+and compactly. (Under Microsoft Windows, you also need Win32::Console::ANSI for
+terminal formatting codes to be honored). If you install Term::ReadLine,
+preferably Term::ReadLine::Gnu, you'll get nice auto-completion support.
+.PP
+I run innotop on Gentoo GNU/Linux, Debian and Ubuntu, and I've had feedback from
+people successfully running it on Red Hat, CentOS, Solaris, and Mac \s-1OSX. I\s0
+don't see any reason why it won't work on other UNIX-ish operating systems, but
+I don't know for sure. It also runs on Windows under ActivePerl without
+problem.
+.PP
+innotop has been used on MySQL versions 3.23.58, 4.0.27, 4.1.0, 4.1.22, 5.0.26,
+5.1.15, and 5.2.3. If it doesn't run correctly for you, that is a bug that
+should be reported.
+.SH "FILES"
+.IX Header "FILES"
+\&\f(CW$HOMEDIR\fR/.innotop and/or /etc/innotop are used to store
+configuration information. Files include the configuration file innotop.conf,
+the core_dump file which contains verbose error messages if \*(L"debug\*(R" is
+enabled, and the plugins/ subdirectory.
+.SH "GLOSSARY OF TERMS"
+.IX Header "GLOSSARY OF TERMS"
+.IP "tick" 4
+.IX Item "tick"
+A tick is a refresh event, when innotop re-fetches data from connections and
+displays it.
+.SH "ACKNOWLEDGEMENTS"
+.IX Header "ACKNOWLEDGEMENTS"
+The following people and organizations are acknowledged for various reasons.
+Hopefully no one has been forgotten.
+.PP
+Aaron Racine,
+Allen K. Smith,
+Aurimas Mikalauskas,
+Bartosz Fenski,
+Brian Miezejewski,
+Christian Hammers,
+Cyril Scetbon,
+Dane Miller,
+David Multer,
+Dr. Frank Ullrich,
+Giuseppe Maxia,
+Google.com Site Reliability Engineers,
+Google Code,
+Jan Pieter Kunst,
+Jari Aalto,
+Jay Pipes,
+Jeremy Zawodny,
+Johan Idren,
+Kristian Kohntopp,
+Lenz Grimmer,
+Maciej Dobrzanski,
+Michiel Betel,
+MySQL \s-1AB,\s0
+Paul McCullagh,
+Sebastien Estienne,
+Sourceforge.net,
+Steven Kreuzer,
+The Gentoo MySQL Team,
+Trevor Price,
+Yaar Schnitman,
+and probably more people that have not been included.
+.PP
+(If your name has been misspelled, it's probably out of fear of putting
+international characters into this documentation; earlier versions of Perl might
+not be able to compile it then).
+.SH "COPYRIGHT, LICENSE AND WARRANTY"
+.IX Header "COPYRIGHT, LICENSE AND WARRANTY"
+This program is copyright (c) 2006 Baron Schwartz.
+Feedback and improvements are welcome.
+.PP
+\&\s-1THIS PROGRAM IS PROVIDED \*(L"AS IS\*(R" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\s0
+.PP
+This program is free software; you can redistribute it and/or modify it under
+the terms of the \s-1GNU\s0 General Public License as published by the Free Software
+Foundation, version 2; \s-1OR\s0 the Perl Artistic License. On \s-1UNIX\s0 and similar
+systems, you can issue `man perlgpl' or `man perlartistic' to read these
+licenses.
+.PP
+You should have received a copy of the \s-1GNU\s0 General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+Street, Fifth Floor, Boston, \s-1MA 02110-1335 USA\s0.
+.PP
+Execute innotop and press '!' to see this information at any time.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Originally written by Baron Schwartz; currently maintained by Aaron Racine.
+.SH "BUGS"
+.IX Header "BUGS"
+You can report bugs, ask for improvements, and get other help and support at
+<https://github.com/innotop/innotop>. There are mailing lists, a source code
+browser, a bug tracker, etc. Please use these instead of contacting the
+maintainer or author directly, as it makes our job easier and benefits others if the
+discussions are permanent and public. Of course, if you need to contact us in
+private, please do.