Skip to content

fevangelou/mytop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 

Repository files navigation

mytop

A powerful MySQL and MariaDB monitoring tool for the command line, mytop displays real-time database server performance information similar to top.

Current Version

v2.1 - released on Jul 5th, 2026

See CHANGELOG section for more info


I know mytop - just show me how to install it

  1. Download mytop directly into /usr/local/bin/ and make it executable
curl -fsSL -o /usr/local/bin/mytop https://raw.githubusercontent.com/fevangelou/mytop/main/mytop && chmod +x /usr/local/bin/mytop
  1. Run anywhere (the defaults work just fine on Debian 11+, Ubuntu 22.04+ and RHEL distros v7 or newer)
mytop

ABOUT

mytop_v2 0_screenshot

This is a fork of the original mytop Perl script, updated for MySQL 8.x & MariaDB 10.3+ (or newer) releases.

It is not a half-baked todo-when-I-get-the-time fork.

As a professional sysadmin, I had used mytop for years. My gradual switch to Ubuntu Server 24.04 though left me with Innotop as the only available (maintained) choice, which simply does not work right, especially when it comes to explaining queries. Plus it never "clicked" as a utility. You had to devote way too many brain cells to configure Innotop just to get the basics that mytop provided out of the box (go figure...). As such, forking mytop was the only sensible thing to do. And as long as I'm active as a sysadmin (17+ years already), I'll keep it updated.

Yes, it has been "vibe coded" with the help of Anthropic's Claude (Perl was never my domain), but I have tested it extensively and since it's a daily tool for me, I'm gonna keep on maintaining it, as well as examine a possible rewrite to another language in the future.

Sincere thanks to Jeremy D. Zawodny (original author) & Mark Grennan (who updated mytop for MySQL 5.x).

WHAT'S NEW

MySQL 8.0 & MariaDB 10.3 (or newer) compatibility fixes

Query Cache Removal

  • MySQL 8.0 completely removed the query cache feature
  • Added intelligent detection that checks for have_query_cache variable
  • Falls back to checking Qcache_hits status variable for older versions
  • Safely defaults to disabled for MySQL 8.0 or newer

Safe Status Variables

  • All Qcache_* status variable references now use null coalescing
  • Prevents undefined variable warnings when query cache doesn't exist
  • Cache hit ratio calculations won't crash on MySQL 8+

Enhanced EXPLAIN

  • Wrapped EXPLAIN execution in eval block for proper error handling
  • Catches non-explainable queries (DDL, some admin commands)
  • Added support for new filtered column in MySQL 8+ EXPLAIN output
  • Dynamic column detection for future MySQL versions

System Compatibility

  • Fixed /proc/loadavg reading for non-Linux systems
  • Added proper error handling with fallback to empty string

User Experience Improvements

Dependency Checking

  • Automatic detection of missing Perl modules (DBI, DBD::mysql or DBD::MariaDB, Term::ReadKey)
  • Detects the MariaDB-common/mysql-common package conflict on RHEL-family systems and suggests the correct CPAN fix
  • Provides exact installation commands based on your distribution

Better Defaults

  • Default database changed from test to mysql
  • Refresh delay reduced from 5 seconds to 1 second
  • Idle thread display threshold set to 2

Code Quality

  • Fixed all Perl syntax warnings
  • Renamed conflicting variables to avoid masking
  • Fixed operator typo (=> to >= in cache ratio comparison)
  • Code formatted with Perl Tidy

INSTALLATION INSTRUCTIONS

1. Prerequisites

mytop requires the following Perl modules:

On Debian 11+ or Ubuntu 22.04+

sudo apt install libdbi-perl libdbd-mysql-perl libterm-readkey-perl

On RHEL distros (v7 or newer)

sudo yum install perl-DBI perl-DBD-MySQL perl-TermReadKey

or

sudo dnf install perl-DBI perl-DBD-MySQL perl-TermReadKey
RHEL 9+ with MariaDB.org or cPanel repos (MariaDB-common installed)

If your system uses MariaDB's own repos (or cPanel's MariaDB packages) instead of the distro's stock MariaDB/MySQL packages, the commands above will fail: perl-DBD-MySQL depends on mysql-common, which conflicts with MariaDB-common. On top of that, the current DBD::mysql 5.x on CPAN no longer compiles against MariaDB's client library (it requires MySQL 8.x client headers). Check with rpm -q MariaDB-common - if it's installed, use CPAN with the MariaDB-native driver instead:

sudo dnf install gcc make MariaDB-devel   # build prerequisites
sudo cpan DBD::MariaDB

mytop detects and uses DBD::MariaDB automatically if DBD::mysql isn't available - no configuration needed.

Via CPAN (for the purists)

cpan DBI DBD::mysql Term::ReadKey

Or, if that fails to compile against your MariaDB client library (see above):

cpan DBI DBD::MariaDB Term::ReadKey

2. One-line installation

No need to run make and make install, clone the repo, or fetch a tarball as with previous versions - mytop is a standalone Perl script, so grab it directly:

# 1. Download mytop directly into /usr/local/bin/ and make it executable
curl -fsSL -o /usr/local/bin/mytop https://raw.githubusercontent.com/fevangelou/mytop/main/mytop && chmod +x /usr/local/bin/mytop

# 2. Run anywhere (the defaults work just fine on Debian 11+, Ubuntu 22.04+ and RHEL distros v7 or newer)
mytop

CONFIGURATION

The .mytop Configuration File

When run as a root user, the defaults should work out of the box. Should you need to adjust them or allow regular system users to access mytop, create a config file at ~/.mytop (either for root or for each user you want to allow using mytop) with your connection settings:

# Place at ~/.mytop - adjust as needed
host=localhost
port=3306
db=mysql
user=myuser
pass=mypassword
delay=1
socket=/var/run/mysqld/mysqld.sock

Command Line Options

Run mytop --help to see all options:

  • -u <user> - MySQL/MariaDB username (default: root)
  • -p <password> - MySQL/MariaDB password
  • -h <host> - MySQL/MariaDB server host (default: localhost)
  • -P <port> - MySQL/MariaDB server port (default: 3306)
  • -S <socket> - MySQL/MariaDB socket file
  • -d <database> - Database to use (default: mysql)
  • -b - Batch mode, print and exit
  • -s <seconds> - Refresh delay in seconds (default: 1)
  • -i - Idle mode - only show non-sleeping threads
  • -I - Idle (big I) - mark idle threads with "." instead of full command
  • -o <field> - Sort order (default: last_cputime)
    • last_cputime - Time spent
    • user - Username
    • db - Database name
    • host - Client host
    • id - Thread ID
    • state - Query state
    • time - Time in current state
  • -r - Reverse sort order
  • --header - Print header rows in batch mode
  • --color - Force color on (even in batch mode)
  • --nocolor - Disable color output

Interactive Commands

Once mytop is running, use these keys:

  • ? - Display help
  • ! - Force past a replication error (at your own risk)
  • c - Switch to command summary mode
  • C - Toggle color display on/off
  • d - Filter by specific database
  • E - Display current replication error
  • e - Explain a query by thread ID
  • F - Remove all filters
  • f - Show full query info for a thread
  • h - Filter by hostname
  • H - Toggle header display
  • i - Toggle idle (sleeping) thread display
  • I - Show InnoDB status
  • k - Kill a specific thread
  • K - Kill all threads owned by a specific user
  • l - Change long running query highlighting threshold
  • m - Switch to QPS (queries per second) mode
  • o - Reverse sort order
  • p - Pause display updates
  • q - Quit
  • r - Reset status counters (FLUSH STATUS)
  • R - Toggle reverse DNS lookup for IP addresses
  • s - Change refresh delay in seconds
  • S - Change slow query highlighting threshold
  • t - Filter by thread state
  • u - Filter by specific user
  • V - Show MySQL/MariaDB variables

Display Information

mytop shows:

  1. Header Section: MySQL/MariaDB uptime, queries per second (QPS), load average, query cache hit rate (if available)
  2. Active Threads: Currently running queries with:
    • Thread ID
    • Username
    • Host
    • Database
    • Time
    • Command/State
    • Query text
  3. Command Summary (mode 'm'): Aggregated count by command type
mytop --user root --password secret --host localhost --db mysql

COMPATIBILITY MATRIX

Database Version Status
MySQL 5.x ✅ Full support (with query cache)
MySQL 8.0+ ✅ Full support (without query cache)
MariaDB 10.x ✅ Full support
MariaDB 11.x ✅ Full support
Operating System Status
Linux ✅ Full support
Other Unix ✅ Full support (no load average)
macOS ✅ Full support
Windows ⚠️ Seriously?

USAGE

Basic Usage

# Connect to local MySQL/MariaDB with default settings
mytop

# Connect to remote server
mytop --host db.example.com --user admin --password secret

# Use a specific database
mytop --db information_schema

# Batch mode (non-interactive)
mytop --batch

CHANGELOG

This changelog also provides a historical record of all previous versions before 2.0.

Version 2.1 - July 5th, 2026

  1. Dual DBD driver support added.

mytop now works with either DBD::mysql or DBD::MariaDB - whichever is installed. At startup it tries DBD::mysql first, then falls back to DBD::MariaDB, and builds the DSN and connection attributes (mysql_* vs mariadb_*) accordingly. This fixes a real-world case on RHEL 9-family systems (AlmaLinux, Rocky, etc.) using MariaDB.org or cPanel's MariaDB repos: the distro's perl-DBD-MySQL package conflicts with MariaDB-common (via its mysql-common dependency), so it can't be installed via dnf/yum at all, and installing the current DBD::mysql from CPAN fails to compile because DBD::mysql 5.x hard-requires MySQL 8.x client libraries, not MariaDB's connector.

The dependency checker now detects this exact conflict (rpm -q MariaDB-common) and points you at the CPAN-based fix instead of a dnf command that's guaranteed to fail. See Prerequisites below for the commands.

  1. Control character stripping fix.

Displayed query text is now stripped of any stray non-printing control bytes (e.g. embedded ESC sequences or NUL bytes from binary data stored in a column) before being printed to the terminal, preventing corrupted or hijacked terminal output when such data shows up in SHOW FULL PROCESSLIST. This was inspired by a similar-looking line in MariaDB's own bundled mytop, which turned out to be dead code - tr/[[:cntrl:]]// is a no-op in Perl since tr/// doesn't expand POSIX bracket classes - so this is a working implementation via s/[[:cntrl:]]//g instead.

  1. Fixed localhost connection failure under DBD::MariaDB.

The default connection settings (host=localhost) failed with Connection error: port cannot be specified when host is localhost or embedded on systems using the DBD::MariaDB fallback. DBD::mysql has always silently ignored a port specified alongside host=localhost (since "localhost" means "use the local socket" to every MySQL/MariaDB client), but DBD::MariaDB validates the DSN strictly and rejects the combination outright. The DSN builder now omits the port whenever host is localhost, regardless of which driver is active. Only affects systems where DBD::MariaDB is the active driver (e.g. RHEL 9+ with MariaDB.org/cPanel repos) - unaffected on systems using DBD::mysql (e.g. Ubuntu 22.04 with MySQL 8.0).

  1. Fixed password default overriding ~/.my.cnf credentials.

mytop always passed an explicit password to DBI->connect() - '' (empty string) by default - which overrides whatever the MySQL/MariaDB client library would otherwise auto-load from [client] in ~/.my.cnf (e.g. /root/.my.cnf, as cPanel-managed MySQL/MariaDB installs typically set up). This caused Access denied for user 'root'@'localhost' (using password: NO) on any system where root requires a real password, even though it was correctly configured in .my.cnf. The default password is now undef instead of '', so - unless you explicitly set one via -p, --password, --prompt, or ~/.mytop - mytop now defers to ~/.my.cnf exactly like the plain mysql CLI does when run without -p.

  1. Cleaner header display: load average and server version.

The load average and uptime shown in the header are now labeled and clearly separated, e.g. Load Avg.: 5.34 (1m) 4.53 (5m) 5.41 (15m) - Uptime: 285 days, 11:08, instead of the old unlabeled load 5.34 4.53 5.41 11/6259 2580836 up 3+12:55:33 [14:03:22], which also dumped the running/total process count and the last PID straight from the raw /proc/loadavg line. Uptime itself is now phrased like the classic uptime command (285 days, 11:08, or 5 min when under an hour) rather than a raw D+HH:MM:SS counter. The current time now gets its own labeled line below (Current Time: 14:03:22) instead of being tacked on unlabeled at the end. Additionally, MariaDB's reported version string includes a redundant -MariaDB build suffix (e.g. 11.4.12-MariaDB), which produced a duplicated MariaDB 11.4.12-MariaDB title; it's now stripped for display, matching MariaDB's own bundled mytop.

Version 2.0 - February 3rd, 2026

MySQL 8.0 & MariaDB 10.3 or newer compatibility patches

  • Fixed query cache detection for MySQL 8.0+ (query cache was removed)
  • Added fallback detection for query cache based on Qcache_hits status variable
  • Made all Qcache status variable references safe with null coalescing
  • Fixed /proc/loadavg reading to handle non-Linux systems gracefully
  • Enhanced EXPLAIN error handling to catch non-explainable queries
  • Updated PrintTable to handle additional MySQL 8+ EXPLAIN columns (filtered, etc.)
  • Added dynamic column detection for future MySQL version compatibility
  • Improved error messages for EXPLAIN failures
  • Made query cache hit ratio calculations safe when variables don't exist
  • Updated default configuration (db: mysql, delay: 1s, idle: 2)
  • Added Term::ReadKey to dependency checks
  • Fixed all Perl syntax warnings and code quality issues

This version is fully compatible with:

  • MySQL 5.x (with query cache)
  • MySQL 8.0+ (without query cache)
  • MariaDB 10.3+
  • On Debian 11+, Ubuntu 22.04+ and RHEL distros v7+

Version 2.0 was based off v1.91 from Mark Grennan.

Version 1.9.1 - February 14, 2012 (Mark Grennan)

  • Added display of system load level on the top line
  • Added Readonly state and Delay to the replication line
  • Added monitoring of Slave status
  • New command '!' to force past a replication error
  • Added number of rows sorted per second
  • Added a new 'Cmd' column to display the State of the query along with the statement
  • New command 'M' to change [mode] to status show changes

Version 1.8 - May 21, 2010 (Mark Grennan)

  • Added fixes for changes in MySQL 5.1 and 64-bit systems
  • Completed TODO - "make 'C' toggle display color"
  • New command 'S' command: Highlights slow queries less than 'S' seconds (default: 10 seconds)
  • New command 'l' for long queries (default: 120 seconds) - colored Magenta
  • New command 't' to filter based on State
  • Removed the 'Daemon' command type from the idle display
  • Fixed documentation errors

Version 1.6 - February 16, 2007

  • Added support for passwords with embedded spaces (patch from Jeffrey Friedl)

Version 1.4 - August 3, 2003

  • Used junk query filter from Steven Roussey
  • Added -prompt option so password doesn't need to be on command-line or in script (patches from jon r. luini and Sean Leach)
  • Added -resolve support to convert IPs to hostnames in thread view (patch from Yogish Baliga)
  • Used excellent patch from Per Andreas Buer to tidy up the top display
    • Shows most values in short form (10k rather than 10000)
    • Fixed query cache hit % calculation bugs
  • Strip port numbers from IP addresses in thread view
  • Added "I" command to get SHOW INNODB STATUS output
  • Added experimental support for reading options from [mytop] section of my.cnf or .my.cnf
  • Various other cleanup and fixes

Version 1.3 - April 17, 2003

  • Added "c" command to switch between thread view and "command summary" view
  • Command summary pulls Com_* values from SHOW STATUS
  • Fixed various bugs
  • Added regex support for filters
  • Added ability to [K]ill all threads owned by a particular user
  • Fixed query cache hit rate computation
  • Use Com_select rather than Questions to calculate Qcache ratio (only SELECT queries are cache candidates)

Version 1.2 - October 27, 2002

  • Better handle MySQL server going offline (shouldn't die with illegal division by zero errors)
  • Make Host column large enough to handle IP addresses (suggestion from Jeremy Tinley)
  • Added query cache stats

Version 1.1 - Not Released

  • Updated option handling so both --pass and --password work (suggested by Paul DuBois)
  • Noted that OS X is supported

Version 1.0 - April 27, 2002

  • Fixed cases when trying to remove domain name from display even if it's an IP address
  • Fixed formatting bugs and "use of uninitialized value" errors
  • Adjusted column widths and headings
  • Added "Now/Sec" to header (real-time queries/sec since last refresh)
  • Added 'o' key to toggle sort order
  • Changed 'h' key to 'H' for toggling header
  • Added 'h' key to filter based on hostname
  • Changed "Query Info" column to "Query or State"
  • Real-time queries/sec computed using Time::HiRes if available
  • Added 'e' key to EXPLAIN a query
  • Moved website to http://jeremy.zawodny.com/mysql/mytop/
  • Created mailing list

Version 0.9

  • Set $0 to 'mytop' to make it easier to spot
  • Included README in distribution

Version 0.8

  • Added "Queries Per Second" (qps) mode - press 'm' key
  • Distributed as a true Perl package with Makefile.PL
  • Can be installed via CPAN shell

Version 0.7

  • Basic support for Windows (screen clearing doesn't work)

Version 0.6

  • Minor code cleanup

Version 0.5

  • Fixed some field widths to handle larger values

Version 0.4

  • Added -P command-line argument (to specify port number)
  • Fixes for better output on small terminals
  • Added 'i' hotkey to toggle display of Idle (sleeping) threads
  • Other minor updates

Version 0.3

  • Updated documentation to reflect command-line arguments
  • Added support for long and short command-line arguments
  • Optional color support via Term::ANSIColor
  • Added batch mode (doesn't clear screen, outputs data once)
  • Fixed division by zero bug in key cache code
  • Implemented 'r' keystroke to reset status counters via FLUSH STATUS
  • Adapts when xterm is resized
  • Implemented 'p' keystroke to pause display
  • Implemented 'h' keystroke to toggle header
  • Implemented 'k' keystroke to kill a thread
  • Fixed various formatting bugs
  • Added more specific error messages from DBI on connect failure

Version 0.2

  • Added support for non-standard port numbers

License

GNU General Public License


Credits

Core Contributors


mytop v2.1 - Keeping a classic MySQL/MariaDB monitoring tool alive for modern database versions.

About

A fork of mytop, updated to fully support MySQL 8.0 & MariaDB 10.3 (or newer) releases

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages