From: Otto Kekäläinen Date: Sat, 13 Jul 2024 03:52:32 +0000 (-0700) Subject: mariadb (1:11.4.2-4) unstable; urgency=medium X-Git-Tag: archive/raspbian/1%11.4.2-4+rpi1^2~17 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=fa0c564357a78422c7da409862cd7de8731cc301;p=mariadb.git mariadb (1:11.4.2-4) unstable; urgency=medium * Revert move of 'mysqld_safe' to compat package to avoid breaking pdns [dgit import unpatched mariadb 1:11.4.2-4] --- fa0c564357a78422c7da409862cd7de8731cc301 diff --cc debian/README.Contributor index 000000000,000000000..be7f5fefe new file mode 100644 --- /dev/null +++ b/debian/README.Contributor @@@ -1,0 -1,0 +1,428 @@@ ++# README for Debian packaging contributors ++ ++This documentation describes how to contribute to the official Debian packages ++of MariaDB. The packaging in Debian repositories is not identical to the packaging ++in mariadb.org repositories, but whatever is in Debian repositories will eventually ++be upstreamed. ++ ++ ++## Development environment and tools ++ ++Use a recent version of Debian or Ubuntu as the environment for Debian packaging ++testing and development. Preferred environment is Debian Sid (unstable). ++ ++Install the tool used to manage and build the source: ++ ++ sudo apt-get install git-buildpackage ++ ++ ++## Getting the source ++ ++The official Debian package source is hosted on the Debian Gitlab server under ++the MariaDB/MySQL packaging team at https://salsa.debian.org/mariadb-team/. You ++are welcome to fork it and make merge requests. ++ ++To get the latest official Debian packaging source of `mariadb`, clone the ++source repository with all relevant branches (main branch `debian/latest`) to ++your local environment using _git-buildpackage_: ++ ++ gbp clone https://salsa.debian.org/mariadb-team/mariadb-server.git ++ ++If you have your own fork and SSH keys set up on Salsa, you can run: ++ ++ gbp clone git@salsa.debian.org:/mariadb-server.git ++ ++ ++The clone needs to be run only once. On later runs you can refresh your clone with ++relevant branches using: ++ ++ gbp pull --force ++ ++ ++## Building the packages ++ ++Build binaries, run testsuite and build Debian packages with: ++ ++ gbp buildpackage ++ ++On the first run git-buildpackage will complain if some of the build dependencies ++defined in debian/control are missing. Simply install those packages and run the ++build again. ++ ++A quick command to install all dependencies: ++ ++ sudo mk-build-deps -r -i debian/control -t "apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends" ++ ++If the build fails, the easiest way to clean up before a new run is ++ ++ git clean -fdx && git reset --hard ++ ++ ++### Build options ++ ++If you want to skip the mysql-test-run step (which takes a lot of time) set ++the following environment variable: ++ ++ export DEB_BUILD_OPTIONS="nocheck" ++ ++If you want to run the build in parallel on 2 CPUs and have verbose output: ++ ++ export DEB_BUILD_OPTIONS="parallel=2 verbose" ++ ++The options above can also be combined freely to get desired behavior. ++ ++ ++### Using special build environments ++ ++If you want to ensure all build dependencies are clean, you can build inside a ++Docker or sbuild (Debian tool) environment. ++ ++#### Build in Docker ++ ++First make a working directory for the build artifacts. Inside that directory ++clone the repository. Then start a Docker session using whatever Debian/Ubuntu ++image you want with the command: ++ ++ docker run -it -v ${PWD}:/build -w /build debian:sid bash ++ ++This will start a session, where you are as the root user in the path /build ++inside the Docker container. Here you can `cd` into the source directory, ++install dependencies and start the build. Note that when you exit the session, ++everything will be lost apart from the files you had inside the mounted volume ++in `/build`. ++ ++#### Build using sbuild ++ ++If you prefer sbuild, you can build with something like: ++ ++ gbp buildpackage --git-builder=sbuild -A -v -d unstable ++ ++## Creating a feature or bugfix branch ++ ++The repository layout follows the DEP-14 standard: ++https://dep-team.pages.debian.net/deps/dep14/ ++ ++All new features and also bug fixes are done only in the `debian/latest` branch. ++The release branches for Debian and Ubuntu are only used for security updates. ++ ++To prepare the Salsa pull request, create a bugfix branch from master with: ++ ++ git checkout -b bugfix/NNNNNN-example-name ++ ++After this you can develop with all the usual git commit and push commands ++until you have in your fork at Salsa the desired change and you are ready ++to open the merge request. ++ ++ ++### Notes about how to make changes in the proper way ++ ++First consider submitting your patch upstream. Upstream MariaDB makes frequent ++maintenance releases and any fix done upstream will therefore be included in ++Debian relatively quickly. You can send email to the developers mailing list ++or open a pull request at https://github.com/MariaDB/server. ++ ++Follow these instructions if your fix is about packaging in Debian specifically. ++Start by using `gitk --all` or similar tool to browse the previous changes. Try ++to follow similar pattern in your new changes. ++ ++Keep in mind that all changes must done only for files residing in the `debian/` ++sub-directory. If you need to create changes outside the `debian/` directory, ++then you need to create a patch file using the same pattern as the patches ++found in `debian/patches` and activated by a line in `debian/patches/series`. ++ ++Do not bundle in your commit any changes to `debian/changelog`. The correct ++changelog entries will be created later by the maintainer using `git-dch` in an ++automated fashion. ++ ++For an example of a patch adding commit see ++https://salsa.debian.org/mariadb-team/mariadb-server/-/commit/7972a38e ++ ++ ++# Quality assurance tips ++ ++Ensure most packaging files are formatted correctly: ++ ++ wrap-and-sort -vast ++ ++Check man pages for syntax errors: ++ ++ LC_ALL=en_US.UTF-8 MANROFFSEQ='' MANWIDTH=80 man --warnings -E UTF-8 -l -Tutf8 -Z mariadb.1 >/dev/null ++ ++Find spelling errors: ++ ++ find * -type f | xargs spellintian ++ ++ ++# Debugging tips ++ ++## Debug mariadb-test-run failures ++ ++If the test suite is failing on Launchpad or some other CI system where you ++don't have access to the build artifacts, you can extend the debian/rules file ++to print out valuable information with the commands: ++ ++ cd $(BUILDDIR)/mysql-test && find var/log/ -ls || true ++ cd $(BUILDDIR)/mysql-test && cat var/log/*.err || true ++ cd $(BUILDDIR)/mysql-test && tail -n 1000 var/log/*.log || true ++ ++The `cd` is required on every line since it is a Makefile and the actual command ++needs to run in the correct directory. Also, the `|| true` at the end ensures ++the build will complete and not abort if any of those debug steps fail. ++ ++## Debugging with gdb ++ ++If the `mariadb-test-run` fails on a `mariadbd` crash it should produce a core ++dump file, from which a full stack trace can be produced with: ++ ++ cd $(BUILDDIR)/mysql-test && gdb --batch --ex 'thr a a bt' var/log/*/mysqld.1/core || true ++ ++To attach `gdb` on a running process and get a stack trace run: ++ ++ gdb -p $(pgrep -x mariadbd) /usr/sbin/mariadbd ++ set height 0 ++ set logging file /tmp/mysqld.log ++ set logging on ++ thread apply all backtrace full ++ ++The readability of the stack traces depends on if symbols are available on the ++system. In Debian and Ubuntu all (C/C++) software is automatically built with ++debug symbols, but to save disk space they are distributed in separate packages ++(usually with `-dbg` or `-dbgsym` suffix) which users need to install in the ++rare case stack traces are needed. See the Debian and Ubuntu documentation on ++how to enable the repository that has the debug symbol packages. ++ ++* https://wiki.ubuntu.com/Debug%20Symbol%20Packages ++* https://wiki.debian.org/HowToGetABacktrace ++ ++## Debug build ++ ++A debug build can be created using the following build flags: ++ ++ -DCMAKE_BUILD_TYPE=Debug \ ++ -DMYSQL_MAINTAINER_MODE=OFF \ ++ ++The latter flag ensures a build does not stop on warnings but continues to the ++end. ++ ++A 'mariadbd' binary from a debug build can be started with argument '--debug' to ++be verbose about what is going on in the server. Debug binaries should not be ++used in production as they are slower than normal binaries. ++ ++Core dumps and stack traces can be produced on any build running with ++`--core-file --stack-trace` and *debug builds are not needed to run `gdb`*. ++ ++## Debugging a running server ++ ++Linux distros come standard with tools like `strace` and `lsof` which can also ++be used to inspect what processes are doing (no need for debug build). For ++example to see what `mariadbd` is writing to the database files can be viewed ++with: ++ ++ strace -ffp $(pgrep -x mariadbd) -e pwrite,write,fsync,fdatasync,sync,send,sendto,sendmsg ++ lsof -a -p $(pgrep -x mariadbd) | grep "/var/lib/mysql" ++ ++## Compare changes between builds ++ ++Diffoscope can be used to investigate small changes between recent builds: ++ ++ docker run --rm -t -w $(pwd) -v $(pwd):$(pwd) registry.salsa.debian.org/reproducible-builds/diffoscope --html-dir report mariadb-server-1.deb mariadb-server-2.deb ++ firefox report/index.html ++ ++## Test autopkgtest locally ++ ++If Debian CI fails (or Ubuntu CI) one might need to debug the autopkgtests ++manually. The easiest way to do it is to start a Docker container that has ++access to the packaging source directory via a local mount: ++ ++ laptop$ docker run -it -v ${PWD}:/build -w /build debian:sid bash ++ container$ apt update && apt install -y autopkgtest ++ container$ autopkgtest --no-built-binaries --shell-fail -- null ++ ++Edit the files in `debian/tests` in your favorite code editor and re-run the ++`autopkgtest -- null` until the tests are passing. When the autopkgtests work ++the container can be shut down and the valid `debian/tests` committed in git. ++ ++If you want to iterate on a single test, use `--test-name`, e.g. ++`autopkgtest --no-built-binaries --test-name=configuration-tracing -- null`. ++ ++If you don't want to use the MariaDB binaries from Debian Sid but instead build ++them from the source tree to be used in autopkgtest directly, simply omit ++`--no-built-binaries` from the `autopkgtest` command. ++ ++For more information please read: ++* https://manpages.debian.org/unstable/autopkgtest/autopkgtest.1.en.html ++* https://salsa.debian.org/ci-team/autopkgtest/-/tree/master/doc ++ ++## Debug installation/upgrade ++ ++To see what exactly the Debian maintainer scripts run, they can be made verbose with: ++ ++ export DEBIAN_SCRIPT_DEBUG=1 ++ apt install ... ++ ++The source files of the Debian maintainer scripts are not the final ones, as the ++package building stage may make changes and additions to them. To view a ++maintainer script in the final form on an installed system run: ++ ++ cat /var/lib/dpkg/info/mariadb-server.postinst ++ ++To review the my.cnf status run: ++ ++ find /etc/mysql/ -ls ++ update-alternatives --display my.cnf ++ ++## Debug apt Depends/Conflicts/Breaks ++ ++It can be quite frustrating to debug situations where `apt` (or `apt-get`) fails ++on an install or upgrade with an error message like: ++ ++ The following packages have unmet dependencies: ++ mariadb-client : Depends: mariadb-client-10.5 but 1:10.5.12 is to be installed ++ mariadb-server : Depends: mariadb-server-10.5 but 1:10.5.12 is to be installed ++ mariadb-test : Depends: mariadb-client-10.5 but 1:10.5.12 is to be installed ++ Depends: mariadb-server-10.5 but 1:10.5.12 is to be installed ++ E: Unable to correct problems, you have held broken packages. ++ ++To make apt show debug information on what it tried to resolve and how it failed ++enable debug features by addin a file in `/etc/apt/apt.conf.d/` with: ++ ++ Debug::pkgProblemResolver 1; ++ Debug::pkgDepCache::AutoInstall 1; ++ Debug::pkgDepCache::Marker 1; ++ ++>lternatively append options directly to `apt` commands: ++ ++ apt dist-upgrade -o Debug::pkgProblemResolver=1 ++ ++It can be also quite annoying to rebuild the entire package to debug small ++changes in the `debian/control` file. To have a much faster change->test->change ++cycle one can simply instruct `apt` to use a custom `Packages` file to read the ++`control` data. ++ ++First ensure `apt` forgets all repositories: ++ ++ rm /etc/apt/sources.list ++ apt clean ++ apt update ++ ++Download a Packages file for so it can be edited: ++ ++ curl -O http://ftp.debian.org/debian/dists/sid/main/binary-amd64/Packages.xz ++ unxz Packages.xz ++ cp Packages Packages.orig ++ ++Open the file in an editor, scroll down to the MariadB packages and make any ++changes you want and then test them: ++ ++ nano Packages ++ apt install --with-source ./Packages -s mariadb-server -o Debug::pkgDepCache::Marker=1 -o Debug::pkgDepCache::AutoInstall=1 -o Debug::pkgProblemResolver=1 ++ ++The example uses maximum verbosity but it is naturally not mandatory. When the ++solution has been found, compare to the original and transfer the changes into ++the actual debian/control in the MariaDB packaging: ++ ++ diff -u Packages.orig Packages ++ ++## Test install/upgrade with local package repository ++ ++Normally the fastest way to test that the built *.deb files install and upgrade ++properly is simply to run `apt` directly on them inside a container that has ++access to the .deb files via a local mount: ++ ++ laptop$ docker run -it -v ${PWD}:/build -w /build debian:sid bash ++ container$ apt update && apt install ./*.deb ++ ++Some bugs however occur only when apt does various dependency resolving and can ++only be tested with an installation from an actual apt repository. The fastest ++way to get a directory with deb files served via a local repository is to run: ++ ++ apt install apt-utils ++ apt-ftparchive packages . > Packages ++ apt-ftparchive release . > Release ++ echo 'deb [trusted=yes] file:/build/mariadb-bionic ./' >> /etc/apt/sources.list ++ apt update ++ apt install mariadb-server ++ ++The example above assumes that the .deb files are in path `/build`. ++ ++## Check Breaks/Replaces ++ ++MariaDB is not only a massive package by itself, it also has several parallel ++major releases at any given time and also other variants (MySQL, Percona Server) ++the packaging might interact with. ++ ++The standard Salsa-CI pipeline checks Breaks/Replaces for what is currently in ++the Debian repositories, but to check Breaks/Replaces across all known ++repositories one needs to run: ++ ++ docker run -it -v ${PWD}:/build -w /build debian:sid bash ++ apt update ++ apt install --yes python3-junit.xml python3-debian apt-file ++ curl -O https://salsa.debian.org/salsa-ci-team/pipeline/-/raw/master/images/scripts/check_for_missing_breaks_replaces.py ++ chmod +x check_for_missing_breaks_replaces.py ++ apt install --no-install-recommends --yes gpg gpg-agent dirmngr ca-certificates curl debian-archive-keyring ++ curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc ++ gpg --list-keys # Initialize default keyring ++ gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/mariadb.gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv-keys 871920D1991BC93C 3B4FE6ACC0B21F32 CBF8D6FD518E17E1 7638D0442B90D010 8C718D3B5072E1F5 9334A25F8507EFA5 CBCB082A1BB943DB 467B942D3A79BD29 B7B3B788A8D3785C ++ chmod 644 /etc/apt/trusted.gpg.d/mariadb.gpg ++ cat > /etc/apt/sources.list.d/mariadb.list <&2 & + +exit 0 diff --cc debian/additions/debian-start.inc.sh index 74340e784,000000000..f6929f7cc mode 100755,000000..100755 --- a/debian/additions/debian-start.inc.sh +++ b/debian/additions/debian-start.inc.sh @@@ -1,79 -1,0 +1,92 @@@ +#!/bin/bash +# +# This file is included by /etc/mysql/debian-start +# + +## Check MyISAM and Aria unclosed tables. +# - Requires the server to be up. +# - Is supposed to run silently in background. +function check_for_crashed_tables() { + set -e + set -u + + # But do it in the background to not stall the boot process. + logger -p daemon.info -i -t"$0" "Triggering myisam-recover for all MyISAM tables and aria-recover for all Aria tables" + + # Checking for $? is unreliable so the size of the output is checked. + # Some table handlers like HEAP do not support CHECK TABLE. + tempfile=$(mktemp) + + # We have to use xargs in this case, because a for loop barfs on the + # spaces in the thing to be looped over. + + # If a crashed table is encountered, the "mariadb" command will return with a status different from 0 ++ # ++ # The first query will generate lines like. ++ # select count(*) into @discard from 'mysql'.'db' ++ # The second line will load all tables without printing any actual results, ++ # but may show warnings and definitely is expected to have some error and ++ # exit code if crashed tables are encountered. ++ # ++ # Note that inside single quotes must be quoted with '\'' (to be outside of single quotes). + set +e - - LC_ALL=C $MARIADB --skip-column-names --batch -e ' - select concat('\''select count(*) into @discard from `'\'', - TABLE_SCHEMA, '\''`.`'\'', TABLE_NAME, '\''`'\'') - from information_schema.TABLES where TABLE_SCHEMA<>'\''INFORMATION_SCHEMA'\'' and TABLE_SCHEMA<>'\''PERFORMANCE_SCHEMA'\'' and ( ENGINE='\''MyISAM'\'' or ENGINE='\''Aria'\'' )' | \ - xargs -i ${MARIADB} --skip-column-names --silent --batch \ - --force -e "{}" &>"${tempfile}" ++ # The $MARIADB is intentionally used to expand into a command and arguments ++ # shellcheck disable=SC2086 ++ LC_ALL=C echo ' ++ SELECT CONCAT("select count(*) into @discard from '\''", TABLE_SCHEMA, "'\''.'\''", TABLE_NAME, "'\''") ++ FROM information_schema.TABLES WHERE TABLE_SCHEMA<>"INFORMATION_SCHEMA" AND TABLE_SCHEMA<>"PERFORMANCE_SCHEMA" ++ AND (ENGINE="MyISAM" OR ENGINE="Aria") ++ ' | ++ $MARIADB --skip-column-names --batch | ++ xargs -i $MARIADB --skip-column-names --silent --batch --force -e "{}" &> "${tempfile}" + set -e + - if [ -s "$tempfile" ]; then ++ if [ -s "$tempfile" ] ++ then + ( + /bin/echo -e "\n" \ + "Improperly closed tables are also reported if clients are accessing\n" \ - "the tables *now*. A list of current connections is below.\n"; - $MYADMIN processlist status ++ "the tables *now*. A list of current connections is below.\n"; ++ $MYADMIN processlist status + ) >> "${tempfile}" + # Check for presence as a dependency on mailx would require an MTA. - if [ -x /usr/bin/mailx ]; then - mailx -e -s"$MYCHECK_SUBJECT" $MYCHECK_RCPT < "$tempfile" ++ if [ -x /usr/bin/mailx ] ++ then ++ mailx -e -s"$MYCHECK_SUBJECT" "$MYCHECK_RCPT" < "$tempfile" + fi + (echo "$MYCHECK_SUBJECT"; cat "${tempfile}") | logger -p daemon.warn -i -t"$0" + fi + rm "${tempfile}" +} + +## Check for tables needing an upgrade. +# - Requires the server to be up. +# - Is supposed to run silently in background. +function upgrade_system_tables_if_necessary() { + set -e + set -u + - logger -p daemon.info -i -t"$0" "Upgrading MySQL tables if necessary." ++ logger -p daemon.info -i -t"$0" "Upgrading MariaDB tables if necessary." + + # Filter all "duplicate column", "duplicate key" and "unknown column" + # errors as the script is designed to be idempotent. + LC_ALL=C $MYUPGRADE \ + 2>&1 \ - | egrep -v '^(1|@had|ERROR (1051|1054|1060|1061|1146|1347|1348))' \ ++ | grep -E -v '^(1|@had|ERROR (1051|1054|1060|1061|1146|1347|1348))' \ + | logger -p daemon.warn -i -t"$0" +} + +## Check for the presence of both, root accounts with and without password. +# This might have been caused by a bug related to mysql_install_db (#418672). +function check_root_accounts() { + set -e + set -u + + logger -p daemon.info -i -t"$0" "Checking for insecure root accounts." + - ret=$( echo "SELECT count(*) FROM mysql.user WHERE user='root' and password='' and plugin in ('', 'mysql_native_password', 'mysql_old_password');" | $MARIADB --skip-column-names ) - if [ "$ret" -ne "0" ]; then ++ ret=$(echo "SELECT count(*) FROM mysql.user WHERE user='root' and password='' and plugin in ('', 'mysql_native_password', 'mysql_old_password');" | $MARIADB --skip-column-names) ++ if [ "$ret" -ne "0" ] ++ then + logger -p daemon.warn -i -t"$0" "WARNING: mysql.user contains $ret root accounts without password!" + fi +} diff --cc debian/additions/innotop/innotop index e88de5611,000000000..e0de8cce6 mode 100755,000000..100755 --- a/debian/additions/innotop/innotop +++ b/debian/additions/innotop/innotop @@@ -1,12263 -1,0 +1,12263 @@@ +#!/usr/bin/perl + +# vim: tw=160:nowrap:expandtab:tabstop=3:shiftwidth=3:softtabstop=3 + +# This program is copyright (c) 2006 Baron Schwartz, baron at xaprb dot com. +# Maintainers since 2013 : Kenny Gryp - Frédéric Descamps +# Feedback and improvements are gratefully received. +# +# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar +# systems, you can issue `man perlgpl' or `man perlartistic' to read these + +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1335 USA + +use strict; +use warnings; +use utf8; +use feature ':5.16'; +use warnings FATAL => 'all'; + +our $VERSION = '1.11.4'; + +# Find the home directory; it's different on different OSes. +our $homepath = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; + +# Configuration files +our $default_home_conf = "$homepath/.innotop/innotop.conf"; +our $default_central_conf = "/etc/innotop/innotop.conf"; +our $conf_file = ""; + +## Begin packages ## + +package DSNParser; + +use DBI; +use Data::Dumper; +$Data::Dumper::Indent = 0; +$Data::Dumper::Quotekeys = 0; +use English qw(-no_match_vars); + +use constant MKDEBUG => $ENV{MKDEBUG} || 0; + +# Defaults are built-in, but you can add/replace items by passing them as +# hashrefs of {key, desc, copy, dsn}. The desc and dsn items are optional. +# You can set properties with the prop() sub. Don't set the 'opts' property. +sub new { + my ( $class, @opts ) = @_; + my $self = { + opts => { + A => { + desc => 'Default character set', + dsn => 'charset', + copy => 1, + }, + D => { + desc => 'Database to use', + dsn => 'database', + copy => 1, + }, + F => { + desc => 'Only read default options from the given file', + dsn => 'mariadb_read_default_file', + copy => 1, + }, + h => { + desc => 'Connect to host', + dsn => 'host', + copy => 1, + }, + p => { + desc => 'Password to use when connecting', + dsn => 'password', + copy => 1, + }, + P => { + desc => 'Port number to use for connection', + dsn => 'port', + copy => 1, + }, + S => { + desc => 'Socket file to use for connection', + dsn => 'mariadb_socket', + copy => 1, + }, + u => { + desc => 'User for login if not current user', + dsn => 'user', + copy => 1, + }, + }, + }; + foreach my $opt ( @opts ) { + if (MKDEBUG) { + _d('Adding extra property ' . $opt->{key}); + } + $self->{opts}->{$opt->{key}} = { desc => $opt->{desc}, copy => $opt->{copy} }; + } + return bless $self, $class; +} + +# Recognized properties: +# * autokey: which key to treat a bareword as (typically h=host). +# * dbidriver: which DBI driver to use; assumes mysql, supports Pg. +# * required: which parts are required (hashref). +# * setvars: a list of variables to set after connecting +sub prop { + my ( $self, $prop, $value ) = @_; + if ( @_ > 2 ) { + MKDEBUG && _d("Setting $prop property"); + $self->{$prop} = $value; + } + return $self->{$prop}; +} + +sub parse { + my ( $self, $dsn, $prev, $defaults ) = @_; + if ( !$dsn ) { + MKDEBUG && _d('No DSN to parse'); + return; + } + MKDEBUG && _d("Parsing $dsn"); + $prev ||= {}; + $defaults ||= {}; + my %given_props; + my %final_props; + my %opts = %{$self->{opts}}; + my $prop_autokey = $self->prop('autokey'); + + # Parse given props + foreach my $dsn_part ( split(/,/, $dsn) ) { + if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) { + # Handle the typical DSN parts like h=host, P=3306, etc. + $given_props{$prop_key} = $prop_val; + } + elsif ( $prop_autokey ) { + # Handle barewords + MKDEBUG && _d("Interpreting $dsn_part as $prop_autokey=$dsn_part"); + $given_props{$prop_autokey} = $dsn_part; + } + else { + MKDEBUG && _d("Bad DSN part: $dsn_part"); + } + } + + # Fill in final props from given, previous, and/or default props + foreach my $key ( keys %opts ) { + MKDEBUG && _d("Finding value for $key"); + $final_props{$key} = $given_props{$key}; + if ( !defined $final_props{$key} + && defined $prev->{$key} && $opts{$key}->{copy} ) + { + $final_props{$key} = $prev->{$key}; + MKDEBUG && _d("Copying value for $key from previous DSN"); + } + if ( !defined $final_props{$key} ) { + $final_props{$key} = $defaults->{$key}; + MKDEBUG && _d("Copying value for $key from defaults"); + } + } + + # Sanity check props + foreach my $key ( keys %given_props ) { + die "Unrecognized DSN part '$key' in '$dsn'\n" + unless exists $opts{$key}; + } + if ( (my $required = $self->prop('required')) ) { + foreach my $key ( keys %$required ) { + die "Missing DSN part '$key' in '$dsn'\n" unless $final_props{$key}; + } + } + + return \%final_props; +} + +sub as_string { + my ( $self, $dsn ) = @_; + return $dsn unless ref $dsn; + return join(',', + map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) } + grep { defined $dsn->{$_} && $self->{opts}->{$_} } + sort keys %$dsn ); +} + +sub usage { + my ( $self ) = @_; + my $usage + = "DSN syntax is key=value[,key=value...] Allowable DSN keys:\n" + . " KEY COPY MEANING\n" + . " === ==== =============================================\n"; + my %opts = %{$self->{opts}}; + foreach my $key ( sort keys %opts ) { + $usage .= " $key " + . ($opts{$key}->{copy} ? 'yes ' : 'no ') + . ($opts{$key}->{desc} || '[No description]') + . "\n"; + } + if ( (my $key = $self->prop('autokey')) ) { + $usage .= " If the DSN is a bareword, the word is treated as the '$key' key.\n"; + } + return $usage; +} + +# Supports PostgreSQL via the dbidriver element of $info, but assumes MySQL by +# default. +sub get_cxn_params { + my ( $self, $info ) = @_; + my $dsn; + my %opts = %{$self->{opts}}; + my $driver = $self->prop('dbidriver') || ''; + if ( $driver eq 'Pg' ) { + $dsn = 'DBI:Pg:dbname=' . ( $info->{D} || '' ) . ';' + . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } + grep { defined $info->{$_} } + qw(h P)); + } + else { + $dsn = 'DBI:MariaDB:' . ( $info->{D} || '' ) . ';' + . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } + grep { defined $info->{$_} } + qw(F h P S A)) + . ';mariadb_read_default_group=client'; + } + MKDEBUG && _d($dsn); + return ($dsn, $info->{u}, $info->{p}); +} + + +# Fills in missing info from a DSN after successfully connecting to the server. +sub fill_in_dsn { + my ( $self, $dbh, $dsn ) = @_; + my $vars = $dbh->selectall_hashref('SHOW VARIABLES', 'Variable_name'); + my ($user, $db) = $dbh->selectrow_array('SELECT USER(), DATABASE()'); + $user =~ s/@.*//; + $dsn->{h} ||= $vars->{hostname}->{Value}; + $dsn->{S} ||= $vars->{'socket'}->{Value}; + $dsn->{P} ||= $vars->{port}->{Value}; + $dsn->{u} ||= $user; + $dsn->{D} ||= $db; +} + +sub get_dbh { + my ( $self, $cxn_string, $user, $pass, $opts ) = @_; + $opts ||= {}; + my $defaults = { + AutoCommit => 0, + RaiseError => 1, + PrintError => 0, + }; + @{$defaults}{ keys %$opts } = values %$opts; + my $dbh; + my $tries = 2; + while ( !$dbh && $tries-- ) { + eval { + MKDEBUG && _d($cxn_string, ' ', $user, ' ', $pass, ' {', + join(', ', map { "$_=>$defaults->{$_}" } keys %$defaults ), '}'); + $dbh = DBI->connect($cxn_string, $user, $pass, $defaults); + # Immediately set character set and binmode on STDOUT. + if ( my ($charset) = $cxn_string =~ m/charset=(\w+)/ ) { + my $sql = "/*!40101 SET NAMES $charset*/"; + MKDEBUG && _d("$dbh: $sql"); + $dbh->do($sql); + MKDEBUG && _d('Enabling charset for STDOUT'); + if ( $charset eq 'utf8' ) { + binmode(STDOUT, ':encoding(UTF-8)') + or die "Can't binmode(STDOUT, ':utf8'): $OS_ERROR"; + } + else { + binmode(STDOUT) or die "Can't binmode(STDOUT): $OS_ERROR"; + } + } + }; + if ( !$dbh && $EVAL_ERROR ) { + MKDEBUG && _d($EVAL_ERROR); + if ( !$tries ) { + die $EVAL_ERROR; + } + } + } + # If setvars exists and it's MySQL connection, set them + my $setvars = $self->prop('setvars'); + if ( $cxn_string =~ m/mysql/i && $setvars ) { + my $sql = "SET $setvars"; + MKDEBUG && _d("$dbh: $sql"); + eval { + $dbh->do($sql); + }; + if ( $EVAL_ERROR ) { + MKDEBUG && _d($EVAL_ERROR); + } + } + MKDEBUG && _d('DBH info: ', + $dbh, + Dumper($dbh->selectrow_hashref( + 'SELECT DATABASE(), CONNECTION_ID(), VERSION()/*!50038 , @@hostname*/')), + ' Connection info: ', ($dbh->{mariadb_hostinfo} || 'undef'), + ' Character set info: ', + Dumper($dbh->selectall_arrayref( + 'SHOW VARIABLES LIKE "character_set%"', { Slice => {}})), + ' $DBD::MariaDB::VERSION: ', $DBD::MariaDB::VERSION, + ' $DBI::VERSION: ', $DBI::VERSION, + ); + return $dbh; +} + +# Tries to figure out a hostname for the connection. +sub get_hostname { + my ( $self, $dbh ) = @_; + if ( my ($host) = ($dbh->{mariadb_hostinfo} || '') =~ m/^(\w+) via/ ) { + return $host; + } + my ( $hostname, $one ) = $dbh->selectrow_array( + 'SELECT /*!50038 @@hostname, */ 1'); + return $hostname; +} + +# Disconnects a database handle, but complains verbosely if there are any active +# children. These are usually $sth handles that haven't been finish()ed. +sub disconnect { + my ( $self, $dbh ) = @_; + MKDEBUG && $self->print_active_handles($dbh); + $dbh->disconnect; +} + +sub print_active_handles { + my ( $self, $thing, $level ) = @_; + $level ||= 0; + printf("# Active %sh: %s %s %s\n", ($thing->{Type} || 'undef'), "\t" x $level, + $thing, (($thing->{Type} || '') eq 'st' ? $thing->{Statement} || '' : '')) + or die "Cannot print: $OS_ERROR"; + foreach my $handle ( grep {defined} @{ $thing->{ChildHandles} } ) { + $self->print_active_handles( $handle, $level + 1 ); + } +} + +sub _d { + my ($package, undef, $line) = caller 0; + @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } + map { defined $_ ? $_ : 'undef' } + @_; + # Use $$ instead of $PID in case the package + # does not use English. + print "# $package:$line $$ ", @_, "\n"; +} + +1; + +package InnoDBParser; + +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; +use English qw(-no_match_vars); +use List::Util qw(max); +use POSIX qw(strftime); + +# Some common patterns +my $d = qr/(\d+)/; # Digit +my $f = qr/(\d+\.\d+)/; # Float +my $t = qr/((?:\d+ \d+)|(?:[A-Fa-f0-9]+))/; # Transaction ID +my $i = qr/((?:\d{1,3}\.){3}\d+)/; # IP address +my $n = qr/([^`\s]+)/; # MySQL object name +my $w = qr/(\w+)/; # Words +my $fl = qr/([\w\.\/]+) line $d/; # Filename and line number +my $h = qr/((?:0x)?[0-9a-f]*)/; # Hex +my $s = qr/(\d{6} .?\d:\d\d:\d\d)/; # InnoDB timestamp + +# If you update this variable, also update the SYNOPSIS in the pod. +my %innodb_section_headers = ( + "TRANSACTIONS" => "tx", + "BUFFER POOL AND MEMORY" => "bp", + "SEMAPHORES" => "sm", + "LOG" => "lg", + "ROW OPERATIONS" => "ro", + "INSERT BUFFER AND ADAPTIVE HASH INDEX" => "ib", + "FILE I/O" => "io", + "LATEST DETECTED DEADLOCK" => "dl", + "LATEST FOREIGN KEY ERROR" => "fk", + "BACKGROUND THREAD" => "bt", +); + +my %parser_for = ( + tx => \&parse_tx_section, + bp => \&parse_bp_section, + sm => \&parse_sm_section, + lg => \&parse_lg_section, + ro => \&parse_ro_section, + ib => \&parse_ib_section, + io => \&parse_io_section, + dl => \&parse_dl_section, + fk => \&parse_fk_section, +); + +my %fk_parser_for = ( + Transaction => \&parse_fk_transaction_error, + Error => \&parse_fk_bad_constraint_error, + Cannot => \&parse_fk_cant_drop_parent_error, +); + +# A thread's proc_info can be at least 98 different things I've found in the +# source. Fortunately, most of them begin with a gerunded verb. These are +# the ones that don't. +my %is_proc_info = ( + 'After create' => 1, + 'Execution of init_command' => 1, + 'FULLTEXT initialization' => 1, + 'Reopen tables' => 1, + 'Repair done' => 1, + 'Repair with keycache' => 1, + 'System lock' => 1, + 'Table lock' => 1, + 'Thread initialized' => 1, + 'User lock' => 1, + 'copy to tmp table' => 1, + 'discard_or_import_tablespace' => 1, + 'end' => 1, + 'got handler lock' => 1, + 'got old table' => 1, + 'init' => 1, + 'key cache' => 1, + 'locks' => 1, + 'malloc' => 1, + 'query end' => 1, + 'rename result table' => 1, + 'rename' => 1, + 'setup' => 1, + 'statistics' => 1, + 'status' => 1, + 'table cache' => 1, + 'update' => 1, +); + +sub new { + bless {}, shift; +} + +# Parse the status and return it. +# See srv_printf_innodb_monitor in innobase/srv/srv0srv.c +# Pass in the text to parse, whether to be in debugging mode, which sections +# to parse (hashref; if empty, parse all), and whether to parse full info from +# locks and such (probably shouldn't unless you need to). +sub parse_status_text { + my ( $self, $fulltext, $debug, $sections, $full, $mysqlversion ) = @_; + + die "I can't parse undef" unless defined $fulltext; + $fulltext =~ s/[\r\n]+/\n/g; + + $sections ||= {}; + die '$sections must be a hashref' unless ref($sections) eq 'HASH'; + + my %innodb_data = ( + got_all => 0, # Whether I was able to get the whole thing + ts => '', # Timestamp the server put on it + last_secs => 0, # Num seconds the averages are over + sections => {}, # Parsed values from each section + ); + + if ( $debug ) { + $innodb_data{'fulltext'} = $fulltext; + } + + # Get the most basic info about the status: beginning and end, and whether + # I got the whole thing (if there has been a big deadlock and there are + # too many locks to print, the output might be truncated) + + my $time_text; + if ( ($mysqlversion =~ /^5\.[67]\./) || ($mysqlversion =~ /^10|11\.[0-9]\./) ) { + ( $time_text ) = $fulltext =~ m/^([0-9-]* [0-9:]*) [0-9a-fx]* INNODB MONITOR OUTPUT/m; + $innodb_data{'ts'} = [ parse_innodb_timestamp_56( $time_text ) ]; + } else { + ( $time_text ) = $fulltext =~ m/^$s INNODB MONITOR OUTPUT$/m; + $innodb_data{'ts'} = [ parse_innodb_timestamp( $time_text ) ]; + } + + $innodb_data{'timestring'} = ts_to_string($innodb_data{'ts'}); + ( $innodb_data{'last_secs'} ) = $fulltext + =~ m/Per second averages calculated from the last $d seconds/; + + ( my $got_all ) = $fulltext =~ m/END OF INNODB MONITOR OUTPUT/; + $innodb_data{'got_all'} = $got_all || 0; + + # Split it into sections. Each section begins with + # ----- + # LABEL + # ----- + my %innodb_sections; + my @matches = $fulltext + =~ m#\n(---+)\n([A-Z /]+)\n\1\n(.*?)(?=\n(---+)\n[A-Z /]+\n\4\n|$)#gs; + while ( my ( $start, $name, $text, $end ) = splice(@matches, 0, 4) ) { + $innodb_sections{$name} = [ $text, $end ? 1 : 0 ]; + } + + # Just for sanity's sake, make sure I understand what to do with each + # section. + eval { + foreach my $section ( keys %innodb_sections ) { + my $header = $innodb_section_headers{$section}; + if ( !$header && $debug ) { + warn "Unknown section $section in $fulltext\n"; + } + + # The last section in the file is a special case, because instead of + # ending with the beginning of another section, it ends with the end of + # the file. So this section is complete if the entire file is + # complete. In different versions of InnoDB, various sections are + # last. + if ( $innodb_sections{$section}->[0] =~ s/\n---+\nEND OF INNODB.+\n=+$// ) { + $innodb_sections{$section}->[1] ||= $innodb_data{'got_all'}; + } + + if ( $header && $section ) { + $innodb_data{'sections'}->{ $header } + ->{'fulltext'} = $innodb_sections{$section}->[0]; + $innodb_data{'sections'}->{ $header } + ->{'complete'} = $innodb_sections{$section}->[1]; + } + else { + _debug( $debug, "header = " . ($header || 'undef') . ", section = " . ($section || 'undef')) if $debug; + } + } + }; + if ( $EVAL_ERROR ) { + _debug( $debug, $EVAL_ERROR); + } + + # ################################################################ + # Parse the detailed data out of the sections. + # ################################################################ + eval { + foreach my $section ( keys %parser_for ) { + if ( defined $innodb_data{'sections'}->{$section} + && (!%$sections || (defined($sections->{$section} && $sections->{$section})) )) { + $parser_for{$section}->( + $innodb_data{'sections'}->{$section}, + $innodb_data{'sections'}->{$section}->{'complete'}, + $debug, + $full, + $mysqlversion) + or delete $innodb_data{'sections'}->{$section}; + } + else { + delete $innodb_data{'sections'}->{$section}; + } + } + }; + if ( $EVAL_ERROR ) { + _debug( $debug, $EVAL_ERROR); + } + + return \%innodb_data; +} + +# Parses the status text and returns it flattened out as a single hash. +sub get_status_hash { + my ( $self, $fulltext, $debug, $sections, $full, $mysqlversion ) = @_; + + # Parse the status text... + my $innodb_status + = $self->parse_status_text($fulltext, $debug, $sections, $full, $mysqlversion ); + + # Flatten the hierarchical structure into a single list by grabbing desired + # sections from it. + return + (map { 'IB_' . $_ => $innodb_status->{$_} } qw(timestring last_secs got_all)), + (map { 'IB_bp_' . $_ => $innodb_status->{'sections'}->{'bp'}->{$_} } + qw( writes_pending buf_pool_hit_rate total_mem_alloc buf_pool_reads + awe_mem_alloc pages_modified writes_pending_lru page_creates_sec + reads_pending pages_total buf_pool_hits writes_pending_single_page + page_writes_sec pages_read pages_written page_reads_sec + writes_pending_flush_list buf_pool_size add_pool_alloc + dict_mem_alloc pages_created buf_free complete )), + (map { 'IB_tx_' . $_ => $innodb_status->{'sections'}->{'tx'}->{$_} } + qw( num_lock_structs history_list_len purge_done_for transactions + purge_undo_for is_truncated trx_id_counter complete )), + (map { 'IB_ib_' . $_ => $innodb_status->{'sections'}->{'ib'}->{$_} } + qw( hash_table_size hash_searches_s non_hash_searches_s + bufs_in_node_heap used_cells size free_list_len seg_size inserts + merged_recs merges complete )), + (map { 'IB_lg_' . $_ => $innodb_status->{'sections'}->{'lg'}->{$_} } + qw( log_ios_done pending_chkp_writes last_chkp log_ios_s + log_flushed_to log_seq_no pending_log_writes complete )), + (map { 'IB_sm_' . $_ => $innodb_status->{'sections'}->{'sm'}->{$_} } + qw( wait_array_size rw_shared_spins rw_excl_os_waits mutex_os_waits + mutex_spin_rounds mutex_spin_waits rw_excl_spins rw_shared_os_waits + waits signal_count reservation_count complete )), + (map { 'IB_ro_' . $_ => $innodb_status->{'sections'}->{'ro'}->{$_} } + qw( queries_in_queue n_reserved_extents main_thread_state + main_thread_proc_no main_thread_id read_sec del_sec upd_sec ins_sec + read_views_open num_rows_upd num_rows_ins num_rows_read + queries_inside num_rows_del complete )), + (map { 'IB_fk_' . $_ => $innodb_status->{'sections'}->{'fk'}->{$_} } + qw( trigger parent_table child_index parent_index attempted_op + child_db timestring fk_name records col_name reason txn parent_db + type child_table parent_col complete )), + (map { 'IB_io_' . $_ => $innodb_status->{'sections'}->{'io'}->{$_} } + qw( pending_buffer_pool_flushes pending_pwrites pending_preads + pending_normal_aio_reads fsyncs_s os_file_writes pending_sync_ios + reads_s flush_type avg_bytes_s pending_ibuf_aio_reads writes_s + threads os_file_reads pending_aio_writes pending_log_ios os_fsyncs + pending_log_flushes complete )), + (map { 'IB_dl_' . $_ => $innodb_status->{'sections'}->{'dl'}->{$_} } + qw( timestring rolled_back txns complete )); + +} + +sub ts_to_string { + my $parts = shift; + return sprintf('%02d-%02d-%02d %02d:%02d:%02d', @$parts); +} + +sub parse_innodb_timestamp { + my $text = shift; + if ( ! defined $text ) { + return (0, 0, 0, 0, 0, 0); + } + my ( $y, $m, $d, $h, $i, $s ) + = $text =~ m/^(\d\d)(\d\d)(\d\d) +(\d+):(\d+):(\d+)$/; + die("Can't get timestamp from $text\n") unless $y; + $y += 2000; + return ( $y, $m, $d, $h, $i, $s ); +} + +sub parse_innodb_timestamp_56 { + my $text = shift; + my ( $y, $m, $d, $h, $i, $s ) + = $text =~ m/^(\d\d\d\d)-(\d\d)-(\d\d) +(\d+):(\d+):(\d+)$/; + die("Can't get timestamp from $text\n") unless $y; + return ( $y, $m, $d, $h, $i, $s ); +} + +sub parse_fk_section { + my ( $section, $complete, $debug, $full, $mysqlversion ) = @_; + my $fulltext = $section->{'fulltext'}; + + return 0 unless $fulltext; + + my ( $ts, $type ); + if ( ($mysqlversion =~ /^5.[67]\./) || ($mysqlversion =~ /^10|11.[0-9]\./) ) { + ( $ts, $type ) = $fulltext =~ m/^([0-9-]* [0-9:]*)\s[0-9a-fx]*\s+(\w+)/m; + $section->{'ts'} = [ parse_innodb_timestamp_56( $ts ) ]; + } else { + ( $ts, $type ) = $fulltext =~ m/^$s\s+(\w+)/m; + $section->{'ts'} = [ parse_innodb_timestamp( $ts ) ]; + } + + $section->{'timestring'} = ts_to_string($section->{'ts'}); + $section->{'type'} = $type; + + # Decide which type of FK error happened, and dispatch to the right parser. + if ( $type && $fk_parser_for{$type} ) { + $fk_parser_for{$type}->( $section, $complete, $debug, $fulltext, $full ); + } + + delete $section->{'fulltext'} unless $debug; + + return 1; +} + +sub parse_fk_cant_drop_parent_error { + my ( $section, $complete, $debug, $fulltext, $full ) = @_; + + # Parse the parent/child table info out + @{$section}{ qw(attempted_op parent_db parent_table) } = $fulltext + =~ m{Cannot $w table `(.*)/(.*)`}m; + @{$section}{ qw(child_db child_table) } = $fulltext + =~ m{because it is referenced by `(.*)/(.*)`}m; + + ( $section->{'reason'} ) = $fulltext =~ m/(Cannot .*)/s; + if ( !defined $section->{reason} ) { + ( $section->{'reason'} ) = $fulltext =~ m/(Trying to add .*)/s; + } + $section->{'reason'} =~ s/\n(?:InnoDB: )?/ /gm + if $section->{'reason'}; + + # Certain data may not be present. Make them '' if not present. + map { $section->{$_} ||= "" } + qw(child_index fk_name col_name parent_col); +} + +# See dict/dict0dict.c, function dict_foreign_error_report +# I don't care much about these. There are lots of different messages, and +# they come from someone trying to create a foreign key, or similar +# statements. They aren't indicative of some transaction trying to insert, +# delete or update data. Sometimes it is possible to parse out a lot of +# information about the tables and indexes involved, but often the message +# contains the DDL string the user entered, which is way too much for this +# module to try to handle. +sub parse_fk_bad_constraint_error { + my ( $section, $complete, $debug, $fulltext, $full ) = @_; + + # Parse the parent/child table and index info out + @{$section}{ qw(child_db child_table) } = $fulltext + =~ m{Error in foreign key constraint of table (.*)/(.*):$}m; + $section->{'attempted_op'} = 'DDL'; + + # FK name, parent info... if possible. + @{$section}{ qw(fk_name col_name parent_db parent_table parent_col) } + = $fulltext + =~ m/CONSTRAINT `?$n`? FOREIGN KEY \(`?$n`?\) REFERENCES (?:`?$n`?\.)?`?$n`? \(`?$n`?\)/; + + if ( !defined($section->{'fk_name'}) ) { + # Try to parse SQL a user might have typed in a CREATE statement or such + @{$section}{ qw(col_name parent_db parent_table parent_col) } + = $fulltext + =~ m/FOREIGN\s+KEY\s*\(`?$n`?\)\s+REFERENCES\s+(?:`?$n`?\.)?`?$n`?\s*\(`?$n`?\)/i; + } + $section->{'parent_db'} ||= $section->{'child_db'}; + + # Name of the child index (index in the same table where the FK is, see + # definition of dict_foreign_struct in include/dict0mem.h, where it is + # called foreign_index, as opposed to referenced_index which is in the + # parent table. This may not be possible to find. + @{$section}{ qw(child_index) } = $fulltext + =~ m/^The index in the foreign key in table is $n$/m; + + @{$section}{ qw(reason) } = $fulltext =~ m/:\s*([^:]+)(?= Constraint:|$)/ms; + $section->{'reason'} =~ s/\s+/ /g + if $section->{'reason'}; + + # Certain data may not be present. Make them '' if not present. + map { $section->{$_} ||= "" } + qw(child_index fk_name col_name parent_table parent_col); +} + +# see source file row/row0ins.c +sub parse_fk_transaction_error { + my ( $section, $complete, $debug, $fulltext, $full ) = @_; + + # Parse the txn info out + my ( $txn ) = $fulltext + =~ m/Transaction:\n(TRANSACTION.*)\nForeign key constraint fails/s; + if ( $txn ) { + $section->{'txn'} = parse_tx_text( $txn, $complete, $debug, $full ); + } + + # Parse the parent/child table and index info out. There are two types: an + # update or a delete of a parent record leaves a child orphaned + # (row_ins_foreign_report_err), and an insert or update of a child record has + # no matching parent record (row_ins_foreign_report_add_err). + + @{$section}{ qw(reason child_db child_table) } + = $fulltext =~ m{^(Foreign key constraint fails for table `(.*?)`?[/.]`?(.*)`:)$}m; + + @{$section}{ qw(fk_name col_name parent_db parent_table parent_col) } + = $fulltext + =~ m/CONSTRAINT `$n` FOREIGN KEY \(`$n`\) REFERENCES (?:`$n`\.)?`$n` \(`$n`\)/; + $section->{'parent_db'} ||= $section->{'child_db'}; + + # Special case, which I don't know how to trigger, but see + # innobase/row/row0ins.c row_ins_check_foreign_constraint + if ( $fulltext =~ m/ibd file does not currently exist!/ ) { + my ( $attempted_op, $index, $records ) + = $fulltext =~ m/^Trying to (add to index) `$n` tuple:\n(.*))?/sm; + $section->{'child_index'} = $index; + $section->{'attempted_op'} = $attempted_op || ''; + if ( $records && $full ) { + ( $section->{'records'} ) + = parse_innodb_record_dump( $records, $complete, $debug ); + } + @{$section}{qw(parent_db parent_table)} + =~ m/^But the parent table `$n`\.`$n`$/m; + } + else { + my ( $attempted_op, $which, $index ) + = $fulltext =~ m/^Trying to ([\w ]*) in (child|parent) table, in index `$n` tuple:$/m; + if ( $which ) { + $section->{$which . '_index'} = $index; + $section->{'attempted_op'} = $attempted_op || ''; + + # Parse out the related records in the other table. + my ( $search_index, $records ); + if ( $which eq 'child' ) { + ( $search_index, $records ) = $fulltext + =~ m/^But in parent table [^,]*, in index `$n`,\nthe closest match we can find is record:\n(.*)/ms; + $section->{'parent_index'} = $search_index; + } + else { + ( $search_index, $records ) = $fulltext + =~ m/^But in child table [^,]*, in index `$n`, (?:the record is not available|there is a record:\n(.*))?/ms; + $section->{'child_index'} = $search_index; + } + if ( $records && $full ) { + $section->{'records'} + = parse_innodb_record_dump( $records, $complete, $debug ); + } + else { + $section->{'records'} = ''; + } + } + } + + # Parse out the tuple trying to be updated, deleted or inserted. + my ( $trigger ) = $fulltext =~ m/^(DATA TUPLE: \d+ fields;\n.*)$/m; + if ( $trigger ) { + $section->{'trigger'} = parse_innodb_record_dump( $trigger, $complete, $debug ); + } + + # Certain data may not be present. Make them '' if not present. + map { $section->{$_} ||= "" } + qw(child_index fk_name col_name parent_table parent_col); +} + +# There are new-style and old-style record formats. See rem/rem0rec.c +# TODO: write some tests for this +sub parse_innodb_record_dump { + my ( $dump, $complete, $debug ) = @_; + # Use bare return as recommend in page 199 of PBP + return unless $dump; + + my $result = {}; + + if ( $dump =~ m/PHYSICAL RECORD/ ) { + my $style = $dump =~ m/compact format/ ? 'new' : 'old'; + $result->{'style'} = $style; + + # This is a new-style record. + if ( $style eq 'new' ) { + @{$result}{qw( heap_no type num_fields info_bits )} + = $dump + =~ m/^(?:Record lock, heap no $d )?([A-Z ]+): n_fields $d; compact format; info bits $d$/m; + } + + # OK, it's old-style. Unfortunately there are variations here too. + elsif ( $dump =~ m/-byte offs / ) { + # Older-old style. + @{$result}{qw( heap_no type num_fields byte_offset info_bits )} + = $dump + =~ m/^(?:Record lock, heap no $d )?([A-Z ]+): n_fields $d; $d-byte offs [A-Z]+; info bits $d$/m; + if ( $dump !~ m/-byte offs TRUE/ ) { + $result->{'byte_offset'} = 0; + } + } + else { + # Newer-old style. + @{$result}{qw( heap_no type num_fields byte_offset info_bits )} + = $dump + =~ m/^(?:Record lock, heap no $d )?([A-Z ]+): n_fields $d; $d-byte offsets; info bits $d$/m; + } + + } + else { + $result->{'style'} = 'tuple'; + @{$result}{qw( type num_fields )} + = $dump =~ m/^(DATA TUPLE): $d fields;$/m; + } + + # Fill in default values for things that couldn't be parsed. + map { $result->{$_} ||= 0 } + qw(heap_no num_fields byte_offset info_bits); + map { $result->{$_} ||= '' } + qw(style type ); + + my @fields = $dump =~ m/ (\d+:.*?;?);(?=$| \d+:)/gm; + $result->{'fields'} = [ map { parse_field($_, $complete, $debug ) } @fields ]; + + return $result; +} + +# New/old-style applies here. See rem/rem0rec.c +# $text should not include the leading space or the second trailing semicolon. +sub parse_field { + my ( $text, $complete, $debug ) = @_; + + # Sample fields: + # '4: SQL NULL, size 4 ' + # '1: len 6; hex 000000005601; asc V ;' + # '6: SQL NULL' + # '5: len 30; hex 687474703a2f2f7777772e737765657477617465722e636f6d2f73746f72; asc http://www.sweetwater.com/stor;...(truncated)' + my ( $id, $nullsize, $len, $hex, $asc, $truncated ); + ( $id, $nullsize ) = $text =~ m/^$d: SQL NULL, size $d $/; + if ( !defined($id) ) { + ( $id ) = $text =~ m/^$d: SQL NULL$/; + } + if ( !defined($id) ) { + ( $id, $len, $hex, $asc, $truncated ) + = $text =~ m/^$d: len $d; hex $h; asc (.*);(\.\.\.\(truncated\))?$/; + } + + die "Could not parse this field: '$text'" unless defined $id; + return { + id => $id, + len => defined($len) ? $len : defined($nullsize) ? $nullsize : 0, + 'hex' => defined($hex) ? $hex : '', + asc => defined($asc) ? $asc : '', + trunc => $truncated ? 1 : 0, + }; + +} + +sub parse_dl_section { + my ( $dl, $complete, $debug, $full, $mysqlversion ) = @_; + return unless $dl; + my $fulltext = $dl->{'fulltext'}; + return 0 unless $fulltext; + + my ( $ts ) = $fulltext =~ m/^$s$/m; + return 0 unless $ts; + + if ( ($mysqlversion =~ /^5\.[67]\./) || ($mysqlversion =~ /^10|11\.[0-9]\./) ) { + $dl->{'ts'} = [ parse_innodb_timestamp_56( $ts ) ]; + } + else { + $dl->{'ts'} = [ parse_innodb_timestamp( $ts ) ]; + } + $dl->{'timestring'} = ts_to_string($dl->{'ts'}); + $dl->{'txns'} = {}; + + my @sections + = $fulltext + =~ m{ + ^\*{3}\s([^\n]*) # *** (1) WAITING FOR THIS... + (.*?) # Followed by anything, non-greedy + (?=(?:^\*{3})|\z) # Followed by another three stars or EOF + }gmsx; + + + # Loop through each section. There are no assumptions about how many + # there are, who holds and wants what locks, and who gets rolled back. + while ( my ($header, $body) = splice(@sections, 0, 2) ) { + my ( $txn_id, $what ) = $header =~ m/^\($d\) (.*):$/; + next unless $txn_id; + $dl->{'txns'}->{$txn_id} ||= {}; + my $txn = $dl->{'txns'}->{$txn_id}; + + if ( $what eq 'TRANSACTION' ) { + $txn->{'tx'} = parse_tx_text( $body, $complete, $debug, $full ); + } + else { + push @{$txn->{'locks'}}, parse_innodb_record_locks( $body, $complete, $debug, $full ); + } + } + + @{ $dl }{ qw(rolled_back) } + = $fulltext =~ m/^\*\*\* WE ROLL BACK TRANSACTION \($d\)$/m; + + # Make sure certain values aren't undef + map { $dl->{$_} ||= '' } qw(rolled_back); + + delete $dl->{'fulltext'} unless $debug; + return 1; +} + +sub parse_innodb_record_locks { + my ( $text, $complete, $debug, $full ) = @_; + my @result; + + foreach my $lock ( $text =~ m/(^(?:RECORD|TABLE) LOCKS?.*$)/gm ) { + my $hash = {}; + @{$hash}{ qw(lock_type space_id page_no n_bits index db table txn_id lock_mode) } + = $lock + =~ m{^(RECORD|TABLE) LOCKS? (?:space id $d page no $d n bits $d index `?$n`? of )?table `$n(?:/|`\.`)$n` trx id $t lock.mode (\S+)}m; + ( $hash->{'special'} ) + = $lock =~ m/^(?:RECORD|TABLE) .*? locks (rec but not gap|gap before rec)/m; + $hash->{'insert_intention'} + = $lock =~ m/^(?:RECORD|TABLE) .*? insert intention/m ? 1 : 0; + $hash->{'waiting'} + = $lock =~ m/^(?:RECORD|TABLE) .*? waiting/m ? 1 : 0; + + # Some things may not be in the text, so make sure they are not + # undef. + map { $hash->{$_} ||= 0 } qw(n_bits page_no space_id); + map { $hash->{$_} ||= "" } qw(index special); + push @result, $hash; + } + + return @result; +} + +sub parse_tx_text { + my ( $txn, $complete, $debug, $full ) = @_; + + my ( $txn_id, $txn_status ) + = $txn + =~ m/^(?:---)?TRANSACTION $t, ([^\n0-9,]*[^\s\d])/m; + $txn_status =~ s/,$// if $txn_status; + my ( $active_secs) + = $txn + =~ m/^[^\n]*\b$d sec\b/m; + my ( $proc_no ) + = $txn + =~ m/process no $d/m; + my ( $os_thread_id ) + = $txn + =~ m/OS thread id $d/m; + my ( $thread_status, $thread_decl_inside ) + = $txn + =~ m/(?:OS thread id \d+|\d sec)(?: ([^,]+?))?(?:, thread declared inside InnoDB $d)?$/m; + + # Parsing the line that begins 'MySQL thread id' is complicated. The only + # thing always in the line is the thread and query id. See function + # innobase_mysql_print_thd in InnoDB source file sql/ha_innodb.cc. + my ( $thread_line ) = $txn =~ m/^((?:MariaDB|MySQL) thread id .*)$/m; + my ( $mysql_thread_id, $query_id, $hostname, $ip, $user, $query_status ); + + if ( $thread_line ) { + # These parts can always be gotten. + ( $mysql_thread_id, $query_id ) = $thread_line =~ m/^(?:MariaDB|MySQL) thread id $d, .*?query id $d/m; + + # If it's a master/slave thread, "Has (read|sent) all" may be the thread's + # proc_info. In these cases, there won't be any host/ip/user info + ( $query_status ) = $thread_line =~ m/(Has (?:read|sent) all .*$)/m; + if ( defined($query_status) ) { + $user = 'system user'; + } + + # It may be the case that the query id is the last thing in the line. + elsif ( $thread_line =~ m/query id \d+ / ) { + # The IP address is the only non-word thing left, so it's the most + # useful marker for where I have to start guessing. + ( $hostname, $ip ) = $thread_line =~ m/query id \d+(?: ([A-Za-z]\S+))? $i/m; + if ( defined $ip ) { + ( $user, $query_status ) = $thread_line =~ m/$ip $w(?: (.*))?$/; + } + else { # OK, there wasn't an IP address. + # There might not be ANYTHING except the query status. + ( $query_status ) = $thread_line =~ m/query id \d+ (.*)$/; + if ( $query_status !~ m/^\w+ing/ && !exists($is_proc_info{$query_status}) ) { + # The remaining tokens are, in order: hostname, user, query_status. + # It's basically impossible to know which is which. + ( $hostname, $user, $query_status ) = $thread_line + =~ m/query id \d+(?: ([A-Za-z]\S+))?(?: $w(?: (.*))?)?$/m; + if ( ($hostname || '') eq 'Slave' ) { + $hostname = ''; + $user = 'system user'; + $query_status = "Slave has $query_status"; + } + } + else { + $user = 'system user'; + } + } + } + } + + my ( $lock_wait_status, $lock_structs, $heap_size, $row_locks, $undo_log_entries ) + = $txn + =~ m/^(?:(\D*) )?$d lock struct\(s\), heap size $d(?:, $d row lock\(s\))?(?:, undo log entries $d)?$/m; + my ( $lock_wait_time ) + = $txn + =~ m/^------- TRX HAS BEEN WAITING $d SEC/m; + + my $locks; + # If the transaction has locks, grab the locks. + if ( $txn =~ m/^TABLE LOCK|RECORD LOCKS/ ) { + $locks = [parse_innodb_record_locks($txn, $complete, $debug, $full)]; + } + + my ( $tables_in_use, $tables_locked ) + = $txn + =~ m/^mysql tables in use $d, locked $d$/m; + my ( $txn_doesnt_see_ge, $txn_sees_lt ) + = $txn + =~ m/^Trx read view will not see trx with id >= $t, sees < $t$/m; + my $has_read_view = defined($txn_doesnt_see_ge); + # Only a certain number of bytes of the query text are included here, at least + # under some circumstances. Some versions include 300, some 600. + my ( $query_text ) + = $txn + =~ m{ + ^MySQL\sthread\sid\s[^\n]+\n # This comes before the query text + (.*?) # The query text + (?= # Followed by any of... + ^Trx\sread\sview + |^-------\sTRX\sHAS\sBEEN\sWAITING + |^TABLE\sLOCK + |^RECORD\sLOCKS\sspace\sid + |^(?:---)?TRANSACTION + |^\*\*\*\s\(\d\) + |\Z + ) + }xms; + if ( $query_text ) { + $query_text =~ s/\s+$//; + } + else { + $query_text = ''; + } + + my %stuff = ( + active_secs => $active_secs, + has_read_view => $has_read_view, + heap_size => $heap_size, + hostname => $hostname, + ip => $ip, + lock_structs => $lock_structs, + lock_wait_status => $lock_wait_status, + lock_wait_time => $lock_wait_time, + mysql_thread_id => $mysql_thread_id, + os_thread_id => $os_thread_id, + proc_no => $proc_no, + query_id => $query_id, + query_status => $query_status, + query_text => $query_text, + row_locks => $row_locks, + tables_in_use => $tables_in_use, + tables_locked => $tables_locked, + thread_decl_inside => $thread_decl_inside, + thread_status => $thread_status, + txn_doesnt_see_ge => $txn_doesnt_see_ge, + txn_id => $txn_id, + txn_sees_lt => $txn_sees_lt, + txn_status => $txn_status, + undo_log_entries => $undo_log_entries, + user => $user, + ); + $stuff{'fulltext'} = $txn if $debug; + $stuff{'locks'} = $locks if $locks; + + # Some things may not be in the txn text, so make sure they are not + # undef. + map { $stuff{$_} ||= 0 } qw(active_secs heap_size lock_structs + tables_in_use undo_log_entries tables_locked has_read_view + thread_decl_inside lock_wait_time proc_no row_locks); + map { $stuff{$_} ||= "" } qw(thread_status txn_doesnt_see_ge + txn_sees_lt query_status ip query_text lock_wait_status user); + $stuff{'hostname'} ||= $stuff{'ip'}; + + return \%stuff; +} + +sub parse_tx_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + $section->{'transactions'} = []; + + # Handle the individual transactions + my @transactions = $fulltext =~ m/(---TRANSACTION [0-9A-Fa-f].*?)(?=\n---TRANSACTION|$)/gs; + foreach my $txn ( @transactions ) { + my $stuff = parse_tx_text( $txn, $complete, $debug, $full ); + delete $stuff->{'fulltext'} unless $debug; + push @{$section->{'transactions'}}, $stuff; + } + + # Handle the general info + @{$section}{ 'trx_id_counter' } + = $fulltext =~ m/^Trx id counter $t$/m; + @{$section}{ 'purge_done_for', 'purge_undo_for' } + = $fulltext =~ m/^Purge done for trx's n:o < $t undo n:o < $t$/m; + @{$section}{ 'history_list_len' } # This isn't present in some 4.x versions + = $fulltext =~ m/^History list length $d$/m; + @{$section}{ 'num_lock_structs' } + = $fulltext =~ m/^Total number of lock structs in row lock hash table $d$/m; + @{$section}{ 'is_truncated' } + = $fulltext =~ m/^\.\.\. truncated\.\.\.$/m ? 1 : 0; + + # Fill in things that might not be present + foreach ( qw(history_list_len) ) { + $section->{$_} ||= 0; + } + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +# I've read the source for this section. +sub parse_ro_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + + # Grab the info + @{$section}{ 'queries_inside', 'queries_in_queue' } + = $fulltext =~ m/^$d queries inside InnoDB, $d queries in queue$/m; + ( $section->{ 'read_views_open' } ) + = $fulltext =~ m/^$d read views open inside InnoDB$/m; + ( $section->{ 'n_reserved_extents' } ) + = $fulltext =~ m/^$d tablespace extents now reserved for B-tree/m; + @{$section}{ 'main_thread_proc_no', 'main_thread_id', 'main_thread_state' } + = $fulltext =~ m/^Main thread (?:process no. $d, )?id $d, state: (.*)$/m; + @{$section}{ 'num_rows_ins', 'num_rows_upd', 'num_rows_del', 'num_rows_read' } + = $fulltext =~ m/^Number of rows inserted $d, updated $d, deleted $d, read $d$/m; + @{$section}{ 'ins_sec', 'upd_sec', 'del_sec', 'read_sec' } + = $fulltext =~ m#^$f inserts/s, $f updates/s, $f deletes/s, $f reads/s$#m; + $section->{'main_thread_proc_no'} ||= 0; + + map { $section->{$_} ||= 0 } qw(read_views_open n_reserved_extents); + delete $section->{'fulltext'} unless $debug; + return 1; +} + +sub parse_lg_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section; + my $fulltext = $section->{'fulltext'}; + + # Grab the info + ( $section->{ 'log_seq_no' } ) + = $fulltext =~ m/Log sequence number \s*(\d.*)$/m; + ( $section->{ 'log_flushed_to' } ) + = $fulltext =~ m/Log flushed up to \s*(\d.*)$/m; + ( $section->{ 'last_chkp' } ) + = $fulltext =~ m/Last checkpoint at \s*(\d.*)$/m; + @{$section}{ 'pending_log_writes', 'pending_chkp_writes' } + = $fulltext =~ m/$d pending log (?:writes|flushes), $d pending chkp writes/; + @{$section}{ 'log_ios_done', 'log_ios_s' } + = $fulltext =~ m#$d log i/o's done, $f log i/o's/second#; + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +sub parse_ib_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + + # Some servers will output ibuf information for tablespace 0, as though there + # might be many tablespaces with insert buffers. (In practice I believe + # the source code shows there will only ever be one). I have to parse both + # cases here, but I assume there will only be one. + @{$section}{ 'size', 'free_list_len', 'seg_size' } + = $fulltext =~ m/^Ibuf(?: for space 0)?: size $d, free list len $d, seg size $d/m; + @{$section}{ 'inserts', 'merged_recs', 'merges' } + = $fulltext =~ m/^$d inserts, $d merged recs, $d merges$/m; + if ( ! defined $section->{inserts} ) { + @{$section}{ 'inserts' } + = $fulltext =~ m/merged operations:\n insert $d,/s; + # This isn't really true, but it's not really important either. We already + # aren't supporting the 'delete' operations. + @{$section}{ 'merged_recs', 'merges' } = (0, 0); + } + + @{$section}{ 'hash_table_size', 'used_cells', 'bufs_in_node_heap' } + = $fulltext =~ m/^Hash table size $d(?:, used cells $d)?, node heap has $d buffer\(s\)$/m; + @{$section}{ 'hash_searches_s', 'non_hash_searches_s' } + = $fulltext =~ m{^$f hash searches/s, $f non-hash searches/s$}m; + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +sub parse_wait_array { + my ( $text, $complete, $debug, $full ) = @_; + my %result; + + @result{ qw(thread waited_at_filename waited_at_line waited_secs) } + = $text =~ m/^--Thread $d has waited at $fl for $f seconds/m; + + # Depending on whether it's a SYNC_MUTEX,RW_LOCK_EX,RW_LOCK_SHARED, + # there will be different text output + if ( $text =~ m/^Mutex at/m ) { + $result{'request_type'} = 'M'; + @result{ qw( lock_mem_addr lock_cfile_name lock_cline lock_var) } + = $text =~ m/^Mutex at $h created file $fl, lock var $d$/m; + @result{ qw( waiters_flag )} + = $text =~ m/^waiters flag $d$/m; + } + else { + @result{ qw( request_type lock_mem_addr lock_cfile_name lock_cline) } + = $text =~ m/^(.)-lock on RW-latch at $h created in file $fl$/m; + @result{ qw( writer_thread writer_lock_mode ) } + = $text =~ m/^a writer \(thread id $d\) has reserved it in mode (.*)$/m; + @result{ qw( num_readers waiters_flag )} + = $text =~ m/^number of readers $d, waiters flag $d$/m; + @result{ qw(last_s_file_name last_s_line ) } + = $text =~ m/Last time read locked in file $fl$/m; + @result{ qw(last_x_file_name last_x_line ) } + = $text =~ m/Last time write locked in file $fl$/m; + } + + $result{'cell_waiting'} = $text =~ m/^wait has ended$/m ? 0 : 1; + $result{'cell_event_set'} = $text =~ m/^wait is ending$/m ? 1 : 0; + + # Because there are two code paths, some things won't get set. + map { $result{$_} ||= '' } + qw(last_s_file_name last_x_file_name writer_lock_mode); + map { $result{$_} ||= 0 } + qw(num_readers lock_var last_s_line last_x_line writer_thread); + + return \%result; +} + +sub parse_sm_section { + my ( $section, $complete, $debug, $full ) = @_; + return 0 unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + + # Grab the info + @{$section}{ 'reservation_count', 'signal_count' } + = $fulltext =~ m/^OS WAIT ARRAY INFO: reservation count $d, signal count $d$/m; + @{$section}{ 'mutex_spin_waits', 'mutex_spin_rounds', 'mutex_os_waits' } + = $fulltext =~ m/^Mutex spin waits $d, rounds $d, OS waits $d$/m; + @{$section}{ 'rw_shared_spins', 'rw_shared_os_waits', 'rw_excl_spins', 'rw_excl_os_waits' } + = $fulltext =~ m/^RW-shared spins $d, OS waits $d; RW-excl spins $d, OS waits $d$/m; + if ( ! defined $section->{rw_shared_spins} ) { + @{$section}{ 'rw_shared_spins', 'rw_shared_os_waits'} + = $fulltext =~ m/^RW-shared spins $d, rounds \d+, OS waits $d$/m; + @{$section}{ 'rw_excl_spins', 'rw_excl_os_waits' } + = $fulltext =~ m/^RW-excl spins $d, rounds \d+, OS waits $d$/m; + } + + # Look for info on waits. + my @waits = $fulltext =~ m/^(--Thread.*?)^(?=Mutex spin|--Thread)/gms; + $section->{'waits'} = [ map { parse_wait_array($_, $complete, $debug) } @waits ]; + $section->{'wait_array_size'} = scalar(@waits); + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +# I've read the source for this section. +sub parse_bp_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + + # Grab the info + @{$section}{ 'total_mem_alloc', 'add_pool_alloc' } + = $fulltext =~ m/^Total memory allocated $d; in additional pool allocated $d$/m; + @{$section}{'dict_mem_alloc'} = $fulltext =~ m/Dictionary memory allocated $d/; + @{$section}{'awe_mem_alloc'} = $fulltext =~ m/$d MB of AWE memory/; + @{$section}{'buf_pool_size'} = $fulltext =~ m/^Buffer pool size\s*$d$/m; + @{$section}{'buf_free'} = $fulltext =~ m/^Free buffers\s*$d$/m; + @{$section}{'pages_total'} = $fulltext =~ m/^Database pages\s*$d$/m; + @{$section}{'pages_modified'} = $fulltext =~ m/^Modified db pages\s*$d$/m; + @{$section}{'pages_read', 'pages_created', 'pages_written'} + = $fulltext =~ m/^Pages read $d, created $d, written $d$/m; + @{$section}{'page_reads_sec', 'page_creates_sec', 'page_writes_sec'} + = $fulltext =~ m{^$f reads/s, $f creates/s, $f writes/s$}m; + @{$section}{'buf_pool_hits', 'buf_pool_reads'} + = $fulltext =~ m{Buffer pool hit rate $d / $d}m; + if ($fulltext =~ m/^No buffer pool page gets since the last printout$/m) { + @{$section}{'buf_pool_hits', 'buf_pool_reads'} = (0, 0); + @{$section}{'buf_pool_hit_rate'} = '--'; + } + else { + @{$section}{'buf_pool_hit_rate'} + = $fulltext =~ m{Buffer pool hit rate (\d+ / \d+)}m; + } + @{$section}{'reads_pending'} = $fulltext =~ m/^Pending reads $d/m; + @{$section}{'writes_pending_lru', 'writes_pending_flush_list', 'writes_pending_single_page' } + = $fulltext =~ m/^Pending writes: LRU $d, flush list $d, single page $d$/m; + + map { $section->{$_} ||= 0 } + qw(writes_pending_lru writes_pending_flush_list writes_pending_single_page + awe_mem_alloc dict_mem_alloc); + @{$section}{'writes_pending'} = List::Util::sum( + @{$section}{ qw(writes_pending_lru writes_pending_flush_list writes_pending_single_page) }); + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +# I've read the source for this. +sub parse_io_section { + my ( $section, $complete, $debug, $full ) = @_; + return unless $section && $section->{'fulltext'}; + my $fulltext = $section->{'fulltext'}; + $section->{'threads'} = {}; + + # Grab the I/O thread info + my @threads = $fulltext =~ m<^(I/O thread \d+ .*)$>gm; + foreach my $thread (@threads) { + my ( $tid, $state, $purpose, $event_set ) + = $thread =~ m{I/O thread $d state: (.+?) \((.*)\)(?: ev set)?$}m; + if ( defined $tid ) { + $section->{'threads'}->{$tid} = { + thread => $tid, + state => $state, + purpose => $purpose, + event_set => $event_set ? 1 : 0, + }; + } + } + + # Grab the reads/writes/flushes info + @{$section}{ 'pending_normal_aio_reads', 'pending_aio_writes' } + = $fulltext =~ m/^Pending normal aio reads: $d(?: [^\]]*\])?, aio writes: $d/m; + @{$section}{ 'pending_ibuf_aio_reads', 'pending_log_ios', 'pending_sync_ios' } + = $fulltext =~ m{^ ibuf aio reads: $d, log i/o's: $d, sync i/o's: $d$}m; + @{$section}{ 'flush_type', 'pending_log_flushes', 'pending_buffer_pool_flushes' } + = $fulltext =~ m/^Pending flushes \($w\) log: $d; buffer pool: $d$/m; + @{$section}{ 'os_file_reads', 'os_file_writes', 'os_fsyncs' } + = $fulltext =~ m/^$d OS file reads, $d OS file writes, $d OS fsyncs$/m; + @{$section}{ 'reads_s', 'avg_bytes_s', 'writes_s', 'fsyncs_s' } + = $fulltext =~ m{^$f reads/s, $d avg bytes/read, $f writes/s, $f fsyncs/s$}m; + @{$section}{ 'pending_preads', 'pending_pwrites' } + = $fulltext =~ m/$d pending preads, $d pending pwrites$/m; + @{$section}{ 'pending_preads', 'pending_pwrites' } = (0, 0) + unless defined($section->{'pending_preads'}); + + delete $section->{'fulltext'} unless $debug; + return 1; +} + +sub _debug { + my ( $debug, $msg ) = @_; + if ( $debug ) { + die $msg; + } + else { + warn $msg; + } + return 1; +} + +1; + +# end_of_package InnoDBParser + +package main; + +use sigtrap qw(handler finish untrapped normal-signals); + +use Data::Dumper; +use DBI; +use English qw(-no_match_vars); +use File::Basename qw(dirname); +use File::Temp; +use Getopt::Long; +use List::Util qw(max min maxstr sum); +use POSIX qw(ceil); +use Time::HiRes qw(time sleep); +use Term::ReadKey qw(ReadMode ReadKey); + +# License and warranty information. {{{1 +# ########################################################################### + +my $innotop_license = <<"LICENSE"; + +This is innotop version $VERSION, a MySQL and InnoDB monitor. + +This program is copyright (c) 2006 Baron Schwartz. +Feedback and improvements are welcome. + +THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, version 2; OR the Perl Artistic License. On UNIX and similar +systems, you can issue `man perlgpl' or `man perlartistic' to read these +licenses. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1335 USA. +LICENSE + +# Configuration information and global setup {{{1 +# ########################################################################### + +# Really, really, super-global variables. +my @config_versions = ( + "000-000-000", "001-003-000", # config file was one big name-value hash. + "001-003-000", "001-004-002", # config file contained non-user-defined stuff. +); + +my $clear_screen_sub; +my $dsn_parser = new DSNParser(); + +# This defines expected properties and defaults for the column definitions that +# eventually end up in tbl_meta. +my %col_props = ( + hdr => '', + just => '-', + dec => 0, # Whether to align the column on the decimal point + num => 0, + label => '', + user => 0, + src => '', + tbl => '', # Helps when writing/reading custom columns in config files + minw => 0, + maxw => 0, + trans => [], + agg => 'first', # Aggregate function + aggonly => 0, # Whether to show only when tbl_meta->{aggregate} is true + agghide => 0, # Whether NOT to show when tbl_meta->{aggregate} is true +); + +# Actual DBI connections to MySQL servers. +my %dbhs; + +# Command-line parameters {{{2 +# ########################################################################### + +my @opt_spec = ( + { s => 'help', d => 'Show this help message' }, + { s => 'color|C!', d => 'Use terminal coloring (default)', c => 'color' }, + { s => 'config|c=s', d => 'Config file to read' }, + { s => 'nonint|n', d => 'Non-interactive, output tab-separated fields' }, + { s => 'count=i', d => 'Number of updates before exiting' }, + { s => 'delay|d=f', d => 'Delay between updates in seconds', c => 'interval' }, + { s => 'mode|m=s', d => 'Operating mode to start in', c => 'mode' }, + { s => 'inc|i!', d => 'Measure incremental differences', c => 'status_inc' }, + { s => 'spark=i', d => 'Length of status sparkline (default 10)', c=> 'spark' }, + { s => 'write|w', d => 'Write running configuration into home directory if no config files were loaded' }, + { s => 'skipcentral|s', d => 'Skip reading the central configuration file' }, + { s => 'version', d => 'Output version information and exit' }, + { s => 'user|u=s', d => 'User for login if not current user' }, + { s => 'password|p=s', d => 'Password to use for connection' }, + { s => 'askpass', d => 'Prompt for a password when connecting to MySQL'}, + { s => 'host|h=s', d => 'Connect to host' }, + { s => 'port|P=i', d => 'Port number to use for connection' }, + { s => 'socket|S=s', d => 'MySQL socket to use for connection' }, + { s => 'timestamp|t+', d => 'Print timestamp in -n mode (1: per iter; 2: per line)' }, +); + +# This is the container for the command-line options' values to be stored in +# after processing. Initial values are defaults. +my %opts = ( + n => !( -t STDIN && -t STDOUT ), # If in/out aren't to terminals, we're interactive +); +# Post-process... +my %opt_seen; +foreach my $spec ( @opt_spec ) { + my ( $long, $short ) = $spec->{s} =~ m/^(\w+)(?:\|([^!+=:]*))?/; + $spec->{k} = $short || $long; + $spec->{l} = $long; + $spec->{t} = $short; + $spec->{n} = $spec->{s} =~ m/!/; + $opts{$spec->{k}} = undef unless defined $opts{$spec->{k}}; + die "Duplicate option $spec->{k}" if $opt_seen{$spec->{k}}++; +} + +Getopt::Long::Configure('no_ignore_case', 'bundling'); +GetOptions( map { $_->{s} => \$opts{$_->{k}} } @opt_spec) or $opts{help} = 1; + +if ( $opts{version} ) { + print "innotop Ver $VERSION\n"; + exit(0); +} + +if ( $opts{c} and ! -f $opts{c} ) { + print $opts{c} . " doesn't exist. Exiting.\n"; + exit(1); +} + +if ( $opts{'askpass'} ) { + $opts{'p'} = noecho_password("Enter password "); +} + +if ( $opts{'help'} ) { + print "Usage: innotop \n\n"; + my $maxw = max(map { length($_->{l}) + ($_->{n} ? 4 : 0)} @opt_spec); + foreach my $spec ( sort { $a->{l} cmp $b->{l} } @opt_spec ) { + my $long = $spec->{n} ? "[no]$spec->{l}" : $spec->{l}; + my $short = $spec->{t} ? "-$spec->{t}" : ''; + printf(" --%-${maxw}s %-4s %s\n", $long, $short, $spec->{d}); + } + print <; + chomp($opts{p}); + ReadMode('normal'); +} + +# Meta-data (table definitions etc) {{{2 +# ########################################################################### + +# Expressions {{{3 +# Convenience so I can copy/paste these in several places... +# ########################################################################### +my %exprs = ( + Host => q{my $host = host || hostname || ''; ($host) = $host =~ m/^((?:[\d.]+(?=:|$))|(?:[a-z0-9-]+))/i; return $host || ''}, + Port => q{my ($p) = host =~ m/:(.*)$/; return $p || 0}, + OldVersions => q{dulint_to_int(IB_tx_trx_id_counter) - dulint_to_int(IB_tx_purge_done_for)}, + MaxTxnTime => q/max(map{ $_->{active_secs} } @{ IB_tx_transactions }) || 0/, + NumTxns => q{scalar @{ IB_tx_transactions } }, + DirtyBufs => q{ $cur->{IB_bp_pages_modified} / ($cur->{IB_bp_buf_pool_size} || 1) }, + BufPoolFill => q{ $cur->{IB_bp_pages_total} / ($cur->{IB_bp_buf_pool_size} || 1) }, + ServerLoad => q{ $cur->{Threads_connected}/(Questions||1)/Uptime_hires }, + Connection => q{ max_connections || $cur->{Threads_connected} }, + chcxn_2_cxn => q{ if ( defined($cur->{cxn}) ) { return $cur->{cxn}; } else { my ($cha, $conn) = split ("=",$cur->{chcxn}) ; return $conn; } }, + chcxn_2_ch => q{ if ( defined($cur->{channel_name}) ) { return $cur->{channel_name}; } else { my ($cha, $conn) = split ("=",$cur->{chcxn}) ; $cha = '' if ($cha = /no_channels/); return $cha || 'failed'; } }, + TxnTimeRemain => q{ defined undo_log_entries && defined $pre->{undo_log_entries} && undo_log_entries < $pre->{undo_log_entries} ? undo_log_entries / (($pre->{undo_log_entries} - undo_log_entries)/((active_secs-$pre->{active_secs})||1))||1 : 0}, + SlaveCatchupRate => ' defined $cur->{seconds_behind_master} && defined $pre->{seconds_behind_master} && $cur->{seconds_behind_master} < $pre->{seconds_behind_master} ? ($pre->{seconds_behind_master}-$cur->{seconds_behind_master})/($cur->{Uptime_hires}-$pre->{Uptime_hires}) : 0', + QcacheHitRatio => q{(Qcache_hits||0)/(((Com_select||0)+(Qcache_hits||0))||1)}, + QueryDetail => q{sprintf("%2d/%2d/%2d/%2d", + ((Com_select||0)+(Qcache_hits||0))/(Questions||1)*100, + ((Com_insert||0)+(Com_replace||0))/(Questions||1)*100, + (Com_update||0)/(Questions||1)*100, + (Com_delete||0)/(Questions||1)*100, +)}, +); + +# ########################################################################### +# Column definitions {{{3 +# Defines every column in every table. A named column has the following +# properties: +# * hdr Column header/title +# * label Documentation for humans. +# * num Whether it's numeric (for sorting). +# * just Alignment; generated from num, user-overridable in tbl_meta +# * minw, maxw Auto-generated, user-overridable. +# Values from this hash are just copied to tbl_meta, which is where everything +# else in the program should read from. +# ########################################################################### + +my %columns = ( + active_secs => { hdr => 'SecsActive', num => 1, label => 'Seconds transaction has been active', }, + add_pool_alloc => { hdr => 'Add\'l Pool', num => 1, label => 'Additional pool allocated' }, + attempted_op => { hdr => 'Action', num => 0, label => 'The action that caused the error' }, + awe_mem_alloc => { hdr => 'AWE Memory', num => 1, label => '[Windows] AWE memory allocated' }, + binlog_cache_overflow => { hdr => 'Binlog Cache', num => 1, label => 'Transactions too big for binlog cache that went to disk' }, + binlog_do_db => { hdr => 'Binlog Do DB', num => 0, label => 'binlog-do-db setting' }, + binlog_ignore_db => { hdr => 'Binlog Ignore DB', num => 0, label => 'binlog-ignore-db setting' }, + blocking_thread => { hdr => 'BThread', num => 1, label => 'Blocking thread' }, + blocking_query => { hdr => 'Blocking Query', num => 0, label => 'Blocking query' }, + blocking_rows_modified => { hdr => 'BRowsMod', num => 1, label => 'Blocking number rows modified' }, + blocking_age => { hdr => 'BAge', num => 1, label => 'Blocking age' }, + blocking_wait_secs => { hdr => 'BWait', num => 1, label => 'Blocking wait time' }, + blocking_user => { hdr => 'BUser', num => 0, label => 'Blocking user' }, + blocking_host => { hdr => 'BHost', num => 0, label => 'Blocking host' }, + blocking_db => { hdr => 'BDB', num => 0, label => 'Blocking database' }, + blocking_status => { hdr => 'BStatus', num => 0, label => 'Blocking thread status' }, + bps_in => { hdr => 'BpsIn', num => 1, label => 'Bytes per second received by the server', }, + bps_out => { hdr => 'BpsOut', num => 1, label => 'Bytes per second sent by the server', }, + buf_free => { hdr => 'Free Bufs', num => 1, label => 'Buffers free in the buffer pool' }, + buf_pool_hit_rate => { hdr => 'Hit Rate', num => 0, label => 'Buffer pool hit rate' }, + buf_pool_hits => { hdr => 'Hits', num => 1, label => 'Buffer pool hits' }, + buf_pool_reads => { hdr => 'Reads', num => 1, label => 'Buffer pool reads' }, + buf_pool_size => { hdr => 'Size', num => 1, label => 'Buffer pool size' }, + bufs_in_node_heap => { hdr => 'Node Heap Bufs', num => 1, label => 'Buffers in buffer pool node heap' }, + bytes_behind_master => { hdr => 'ByteLag', num => 1, label => 'Bytes the slave lags the master in binlog' }, + cell_event_set => { hdr => 'Ending?', num => 1, label => 'Whether the cell event is set' }, + cell_waiting => { hdr => 'Waiting?', num => 1, label => 'Whether the cell is waiting' }, + channel_name => { hdr => 'Channel', num => 0, label => 'The name of the replication channel' }, + child_db => { hdr => 'Child DB', num => 0, label => 'The database of the child table' }, + child_index => { hdr => 'Child Index', num => 0, label => 'The index in the child table' }, + child_table => { hdr => 'Child Table', num => 0, label => 'The child table' }, + cmd => { hdr => 'Cmd', num => 0, label => 'Type of command being executed', }, + cnt => { hdr => 'Cnt', num => 0, label => 'Count', agg => 'count', aggonly => 1 }, + connections => { hdr => 'Cxns', num => 1, label => 'Connections' }, + connect_retry => { hdr => 'Connect Retry', num => 1, label => 'Slave connect-retry timeout' }, + cxn => { hdr => 'CXN', num => 0, label => 'Connection from which the data came', }, + db => { hdr => 'DB', num => 0, label => 'Current database', }, + dict_mem_alloc => { hdr => 'Dict Mem', num => 1, label => 'Dictionary memory allocated' }, + dirty_bufs => { hdr => 'Dirty Buf', num => 1, label => 'Dirty buffer pool pages' }, + dl_txn_num => { hdr => 'Num', num => 0, label => 'Deadlocked transaction number', }, + event_set => { hdr => 'Evt Set?', num => 1, label => '[Win32] if a wait event is set', }, + exec_master_log_pos => { hdr => 'Exec Master Log Pos', num => 1, label => 'Exec Master Log Position' }, + executed_gtid_set => { hdr => 'Executed GTID Set', num => 0, label => 'Executed GTID Set', }, + fk_name => { hdr => 'Constraint', num => 0, label => 'The name of the FK constraint' }, + free_list_len => { hdr => 'Free List Len', num => 1, label => 'Length of the free list' }, + has_read_view => { hdr => 'Rd View', num => 1, label => 'Whether the transaction has a read view' }, + hash_searches_s => { hdr => 'Hash/Sec', num => 1, label => 'Number of hash searches/sec' }, + hash_table_size => { hdr => 'Size', num => 1, label => 'Number of non-hash searches/sec' }, + heap_no => { hdr => 'Heap', num => 1, label => 'Heap number' }, + heap_size => { hdr => 'Heap', num => 1, label => 'Heap size' }, + history_list_len => { hdr => 'History', num => 1, label => 'History list length' }, + host_and_domain => { hdr => 'Host', num => 0, label => 'Hostname/IP and domain' }, + host_and_port => { hdr => 'Host/IP', num => 0, label => 'Hostname or IP address, and port number', }, + hostname => { hdr => 'Host', num => 0, label => 'Hostname' }, + index => { hdr => 'Index', num => 0, label => 'The index involved', agghide => 1 }, + index_ref => { hdr => 'Index Ref', num => 0, label => 'Index referenced' }, + info => { hdr => 'Query', num => 0, label => 'Info or the current query', }, + insert_intention => { hdr => 'Ins Intent', num => 1, label => 'Whether the thread was trying to insert' }, + inserts => { hdr => 'Inserts', num => 1, label => 'Inserts' }, + io_bytes_s => { hdr => 'Bytes/Sec', num => 1, label => 'Average I/O bytes/sec' }, + io_flush_type => { hdr => 'Flush Type', num => 0, label => 'I/O Flush Type' }, + io_fsyncs_s => { hdr => 'fsyncs/sec', num => 1, label => 'I/O fsyncs/sec' }, + io_reads_s => { hdr => 'Reads/Sec', num => 1, label => 'Average I/O reads/sec' }, + io_writes_s => { hdr => 'Writes/Sec', num => 1, label => 'Average I/O writes/sec' }, + ip => { hdr => 'IP', num => 0, label => 'IP address' }, + is_name_locked => { hdr => 'Locked', num => 1, label => 'Whether table is name locked', }, + key_buffer_hit => { hdr => 'KCacheHit', num => 1, label => 'Key cache hit ratio', }, + key_len => { hdr => 'Key Length', num => 1, label => 'Number of bytes used in the key' }, + last_chkp => { hdr => 'Last Checkpoint', num => 0, label => 'Last log checkpoint' }, + last_errno => { hdr => 'Last Errno', num => 1, label => 'Last error number' }, + last_error => { hdr => 'Last Error', num => 0, label => 'Last error' }, + last_s_file_name => { hdr => 'S-File', num => 0, label => 'Filename where last read locked' }, + last_s_line => { hdr => 'S-Line', num => 1, label => 'Line where last read locked' }, + last_x_file_name => { hdr => 'X-File', num => 0, label => 'Filename where last write locked' }, + last_x_line => { hdr => 'X-Line', num => 1, label => 'Line where last write locked' }, + last_pct => { hdr => 'Pct', num => 1, label => 'Last Percentage' }, + last_total => { hdr => 'Last Total', num => 1, label => 'Last Total' }, + last_value => { hdr => 'Last Incr', num => 1, label => 'Last Value' }, + load => { hdr => 'Load', num => 1, label => 'Server load' }, + locked_count => { hdr => 'Lock', num => 1, label => 'Number of locked threads' }, + lock_cfile_name => { hdr => 'Crtd File', num => 0, label => 'Filename where lock created' }, + lock_cline => { hdr => 'Crtd Line', num => 1, label => 'Line where lock created' }, + lock_info => { hdr => 'Lock Info', num => 0, label => 'Lock information' }, + lock_mem_addr => { hdr => 'Addr', num => 0, label => 'The lock memory address' }, + lock_mode => { hdr => 'Mode', num => 0, label => 'The lock mode' }, + lock_structs => { hdr => 'LStrcts', num => 1, label => 'Number of lock structs' }, + lock_type => { hdr => 'Type', num => 0, label => 'The lock type' }, + lock_var => { hdr => 'Lck Var', num => 1, label => 'The lock variable' }, + lock_wait_time => { hdr => 'Wait', num => 1, label => 'How long txn has waited for a lock' }, + log_flushed_to => { hdr => 'Flushed To', num => 0, label => 'Log position flushed to' }, + log_ios_done => { hdr => 'IO Done', num => 1, label => 'Log I/Os done' }, + log_ios_s => { hdr => 'IO/Sec', num => 1, label => 'Average log I/Os per sec' }, + log_seq_no => { hdr => 'Sequence No.', num => 0, label => 'Log sequence number' }, + longest_sql => { hdr => 'SQL', num => 0, label => 'Longest-running SQL statement' }, + main_thread_id => { hdr => 'Main Thread ID', num => 1, label => 'Main thread ID' }, + main_thread_proc_no => { hdr => 'Main Thread Proc', num => 1, label => 'Main thread process number' }, + main_thread_state => { hdr => 'Main Thread State', num => 0, label => 'Main thread state' }, + master_file => { hdr => 'File', num => 0, label => 'Master file' }, + master_host => { hdr => 'Master', num => 0, label => 'Master server hostname' }, + master_log_file => { hdr => 'Master Log File', num => 0, label => 'Master log file' }, + master_port => { hdr => 'Master Port', num => 1, label => 'Master port' }, + master_pos => { hdr => 'Position', num => 1, label => 'Master position' }, + master_ssl_allowed => { hdr => 'Master SSL Allowed', num => 0, label => 'Master SSL Allowed' }, + master_ssl_ca_file => { hdr => 'Master SSL CA File', num => 0, label => 'Master SSL Cert Auth File' }, + master_ssl_ca_path => { hdr => 'Master SSL CA Path', num => 0, label => 'Master SSL Cert Auth Path' }, + master_ssl_cert => { hdr => 'Master SSL Cert', num => 0, label => 'Master SSL Cert' }, + master_ssl_cipher => { hdr => 'Master SSL Cipher', num => 0, label => 'Master SSL Cipher' }, + master_ssl_key => { hdr => 'Master SSL Key', num => 0, label => 'Master SSL Key' }, + master_user => { hdr => 'Master User', num => 0, label => 'Master username' }, + master_uuid => { hdr => 'Master UUID', num => 0, label => 'Master UUID', }, + max_txn => { hdr => 'MaxTxnTime', num => 1, label => 'MaxTxn' }, + max_query_time => { hdr => 'MaxSQL', num => 1, label => 'Longest running SQL' }, + merged_recs => { hdr => 'Merged Recs', num => 1, label => 'Merged records' }, + merges => { hdr => 'Merges', num => 1, label => 'Merges' }, + miss_rate => { hdr => 'Miss', num => 1, label => 'InnoDB buffer pool miss rate' }, + mutex_os_waits => { hdr => 'Waits', num => 1, label => 'Mutex OS Waits' }, + mutex_spin_rounds => { hdr => 'Rounds', num => 1, label => 'Mutex Spin Rounds' }, + mutex_spin_waits => { hdr => 'Spins', num => 1, label => 'Mutex Spin Waits' }, + mysql_thread_id => { hdr => 'ID', num => 1, label => 'MySQL connection (thread) ID', }, + name => { hdr => 'Name', num => 0, label => 'Variable Name' }, + n_bits => { hdr => '# Bits', num => 1, label => 'Number of bits' }, + non_hash_searches_s => { hdr => 'Non-Hash/Sec', num => 1, label => 'Non-hash searches/sec' }, + num_deletes => { hdr => 'Del', num => 1, label => 'Number of deletes' }, + num_deletes_sec => { hdr => 'Del/Sec', num => 1, label => 'Number of deletes' }, + num_inserts => { hdr => 'Ins', num => 1, label => 'Number of inserts' }, + num_inserts_sec => { hdr => 'Ins/Sec', num => 1, label => 'Number of inserts' }, + num_readers => { hdr => 'Readers', num => 1, label => 'Number of readers' }, + num_reads => { hdr => 'Read', num => 1, label => 'Number of reads' }, + num_reads_sec => { hdr => 'Read/Sec', num => 1, label => 'Number of reads' }, + num_res_ext => { hdr => 'BTree Extents', num => 1, label => 'Number of extents reserved for B-Tree' }, + num_rows => { hdr => 'Row Count', num => 1, label => 'Number of rows estimated to examine' }, + num_times_open => { hdr => 'In Use', num => 1, label => '# times table is opened', }, + num_txns => { hdr => 'Txns', num => 1, label => 'Number of transactions' }, + num_updates => { hdr => 'Upd', num => 1, label => 'Number of updates' }, + num_updates_sec => { hdr => 'Upd/Sec', num => 1, label => 'Number of updates' }, + 'open' => { hdr => 'Tbls', num => 1, label => 'Number of open tables' }, + os_file_reads => { hdr => 'OS Reads', num => 1, label => 'OS file reads' }, + os_file_writes => { hdr => 'OS Writes', num => 1, label => 'OS file writes' }, + os_fsyncs => { hdr => 'OS fsyncs', num => 1, label => 'OS fsyncs' }, + os_thread_id => { hdr => 'OS Thread', num => 1, label => 'The operating system thread ID' }, + p_aio_writes => { hdr => 'Async Wrt', num => 1, label => 'Pending asynchronous I/O writes' }, + p_buf_pool_flushes => { hdr => 'Buffer Pool Flushes', num => 1, label => 'Pending buffer pool flushes' }, + p_ibuf_aio_reads => { hdr => 'IBuf Async Rds', num => 1, label => 'Pending insert buffer asynch I/O reads' }, + p_log_flushes => { hdr => 'Log Flushes', num => 1, label => 'Pending log flushes' }, + p_log_ios => { hdr => 'Log I/Os', num => 1, label => 'Pending log I/O operations' }, + p_normal_aio_reads => { hdr => 'Async Rds', num => 1, label => 'Pending asynchronous I/O reads' }, + p_preads => { hdr => 'preads', num => 1, label => 'Pending p-reads' }, + p_pwrites => { hdr => 'pwrites', num => 1, label => 'Pending p-writes' }, + p_sync_ios => { hdr => 'Sync I/Os', num => 1, label => 'Pending synchronous I/O operations' }, + page_creates_sec => { hdr => 'Creates/Sec', num => 1, label => 'Page creates/sec' }, + page_no => { hdr => 'Page', num => 1, label => 'Page number' }, + page_reads_sec => { hdr => 'Reads/Sec', num => 1, label => 'Page reads per second' }, + page_writes_sec => { hdr => 'Writes/Sec', num => 1, label => 'Page writes per second' }, + pages_created => { hdr => 'Created', num => 1, label => 'Pages created' }, + pages_modified => { hdr => 'Dirty Pages', num => 1, label => 'Pages modified (dirty)' }, + pages_read => { hdr => 'Reads', num => 1, label => 'Pages read' }, + pages_total => { hdr => 'Pages', num => 1, label => 'Pages total' }, + pages_written => { hdr => 'Writes', num => 1, label => 'Pages written' }, + parent_col => { hdr => 'Parent Column', num => 0, label => 'The referred column in the parent table', }, + parent_db => { hdr => 'Parent DB', num => 0, label => 'The database of the parent table' }, + parent_index => { hdr => 'Parent Index', num => 0, label => 'The referred index in the parent table' }, + parent_table => { hdr => 'Parent Table', num => 0, label => 'The parent table' }, + part_id => { hdr => 'Part ID', num => 1, label => 'Sub-part ID of the query' }, + partitions => { hdr => 'Partitions', num => 0, label => 'Query partitions used' }, + pct => { hdr => 'Pct', num => 1, label => 'Percentage' }, + pending_chkp_writes => { hdr => 'Chkpt Writes', num => 1, label => 'Pending log checkpoint writes' }, + pending_log_writes => { hdr => 'Log Writes', num => 1, label => 'Pending log writes' }, + port => { hdr => 'Port', num => 1, label => 'Client port number', }, + possible_keys => { hdr => 'Poss. Keys', num => 0, label => 'Possible keys' }, + proc_no => { hdr => 'Proc', num => 1, label => 'Process number' }, + q_detail => { hdr => 'Se/In/Up/De%', num => 0, label => 'Detailed Query', }, + q_cache_hit => { hdr => 'QCacheHit', num => 1, label => 'Query cache hit ratio', }, + qps => { hdr => 'QPS', num => 1, label => 'How many queries/sec', }, + queries_in_queue => { hdr => 'Queries Queued', num => 1, label => 'Queries in queue' }, + queries_inside => { hdr => 'Queries Inside', num => 1, label => 'Queries inside InnoDB' }, + query_id => { hdr => 'Query ID', num => 1, label => 'Query ID' }, + query_status => { hdr => 'Query Status', num => 0, label => 'The query status' }, + query_text => { hdr => 'Query Text', num => 0, label => 'The query text' }, + questions => { hdr => 'Questions', num => 1, label => 'How many queries the server has gotten', }, + read_master_log_pos => { hdr => 'Read Master Pos', num => 1, label => 'Read master log position' }, + read_views_open => { hdr => 'Rd Views', num => 1, label => 'Number of read views open' }, + reads_pending => { hdr => 'Pending Reads', num => 1, label => 'Reads pending' }, + relay_log_file => { hdr => 'Relay File', num => 0, label => 'Relay log file' }, + relay_log_pos => { hdr => 'Relay Pos', num => 1, label => 'Relay log position' }, + relay_log_size => { hdr => 'Relay Size', num => 1, label => 'Relay log size' }, + relay_master_log_file => { hdr => 'Relay Master File', num => 0, label => 'Relay master log file' }, + replicate_do_db => { hdr => 'Do DB', num => 0, label => 'Replicate-do-db setting' }, + replicate_do_table => { hdr => 'Do Table', num => 0, label => 'Replicate-do-table setting' }, + replicate_ignore_db => { hdr => 'Ignore DB', num => 0, label => 'Replicate-ignore-db setting' }, + replicate_ignore_table => { hdr => 'Ignore Table', num => 0, label => 'Replicate-do-table setting' }, + replicate_wild_do_table => { hdr => 'Wild Do Table', num => 0, label => 'Replicate-wild-do-table setting' }, + replicate_wild_ignore_table => { hdr => 'Wild Ignore Table', num => 0, label => 'Replicate-wild-ignore-table setting' }, + request_type => { hdr => 'Type', num => 0, label => 'Type of lock the thread waits for' }, + reservation_count => { hdr => 'ResCnt', num => 1, label => 'Reservation Count' }, + retrieved_gtid_set => { hdr => 'Retrieved GTID Set', num => 0, label => 'Retrieved GTID Set', }, + row_locks => { hdr => 'RLocks', num => 1, label => 'Number of row locks' }, + rows_changed => { hdr => 'Changed', num => 1, label => 'Number of rows changed' }, + rows_changed_x_indexes => { hdr => 'Chg X Idx', num => 1, label => 'Number of rows changed X indexes' }, + rows_read => { hdr => 'Reads', num => 1, label => 'Number of rows read' }, + rows_read_from_indexes => { hdr => 'Reads Via Idx', num => 1, label => 'Number of rows read from indexes' }, + run => { hdr => 'Run', num => 1, label => 'Threads_running' }, + rw_excl_os_waits => { hdr => 'RW Waits', num => 1, label => 'R/W Excl. OS Waits' }, + rw_excl_spins => { hdr => 'RW Spins', num => 1, label => 'R/W Excl. Spins' }, + rw_shared_os_waits => { hdr => 'Sh Waits', num => 1, label => 'R/W Shared OS Waits' }, + rw_shared_spins => { hdr => 'Sh Spins', num => 1, label => 'R/W Shared Spins' }, + spark_qps => { hdr => 'QPS', num => 0, label => 'QPS Sparkline' }, + spark_run => { hdr => 'Run', num => 0, label => 'Threads_running Sparkline' }, + scan_type => { hdr => 'Type', num => 0, label => 'Scan type in chosen' }, + seg_size => { hdr => 'Seg. Size', num => 1, label => 'Segment size' }, + select_type => { hdr => 'Select Type', num => 0, label => 'Type of select used' }, + server_uuid => { hdr => 'Server UUID', num => 0, label => 'Server UUID', }, + signal_count => { hdr => 'Signals', num => 1, label => 'Signal Count' }, + size => { hdr => 'Size', num => 1, label => 'Size of the tablespace' }, + skip_counter => { hdr => 'Skip Counter', num => 1, label => 'Skip counter' }, + slave_catchup_rate => { hdr => 'Catchup', num => 1, label => 'How fast the slave is catching up in the binlog' }, + slave_io_running => { hdr => 'Slave-IO', num => 0, label => 'Whether the slave I/O thread is running' }, + slave_io_state => { hdr => 'Slave IO State', num => 0, label => 'Slave I/O thread state' }, + slave_open_temp_tables => { hdr => 'Temp', num => 1, label => 'Slave open temp tables' }, + slave_running => { hdr => 'Repl', num => 0, label => 'Slave running' }, + slave_sql_running => { hdr => 'Slave-SQL', num => 0, label => 'Whether the slave SQL thread is running' }, + sort_time => { hdr => 'SortTimeLag', num => 1, label => 'Time slave lags master sort' }, + slow => { hdr => 'Slow', num => 1, label => 'How many slow queries', }, + space_id => { hdr => 'Space', num => 1, label => 'Tablespace ID' }, + special => { hdr => 'Special', num => 0, label => 'Special/Other info' }, + state => { hdr => 'State', num => 0, label => 'Connection state', maxw => 18, }, + tables_in_use => { hdr => 'Tbl Used', num => 1, label => 'Number of tables in use' }, + tables_locked => { hdr => 'Tbl Lck', num => 1, label => 'Number of tables locked' }, + tbl => { hdr => 'Table', num => 0, label => 'Table', }, + thread => { hdr => 'Thread', num => 1, label => 'Thread number' }, + thread_decl_inside => { hdr => 'Thread Inside', num => 0, label => 'What the thread is declared inside' }, + thread_purpose => { hdr => 'Purpose', num => 0, label => "The thread's purpose" }, + thread_status => { hdr => 'Thread Status', num => 0, label => 'The thread status' }, + time => { hdr => 'Time', num => 1, label => 'Time since the last event', }, + time_behind_master => { hdr => 'TimeLag', num => 1, label => 'Time slave lags master' }, + timestring => { hdr => 'Timestring', num => 0, label => 'Time the event occurred' }, + total => { hdr => 'Total', num => 1, label => 'Total' }, + total_mem_alloc => { hdr => 'Memory', num => 1, label => 'Total memory allocated' }, + truncates => { hdr => 'Trunc', num => 0, label => 'Whether the deadlock is truncating InnoDB status' }, + txn_doesnt_see_ge => { hdr => "Txn Won't See", num => 0, label => 'Where txn read view is limited' }, + txn_id => { hdr => 'ID', num => 0, label => 'Transaction ID' }, + txn_sees_lt => { hdr => 'Txn Sees', num => 1, label => 'Where txn read view is limited' }, + txn_status => { hdr => 'Txn Status', num => 0, label => 'Transaction status' }, + txn_time_remain => { hdr => 'Remaining', num => 1, label => 'Time until txn rollback/commit completes' }, + undo_log_entries => { hdr => 'Undo', num => 1, label => 'Number of undo log entries' }, + undo_for => { hdr => 'Undo', num => 0, label => 'Undo for' }, + until_condition => { hdr => 'Until Condition', num => 0, label => 'Slave until condition' }, + until_log_file => { hdr => 'Until Log File', num => 0, label => 'Slave until log file' }, + uptime => { hdr => 'Uptime', num => 1, label => 'Uptime' }, + until_log_pos => { hdr => 'Until Log Pos', num => 1, label => 'Slave until log position' }, + used_cells => { hdr => 'Cells Used', num => 1, label => 'Number of cells used' }, + used_bufs => { hdr => 'Used Bufs', num => 1, label => 'Number of buffer pool pages used' }, + user => { hdr => 'User', num => 0, label => 'Database username', }, + value => { hdr => 'Value', num => 1, label => 'Value' }, + versions => { hdr => 'Versions', num => 1, label => 'Number of InnoDB MVCC versions unpurged' }, + victim => { hdr => 'Victim', num => 0, label => 'Whether this txn was the deadlock victim' }, + wait_array_size => { hdr => 'Wait Array Size', num => 1, label => 'Wait Array Size' }, + wait_status => { hdr => 'Lock Status', num => 0, label => 'Status of txn locks' }, + waited_at_filename => { hdr => 'File', num => 0, label => 'Filename at which thread waits' }, + waited_at_line => { hdr => 'Line', num => 1, label => 'Line at which thread waits' }, + waiters_flag => { hdr => 'Waiters', num => 1, label => 'Waiters Flag' }, + waiting => { hdr => 'Waiting', num => 1, label => 'Whether lock is being waited for' }, + waiting_thread => { hdr => 'WThread', num => 1, label => 'Waiting thread' }, + waiting_query => { hdr => 'Waiting Query', num => 0, label => 'Waiting query' }, + waiting_rows_modified => { hdr => 'WRowsMod', num => 1, label => 'Waiting number rows modified' }, + waiting_age => { hdr => 'WAge', num => 1, label => 'Waiting age' }, + waiting_wait_secs => { hdr => 'WWait', num => 1, label => 'Waiting wait time' }, + waiting_user => { hdr => 'WUser', num => 0, label => 'Waiting user' }, + waiting_host => { hdr => 'WHost', num => 0, label => 'Waiting host' }, + waiting_db => { hdr => 'WDB', num => 0, label => 'Waiting database' }, + when => { hdr => 'When', num => 0, label => 'Time scale' }, + writer_lock_mode => { hdr => 'Wrtr Lck Mode', num => 0, label => 'Writer lock mode' }, + writer_thread => { hdr => 'Wrtr Thread', num => 1, label => 'Writer thread ID' }, + writes_pending => { hdr => 'Writes', num => 1, label => 'Number of writes pending' }, + writes_pending_flush_list => { hdr => 'Flush List Writes', num => 1, label => 'Number of flush list writes pending' }, + writes_pending_lru => { hdr => 'LRU Writes', num => 1, label => 'Number of LRU writes pending' }, + writes_pending_single_page => { hdr => '1-Page Writes', num => 1, label => 'Number of 1-page writes pending' }, +); + +# Apply a default property or three. By default, columns are not width-constrained, +# aligned left, and sorted alphabetically, not numerically. +foreach my $col ( values %columns ) { + map { $col->{$_} ||= 0 } qw(num minw maxw); + $col->{just} = $col->{num} ? '' : '-'; +} + +# Filters {{{3 +# This hash defines every filter that can be applied to a table. These +# become part of tbl_meta as well. Each filter is just an expression that +# returns true or false. +# Properties of each entry: +# * func: the subroutine +# * name: the name, repeated +# * user: whether it's a user-defined filter (saved in config) +# * text: text of the subroutine +# * note: explanation +my %filters = (); + +# These are pre-processed to live in %filters above, by compiling them. +my %builtin_filters = ( + hide_self => { + text => <<' END', + return ( ($set->{info} || '') !~ m#/\*innotop\*/# ); + END + note => 'Removes the innotop processes from the list', + tbls => [qw(innodb_transactions processlist)], + }, + hide_inactive => { + text => <<' END', + return ( !defined($set->{txn_status}) || $set->{txn_status} ne 'not started' ) + && ( !defined($set->{cmd}) || $set->{cmd} !~ m/Sleep|Binlog Dump/ ) + && ( !defined($set->{state}) || $set->{state} !~ m/^handlersocket/ ) + && ( !defined($set->{info}) || $set->{info} =~ m/\S/ ); + END + note => 'Removes processes which are not doing anything', + tbls => [qw(innodb_transactions processlist)], + }, + hide_connect => { + text => <<' END', + return ( !defined($set->{cmd}) || $set->{cmd} !~ m/Connect/ ); + END + note => 'Removes the slave processes from the list', + tbls => [qw(processlist)], + }, + hide_slave_io => { + text => <<' END', + return !$set->{state} || $set->{state} !~ m/^(?:Waiting for master|read all relay)/; + END + note => 'Removes slave I/O threads from the list', + tbls => [qw(processlist slave_io_status)], + }, + hide_event => { + text => <<' END', + return (($set->{state} || '') !~ m/^Daemon/) || (($set->{info} || '') !~ m/\S/); + END + note => 'Removes idle event threads from the list', + tbls => [qw(processlist)], + }, + table_is_open => { + text => <<' END', + return $set->{num_times_open} + $set->{is_name_locked}; + END + note => 'Removes tables that are not in use or locked', + tbls => [qw(open_tables)], + }, + cxn_is_master => { + text => <<' END', + return $set->{master_file} ? 1 : 0; + END + note => 'Removes servers that are not masters', + tbls => [qw(master_status)], + }, + cxn_is_slave => { + text => <<' END', + return $set->{master_host} ? 1 : 0; + END + note => 'Removes servers that are not slaves', + tbls => [qw(slave_io_status slave_sql_status)], + }, + thd_is_not_waiting => { + text => <<' END', + return $set->{thread_status} !~ m#waiting for i/o request#; + END + note => 'Removes idle I/O threads', + tbls => [qw(io_threads)], + }, +); +foreach my $key ( keys %builtin_filters ) { + my ( $sub, $err ) = compile_filter($builtin_filters{$key}->{text}); + $filters{$key} = { + func => $sub, + text => $builtin_filters{$key}->{text}, + user => 0, + name => $key, # useful for later + note => $builtin_filters{$key}->{note}, + tbls => $builtin_filters{$key}->{tbls}, + } +} + +# Variable sets {{{3 +# Sets (arrayrefs) of variables that are used in S mode. They are read/written to +# the config file. +my %var_sets = ( + general => { + text => join( + ', ', + 'set_precision(Questions/Uptime_hires) as QPS', + 'set_precision(Com_commit/Uptime_hires) as Commit_PS', + 'set_precision((Com_rollback||0)/(Com_commit||1)) as Rollback_Commit', + 'set_precision((' + . join('+', map { "($_||0)" } + qw(Com_delete Com_delete_multi Com_insert Com_insert_select Com_replace + Com_replace_select Com_select Com_update Com_update_multi)) + . ')/(Com_commit||1)) as Write_Commit', + 'set_precision((Com_select+(Qcache_hits||0))/((' + . join('+', map { "($_||0)" } + qw(Com_delete Com_delete_multi Com_insert Com_insert_select Com_replace + Com_replace_select Com_select Com_update Com_update_multi)) + . ')||1)) as R_W_Ratio', + 'set_precision(Opened_tables/Uptime_hires) as Opens_PS', + 'percent($cur->{Open_tables}/($cur->{table_cache})) as Table_Cache_Used', + 'set_precision(Threads_created/Uptime_hires) as Threads_PS', + 'percent($cur->{Threads_cached}/($cur->{thread_cache_size}||1)) as Thread_Cache_Used', + 'percent($cur->{Max_used_connections}/($cur->{max_connections}||1)) as CXN_Used_Ever', + 'percent($cur->{Threads_connected}/($cur->{max_connections}||1)) as CXN_Used_Now', + ), + }, + commands => { + text => join( + ', ', + qw(Uptime Questions Com_delete Com_delete_multi Com_insert + Com_insert_select Com_replace Com_replace_select Com_select Com_update + Com_update_multi) + ), + }, + query_status => { + text => join( + ',', + qw( Uptime Select_full_join Select_full_range_join Select_range + Select_range_check Select_scan Slow_queries Sort_merge_passes + Sort_range Sort_rows Sort_scan) + ), + }, + innodb => { + text => join( + ',', + qw( Uptime Innodb_row_lock_current_waits Innodb_row_lock_time + Innodb_row_lock_time_avg Innodb_row_lock_time_max Innodb_row_lock_waits + Innodb_rows_deleted Innodb_rows_inserted Innodb_rows_read + Innodb_rows_updated) + ), + }, + txn => { + text => join( + ',', + qw( Uptime Com_begin Com_commit Com_rollback Com_savepoint + Com_xa_commit Com_xa_end Com_xa_prepare Com_xa_recover Com_xa_rollback + Com_xa_start) + ), + }, + key_cache => { + text => join( + ',', + qw( Uptime Key_blocks_not_flushed Key_blocks_unused Key_blocks_used + Key_read_requests Key_reads Key_write_requests Key_writes ) + ), + }, + query_cache => { + text => join( + ',', + "percent($exprs{QcacheHitRatio}) as Hit_Pct", + 'set_precision((Qcache_hits||0)/(Qcache_inserts||1)) as Hit_Ins', + 'set_precision((Qcache_lowmem_prunes||0)/Uptime_hires) as Lowmem_Prunes_sec', + 'percent(1-((Qcache_free_blocks||0)/(Qcache_total_blocks||1))) as Blocks_used', + qw( Qcache_free_blocks Qcache_free_memory Qcache_not_cached Qcache_queries_in_cache) + ), + }, + handler => { + text => join( + ',', + qw( Uptime Handler_read_key Handler_read_first Handler_read_next + Handler_read_prev Handler_read_rnd Handler_read_rnd_next Handler_delete + Handler_update Handler_write) + ), + }, + cxns_files_threads => { + text => join( + ',', + qw( Uptime Aborted_clients Aborted_connects Bytes_received Bytes_sent + Compression Connections Created_tmp_disk_tables Created_tmp_files + Created_tmp_tables Max_used_connections Open_files Open_streams + Open_tables Opened_tables Table_locks_immediate Table_locks_waited + Threads_cached Threads_connected Threads_created Threads_running) + ), + }, + prep_stmt => { + text => join( + ',', + qw( Uptime Com_dealloc_sql Com_execute_sql Com_prepare_sql Com_reset + Com_stmt_close Com_stmt_execute Com_stmt_fetch Com_stmt_prepare + Com_stmt_reset Com_stmt_send_long_data ) + ), + }, + innodb_health => { + text => join( + ',', + "$exprs{OldVersions} as OldVersions", + qw(IB_sm_mutex_spin_waits IB_sm_mutex_spin_rounds IB_sm_mutex_os_waits), + "$exprs{NumTxns} as NumTxns", + "$exprs{MaxTxnTime} as MaxTxnTime", + qw(IB_ro_queries_inside IB_ro_queries_in_queue), + "set_precision($exprs{DirtyBufs} * 100) as dirty_bufs", + "set_precision($exprs{BufPoolFill} * 100) as buf_fill", + qw(IB_bp_pages_total IB_bp_pages_read IB_bp_pages_written IB_bp_pages_created) + ), + }, + innodb_health2 => { + text => join( + ', ', + 'percent(1-((Innodb_buffer_pool_pages_free||0)/($cur->{Innodb_buffer_pool_pages_total}||1))) as BP_page_cache_usage', + 'percent(1-((Innodb_buffer_pool_reads||0)/(Innodb_buffer_pool_read_requests||1))) as BP_cache_hit_ratio', + 'Innodb_buffer_pool_wait_free', + 'Innodb_log_waits', + ), + }, + slow_queries => { + text => join( + ', ', + 'set_precision(Slow_queries/Uptime_hires) as Slow_PS', + 'set_precision(Select_full_join/Uptime_hires) as Full_Join_PS', + 'percent(Select_full_join/(Com_select||1)) as Full_Join_Ratio', + ), + }, +); + +# Server sets {{{3 +# Defines sets of servers between which the user can quickly switch. +my %server_groups; + +# Connections {{{3 +# This hash defines server connections. Each connection is a string that can be passed to +# the DBI connection. These are saved in the connections section in the config file. +my %connections; +# Defines the parts of connections. +my @conn_parts = qw(user have_user pass have_pass dsn savepass dl_table); + +# Graph widths {{{3 +# This hash defines the max values seen for various status/variable values, for graphing. +# These are stored in their own section in the config file. These are just initial values: +my %mvs = ( + Com_select => 50, + Com_insert => 50, + Com_update => 50, + Com_delete => 50, + Questions => 100, +); + +# ########################################################################### +# Valid Term::ANSIColor color strings. +# ########################################################################### +my %ansicolors = map { $_ => 1 } + qw( black blink blue bold clear concealed cyan dark green magenta on_black + on_blue on_cyan on_green on_magenta on_red on_white on_yellow red reset + reverse underline underscore white yellow); + +# ########################################################################### +# Valid comparison operators for color rules +# ########################################################################### +my %comp_ops = ( + '==' => 'Numeric equality', + '>' => 'Numeric greater-than', + '<' => 'Numeric less-than', + '>=' => 'Numeric greater-than/equal', + '<=' => 'Numeric less-than/equal', + '!=' => 'Numeric not-equal', + 'eq' => 'String equality', + 'gt' => 'String greater-than', + 'lt' => 'String less-than', + 'ge' => 'String greater-than/equal', + 'le' => 'String less-than/equal', + 'ne' => 'String not-equal', + '=~' => 'Pattern match', + '!~' => 'Negated pattern match', +); + +# ########################################################################### +# Valid aggregate functions. +# ########################################################################### +my %agg_funcs = ( + first => sub { + return $_[0] + }, + count => sub { + return 0 + @_; + }, + avg => sub { + my @args = grep { defined $_ } @_; + return (sum(map { m/([\d\.-]+)/g } @args) || 0) / (scalar(@args) || 1); + }, + sum => sub { + my @args = grep { defined $_ } @_; + return sum(@args); + } +); + +# ########################################################################### +# Valid functions for transformations. +# ########################################################################### +my %trans_funcs = ( + shorten => \&shorten, + secs_to_time => \&secs_to_time, + distill => \&distill, + no_ctrl_char => \&no_ctrl_char, + percent => \&percent, + commify => \&commify, + dulint_to_int => \&dulint_to_int, + set_precision => \&set_precision, + fuzzy_time => \&fuzzy_time, +); + +# Table definitions {{{3 +# This hash defines every table that can get displayed in every mode. Each +# table specifies columns and column data sources. The column is +# defined by the %columns hash. +# +# Example: foo => { src => 'bar' } means the foo column (look at +# $columns{foo} for its definition) gets its data from the 'bar' element of +# the current data set, whatever that is. +# +# These columns are post-processed after being defined, because they get stuff +# from %columns. After all the config is loaded for columns, there's more +# post-processing too; the subroutines compiled from src get added to +# the hash elements for extract_values to use. +# ########################################################################### + +my %tbl_meta = ( + adaptive_hash_index => { + capt => 'Adaptive Hash Index', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + hash_table_size => { src => 'IB_ib_hash_table_size', trans => [qw(shorten)], }, + used_cells => { src => 'IB_ib_used_cells' }, + bufs_in_node_heap => { src => 'IB_ib_bufs_in_node_heap' }, + hash_searches_s => { src => 'IB_ib_hash_searches_s' }, + non_hash_searches_s => { src => 'IB_ib_non_hash_searches_s' }, + }, + visible => [ qw(cxn hash_table_size used_cells bufs_in_node_heap hash_searches_s non_hash_searches_s) ], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'ib', + group_by => [], + aggregate => 0, + }, + buffer_pool => { + capt => 'Buffer Pool', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + total_mem_alloc => { src => 'IB_bp_total_mem_alloc', trans => [qw(shorten)], }, + awe_mem_alloc => { src => 'IB_bp_awe_mem_alloc', trans => [qw(shorten)], }, + add_pool_alloc => { src => 'IB_bp_add_pool_alloc', trans => [qw(shorten)], }, + buf_pool_size => { src => 'IB_bp_buf_pool_size', trans => [qw(shorten)], }, + buf_free => { src => 'IB_bp_buf_free' }, + buf_pool_hit_rate => { src => 'IB_bp_buf_pool_hit_rate' }, + buf_pool_reads => { src => 'IB_bp_buf_pool_reads' }, + buf_pool_hits => { src => 'IB_bp_buf_pool_hits' }, + dict_mem_alloc => { src => 'IB_bp_dict_mem_alloc' }, + pages_total => { src => 'IB_bp_pages_total' }, + pages_modified => { src => 'IB_bp_pages_modified' }, + reads_pending => { src => 'IB_bp_reads_pending' }, + writes_pending => { src => 'IB_bp_writes_pending' }, + writes_pending_lru => { src => 'IB_bp_writes_pending_lru' }, + writes_pending_flush_list => { src => 'IB_bp_writes_pending_flush_list' }, + writes_pending_single_page => { src => 'IB_bp_writes_pending_single_page' }, + page_creates_sec => { src => 'IB_bp_page_creates_sec' }, + page_reads_sec => { src => 'IB_bp_page_reads_sec' }, + page_writes_sec => { src => 'IB_bp_page_writes_sec' }, + pages_created => { src => 'IB_bp_pages_created' }, + pages_read => { src => 'IB_bp_pages_read' }, + pages_written => { src => 'IB_bp_pages_written' }, + }, + visible => [ qw(cxn buf_pool_size buf_free pages_total pages_modified buf_pool_hit_rate total_mem_alloc add_pool_alloc)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'bp', + group_by => [], + aggregate => 0, + }, + # TODO: a new step in set_to_tbl: join result to itself, grouped? + # TODO: this would also enable pulling Q and T data together. + # TODO: using a SQL-ish language would also allow pivots to be easier -- treat the pivoted data as a view and SELECT from it. + cmd_summary => { + capt => 'Command Summary', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + name => { src => 'name' }, + total => { src => 'total' }, + value => { src => 'value', agg => 'sum'}, + pct => { src => 'value/total', trans => [qw(percent)] }, + last_total => { src => 'last_total' }, + last_value => { src => 'last_value', agg => 'sum'}, + last_pct => { src => 'last_value/last_total', trans => [qw(percent)] }, + }, + visible => [qw(cxn name value pct last_value last_pct)], + filters => [qw()], + sort_cols => '-value', + sort_dir => '1', + innodb => '', + group_by => [qw(name)], + aggregate => 1, + }, + deadlock_locks => { + capt => 'Deadlock Locks', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + mysql_thread_id => { src => 'mysql_thread_id' }, + dl_txn_num => { src => 'dl_txn_num' }, + lock_type => { src => 'lock_type' }, + space_id => { src => 'space_id' }, + page_no => { src => 'page_no' }, + heap_no => { src => 'heap_no' }, + n_bits => { src => 'n_bits' }, + index => { src => 'index' }, + db => { src => 'db' }, + tbl => { src => 'table' }, + lock_mode => { src => 'lock_mode' }, + special => { src => 'special' }, + insert_intention => { src => 'insert_intention' }, + waiting => { src => 'waiting' }, + }, + visible => [ qw(cxn mysql_thread_id waiting lock_mode db tbl index special insert_intention)], + filters => [], + sort_cols => 'cxn mysql_thread_id', + sort_dir => '1', + innodb => 'dl', + group_by => [], + aggregate => 0, + }, + deadlock_transactions => { + capt => 'Deadlock Transactions', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + active_secs => { src => 'active_secs' }, + dl_txn_num => { src => 'dl_txn_num' }, + has_read_view => { src => 'has_read_view' }, + heap_size => { src => 'heap_size' }, + host_and_domain => { src => 'hostname' }, + hostname => { src => $exprs{Host} }, + ip => { src => 'ip' }, + lock_structs => { src => 'lock_structs' }, + lock_wait_time => { src => 'lock_wait_time', trans => [ qw(secs_to_time) ] }, + mysql_thread_id => { src => 'mysql_thread_id' }, + os_thread_id => { src => 'os_thread_id' }, + proc_no => { src => 'proc_no' }, + query_id => { src => 'query_id' }, + query_status => { src => 'query_status' }, + query_text => { src => 'query_text', trans => [ qw(no_ctrl_char) ] }, + row_locks => { src => 'row_locks' }, + tables_in_use => { src => 'tables_in_use' }, + tables_locked => { src => 'tables_locked' }, + thread_decl_inside => { src => 'thread_decl_inside' }, + thread_status => { src => 'thread_status' }, + 'time' => { src => 'active_secs', trans => [ qw(secs_to_time) ] }, + timestring => { src => 'timestring' }, + txn_doesnt_see_ge => { src => 'txn_doesnt_see_ge' }, + txn_id => { src => 'txn_id' }, + txn_sees_lt => { src => 'txn_sees_lt' }, + txn_status => { src => 'txn_status' }, + truncates => { src => 'truncates' }, + undo_log_entries => { src => 'undo_log_entries' }, + user => { src => 'user' }, + victim => { src => 'victim' }, + wait_status => { src => 'lock_wait_status' }, + }, + visible => [ qw(cxn mysql_thread_id timestring user hostname victim time undo_log_entries lock_structs query_text)], + filters => [], + sort_cols => 'cxn mysql_thread_id', + sort_dir => '1', + innodb => 'dl', + group_by => [], + aggregate => 0, + }, + explain => { + capt => 'EXPLAIN Results', + cust => {}, + cols => { + part_id => { src => 'id' }, + select_type => { src => 'select_type' }, + tbl => { src => 'table' }, + partitions => { src => 'partitions' }, + scan_type => { src => 'type' }, + possible_keys => { src => 'possible_keys' }, + index => { src => 'key' }, + key_len => { src => 'key_len' }, + index_ref => { src => 'ref' }, + num_rows => { src => 'rows' }, + special => { src => 'extra' }, + }, + visible => [ qw(select_type tbl partitions scan_type possible_keys index key_len index_ref num_rows special)], + filters => [], + sort_cols => '', + sort_dir => '1', + innodb => '', + group_by => [], + aggregate => 0, + }, + file_io_misc => { + capt => 'File I/O Misc', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + io_bytes_s => { src => 'IB_io_avg_bytes_s' }, + io_flush_type => { src => 'IB_io_flush_type' }, + io_fsyncs_s => { src => 'IB_io_fsyncs_s' }, + io_reads_s => { src => 'IB_io_reads_s' }, + io_writes_s => { src => 'IB_io_writes_s' }, + os_file_reads => { src => 'IB_io_os_file_reads' }, + os_file_writes => { src => 'IB_io_os_file_writes' }, + os_fsyncs => { src => 'IB_io_os_fsyncs' }, + }, + visible => [ qw(cxn os_file_reads os_file_writes os_fsyncs io_reads_s io_writes_s io_bytes_s)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'io', + group_by => [], + aggregate => 0, + }, + fk_error => { + capt => 'Foreign Key Error Info', + cust => {}, + cols => { + timestring => { src => 'IB_fk_timestring' }, + child_db => { src => 'IB_fk_child_db' }, + child_table => { src => 'IB_fk_child_table' }, + child_index => { src => 'IB_fk_child_index' }, + fk_name => { src => 'IB_fk_fk_name' }, + parent_db => { src => 'IB_fk_parent_db' }, + parent_table => { src => 'IB_fk_parent_table' }, + parent_col => { src => 'IB_fk_parent_col' }, + parent_index => { src => 'IB_fk_parent_index' }, + attempted_op => { src => 'IB_fk_attempted_op' }, + }, + visible => [ qw(timestring child_db child_table child_index parent_db parent_table parent_col parent_index fk_name attempted_op)], + filters => [], + sort_cols => '', + sort_dir => '1', + innodb => 'fk', + group_by => [], + aggregate => 0, + }, + index_statistics => { + capt => 'Data from INDEX_STATISTICS', + cust => {}, + cols => { + cxn => { src => 'cxn', minw => 6, maxw => 10 }, + db => { src => 'table_schema' }, + tbl => { src => 'table_name' }, + index => { src => 'index_name' }, + rows_read => { src => 'rows_read', agg => 'sum' }, + }, + visible => [ qw(cxn db tbl index rows_read) ], + filters => [ ], + sort_cols => 'rows_read', + sort_dir => '-1', + innodb => '', + colors => [], + hide_caption => 1, + group_by => [qw(cxn db tbl)], + aggregate => 0, + }, + index_table_statistics => { + capt => 'Data from {TABLE,INDEX}_STATISTICS', + cust => {}, + cols => { + cxn => { src => 'cxn', minw => 6, maxw => 10 }, + db => { src => 'table_schema' }, + tbl => { src => 'table_name' }, + index => { src => 'index_name' }, + rows_read => { src => 'rows_read' }, + rows_read_from_indexes => { src => 'rows_read_from_indexes' }, + rows_changed => { src => 'rows_changed' }, + rows_changed_x_indexes => { src => 'rows_changed_x_indexes' }, + }, + visible => [ qw(cxn db tbl rows_read rows_read_from_indexes rows_changed rows_changed_x_indexes) ], + filters => [ ], + sort_cols => 'rows_read', + sort_dir => '-1', + innodb => '', + colors => [], + hide_caption => 1, + group_by => [qw(cxn db tbl)], + aggregate => 0, + }, + insert_buffers => { + capt => 'Insert Buffers', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + inserts => { src => 'IB_ib_inserts' }, + merged_recs => { src => 'IB_ib_merged_recs' }, + merges => { src => 'IB_ib_merges' }, + size => { src => 'IB_ib_size' }, + free_list_len => { src => 'IB_ib_free_list_len' }, + seg_size => { src => 'IB_ib_seg_size' }, + }, + visible => [ qw(cxn inserts merged_recs merges size free_list_len seg_size)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'ib', + group_by => [], + aggregate => 0, + }, + innodb_blocked_blocker => { + capt => 'InnoDB Blocked/Blocking', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + waiting_thread => { src => 'waiting_thread' }, + waiting_query => { src => 'waiting_query', trans => [qw(distill)] }, + waiting_rows_modified => { src => 'waiting_rows_modified' }, + waiting_age => { src => 'waiting_age', trans => [qw(fuzzy_time)] }, + waiting_wait_secs => { src => 'waiting_wait_secs', trans => [qw(fuzzy_time)] }, + waiting_user => { src => 'waiting_user' }, + waiting_host => { src => 'waiting_host' }, + waiting_db => { src => 'waiting_db' }, + blocking_thread => { src => 'blocking_thread' }, + blocking_query => { src => 'blocking_query', trans => [qw(distill)] }, + blocking_rows_modified => { src => 'blocking_rows_modified' }, + blocking_age => { src => 'blocking_age', trans => [qw(fuzzy_time)] }, + blocking_wait_secs => { src => 'blocking_wait_secs', trans => [qw(fuzzy_time)] }, + blocking_user => { src => 'blocking_user' }, + blocking_host => { src => 'blocking_host' }, + blocking_db => { src => 'blocking_db' }, + blocking_status => { src => 'blocking_status' }, + lock_info => { src => 'lock_info' }, + }, + visible => [ qw(cxn waiting_thread waiting_query waiting_wait_secs + blocking_thread blocking_rows_modified blocking_age blocking_wait_secs + blocking_status blocking_query)], + filters => [], + sort_cols => 'cxn -waiting_wait_secs', + sort_dir => '1', + innodb => 'tx', + colors => [ + ], + group_by => [], + aggregate => 0, + hide_caption => 1, + }, + innodb_locks => { + capt => 'InnoDB Locks', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + db => { src => 'db' }, + index => { src => 'index' }, + insert_intention => { src => 'insert_intention' }, + lock_mode => { src => 'lock_mode' }, + lock_type => { src => 'lock_type' }, + lock_wait_time => { src => 'lock_wait_time', trans => [ qw(secs_to_time) ] }, + mysql_thread_id => { src => 'mysql_thread_id' }, + n_bits => { src => 'n_bits' }, + page_no => { src => 'page_no' }, + space_id => { src => 'space_id' }, + special => { src => 'special' }, + tbl => { src => 'table' }, + 'time' => { src => 'active_secs', hdr => 'Active', trans => [ qw(secs_to_time) ] }, + txn_id => { src => 'txn_id' }, + waiting => { src => 'waiting' }, + }, + visible => [ qw(cxn mysql_thread_id lock_type waiting lock_wait_time time lock_mode db tbl index insert_intention special)], + filters => [], + sort_cols => 'cxn -lock_wait_time', + sort_dir => '1', + innodb => 'tx', + colors => [ + { col => 'lock_wait_time', op => '>', arg => 60, color => 'red' }, + { col => 'lock_wait_time', op => '>', arg => 30, color => 'yellow' }, + { col => 'lock_wait_time', op => '>', arg => 10, color => 'green' }, + ], + group_by => [], + aggregate => 0, + }, + innodb_transactions => { + capt => 'InnoDB Transactions', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + active_secs => { src => 'active_secs' }, + has_read_view => { src => 'has_read_view' }, + heap_size => { src => 'heap_size' }, + hostname => { src => $exprs{Host} }, + ip => { src => 'ip' }, + wait_status => { src => 'lock_wait_status' }, + lock_wait_time => { src => 'lock_wait_time', trans => [ qw(secs_to_time) ] }, + lock_structs => { src => 'lock_structs' }, + mysql_thread_id => { src => 'mysql_thread_id' }, + os_thread_id => { src => 'os_thread_id' }, + proc_no => { src => 'proc_no' }, + query_id => { src => 'query_id' }, + query_status => { src => 'query_status' }, + query_text => { src => 'query_text', trans => [ qw(no_ctrl_char) ] }, + txn_time_remain => { src => $exprs{TxnTimeRemain}, trans => [ qw(secs_to_time) ] }, + row_locks => { src => 'row_locks' }, + tables_in_use => { src => 'tables_in_use' }, + tables_locked => { src => 'tables_locked' }, + thread_decl_inside => { src => 'thread_decl_inside' }, + thread_status => { src => 'thread_status' }, + 'time' => { src => 'active_secs', trans => [ qw(secs_to_time) ], agg => 'sum' }, + txn_doesnt_see_ge => { src => 'txn_doesnt_see_ge' }, + txn_id => { src => 'txn_id' }, + txn_sees_lt => { src => 'txn_sees_lt' }, + txn_status => { src => 'txn_status', minw => 10, maxw => 10 }, + undo_log_entries => { src => 'undo_log_entries' }, + user => { src => 'user', maxw => 10 }, + cnt => { src => 'mysql_thread_id', minw => 0 }, + }, + visible => [ qw(cxn cnt mysql_thread_id user hostname txn_status time undo_log_entries query_text)], + filters => [ qw( hide_self hide_inactive ) ], + sort_cols => '-active_secs txn_status cxn mysql_thread_id', + sort_dir => '1', + innodb => 'tx', + hide_caption => 1, + colors => [ + { col => 'wait_status', op => 'eq', arg => 'LOCK WAIT', color => 'black on_red' }, + { col => 'time', op => '>', arg => 600, color => 'red' }, + { col => 'time', op => '>', arg => 300, color => 'yellow' }, + { col => 'time', op => '>', arg => 60, color => 'green' }, + { col => 'time', op => '>', arg => 30, color => 'cyan' }, + { col => 'txn_status', op => 'eq', arg => 'not started', color => 'white' }, + ], + group_by => [ qw(cxn txn_status) ], + aggregate => 0, + }, + io_threads => { + capt => 'I/O Threads', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + thread => { src => 'thread' }, + thread_purpose => { src => 'purpose' }, + event_set => { src => 'event_set' }, + thread_status => { src => 'state' }, + }, + visible => [ qw(cxn thread thread_purpose thread_status)], + filters => [ qw() ], + sort_cols => 'cxn thread', + sort_dir => '1', + innodb => 'io', + group_by => [], + aggregate => 0, + }, + log_statistics => { + capt => 'Log Statistics', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + last_chkp => { src => 'IB_lg_last_chkp' }, + log_flushed_to => { src => 'IB_lg_log_flushed_to' }, + log_ios_done => { src => 'IB_lg_log_ios_done' }, + log_ios_s => { src => 'IB_lg_log_ios_s' }, + log_seq_no => { src => 'IB_lg_log_seq_no' }, + pending_chkp_writes => { src => 'IB_lg_pending_chkp_writes' }, + pending_log_writes => { src => 'IB_lg_pending_log_writes' }, + }, + visible => [ qw(cxn log_seq_no log_flushed_to last_chkp log_ios_done log_ios_s)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'lg', + group_by => [], + aggregate => 0, + }, + master_status => { + capt => 'Master Status', + cust => {}, + cols => { + cxn => { src => $exprs{chcxn_2_cxn}, hdr => 'CXN' }, + binlog_do_db => { src => 'binlog_do_db' }, + binlog_ignore_db => { src => 'binlog_ignore_db' }, + master_file => { src => 'file' }, + master_pos => { src => 'position' }, + binlog_cache_overflow => { src => '(Binlog_cache_disk_use||0)/(Binlog_cache_use||1)', trans => [ qw(percent) ] }, + executed_gtid_set => { src => '(executed_gtid_set||"N/A")' }, + server_uuid => { src => '(server_uuid||"N/A")' }, + channel_name => { src => $exprs{chcxn_2_ch}, hdr => 'Channel'}, + }, + visible => [ qw(cxn channel_name master_file master_pos binlog_cache_overflow executed_gtid_set server_uuid)], + filters => [ qw(cxn_is_master) ], + sort_cols => 'cxn', + sort_dir => '1', + innodb => '', + group_by => [qw(channel_name)], + aggregate => 0, + }, + pending_io => { + capt => 'Pending I/O', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + p_normal_aio_reads => { src => 'IB_io_pending_normal_aio_reads' }, + p_aio_writes => { src => 'IB_io_pending_aio_writes' }, + p_ibuf_aio_reads => { src => 'IB_io_pending_ibuf_aio_reads' }, + p_sync_ios => { src => 'IB_io_pending_sync_ios' }, + p_buf_pool_flushes => { src => 'IB_io_pending_buffer_pool_flushes' }, + p_log_flushes => { src => 'IB_io_pending_log_flushes' }, + p_log_ios => { src => 'IB_io_pending_log_ios' }, + p_preads => { src => 'IB_io_pending_preads' }, + p_pwrites => { src => 'IB_io_pending_pwrites' }, + }, + visible => [ qw(cxn p_normal_aio_reads p_aio_writes p_ibuf_aio_reads p_sync_ios p_log_flushes p_log_ios)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'io', + group_by => [], + aggregate => 0, + }, + open_tables => { + capt => 'Open Tables', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + db => { src => 'database' }, + tbl => { src => 'table' }, + num_times_open => { src => 'in_use' }, + is_name_locked => { src => 'name_locked' }, + }, + visible => [ qw(cxn db tbl num_times_open is_name_locked)], + filters => [ qw(table_is_open) ], + sort_cols => '-num_times_open cxn db tbl', + sort_dir => '1', + innodb => '', + group_by => [], + aggregate => 0, + }, + page_statistics => { + capt => 'Page Statistics', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + pages_read => { src => 'IB_bp_pages_read' }, + pages_written => { src => 'IB_bp_pages_written' }, + pages_created => { src => 'IB_bp_pages_created' }, + page_reads_sec => { src => 'IB_bp_page_reads_sec' }, + page_writes_sec => { src => 'IB_bp_page_writes_sec' }, + page_creates_sec => { src => 'IB_bp_page_creates_sec' }, + }, + visible => [ qw(cxn pages_read pages_written pages_created page_reads_sec page_writes_sec page_creates_sec)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'bp', + group_by => [], + aggregate => 0, + }, + processlist => { + capt => 'MySQL Process List', + cust => {}, + cols => { + cxn => { src => 'cxn', minw => 6, maxw => 10 }, + mysql_thread_id => { src => 'id', minw => 6, maxw => 0 }, + user => { src => 'user', minw => 5, maxw => 8 }, + hostname => { src => $exprs{Host}, minw => 7, maxw => 15, }, + port => { src => $exprs{Port}, minw => 0, maxw => 0, }, + host_and_port => { src => 'host', minw => 0, maxw => 0 }, + db => { src => 'db', minw => 6, maxw => 12 }, + cmd => { src => 'command', minw => 5, maxw => 0 }, + time => { src => 'time', minw => 5, maxw => 0, trans => [ qw(secs_to_time) ], agg => 'sum' }, + state => { src => 'state', minw => 0, maxw => 0 }, + info => { src => 'info', minw => 0, maxw => 0, trans => [ qw(no_ctrl_char) ] }, + cnt => { src => 'id', minw => 0, maxw => 0 }, + }, + visible => [ qw(cxn cmd cnt mysql_thread_id state user hostname db time info)], + filters => [ qw(hide_self hide_inactive hide_slave_io hide_event hide_connect) ], + sort_cols => '-time cxn hostname mysql_thread_id', + sort_dir => '1', + innodb => '', + hide_caption => 1, + colors => [ + { col => 'state', op => 'eq', arg => 'Locked', color => 'black on_red' }, + { col => 'cmd', op => 'eq', arg => 'Sleep', color => 'white' }, + { col => 'user', op => 'eq', arg => 'system user', color => 'white' }, + { col => 'cmd', op => 'eq', arg => 'Connect', color => 'white' }, + { col => 'cmd', op => 'eq', arg => 'Binlog Dump', color => 'white' }, + { col => 'time', op => '>', arg => 600, color => 'red' }, + { col => 'time', op => '>', arg => 120, color => 'yellow' }, + { col => 'time', op => '>', arg => 60, color => 'green' }, + { col => 'time', op => '>', arg => 30, color => 'cyan' }, + ], + group_by => [qw(cxn cmd)], + aggregate => 0, + }, + + # TODO: some more columns: + # kb_used=hdr='BufUsed' minw='0' num='0' src='percent(1 - ((Key_blocks_unused * key_cache_block_size) / (key_buffer_size||1)))' dec='0' trans='' tbl='q_header' just='-' user='1' maxw='0' label='User-defined' + # retries=hdr='Retries' minw='0' num='0' src='Slave_retried_transactions' dec='0' trans='' tbl='slave_sql_status' just='-' user='1' maxw='0' label='User-defined' + # thd=hdr='Thd' minw='0' num='0' src='Threads_connected' dec='0' trans='' tbl='slave_sql_status' just='-' user='1' maxw='0' label='User-defined' + + q_header => { + capt => 'Q-mode Header', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + questions => { src => 'Questions' }, + qps => { src => 'Questions/Uptime_hires', dec => 1, trans => [qw(shorten)] }, + load => { src => $exprs{ServerLoad}, dec => 1, trans => [qw(shorten)] }, + connections => { src => $exprs{Connection}, dec => 1, trans => [qw(shorten)] }, + slow => { src => 'Slow_queries', dec => 1, trans => [qw(shorten)] }, + q_cache_hit => { src => $exprs{QcacheHitRatio}, dec => 1, trans => [qw(percent)] }, + key_buffer_hit => { src => '1-(Key_reads/(Key_read_requests||1))', dec => 1, trans => [qw(percent)] }, + bps_in => { src => 'Bytes_received/Uptime_hires', dec => 1, trans => [qw(shorten)] }, + bps_out => { src => 'Bytes_sent/Uptime_hires', dec => 1, trans => [qw(shorten)] }, + when => { src => 'when' }, + q_detail => { src => $exprs{QueryDetail} }, + }, + visible => [ qw(cxn when load connections qps slow q_detail q_cache_hit key_buffer_hit bps_in bps_out)], + filters => [], + sort_cols => 'when cxn', + sort_dir => '1', + innodb => '', + hide_caption => 1, + group_by => [], + aggregate => 0, + }, + row_operations => { + capt => 'InnoDB Row Operations', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + num_inserts => { src => 'IB_ro_num_rows_ins' }, + num_updates => { src => 'IB_ro_num_rows_upd' }, + num_reads => { src => 'IB_ro_num_rows_read' }, + num_deletes => { src => 'IB_ro_num_rows_del' }, + num_inserts_sec => { src => 'IB_ro_ins_sec' }, + num_updates_sec => { src => 'IB_ro_upd_sec' }, + num_reads_sec => { src => 'IB_ro_read_sec' }, + num_deletes_sec => { src => 'IB_ro_del_sec' }, + }, + visible => [ qw(cxn num_inserts num_updates num_reads num_deletes num_inserts_sec + num_updates_sec num_reads_sec num_deletes_sec)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'ro', + group_by => [], + aggregate => 0, + }, + row_operation_misc => { + capt => 'Row Operation Misc', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + queries_in_queue => { src => 'IB_ro_queries_in_queue' }, + queries_inside => { src => 'IB_ro_queries_inside' }, + read_views_open => { src => 'IB_ro_read_views_open' }, + main_thread_id => { src => 'IB_ro_main_thread_id' }, + main_thread_proc_no => { src => 'IB_ro_main_thread_proc_no' }, + main_thread_state => { src => 'IB_ro_main_thread_state' }, + num_res_ext => { src => 'IB_ro_n_reserved_extents' }, + }, + visible => [ qw(cxn queries_in_queue queries_inside read_views_open main_thread_state)], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'ro', + group_by => [], + aggregate => 0, + }, + semaphores => { + capt => 'InnoDB Semaphores', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + mutex_os_waits => { src => 'IB_sm_mutex_os_waits' }, + mutex_spin_rounds => { src => 'IB_sm_mutex_spin_rounds' }, + mutex_spin_waits => { src => 'IB_sm_mutex_spin_waits' }, + reservation_count => { src => 'IB_sm_reservation_count' }, + rw_excl_os_waits => { src => 'IB_sm_rw_excl_os_waits' }, + rw_excl_spins => { src => 'IB_sm_rw_excl_spins' }, + rw_shared_os_waits => { src => 'IB_sm_rw_shared_os_waits' }, + rw_shared_spins => { src => 'IB_sm_rw_shared_spins' }, + signal_count => { src => 'IB_sm_signal_count' }, + wait_array_size => { src => 'IB_sm_wait_array_size' }, + }, + visible => [ qw(cxn mutex_os_waits mutex_spin_waits mutex_spin_rounds + rw_excl_os_waits rw_excl_spins rw_shared_os_waits rw_shared_spins + signal_count reservation_count )], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => 'sm', + group_by => [], + aggregate => 0, + }, + slave_io_status => { + capt => 'Slave I/O Status', + cust => {}, + cols => { + cxn => { src => $exprs{chcxn_2_cxn}, hdr => 'CXN' }, + connect_retry => { src => 'connect_retry' }, + master_host => { src => 'master_host', hdr => 'Master'}, + master_uuid => { src => '(master_uuid||"N/A")' }, + master_log_file => { src => 'master_log_file', hdr => 'File' }, + master_port => { src => 'master_port' }, + master_ssl_allowed => { src => 'master_ssl_allowed' }, + master_ssl_ca_file => { src => 'master_ssl_ca_file' }, + master_ssl_ca_path => { src => 'master_ssl_ca_path' }, + master_ssl_cert => { src => 'master_ssl_cert' }, + master_ssl_cipher => { src => 'master_ssl_cipher' }, + master_ssl_key => { src => 'master_ssl_key' }, + master_user => { src => 'master_user' }, + read_master_log_pos => { src => 'read_master_log_pos', hdr => 'Pos' }, + relay_log_size => { src => 'relay_log_space', trans => [qw(shorten)] }, + slave_io_running => { src => 'slave_io_running', hdr => 'On?' }, + slave_io_state => { src => 'slave_io_state', hdr => 'State' }, + channel_name => { src => $exprs{chcxn_2_ch}, hdr => 'Channel'}, + }, + visible => [ qw(cxn channel_name master_host master_uuid slave_io_running master_log_file relay_log_size read_master_log_pos slave_io_state)], + filters => [ qw( cxn_is_slave ) ], + sort_cols => 'slave_io_running channel_name cxn', + colors => [ + { col => 'slave_io_running', op => 'ne', arg => 'Yes', color => 'black on_red' }, + ], + sort_dir => '1', + innodb => '', + group_by => [qw(channel_name)], + aggregate => 0, + }, + slave_sql_status => { + capt => 'Slave SQL Status', + cust => {}, + cols => { + cxn => { src => $exprs{chcxn_2_cxn}, hdr => 'CXN' }, + exec_master_log_pos => { src => 'exec_master_log_pos', hdr => 'Master Pos' }, + last_errno => { src => 'last_errno' }, + last_error => { src => 'last_error' }, + master_host => { src => 'master_host', hdr => 'Master' }, + master_uuid => { src => '(master_uuid||"N/A")' }, + relay_log_file => { src => 'relay_log_file' }, + relay_log_pos => { src => 'relay_log_pos' }, + relay_log_size => { src => 'relay_log_space', trans => [qw(shorten)] }, + relay_master_log_file => { src => 'relay_master_log_file', hdr => 'Master File' }, + replicate_do_db => { src => 'replicate_do_db' }, + replicate_do_table => { src => 'replicate_do_table' }, + replicate_ignore_db => { src => 'replicate_ignore_db' }, + replicate_ignore_table => { src => 'replicate_ignore_table' }, + replicate_wild_do_table => { src => 'replicate_wild_do_table' }, + replicate_wild_ignore_table => { src => 'replicate_wild_ignore_table' }, + skip_counter => { src => 'skip_counter' }, + slave_sql_running => { src => 'slave_sql_running', hdr => 'On?' }, + sort_time => { src => 'int(seconds_behind_master/60)' }, + until_condition => { src => 'until_condition' }, + until_log_file => { src => 'until_log_file' }, + until_log_pos => { src => 'until_log_pos' }, + time_behind_master => { src => 'seconds_behind_master', trans => [ qw(secs_to_time) ] }, + bytes_behind_master => { src => 'master_log_file && master_log_file eq relay_master_log_file ? read_master_log_pos - exec_master_log_pos : 0', trans => [qw(shorten)] }, + slave_catchup_rate => { src => $exprs{SlaveCatchupRate}, trans => [ qw(set_precision) ] }, + slave_open_temp_tables => { src => 'Slave_open_temp_tables' }, + retrieved_gtid_set => { src => '(retrieved_gtid_set||"N/A")' }, + executed_gtid_set => { src => '(executed_gtid_set||"N/A")' }, + channel_name => { src => $exprs{chcxn_2_ch}, hdr => 'Channel'}, + }, + visible => [ qw(cxn channel_name master_host master_uuid slave_sql_running time_behind_master slave_catchup_rate slave_open_temp_tables relay_log_pos last_error retrieved_gtid_set executed_gtid_set)], + filters => [ qw( cxn_is_slave ) ], + sort_cols => 'slave_sql_running -sort_time channel_name cxn', + sort_dir => '1', + innodb => '', + colors => [ + { col => 'slave_sql_running', op => 'ne', arg => 'Yes', color => 'black on_red' }, + { col => 'time_behind_master', op => '>', arg => 600, color => 'red' }, + { col => 'time_behind_master', op => '>', arg => 60, color => 'yellow' }, + { col => 'time_behind_master', op => '==', arg => 0, color => 'white' }, + ], + group_by => [qw(channel_name)], + aggregate => 0, + }, + table_statistics => { + capt => 'Data from TABLE_STATISTICS', + cust => {}, + cols => { + cxn => { src => 'cxn', minw => 6, maxw => 10 }, + db => { src => 'table_schema' }, + tbl => { src => 'table_name' }, + rows_read => { src => 'rows_read' }, + rows_changed => { src => 'rows_changed' }, + rows_changed_x_indexes => { src => 'rows_changed_x_indexes' }, + }, + visible => [ qw(cxn db tbl rows_read rows_changed rows_changed_x_indexes) ], + filters => [ ], + sort_cols => 'rows_read', + sort_dir => '-1', + innodb => '', + colors => [], + hide_caption => 1, + group_by => [], + aggregate => 0, + }, + t_header => { + capt => 'T-Mode Header', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + dirty_bufs => { src => $exprs{DirtyBufs}, trans => [qw(percent)] }, + history_list_len => { src => 'IB_tx_history_list_len' }, + lock_structs => { src => 'IB_tx_num_lock_structs' }, + num_txns => { src => $exprs{NumTxns} }, + max_txn => { src => $exprs{MaxTxnTime}, trans => [qw(secs_to_time)] }, + undo_for => { src => 'IB_tx_purge_undo_for' }, + used_bufs => { src => $exprs{BufPoolFill}, trans => [qw(percent)]}, + versions => { src => $exprs{OldVersions} }, + }, + visible => [ qw(cxn history_list_len versions undo_for dirty_bufs used_bufs num_txns max_txn lock_structs)], + filters => [ ], + sort_cols => 'cxn', + sort_dir => '1', + innodb => '', + colors => [], + hide_caption => 1, + group_by => [], + aggregate => 0, + }, + var_status => { + capt => 'Variables & Status', + cust => {}, + cols => {}, # Generated from current varset + visible => [], # Generated from current varset + filters => [], + sort_cols => '', + sort_dir => 1, + innodb => '', + temp => 1, # Do not persist to config file. + hide_caption => 1, + pivot => 0, + group_by => [], + aggregate => 0, + }, + wait_array => { + capt => 'InnoDB Wait Array', + cust => {}, + cols => { + cxn => { src => 'cxn' }, + thread => { src => 'thread' }, + waited_at_filename => { src => 'waited_at_filename' }, + waited_at_line => { src => 'waited_at_line' }, + 'time' => { src => 'waited_secs', trans => [ qw(secs_to_time) ] }, + request_type => { src => 'request_type' }, + lock_mem_addr => { src => 'lock_mem_addr' }, + lock_cfile_name => { src => 'lock_cfile_name' }, + lock_cline => { src => 'lock_cline' }, + writer_thread => { src => 'writer_thread' }, + writer_lock_mode => { src => 'writer_lock_mode' }, + num_readers => { src => 'num_readers' }, + lock_var => { src => 'lock_var' }, + waiters_flag => { src => 'waiters_flag' }, + last_s_file_name => { src => 'last_s_file_name' }, + last_s_line => { src => 'last_s_line' }, + last_x_file_name => { src => 'last_x_file_name' }, + last_x_line => { src => 'last_x_line' }, + cell_waiting => { src => 'cell_waiting' }, + cell_event_set => { src => 'cell_event_set' }, + }, + visible => [ qw(cxn thread time waited_at_filename waited_at_line request_type num_readers lock_var waiters_flag cell_waiting cell_event_set)], + filters => [], + sort_cols => 'cxn -time', + sort_dir => '1', + innodb => 'sm', + group_by => [], + aggregate => 0, + }, + health_dashboard => { + capt => 'Health Dashboard', + hide_caption => 1, + cust => {}, + cols => { + cxn => { src => 'cxn' }, + uptime => { src => 'Uptime', trans => [qw(fuzzy_time)] }, + qps => { src => 'Questions/Uptime_hires', dec => 1, trans => [qw(shorten)] }, + spark_qps => { src => 'SPARK_qps' }, + run => { src => 'User_threads_running' }, + spark_run => { src => 'SPARK_run' }, + max_query_time => { src => 'Max_query_time', trans => [qw(fuzzy_time)] }, + connections => { src => 'Threads_connected' }, + miss_rate => { src => 'Innodb_buffer_pool_reads/Uptime_hires', trans => [qw(set_precision)] }, + locked_count => { src => 'Locked_count' }, + 'open' => { src => 'Open_tables' }, + slave_running => { src => 'Slave_ok . " " . (Slaves || "")' }, + time_behind_master => { src => 'seconds_behind_master', hdr => 'ReplLag' , trans => [qw(fuzzy_time)] }, + longest_sql => { src => 'Longest_sql', trans => [qw(distill)] }, + }, + visible => [qw( + cxn uptime max_query_time time_behind_master qps connections run + miss_rate locked_count open slave_running longest_sql + )], + filters => [], + sort_cols => 'cxn', + sort_dir => '1', + innodb => '', + colors => [ + { col => 'slave_running', op => '=~', arg => 'No', color => 'black on_red' }, + { col => 'max_query_time', op => '>', arg => 30 * 60, color => 'red' }, + { col => 'max_query_time', op => '>', arg => 600, color => 'yellow' }, + { col => 'time_behind_master', op => '>', arg => 3600, color => 'cyan' }, + ], + group_by => [], + aggregate => 0, + }, +); + +# Initialize %tbl_meta from %columns and do some checks. +foreach my $table_name ( keys %tbl_meta ) { + my $table = $tbl_meta{$table_name}; + my $cols = $table->{cols}; + + foreach my $col_name ( keys %$cols ) { + my $col_def = $table->{cols}->{$col_name}; + die "I can't find a column named '$col_name' for '$table_name'" unless $columns{$col_name}; + $columns{$col_name}->{referenced} = 1; + + foreach my $prop ( keys %col_props ) { + # Each column gets non-existing values set from %columns or defaults from %col_props. + if ( !$col_def->{$prop} ) { + $col_def->{$prop} + = defined($columns{$col_name}->{$prop}) + ? $columns{$col_name}->{$prop} + : $col_props{$prop}; + } + } + + # Ensure transformations and aggregate functions are valid + die "Unknown aggregate function '$col_def->{agg}' " + . "for column '$col_name' in table '$table_name'" + unless exists $agg_funcs{$col_def->{agg}}; + foreach my $trans ( @{$col_def->{trans}} ) { + die "Unknown transformation '$trans' " + . "for column '$col_name' in table '$table_name'" + unless exists $trans_funcs{$trans}; + } + } + + # Ensure each column in visible and group_by exists in cols + foreach my $place ( qw(visible group_by) ) { + foreach my $col_name ( @{$table->{$place}} ) { + if ( !exists $cols->{$col_name} ) { + die "Column '$col_name' is listed in '$place' for '$table_name', but doesn't exist"; + } + } + } + + # Compile sort and color subroutines + $table->{sort_func} = make_sort_func($table); + $table->{color_func} = make_color_func($table); +} + +# This is for code cleanup: +{ + my @unused_cols = grep { !$columns{$_}->{referenced} } sort keys %columns; + if ( @unused_cols ) { + die "The following columns are not used: " + . join(' ', @unused_cols); + } +} + +# ########################################################################### +# Operating modes {{{3 +# ########################################################################### +my %modes = ( + A => { + hdr => 'Dashboard', + cust => {}, + note => 'Shows health/status dashboard', + action_for => { + k => { + action => sub { kill_query('CONNECTION') }, + label => "Kill a query's connection", + }, + x => { + action => sub { kill_query('QUERY') }, + label => "Kill a query", + }, + r => { + action => sub { reverse_sort('health_dashboard'); }, + label => 'Reverse sort order', + }, + s => { + action => sub { choose_sort_cols('health_dashboard'); }, + label => "Choose sort column", + }, + }, + display_sub => \&display_A, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(health_dashboard)], + visible_tables => [qw(health_dashboard)], + }, + B => { + hdr => 'InnoDB Buffers', + cust => {}, + note => 'Shows buffer info from InnoDB', + action_for => { + i => { + action => sub { toggle_config('status_inc') }, + label => 'Toggle incremental status display', + }, + }, + display_sub => \&display_B, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(buffer_pool page_statistics insert_buffers adaptive_hash_index)], + visible_tables => [qw(buffer_pool page_statistics insert_buffers adaptive_hash_index)], + }, + C => { + hdr => 'Command Summary', + cust => {}, + note => 'Shows relative magnitude of variables', + action_for => { + s => { + action => sub { get_config_interactive('cmd_filter') }, + label => 'Choose variable prefix', + }, + }, + display_sub => \&display_C, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(cmd_summary)], + visible_tables => [qw(cmd_summary)], + }, + D => { + hdr => 'InnoDB Deadlocks', + cust => {}, + note => 'View InnoDB deadlock information', + action_for => { + c => { + action => sub { edit_table('deadlock_transactions') }, + label => 'Choose visible columns', + }, + w => { + action => \&create_deadlock, + label => 'Wipe deadlock status info by creating a deadlock', + }, + }, + display_sub => \&display_D, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(deadlock_transactions deadlock_locks)], + visible_tables => [qw(deadlock_transactions deadlock_locks)], + }, + F => { + hdr => 'InnoDB FK Err', + cust => {}, + note => 'View the latest InnoDB foreign key error', + action_for => {}, + display_sub => \&display_F, + connections => [], + server_group => '', + one_connection => 1, + tables => [qw(fk_error)], + visible_tables => [qw(fk_error)], + }, + I => { + hdr => 'InnoDB I/O Info', + cust => {}, + note => 'Shows I/O info (i/o, log...) from InnoDB', + action_for => { + i => { + action => sub { toggle_config('status_inc') }, + label => 'Toggle incremental status display', + }, + }, + display_sub => \&display_I, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(io_threads pending_io file_io_misc log_statistics)], + visible_tables => [qw(io_threads pending_io file_io_misc log_statistics)], + }, + K => { + hdr => 'InnoDB Lock Waits', + cust => {}, + note => 'Shows blocked and blocking transactions', + action_for => { + k => { + action => sub { kill_query('CONNECTION') }, + label => "Kill a query's connection", + }, + }, + display_sub => \&display_K, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(innodb_blocked_blocker)], + visible_tables => [qw(innodb_blocked_blocker)], + }, + L => { + hdr => 'Locks', + cust => {}, + note => 'Shows transaction locks', + action_for => { + a => { + action => sub { send_cmd_to_servers('CREATE TABLE IF NOT EXISTS test.innodb_lock_monitor(a int) ENGINE=InnoDB', 0, '', []); }, + label => 'Start the InnoDB Lock Monitor', + }, + o => { + action => sub { send_cmd_to_servers('DROP TABLE IF EXISTS test.innodb_lock_monitor', 0, '', []); }, + label => 'Stop the InnoDB Lock Monitor', + }, + }, + display_sub => \&display_L, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(innodb_locks)], + visible_tables => [qw(innodb_locks)], + }, + M => { + hdr => 'Replication Status', + cust => {}, + note => 'Shows replication (master and slave) status', + action_for => { + a => { + action => sub { send_cmd_to_servers('START SLAVE', 0, 'START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE = ?, MASTER_LOG_POS = ?', []); }, + label => 'Start slave(s)', + }, + i => { + action => sub { toggle_config('status_inc') }, + label => 'Toggle incremental status display', + }, + o => { + action => sub { send_cmd_to_servers('STOP SLAVE', 0, '', []); }, + label => 'Stop slave(s)', + }, + b => { + action => sub { purge_master_logs() }, + label => 'Purge unused master logs', + }, + }, + display_sub => \&display_M, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(slave_sql_status slave_io_status master_status)], + visible_tables => [qw(slave_sql_status slave_io_status master_status)], + }, + O => { + hdr => 'Open Tables', + cust => {}, + note => 'Shows open tables in MySQL', + action_for => { + r => { + action => sub { reverse_sort('open_tables'); }, + label => 'Reverse sort order', + }, + s => { + action => sub { choose_sort_cols('open_tables'); }, + label => "Choose sort column", + }, + }, + display_sub => \&display_O, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(open_tables)], + visible_tables => [qw(open_tables)], + }, + U => { + hdr => 'User Statistics', + cust => {}, + note => 'Displays Percona/MariaDB enhancements such as table statistics', + action_for => { + i => { + action => sub { set_visible_table('index_statistics') }, + label => 'Switch to INDEX_STATISTICS', + }, + s => { + action => sub { $clear_screen_sub->(); send_cmd_to_servers('SET @@global.userstat_running := 1 - @@global.userstat_running', 1, undef, []); }, + label => "Change the display's sort column", + }, + t => { + action => sub { set_visible_table('table_statistics') }, + label => 'Switch to TABLE_STATISTICS', + }, + x => { + action => sub { set_visible_table('index_table_statistics') }, + label => 'Switch to {INDEX,TABLE}_STATISTICS', + }, + }, + display_sub => \&display_P, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(table_statistics index_statistics index_table_statistics)], + visible_tables => [qw(index_table_statistics)], + }, + Q => { + hdr => 'Query List', + cust => {}, + note => 'Shows queries from SHOW FULL PROCESSLIST', + action_for => { + a => { + action => sub { toggle_filter('processlist', 'hide_self') }, + label => 'Toggle the innotop process', + }, + c => { + action => sub { edit_table('processlist') }, + label => 'Choose visible columns', + }, + e => { + action => sub { analyze_query('e'); }, + label => "Explain a thread's query", + }, + f => { + action => sub { analyze_query('f'); }, + label => "Show a thread's full query", + }, + h => { + action => sub { toggle_visible_table('Q', 'q_header') }, + label => 'Toggle the header on and off', + }, + i => { + action => sub { toggle_filter('processlist', 'hide_inactive') }, + label => 'Toggle idle processes', + }, + k => { + action => sub { kill_query('CONNECTION') }, + label => "Kill a query's connection", + }, + r => { + action => sub { reverse_sort('processlist'); }, + label => 'Reverse sort order', + }, + s => { + action => sub { choose_sort_cols('processlist'); }, + label => "Change the display's sort column", + }, + t => { + action => sub { toggle_filter('processlist', 'hide_connect') }, + label => 'Toggle slave processes', + }, + x => { + action => sub { kill_query('QUERY') }, + label => "Kill a query", + }, + }, + display_sub => \&display_Q, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(q_header processlist)], + visible_tables => [qw(q_header processlist)], + }, + R => { + hdr => 'InnoDB Row Ops', + cust => {}, + note => 'Shows InnoDB row operation and semaphore info', + action_for => { + i => { + action => sub { toggle_config('status_inc') }, + label => 'Toggle incremental status display', + }, + }, + display_sub => \&display_R, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(row_operations row_operation_misc semaphores wait_array)], + visible_tables => [qw(row_operations row_operation_misc semaphores wait_array)], + }, + S => { + hdr => 'Variables & Status', + cust => {}, + note => 'Shows query load statistics a la vmstat', + action_for => { + '>' => { + action => sub { switch_var_set('S_set', 1) }, + label => 'Switch to next variable set', + }, + '<' => { + action => sub { switch_var_set('S_set', -1) }, + label => 'Switch to prev variable set', + }, + c => { + action => sub { + choose_var_set('S_set'); + start_S_mode(); + }, + label => "Choose which set to display", + }, + e => { + action => \&edit_current_var_set, + label => 'Edit the current set of variables', + }, + i => { + action => sub { $clear_screen_sub->(); toggle_config('status_inc') }, + label => 'Toggle incremental status display', + }, + '-' => { + action => sub { set_display_precision(-1) }, + label => 'Decrease fractional display precision', + }, + '+' => { + action => sub { set_display_precision(1) }, + label => 'Increase fractional display precision', + }, + g => { + action => sub { set_s_mode('g') }, + label => 'Switch to graph (tload) view', + }, + s => { + action => sub { set_s_mode('s') }, + label => 'Switch to standard (vmstat) view', + }, + v => { + action => sub { set_s_mode('v') }, + label => 'Switch to pivoted view', + }, + }, + display_sub => \&display_S, + no_clear_screen => 1, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(var_status)], + visible_tables => [qw(var_status)], + }, + T => { + hdr => 'InnoDB Txns', + cust => {}, + note => 'Shows InnoDB transactions in top-like format', + action_for => { + a => { + action => sub { toggle_filter('innodb_transactions', 'hide_self') }, + label => 'Toggle the innotop process', + }, + c => { + action => sub { edit_table('innodb_transactions') }, + label => 'Choose visible columns', + }, + e => { + action => sub { analyze_query('e'); }, + label => "Explain a thread's query", + }, + f => { + action => sub { analyze_query('f'); }, + label => "Show a thread's full query", + }, + h => { + action => sub { toggle_visible_table('T', 't_header') }, + label => 'Toggle the header on and off', + }, + i => { + action => sub { toggle_filter('innodb_transactions', 'hide_inactive') }, + label => 'Toggle inactive transactions', + }, + k => { + action => sub { kill_query('CONNECTION') }, + label => "Kill a transaction's connection", + }, + r => { + action => sub { reverse_sort('innodb_transactions'); }, + label => 'Reverse sort order', + }, + s => { + action => sub { choose_sort_cols('innodb_transactions'); }, + label => "Change the display's sort column", + }, + x => { + action => sub { kill_query('QUERY') }, + label => "Kill a query", + }, + }, + display_sub => \&display_T, + connections => [], + server_group => '', + one_connection => 0, + tables => [qw(t_header innodb_transactions)], + visible_tables => [qw(t_header innodb_transactions)], + }, +); + +# ########################################################################### +# Global key mappings {{{3 +# Keyed on a single character, which is read from the keyboard. Uppercase +# letters switch modes. Lowercase letters access commands when in a mode. +# These can be overridden by action_for in %modes. +# ########################################################################### +my %action_for = ( + '$' => { + action => \&edit_configuration, + label => 'Edit configuration settings', + }, + '?' => { + action => \&display_help, + label => 'Show help', + }, + '!' => { + action => \&display_license, + label => 'Show license and warranty', + }, + '^' => { + action => \&edit_table, + label => "Edit the displayed table(s)", + }, + '#' => { + action => \&choose_server_groups, + label => 'Select/create server groups', + }, + '@' => { + action => \&choose_servers, + label => 'Select/create server connections', + }, + '/' => { + action => \&add_quick_filter, + label => 'Quickly filter what you see', + }, + '\\' => { + action => \&clear_quick_filters, + label => 'Clear quick-filters', + }, + '%' => { + action => \&choose_filters, + label => 'Choose and edit table filters', + }, + "\t" => { + action => \&next_server_group, + label => 'Switch to the next server group', + key => 'TAB', + }, + '=' => { + action => \&toggle_aggregate, + label => 'Toggle aggregation', + }, + # TODO: can these be auto-generated from %modes? + A => { + action => sub { switch_mode('A') }, + label => '', + }, + B => { + action => sub { switch_mode('B') }, + label => '', + }, + C => { + action => sub { switch_mode('C') }, + label => '', + }, + D => { + action => sub { switch_mode('D') }, + label => '', + }, + F => { + action => sub { switch_mode('F') }, + label => '', + }, + I => { + action => sub { switch_mode('I') }, + label => '', + }, + K => { + action => sub { switch_mode('K') }, + label => '', + }, + L => { + action => sub { switch_mode('L') }, + label => '', + }, + M => { + action => sub { switch_mode('M') }, + label => '', + }, + O => { + action => sub { switch_mode('O') }, + label => '', + }, + Q => { + action => sub { switch_mode('Q') }, + label => '', + }, + R => { + action => sub { switch_mode('R') }, + label => '', + }, + S => { + action => \&start_S_mode, + label => '', + }, + T => { + action => sub { switch_mode('T') }, + label => '', + }, + U => { + action => sub { switch_mode('U') }, + label => '', + }, + d => { + action => sub { get_config_interactive('interval') }, + label => 'Change refresh interval', + }, + n => { action => \&next_server, label => 'Switch to the next connection' }, + p => { action => \&pause, label => 'Pause innotop', }, + q => { action => \&finish, label => 'Quit innotop', }, +); + +# ########################################################################### +# Sleep times after certain statements {{{3 +# ########################################################################### +my %stmt_sleep_time_for = (); + +# ########################################################################### +# Config editor key mappings {{{3 +# ########################################################################### +my %cfg_editor_action = ( + c => { + note => 'Edit columns, etc in the displayed table(s)', + func => \&edit_table, + }, + g => { + note => 'Edit general configuration', + func => \&edit_configuration_variables, + }, + k => { + note => 'Edit row-coloring rules', + func => \&edit_color_rules, + }, + p => { + note => 'Manage plugins', + func => \&edit_plugins, + }, + s => { + note => 'Edit server groups', + func => \&edit_server_groups, + }, + S => { + note => 'Edit SQL statement sleep delays', + func => \&edit_stmt_sleep_times, + }, + t => { + note => 'Choose which table(s) to display in this mode', + func => \&choose_mode_tables, + }, +); + +# ########################################################################### +# Color editor key mappings {{{3 +# ########################################################################### +my %color_editor_action = ( + n => { + note => 'Create a new color rule', + func => sub { + my ( $tbl, $idx ) = @_; + my $meta = $tbl_meta{$tbl}; + + $clear_screen_sub->(); + my $col; + do { + $col = prompt_list( + 'Choose the target column for the rule', + '', + sub { return keys %{$meta->{cols}} }, + { map { $_ => $meta->{cols}->{$_}->{label} } keys %{$meta->{cols}} }); + } while ( !$col ); + ( $col ) = grep { $_ } split(/\W+/, $col); + return $idx unless $col && exists $meta->{cols}->{$col}; + + $clear_screen_sub->(); + my $op; + do { + $op = prompt_list( + 'Choose the comparison operator for the rule', + '', + sub { return keys %comp_ops }, + { map { $_ => $comp_ops{$_} } keys %comp_ops } ); + } until ( $op ); + $op =~ s/\s+//g; + return $idx unless $op && exists $comp_ops{$op}; + + my $arg; + do { + $arg = prompt('Specify an argument for the comparison'); + } until defined $arg; + + my $color; + do { + $color = prompt_list( + 'Choose the color(s) the row should be when the rule matches', + '', + sub { return keys %ansicolors }, + { map { $_ => $_ } keys %ansicolors } ); + } until defined $color; + $color = join(' ', unique(grep { exists $ansicolors{$_} } split(/\W+/, $color))); + return $idx unless $color; + + push @{$tbl_meta{$tbl}->{colors}}, { + col => $col, + op => $op, + arg => $arg, + color => $color + }; + $tbl_meta{$tbl}->{cust}->{colors} = 1; + + return $idx; + }, + }, + d => { + note => 'Remove the selected rule', + func => sub { + my ( $tbl, $idx ) = @_; + my @rules = @{ $tbl_meta{$tbl}->{colors} }; + return 0 unless @rules > 0 && $idx < @rules && $idx >= 0; + splice(@{$tbl_meta{$tbl}->{colors}}, $idx, 1); + $tbl_meta{$tbl}->{cust}->{colors} = 1; + return $idx == @rules ? $#rules : $idx; + }, + }, + j => { + note => 'Move highlight down one', + func => sub { + my ( $tbl, $idx ) = @_; + my $num_rules = scalar @{$tbl_meta{$tbl}->{colors}}; + return ($idx + 1) % $num_rules; + }, + }, + k => { + note => 'Move highlight up one', + func => sub { + my ( $tbl, $idx ) = @_; + my $num_rules = scalar @{$tbl_meta{$tbl}->{colors}}; + return ($idx - 1) % $num_rules; + }, + }, + '+' => { + note => 'Move selected rule up one', + func => sub { + my ( $tbl, $idx ) = @_; + my $meta = $tbl_meta{$tbl}; + my $dest = $idx == 0 ? scalar(@{$meta->{colors}} - 1) : $idx - 1; + my $temp = $meta->{colors}->[$idx]; + $meta->{colors}->[$idx] = $meta->{colors}->[$dest]; + $meta->{colors}->[$dest] = $temp; + $meta->{cust}->{colors} = 1; + return $dest; + }, + }, + '-' => { + note => 'Move selected rule down one', + func => sub { + my ( $tbl, $idx ) = @_; + my $meta = $tbl_meta{$tbl}; + my $dest = $idx == scalar(@{$meta->{colors}} - 1) ? 0 : $idx + 1; + my $temp = $meta->{colors}->[$idx]; + $meta->{colors}->[$idx] = $meta->{colors}->[$dest]; + $meta->{colors}->[$dest] = $temp; + $meta->{cust}->{colors} = 1; + return $dest; + }, + }, +); + +# ########################################################################### +# Plugin editor key mappings {{{3 +# ########################################################################### +my %plugin_editor_action = ( + '*' => { + note => 'Toggle selected plugin active/inactive', + func => sub { + my ( $plugins, $idx ) = @_; + my $plugin = $plugins->[$idx]; + $plugin->{active} = $plugin->{active} ? 0 : 1; + return $idx; + }, + }, + j => { + note => 'Move highlight down one', + func => sub { + my ( $plugins, $idx ) = @_; + return ($idx + 1) % scalar(@$plugins); + }, + }, + k => { + note => 'Move highlight up one', + func => sub { + my ( $plugins, $idx ) = @_; + return $idx == 0 ? @$plugins - 1 : $idx - 1; + }, + }, +); + +# ########################################################################### +# Table editor key mappings {{{3 +# ########################################################################### +my %tbl_editor_action = ( + a => { + note => 'Add a column to the table', + func => sub { + my ( $tbl, $col ) = @_; + my @visible_cols = @{ $tbl_meta{$tbl}->{visible} }; + my %all_cols = %{ $tbl_meta{$tbl}->{cols} }; + delete @all_cols{@visible_cols}; + my $choice = prompt_list( + 'Choose a column', + '', + sub { return keys %all_cols; }, + { map { $_ => $all_cols{$_}->{label} || $all_cols{$_}->{hdr} } keys %all_cols }); + if ( $all_cols{$choice} ) { + push @{$tbl_meta{$tbl}->{visible}}, $choice; + $tbl_meta{$tbl}->{cust}->{visible} = 1; + return $choice; + } + return $col; + }, + }, + n => { + note => 'Create a new column and add it to the table', + func => sub { + my ( $tbl, $col ) = @_; + + $clear_screen_sub->(); + print word_wrap("Choose a name for the column. This name is not displayed, and is used only " + . "for internal reference. It can contain only lowercase letters, numbers, " + . "and underscores."); + print "\n\n"; + do { + $col = prompt("Enter column name"); + $col = '' if $col =~ m/[^a-z0-9_]/; + } while ( !$col ); + + $clear_screen_sub->(); + my $hdr; + do { + $hdr = prompt("Enter column header"); + } while ( !$hdr ); + + $clear_screen_sub->(); + print "Choose a source for the column's data\n\n"; + my ( $src, $sub, $err ); + do { + if ( $err ) { + print "Error: $err\n\n"; + } + $src = prompt("Enter column source"); + if ( $src ) { + ( $sub, $err ) = compile_expr($src); + } + } until ( !$err); + + # TODO: this duplicates %col_props. + $tbl_meta{$tbl}->{cols}->{$col} = { + hdr => $hdr, + src => $src, + just => '-', + num => 0, + label => 'User-defined', + user => 1, + tbl => $tbl, + minw => 0, + maxw => 0, + trans => [], + func => $sub, + dec => 0, + agg => 0, + aggonly => 0, + agghide => 0, + }; + + $tbl_meta{$tbl}->{visible} = [ unique(@{$tbl_meta{$tbl}->{visible}}, $col) ]; + $tbl_meta{$tbl}->{cust}->{visible} = 1; + return $col; + }, + }, + d => { + note => 'Remove selected column', + func => sub { + my ( $tbl, $col ) = @_; + my @visible_cols = @{ $tbl_meta{$tbl}->{visible} }; + my $idx = 0; + return $col unless @visible_cols > 1; + while ( $visible_cols[$idx] ne $col ) { + $idx++; + } + $tbl_meta{$tbl}->{visible} = [ grep { $_ ne $col } @visible_cols ]; + $tbl_meta{$tbl}->{cust}->{visible} = 1; + return $idx == $#visible_cols ? $visible_cols[$idx - 1] : $visible_cols[$idx + 1]; + }, + }, + e => { + note => 'Edit selected column', + func => sub { + # TODO: make this editor hotkey-driven and give readline support. + my ( $tbl, $col ) = @_; + $clear_screen_sub->(); + my $meta = $tbl_meta{$tbl}->{cols}->{$col}; + my @prop = qw(hdr label src just num minw maxw trans agg); # TODO redundant + + my $answer; + do { + # Do what the user asked... + if ( $answer && grep { $_ eq $answer } @prop ) { + # Some properties are arrays, others scalars. + my $ini = ref $col_props{$answer} ? join(' ', @{$meta->{$answer}}) : $meta->{$answer}; + my $val = prompt("New value for $answer", undef, $ini); + $val = [ split(' ', $val) ] if ref($col_props{$answer}); + if ( $answer eq 'trans' ) { + $val = [ unique(grep{ exists $trans_funcs{$_} } @$val) ]; + } + @{$meta}{$answer, 'user', 'tbl' } = ( $val, 1, $tbl ); + } + + my @display_lines = ( + '', + "You are editing column $tbl.$col.\n", + ); + + push @display_lines, create_table2( + \@prop, + { map { $_ => $_ } @prop }, + { map { $_ => ref $meta->{$_} eq 'ARRAY' ? join(' ', @{$meta->{$_}}) + : ref $meta->{$_} ? '[expression code]' + : $meta->{$_} + } @prop + }, + { sep => ' ' }); + draw_screen(\@display_lines, { raw => 1 }); + print "\n\n"; # One to add space, one to clear readline artifacts + $answer = prompt('Edit what? (q to quit)'); + } while ( $answer ne 'q' ); + + return $col; + }, + }, + j => { + note => 'Move highlight down one', + func => sub { + my ( $tbl, $col ) = @_; + my @visible_cols = @{ $tbl_meta{$tbl}->{visible} }; + my $idx = 0; + while ( $visible_cols[$idx] ne $col ) { + $idx++; + } + return $visible_cols[ ($idx + 1) % @visible_cols ]; + }, + }, + k => { + note => 'Move highlight up one', + func => sub { + my ( $tbl, $col ) = @_; + my @visible_cols = @{ $tbl_meta{$tbl}->{visible} }; + my $idx = 0; + while ( $visible_cols[$idx] ne $col ) { + $idx++; + } + return $visible_cols[ $idx - 1 ]; + }, + }, + '+' => { + note => 'Move selected column up one', + func => sub { + my ( $tbl, $col ) = @_; + my $meta = $tbl_meta{$tbl}; + my @visible_cols = @{$meta->{visible}}; + my $idx = 0; + while ( $visible_cols[$idx] ne $col ) { + $idx++; + } + if ( $idx ) { + $visible_cols[$idx] = $visible_cols[$idx - 1]; + $visible_cols[$idx - 1] = $col; + $meta->{visible} = \@visible_cols; + } + else { + shift @{$meta->{visible}}; + push @{$meta->{visible}}, $col; + } + $meta->{cust}->{visible} = 1; + return $col; + }, + }, + '-' => { + note => 'Move selected column down one', + func => sub { + my ( $tbl, $col ) = @_; + my $meta = $tbl_meta{$tbl}; + my @visible_cols = @{$meta->{visible}}; + my $idx = 0; + while ( $visible_cols[$idx] ne $col ) { + $idx++; + } + if ( $idx == $#visible_cols ) { + unshift @{$meta->{visible}}, $col; + pop @{$meta->{visible}}; + } + else { + $visible_cols[$idx] = $visible_cols[$idx + 1]; + $visible_cols[$idx + 1] = $col; + $meta->{visible} = \@visible_cols; + } + $meta->{cust}->{visible} = 1; + return $col; + }, + }, + f => { + note => 'Choose filters', + func => sub { + my ( $tbl, $col ) = @_; + choose_filters($tbl); + return $col; + }, + }, + o => { + note => 'Edit color rules', + func => sub { + my ( $tbl, $col ) = @_; + edit_color_rules($tbl); + return $col; + }, + }, + s => { + note => 'Choose sort columns', + func => sub { + my ( $tbl, $col ) = @_; + choose_sort_cols($tbl); + return $col; + }, + }, + g => { + note => 'Choose group-by (aggregate) columns', + func => sub { + my ( $tbl, $col ) = @_; + choose_group_cols($tbl); + return $col; + }, + }, +); + +# ########################################################################### +# Global variables and environment {{{2 +# ########################################################################### + +my @this_term_size; # w_chars, h_chars, w_pix, h_pix +my @last_term_size; # w_chars, h_chars, w_pix, h_pix +my $char; +my $windows = $OSNAME =~ m/MSWin/; +my $have_color = 0; +my $MAX_ULONG = 4294967295; # 2^32-1 +my $num_regex = qr/^[+-]?(?=\d|\.)\d*(?:\.\d+)?(?:E[+-]?\d+|)$/i; +my $int_regex = qr/^\d+$/; +my $bool_regex = qr/^[01]$/; +my $term = undef; +my $file = undef; # File to watch for InnoDB monitor output +my $file_mtime = undef; # Status of watched file +my $file_data = undef; # Last chunk of text read from file +my $innodb_parser = InnoDBParser->new; + +my $nonfatal_errs = join('|', + 'Access denied for user', + 'Unknown MariaDB server host', + 'Unknown database', + 'Can\'t connect to local MariaDB server through socket', + 'Can\'t connect to MariaDB server on', + 'MySQL server has gone away', + 'Cannot call SHOW INNODB STATUS', + 'Access denied', + 'AutoCommit', + 'Lost connection to MariaDB server', + 'Lost connection to server', + 'Too many connections', +); + +if ( !$opts{n} ) { + require Term::ReadLine; + $term = Term::ReadLine->new('innotop'); +} + +# Stores status, variables, innodb status, master/slave status etc. +# Keyed on connection name. Each entry is a hashref of current and past data sets, +# keyed on clock tick. +my %vars; +my %info_gotten = (); # Which things have been retrieved for the current clock tick. +my %show_variables; # Stores SHOW VARIABLES for each cxn so we don't re-fetch. + +# Stores info on currently displayed queries: cxn, connection ID, query text, +# user, and host. +my @current_queries; + +my $lines_printed = 0; +my $clock = 0; # Incremented with every wake-sleep cycle +my $clearing_deadlocks = 0; + +# If terminal coloring is available, use it. The only function I want from +# the module is the colored() function. +eval { + if ( !$opts{n} ) { + if ( $windows ) { + require Win32::Console::ANSI; + } + require Term::ANSIColor; + import Term::ANSIColor qw(colored); + $have_color = 1; + } +}; +if ( $EVAL_ERROR || $opts{n} ) { + # If there was an error, manufacture my own colored() function that does no + # coloring. + *colored = sub { pop @_; @_; }; +} + +if ( $opts{n} ) { + $clear_screen_sub = sub {}; +} +elsif ( $windows ) { + $clear_screen_sub = sub { $lines_printed = 0; system("cls") }; +} +else { + my $clear = `clear`; + $clear_screen_sub = sub { $lines_printed = 0; print $clear }; +} + +# ########################################################################### +# Config storage. {{{2 +# ########################################################################### +my %config = ( + color => { + val => $have_color, + note => 'Whether to use terminal coloring', + conf => 'ALL', + pat => $bool_regex, + }, + cmd_filter => { + val => 'Com_', + note => 'Prefix for values in C mode', + conf => [qw(C)], + }, + plugin_dir => { + val => "$homepath/.innotop/plugins", + note => 'Directory where plugins can be found', + conf => 'ALL', + }, + show_percent => { + val => 1, + note => 'Show the % symbol after percentages', + conf => 'ALL', + pat => $bool_regex, + }, + skip_innodb => { + val => 0, + note => 'Disable SHOW INNODB STATUS', + conf => 'ALL', + pat => $bool_regex, + }, + S_func => { + val => 's', + note => 'What to display in S mode: graph, status, pivoted status', + conf => [qw(S)], + pat => qr/^[gsv]$/, + }, + cxn_timeout => { + val => 28800, + note => 'Connection timeout for keeping unused connections alive', + conf => 'ALL', + pat => $int_regex, + }, + graph_char => { + val => '*', + note => 'Character for drawing graphs', + conf => [ qw(S) ], + pat => qr/^.$/, + }, + show_cxn_errors_in_tbl => { + val => 1, + note => 'Whether to display connection errors as rows in the table', + conf => 'ALL', + pat => $bool_regex, + }, + hide_hdr => { + val => 0, + note => 'Whether to show column headers', + conf => 'ALL', + pat => $bool_regex, + }, + show_cxn_errors => { + val => 1, + note => 'Whether to print connection errors to STDOUT', + conf => 'ALL', + pat => $bool_regex, + }, + readonly => { + val => 1, + note => 'Whether the config file is read-only', + conf => [ qw() ], + pat => $bool_regex, + }, + global => { + val => 1, + note => 'Whether to show GLOBAL variables and status', + conf => 'ALL', + pat => $bool_regex, + }, + header_highlight => { + val => 'bold', + note => 'How to highlight table column headers', + conf => 'ALL', + pat => qr/^(?:bold|underline)$/, + }, + display_table_captions => { + val => 1, + note => 'Whether to put captions on tables', + conf => 'ALL', + pat => $bool_regex, + }, + charset => { + val => 'ascii', + note => 'What type of characters should be displayed in queries (ascii, unicode, none)', + conf => 'ALL', + pat => qr/^(?:ascii|unicode|none)$/, + }, + auto_wipe_dl => { + val => 0, + note => 'Whether to auto-wipe InnoDB deadlocks', + conf => 'ALL', + pat => $bool_regex, + }, + max_height => { + val => 30, + note => '[Win32] Max window height', + conf => 'ALL', + }, + debug => { + val => 0, + pat => $bool_regex, + note => 'Debug mode (more verbose errors, uses more memory)', + conf => 'ALL', + }, + num_digits => { + val => 2, + pat => $int_regex, + note => 'How many digits to show in fractional numbers and percents', + conf => 'ALL', + }, + debugfile => { + val => "$homepath/.innotop/core_dump", + note => 'A debug file in case you are interested in error output', + }, + show_statusbar => { + val => 1, + pat => $bool_regex, + note => 'Whether to show the status bar in the display', + conf => 'ALL', + }, + mode => { + val => "A", + note => "Which mode to start in", + cmdline => 1, + }, + status_inc => { + val => 0, + note => 'Whether to show raw or incremental values for status variables', + pat => $bool_regex, + }, + interval => { + val => 10, + pat => qr/^(?:(?:\d*?[1-9]\d*(?:\.\d*)?)|(?:\d*\.\d*?[1-9]\d*))$/, + note => "The interval at which the display will be refreshed. Fractional values allowed.", + }, + num_status_sets => { + val => 9, + pat => $int_regex, + note => 'How many sets of STATUS and VARIABLES values to show', + conf => [ qw(S) ], + }, + S_set => { + val => 'general', + pat => qr/^\w+$/, + note => 'Which set of variables to display in S (Variables & Status) mode', + conf => [ qw(S) ], + }, + timeformat => { + val => '%Y-%m-%dT%H:%M:%S', + pat => qr//, + note => 'The strftime() timestamp format to write in -n mode', + }, + spark => { + val => 10, + note => 'How long to make status variable sparklines', + conf => 'ALL', + pat => $int_regex, + }, +); + +# ########################################################################### +# Config file sections {{{2 +# The configuration file is broken up into sections like a .ini file. This +# variable defines those sections and the subroutines responsible for reading +# and writing them. +# ########################################################################### +my %config_file_sections = ( + plugins => { + reader => \&load_config_plugins, + writer => \&save_config_plugins, + }, + group_by => { + reader => \&load_config_group_by, + writer => \&save_config_group_by, + }, + filters => { + reader => \&load_config_filters, + writer => \&save_config_filters, + }, + active_filters => { + reader => \&load_config_active_filters, + writer => \&save_config_active_filters, + }, + visible_tables => { + reader => \&load_config_visible_tables, + writer => \&save_config_visible_tables, + }, + sort_cols => { + reader => \&load_config_sort_cols, + writer => \&save_config_sort_cols, + }, + active_columns => { + reader => \&load_config_active_columns, + writer => \&save_config_active_columns, + }, + tbl_meta => { + reader => \&load_config_tbl_meta, + writer => \&save_config_tbl_meta, + }, + general => { + reader => \&load_config_config, + writer => \&save_config_config, + }, + connections => { + reader => \&load_config_connections, + writer => \&save_config_connections, + }, + active_connections => { + reader => \&load_config_active_connections, + writer => \&save_config_active_connections, + }, + server_groups => { + reader => \&load_config_server_groups, + writer => \&save_config_server_groups, + }, + active_server_groups => { + reader => \&load_config_active_server_groups, + writer => \&save_config_active_server_groups, + }, + max_values_seen => { + reader => \&load_config_mvs, + writer => \&save_config_mvs, + }, + varsets => { + reader => \&load_config_varsets, + writer => \&save_config_varsets, + }, + colors => { + reader => \&load_config_colors, + writer => \&save_config_colors, + }, + stmt_sleep_times => { + reader => \&load_config_stmt_sleep_times, + writer => \&save_config_stmt_sleep_times, + }, +); + +# Config file sections have some dependencies, so they have to be read/written in order. +my @ordered_config_file_sections = qw(general plugins filters active_filters tbl_meta + connections active_connections server_groups active_server_groups max_values_seen + active_columns sort_cols visible_tables varsets colors stmt_sleep_times + group_by); + +# All events for which plugins may register themselves. Entries are arrayrefs. +my %event_listener_for = map { $_ => [] } + qw( + extract_values + 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 + draw_screen + ); + +# All variables to which plugins have access. +my %pluggable_vars = ( + action_for => \%action_for, + agg_funcs => \%agg_funcs, + config => \%config, + connections => \%connections, + dbhs => \%dbhs, + filters => \%filters, + modes => \%modes, + server_groups => \%server_groups, + tbl_meta => \%tbl_meta, + trans_funcs => \%trans_funcs, + var_sets => \%var_sets, +); + +# ########################################################################### +# Contains logic to generate prepared statements for a given function for a +# given DB connection. Returns a $sth. +# ########################################################################### +my %stmt_maker_for = ( + INDEX_STATISTICS => sub { + my ( $dbh ) = @_; + # Detect whether there's a Percona Server with INFORMATION_SCHEMA.INDEX_STATISTICS + # and if not, just select nothing. + my $sth; + eval { # This can fail if the table doesn't exist, INFORMATION_SCHEMA doesn't exist, etc. + my $cols = $dbh->selectall_arrayref(q{SHOW /*innotop*/ COLUMNS FROM INFORMATION_SCHEMA.INDEX_STATISTICS}); + if ( @$cols ) { + $sth = $dbh->prepare(q{SELECT /*innotop*/ * FROM INFORMATION_SCHEMA.INDEX_STATISTICS}); + } + }; + $sth ||= $dbh->prepare(q{SELECT /*innotop*/ '' FROM DUAL WHERE 1 = 0}); + return $sth; + }, + INDEX_TABLE_STATISTICS => sub { + my ( $dbh ) = @_; + # Detect whether there's a Percona Server with INFORMATION_SCHEMA.INDEX_STATISTICS + # and if not, just select nothing. + my $sth; + eval { # This can fail if the table doesn't exist, INFORMATION_SCHEMA doesn't exist, etc. + my $cols = $dbh->selectall_arrayref(q{SHOW /*innotop*/ COLUMNS FROM INFORMATION_SCHEMA.INDEX_STATISTICS}); + if ( @$cols ) { + $sth = $dbh->prepare(q{SELECT /*innotop*/ L.TABLE_SCHEMA, L.TABLE_NAME, } + . q{SUM(L.ROWS_READ) AS ROWS_READ, SUM(R.ROWS_READ) AS ROWS_READ_FROM_INDEXES, } + . q{SUM(L.ROWS_CHANGED) AS ROWS_CHANGED, } + . q{SUM(L.ROWS_CHANGED_X_INDEXES) AS ROWS_CHANGED_X_INDEXES } + . q{FROM INFORMATION_SCHEMA.TABLE_STATISTICS AS L LEFT JOIN INFORMATION_SCHEMA.INDEX_STATISTICS AS R } + . q{USING(TABLE_SCHEMA, TABLE_NAME) GROUP BY L.TABLE_SCHEMA, L.TABLE_NAME}); + } + }; + $sth ||= $dbh->prepare(q{SELECT /*innotop*/ '' FROM DUAL WHERE 1 = 0}); + return $sth; + }, + INNODB_BLOCKED_BLOCKER => sub { + my ( $dbh ) = @_; + # Detect whether the server supports the I_S tables and if not, just select nothing. + my $sth; + eval { # This can fail if the table doesn't exist, INFORMATION_SCHEMA doesn't exist, etc. + my $cols = $dbh->selectall_arrayref(q{SHOW /*innotop*/ COLUMNS FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS}); + if ( @$cols ) { + if ($dbh->{mariadb_serverinfo} =~ /^5.1/) { + $sth = $dbh->prepare(q{ + SELECT /*innotop*/ + r.trx_mysql_thread_id AS waiting_thread, + r.trx_query AS waiting_query, + "n/a" AS waiting_rows_modified, + TIMESTAMPDIFF(SECOND, r.trx_started, NOW()) AS waiting_age, + TIMESTAMPDIFF(SECOND, r.trx_wait_started, NOW()) AS waiting_wait_secs, + rp.user AS waiting_user, + rp.host AS waiting_host, + rp.db AS waiting_db, + b.trx_mysql_thread_id AS blocking_thread, + b.trx_query AS blocking_query, + "n/a" AS blocking_rows_modified, + TIMESTAMPDIFF(SECOND, b.trx_started, NOW()) AS blocking_age, + TIMESTAMPDIFF(SECOND, b.trx_wait_started, NOW()) AS blocking_wait_secs, + bp.user AS blocking_user, + bp.host AS blocking_host, + bp.db AS blocking_db, + CONCAT(bp.command, IF(bp.command = 'Sleep', CONCAT(' ', bp.time), '')) AS blocking_status, + CONCAT(lock_mode, ' ', lock_type, ' ', lock_table, '(', lock_index, ')') AS lock_info + FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS w + JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.blocking_trx_id + JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.requesting_trx_id + JOIN INFORMATION_SCHEMA.INNODB_LOCKS l ON l.lock_id = w.requested_lock_id + LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST bp ON bp.id = b.trx_mysql_thread_id + LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST rp ON rp.id = r.trx_mysql_thread_id + }); + } else { + $sth = $dbh->prepare(q{ + SELECT /*innotop*/ + r.trx_mysql_thread_id AS waiting_thread, + r.trx_query AS waiting_query, + r.trx_rows_modified AS waiting_rows_modified, + TIMESTAMPDIFF(SECOND, r.trx_started, NOW()) AS waiting_age, + TIMESTAMPDIFF(SECOND, r.trx_wait_started, NOW()) AS waiting_wait_secs, + rp.user AS waiting_user, + rp.host AS waiting_host, + rp.db AS waiting_db, + b.trx_mysql_thread_id AS blocking_thread, + b.trx_query AS blocking_query, + b.trx_rows_modified AS blocking_rows_modified, + TIMESTAMPDIFF(SECOND, b.trx_started, NOW()) AS blocking_age, + TIMESTAMPDIFF(SECOND, b.trx_wait_started, NOW()) AS blocking_wait_secs, + bp.user AS blocking_user, + bp.host AS blocking_host, + bp.db AS blocking_db, + CONCAT(bp.command, IF(bp.command = 'Sleep', CONCAT(' ', bp.time), '')) AS blocking_status, + CONCAT(lock_mode, ' ', lock_type, ' ', lock_table, '(', lock_index, ')') AS lock_info + FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS w + JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.blocking_trx_id + JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.requesting_trx_id + JOIN INFORMATION_SCHEMA.INNODB_LOCKS l ON l.lock_id = w.requested_lock_id + LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST bp ON bp.id = b.trx_mysql_thread_id + LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST rp ON rp.id = r.trx_mysql_thread_id + }); + } + } + }; + $sth ||= $dbh->prepare(q{SELECT /*innotop*/ '' FROM DUAL WHERE 1 = 0}); + return $sth; + }, + INNODB_STATUS => sub { + my ( $dbh ) = @_; + return $dbh->prepare(version_ge( $dbh, '5.0.0' ) + ? 'SHOW /*innotop*/ ENGINE INNODB STATUS' + : 'SHOW /*innotop*/ INNODB STATUS'); + }, + SHOW_VARIABLES => sub { + my ( $dbh ) = @_; + return $dbh->prepare($config{global}->{val} && version_ge( $dbh, '4.0.3' ) + ? 'SHOW /*innotop*/ GLOBAL VARIABLES' + : 'SHOW /*innotop*/ VARIABLES'); + }, + SHOW_STATUS => sub { + my ( $dbh ) = @_; + return $dbh->prepare($config{global}->{val} && version_ge( $dbh, '5.0.2' ) + ? 'SHOW /*innotop*/ GLOBAL STATUS' + : 'SHOW /*innotop*/ STATUS'); + }, + KILL_QUERY => sub { + my ( $dbh ) = @_; + return $dbh->prepare(version_ge( $dbh, '5.0.0' ) + ? 'KILL /*innotop*/ QUERY ?' + : 'KILL /*innotop*/ ?'); + }, + SHOW_MASTER_LOGS => sub { + my ( $dbh ) = @_; + return $dbh->prepare('SHOW /*innotop*/ MASTER LOGS'); + }, + SHOW_MASTER_STATUS => sub { + my ( $dbh ) = @_; + return $dbh->prepare('SHOW /*innotop*/ MASTER STATUS'); + }, + SHOW_SLAVE_STATUS => sub { + my ( $dbh ) = @_; + return $dbh->prepare('SHOW /*innotop*/ SLAVE STATUS'); + }, + GET_CHANNELS => sub { + my ( $dbh ) = @_; + return $dbh->prepare(version_ge( $dbh, '5.7.0' ) + ? 'select CHANNEL_NAME from performance_schema.replication_applier_status where CHANNEL_NAME regexp "^[a-zA-Z].*";' + : 'select "no_channels"'); + }, + KILL_CONNECTION => sub { + my ( $dbh ) = @_; + return $dbh->prepare(version_ge( $dbh, '5.0.0' ) + ? 'KILL /*innotop*/ CONNECTION ?' + : 'KILL /*innotop*/ ?'); + }, + OPEN_TABLES => sub { + my ( $dbh ) = @_; + return version_ge($dbh, '4.0.0') + ? $dbh->prepare('SHOW /*innotop*/ OPEN TABLES') + : undef; + }, + PROCESSLIST => sub { + my ( $dbh ) = @_; + # In newer versions of the server, use INFORMATION_SCHEMA table if it exists, + # and use the TIME_MS column (in Percona Server) if that exists. + my $sth; + eval { # This can fail if the table doesn't exist, INFORMATION_SCHEMA doesn't exist, etc. + my $cols = $dbh->selectall_arrayref(q{SHOW /*innotop*/ COLUMNS FROM INFORMATION_SCHEMA.PROCESSLIST LIKE 'TIME_MS'}); + if ( @$cols ) { # The TIME_MS column exists + $sth = $dbh->prepare(q{SELECT /*innotop*/ ID, USER, HOST, DB, COMMAND, CASE WHEN TIME_MS/1000 > 365*86400 THEN TIME ELSE TIME_MS/1000 END AS TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST}); + } + }; + $sth ||= $dbh->prepare('SHOW /*innotop*/ FULL PROCESSLIST'); + return $sth; + }, + PROCESSLIST_NO_IS => sub { + my ( $dbh ) = @_; + # We do not use INFORMATION_SCHEMA table because it doesn't show slave + # SQL statements. http://bugs.mysql.com/66401 + my $sth = $dbh->prepare('SHOW /*innotop*/ FULL PROCESSLIST'); + return $sth; + }, + TABLE_STATISTICS => sub { + my ( $dbh ) = @_; + # Detect whether there's a Percona Server with INFORMATION_SCHEMA.TABLE_STATISTICS + # and if not, just select nothing. + my $sth; + eval { # This can fail if the table doesn't exist, INFORMATION_SCHEMA doesn't exist, etc. + my $cols = $dbh->selectall_arrayref(q{SHOW /*innotop*/ COLUMNS FROM INFORMATION_SCHEMA.TABLE_STATISTICS}); + if ( @$cols ) { + $sth = $dbh->prepare(q{SELECT /*innotop*/ * FROM INFORMATION_SCHEMA.TABLE_STATISTICS}); + } + }; + $sth ||= $dbh->prepare(q{SELECT /*innotop*/ '' FROM DUAL WHERE 1 = 0}); + return $sth; + }, +); + +# Plugins! +my %plugins = ( +); + +# ########################################################################### +# Run the program {{{1 +# ########################################################################### +sub main { + # This config variable is only useful for MS Windows because its terminal + # can't tell how tall it is. + if ( !$windows ) { + delete $config{max_height}; + } + + # Try to lower my priority. + eval { setpriority(0, 0, getpriority(0, 0) + 10); }; + + # Print stuff to the screen immediately, don't wait for a newline. + $OUTPUT_AUTOFLUSH = 1; + + # Clear the screen and load the configuration. + $clear_screen_sub->(); + load_config(); + + # Override config variables with command-line options + my %cmdline = + map { $_->{c} => $opts{$_->{k}} } + grep { exists $_->{c} && exists $opts{$_->{k}} } + @opt_spec; + + foreach my $name (keys %cmdline) { + next if not defined $cmdline{$name}; + my $val = $cmdline{$name}; + if ( exists($config{$name}) and (!$config{$name}->{pat} or $val =~ m/$config{$name}->{pat}/ )) { + $config{$name}->{val} = $val; + } + } + + post_process_tbl_meta(); + + # Make sure no changes are written to config file in non-interactive mode. + if ( $opts{n} ) { + $config{readonly}->{val} = 1; + } + + eval { + + # Open the file for InnoDB status + if ( @ARGV ) { + my $filename = shift @ARGV; + open $file, "<", $filename + or die "Cannot open '$filename': $OS_ERROR"; + } + + # In certain modes we might have to collect data for two cycles + # before printing anything out, so we need to bump up the count one. + if ( $opts{n} && $opts{count} && $config{status_inc}->{val} + && $config{mode}->{val} =~ m/[S]/ ) + { + $opts{count}++; + } + + while (++$clock) { + + my $mode = $config{mode}->{val} || 'Q'; + if ( !$modes{$mode} ) { + die "Mode '$mode' doesn't exist; try one of these:\n" + . join("\n", map { " $_ $modes{$_}->{hdr}" } sort keys %modes) + . "\n"; + } + + if ( !$opts{n} ) { + @last_term_size = @this_term_size; + @this_term_size = Term::ReadKey::GetTerminalSize(\*STDOUT); + if ( $windows ) { + $this_term_size[0]--; + $this_term_size[1] + = min($this_term_size[1], $config{max_height}->{val}); + } + die("Can't read terminal size") unless @this_term_size; + } + + # If there's no connection to a database server, we need to fix that... + if ( !%connections ) { + print "You have not defined any database connections.\n\n"; + add_new_dsn(); + } + + # See whether there are any connections defined for this mode. If there's only one + # connection total, assume the user wants to just use innotop for a single server + # and don't ask which server to connect to. Also, if we're monitoring from a file, + # we just use the first connection. + if ( !get_connections() ) { + if ( $file || 1 == scalar keys %connections ) { + $modes{$config{mode}->{val}}->{connections} = [ keys %connections ]; + } + else { + choose_connections(); + } + } + + # Term::ReadLine might have re-set $OUTPUT_AUTOFLUSH. + $OUTPUT_AUTOFLUSH = 1; + + # Prune old data + my $sets = $config{num_status_sets}->{val}; + foreach my $store ( values %vars ) { + delete @{$store}{ grep { $_ < $clock - $sets } keys %$store }; + } + %info_gotten = (); + + # Call the subroutine to display this mode. + $modes{$mode}->{display_sub}->(); + + # It may be time to quit now. + if ( $opts{count} && $clock >= $opts{count} ) { + finish(); + } + + # RECON: Try to reconnect failed connections, while the user sees no lag. + foreach my $cxn ( grep { $dbhs{$_}->{failed} } keys %dbhs ) { + eval { connect_to_db($cxn); }; # Ignore errors entirely here. + } + + # Wait for a bit. + if ( $opts{n} ) { + sleep($config{interval}->{val}); + } + else { + ReadMode('cbreak'); + $char = ReadKey($config{interval}->{val}); + ReadMode('normal'); + } + + # Handle whatever action the key indicates. + do_key_action(); + + } + }; + if ( $EVAL_ERROR ) { + core_dump( $EVAL_ERROR ); + } + finish(); +} +main() unless caller(); # make me testable! + +# Subroutines {{{1 +# Mode functions{{{2 +# switch_mode {{{3 +sub switch_mode { + my $mode = shift; + $config{mode}->{val} = $mode; +} + +# Prompting functions {{{2 +# prompt_list {{{3 +# Prompts the user for a value, given a question, initial value, +# a completion function and a hashref of hints. +sub prompt_list { + die "Can't call in non-interactive mode" if $opts{n}; + my ( $question, $init, $completion, $hints ) = @_; + if ( $hints ) { + # Figure out how wide the table will be + my $max_name = max(map { length($_) } keys %$hints ); + $max_name ||= 0; + $max_name += 3; + my @meta_rows = create_table2( + [ sort keys %$hints ], + { map { $_ => $_ } keys %$hints }, + { map { $_ => trunc($hints->{$_}, $this_term_size[0] - $max_name) } keys %$hints }, + { sep => ' ' }); + if (@meta_rows > 10) { + # Try to split and stack the meta rows next to each other + my $split = int(@meta_rows / 2); + @meta_rows = stack_next( + [@meta_rows[0..$split - 1]], + [@meta_rows[$split..$#meta_rows]], + { pad => ' | '}, + ); + } + print join( "\n", + '', + map { ref $_ ? colored(@$_) : $_ } create_caption('Choose from', @meta_rows), ''), + "\n"; + } + $term->Attribs->{completion_function} = $completion; + my $answer = $term->readline("$question: ", $init); + $OUTPUT_AUTOFLUSH = 1; + $answer = '' if !defined($answer); + $answer =~ s/\s+$//; + return $answer; +} + +# prompt {{{3 +# Prints out a prompt and reads from the keyboard, then validates with the +# validation regex until the input is correct. +sub prompt { + die "Can't call in non-interactive mode" if $opts{n}; + my ( $prompt, $regex, $init, $completion ) = @_; + my $response; + my $success = 0; + do { + if ( $completion ) { + $term->Attribs->{completion_function} = $completion; + } + $response = $term->readline("$prompt: ", $init); + if ( $regex && $response !~ m/$regex/ ) { + print "Invalid response.\n\n"; + } + else { + $success = 1; + } + } while ( !$success ); + $OUTPUT_AUTOFLUSH = 1; + $response =~ s/\s+$//; + return $response; +} + +# prompt_noecho {{{3 +# Unfortunately, suppressing echo with Term::ReadLine isn't reliable; the user might not +# have that library, or it might not support that feature. +sub prompt_noecho { + my ( $prompt ) = @_; + print colored("$prompt: ", 'underline'); + my $response; + ReadMode('noecho'); + $response = ; + chomp($response); + ReadMode('normal'); + return $response; +} + +# noecho_password {{{3 +# read password for command line parameters with noecho +sub noecho_password { + my $prompt = shift @_; + local $OUTPUT_AUTOFLUSH = 1; + my $response; + eval { + if ( $windows ) { + require Win32::Console::ANSI; + } + require Term::ANSIColor; + import Term::ANSIColor qw(colored); + $response = prompt_noecho($prompt); + print "\n" or die + "Cannot print: $OS_ERROR"; + }; + + if ( $EVAL_ERROR ) { + die "Cannot read response; is Term::ReadKey installed? $EVAL_ERROR"; + } + return $response; +} + +# do_key_action {{{3 +# Depending on whether a key was read, do something. Keys have certain +# actions defined in lookup tables. Each mode may have its own lookup table, +# which trumps the global table -- so keys can be context-sensitive. The key +# may be read and written in a subroutine, so it's a global. +sub do_key_action { + if ( defined $char ) { + my $mode = $config{mode}->{val}; + my $action + = defined($modes{$mode}->{action_for}->{$char}) ? $modes{$mode}->{action_for}->{$char}->{action} + : defined($action_for{$char}) ? $action_for{$char}->{action} + : sub{}; + $action->(); + } +} + +# pause {{{3 +sub pause { + die "Can't call in non-interactive mode" if $opts{n}; + my $msg = shift; + print defined($msg) ? "\n$msg" : "\nPress any key to continue"; + ReadMode('cbreak'); + my $char = ReadKey(0); + ReadMode('normal'); + return $char; +} + +# reverse_sort {{{3 +sub reverse_sort { + my $tbl = shift; + $tbl_meta{$tbl}->{sort_dir} *= -1; +} + +# select_cxn {{{3 +# Selects connection(s). If the mode (or argument list) has only one, returns +# it without prompt. +sub select_cxn { + my ( $prompt, @cxns ) = @_; + if ( !@cxns ) { + @cxns = get_connections(); + } + if ( @cxns == 1 ) { + return $cxns[0]; + } + my $choices = prompt_list( + $prompt, + $cxns[0], + sub{ return @cxns }, + { map { $_ => $connections{$_}->{dsn} } @cxns }); + my @result = unique(grep { my $a = $_; grep { $_ eq $a } @cxns } split(/\s+/, $choices)); + return @result; +} + +# kill_query {{{3 +# Kills a connection, or on new versions, optionally a query but not connection. +sub kill_query { + my ( $q_or_c ) = @_; + + my $info = choose_thread( + sub { 1 }, + 'Select a thread to kill the ' . $q_or_c, + ); + return unless $info; + my $distill = distill($info->{query} || ''); + $distill = " running '$distill'" if $distill; + return unless pause("Kill $info->{id} (" + . ($info->{user} || '') + . '@' + . ($info->{host} || '') + . ")$distill ? ") =~ m/y/i; + + eval { + do_stmt($info->{cxn}, $q_or_c eq 'QUERY' ? 'KILL_QUERY' : 'KILL_CONNECTION', $info->{id} ); + }; + + if ( $EVAL_ERROR ) { + print "\nError: $EVAL_ERROR"; + pause(); + } +} + +# set_display_precision {{{3 +sub set_display_precision { + my $dir = shift; + $config{num_digits}->{val} = min(9, max(0, $config{num_digits}->{val} + $dir)); +} + +sub toggle_visible_table { + my ( $mode, $table ) = @_; + my $visible = $modes{$mode}->{visible_tables}; + if ( grep { $_ eq $table } @$visible ) { + $modes{$mode}->{visible_tables} = [ grep { $_ ne $table } @$visible ]; + } + else { + unshift @$visible, $table; + } + $modes{$mode}->{cust}->{visible_tables} = 1; +} + +# toggle_filter{{{3 +sub toggle_filter { + my ( $tbl, $filter ) = @_; + my $filters = $tbl_meta{$tbl}->{filters}; + if ( grep { $_ eq $filter } @$filters ) { + $tbl_meta{$tbl}->{filters} = [ grep { $_ ne $filter } @$filters ]; + } + else { + push @$filters, $filter; + } + $tbl_meta{$tbl}->{cust}->{filters} = 1; +} + +# toggle_config {{{3 +sub toggle_config { + my ( $key ) = @_; + $config{$key}->{val} ^= 1; +} + +# create_deadlock {{{3 +sub create_deadlock { + $clear_screen_sub->(); + + print "This function will deliberately cause a small deadlock, " + . "clearing deadlock information from the InnoDB monitor.\n\n"; + + my $answer = prompt("Are you sure you want to proceed? Say 'y' if you do"); + return 0 unless $answer eq 'y'; + + my ( $cxn ) = select_cxn('Clear on which server? '); + return unless $cxn && exists($connections{$cxn}); + + clear_deadlock($cxn); +} + +# deadlock_thread {{{3 +sub deadlock_thread { + my ( $id, $tbl, $cxn ) = @_; + + eval { + my $dbh = get_new_db_connection($cxn, 1); + + # disable binary logging for this session + $dbh->do("set SQL_LOG_BIN=0"); + + my @stmts = ( + "set transaction isolation level serializable", + (version_ge($dbh, '4.0.11') ? "start transaction" : 'begin'), + "select * from $tbl where a = $id", + "update $tbl set a = $id where a <> $id", + ); + + foreach my $stmt (@stmts[0..2]) { + $dbh->do($stmt); + } + sleep(1 + $id); + $dbh->do($stmts[-1]); + }; + if ( $EVAL_ERROR ) { + if ( $EVAL_ERROR !~ m/Deadlock found/ ) { + die $EVAL_ERROR; + } + } + exit(0); +} + +# Purges unused binlogs on the master, up to but not including the latest log. +# TODO: guess which connections are slaves of a given master. +sub purge_master_logs { + my @cxns = get_connections(); + + get_master_slave_status(@cxns); + + # Toss out the rows that don't have master/slave status... + my @vars = + grep { $_ && ($_->{file} || $_->{master_host}) } + map { $vars{$_}->{$clock} } @cxns; + @cxns = map { $_->{cxn} } @vars; + + # Figure out which master to purge ons. + my @masters = map { $_->{cxn} } grep { $_->{file} } @vars; + my ( $master ) = select_cxn('Which master?', @masters ); + return unless $master; + my ($master_status) = grep { $_->{cxn} eq $master } @vars; + + # Figure out the result order (not lexical order) of master logs. + my @master_logs = get_master_logs($master); + my $i = 0; + my %master_logs = map { $_->{log_name} => $i++ } @master_logs; + + # Ask which slave(s) are reading from this master. + my @slave_status = grep { $_->{master_host} } @vars; + my @slaves = map { $_->{cxn} } @slave_status; + @slaves = select_cxn("Which slaves are reading from $master?", @slaves); + @slave_status = grep { my $item = $_; grep { $item->{cxn} eq $_ } @slaves } @slave_status; + return unless @slave_status; + + # Find the minimum binary log in use. + my $min_log = min(map { $master_logs{$_->{master_log_file}} } @slave_status); + my $log_name = $master_logs[$min_log]->{log_name}; + + my $stmt = "PURGE MASTER LOGS TO '$log_name'"; + send_cmd_to_servers($stmt, 0, 'PURGE {MASTER | BINARY} LOGS {TO "log_name" | BEFORE "date"}', [$master]); +} + +sub send_cmd_to_servers { + my ( $cmd, $all, $hint, $cxns ) = @_; + if ( $all ) { + @$cxns = get_connections(); + } + elsif ( !@$cxns ) { + @$cxns = select_cxn('Which servers?', @$cxns); + } + if ( $hint ) { + print "\nHint: $hint\n"; + } + $cmd = prompt('Command to send', undef, $cmd); + foreach my $cxn ( @$cxns ) { + eval { + my $sth = do_query($cxn, $cmd); + }; + if ( $EVAL_ERROR ) { + print "Error from $cxn: $EVAL_ERROR\n"; + } + else { + print "Success on $cxn\n"; + } + } + pause(); +} + +# Display functions {{{2 + +sub set_s_mode { + my ( $func ) = @_; + $clear_screen_sub->(); + $config{S_func}->{val} = $func; +} + +# start_S_mode {{{3 +sub start_S_mode { + $clear_screen_sub->(); + switch_mode('S'); +} + +# display_A {{{3 +sub display_A { + my @display_lines; + my @cxns = get_connections(); + get_processlist_stats(@cxns); + get_status_info(@cxns); + get_master_slave_status(@cxns); + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + my @health_dashboard; + my %rows_for = ( + health_dashboard => \@health_dashboard, + ); + + foreach my $cxn ( @cxns ) { + # Get the status variables + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + my $hash = extract_values($set, $set, $pre, 'health_dashboard'); + # Make QPS and Miss show now, not overall. + if ( exists $vars{$cxn}->{$clock - 1} ) { + my $inc = inc(0, $cxn); + my $hash2 = extract_values($inc, $set, $pre, 'health_dashboard'); + map { $hash->{$_} = $hash2->{$_} } qw(qps miss_rate); + } + push @health_dashboard, $hash; + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_B {{{3 +sub display_B { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + get_innodb_status(\@cxns); + + my @buffer_pool; + my @page_statistics; + my @insert_buffers; + my @adaptive_hash_index; + my %rows_for = ( + buffer_pool => \@buffer_pool, + page_statistics => \@page_statistics, + insert_buffers => \@insert_buffers, + adaptive_hash_index => \@adaptive_hash_index, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + + if ( $set->{IB_bp_complete} ) { + if ( $wanted{buffer_pool} ) { + push @buffer_pool, extract_values($set, $set, $pre, 'buffer_pool'); + } + if ( $wanted{page_statistics} ) { + push @page_statistics, extract_values($set, $set, $pre, 'page_statistics'); + } + } + if ( $set->{IB_ib_complete} ) { + if ( $wanted{insert_buffers} ) { + push @insert_buffers, extract_values( + $config{status_inc}->{val} ? inc(0, $cxn) : $set, $set, $pre, + 'insert_buffers'); + } + if ( $wanted{adaptive_hash_index} ) { + push @adaptive_hash_index, extract_values($set, $set, $pre, 'adaptive_hash_index'); + } + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_C {{{3 +sub display_C { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + + my @cmd_summary; + my %rows_for = ( + cmd_summary => \@cmd_summary, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + # For now, I'm manually pulling these variables out and pivoting. Eventually a SQL-ish + # dialect should let me join a table to a grouped and pivoted table and do this more easily. + # TODO: make it so. + my $prefix = qr/^$config{cmd_filter}->{val}/; # TODO: this is a total hack + my @values; + my ($total, $last_total) = (0, 0); + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + foreach my $key ( keys %$set ) { + next unless $key =~ m/$prefix/i; + my $val = $set->{$key}; + next unless defined $val && $val =~ m/^\d+$/; + my $last_val = $val - ($pre->{$key} || 0); + $total += $val; + $last_total += $last_val; + push @values, { + name => $key, + value => $val, + last_value => $last_val, + }; + } + } + + # Add aggregation and turn into a real set TODO: total hack + if ( $wanted{cmd_summary} ) { + foreach my $value ( @values ) { + @{$value}{qw(total last_total)} = ($total, $last_total); + push @cmd_summary, extract_values($value, $value, $value, 'cmd_summary'); + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_D {{{3 +sub display_D { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + get_innodb_status(\@cxns); + + my @deadlock_transactions; + my @deadlock_locks; + my %rows_for = ( + deadlock_transactions => \@deadlock_transactions, + deadlock_locks => \@deadlock_locks, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + foreach my $cxn ( @cxns ) { + my $innodb_status = $vars{$cxn}->{$clock}; + my $prev_status = $vars{$cxn}->{$clock-1} || $innodb_status; + + if ( $innodb_status->{IB_dl_timestring} ) { + + my $victim = $innodb_status->{IB_dl_rolled_back} || 0; + + if ( %wanted ) { + foreach my $txn_id ( keys %{$innodb_status->{IB_dl_txns}} ) { + my $txn = $innodb_status->{IB_dl_txns}->{$txn_id}; + my $pre = $prev_status->{IB_dl_txns}->{$txn_id} || $txn; + + if ( $wanted{deadlock_transactions} ) { + my $hash = extract_values($txn->{tx}, $txn->{tx}, $pre->{tx}, 'deadlock_transactions'); + $hash->{cxn} = $cxn; + $hash->{dl_txn_num} = $txn_id; + $hash->{victim} = $txn_id == $victim ? 'Yes' : 'No'; + $hash->{timestring} = $innodb_status->{IB_dl_timestring}; + $hash->{truncates} = $innodb_status->{IB_dl_complete} ? 'No' : 'Yes'; + push @deadlock_transactions, $hash; + } + + if ( $wanted{deadlock_locks} ) { + foreach my $lock ( @{$txn->{locks}} ) { + my $hash = extract_values($lock, $lock, $lock, 'deadlock_locks'); + $hash->{dl_txn_num} = $txn_id; + $hash->{cxn} = $cxn; + $hash->{mysql_thread_id} = $txn->{tx}->{mysql_thread_id}; + push @deadlock_locks, $hash; + } + } + + } + } + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_F {{{3 +sub display_F { + my @display_lines; + my ( $cxn ) = get_connections(); + get_status_info($cxn); + get_innodb_status([$cxn]); + my $innodb_status = $vars{$cxn}->{$clock}; + + if ( $innodb_status->{IB_fk_timestring} ) { + + push @display_lines, 'Reason: ' . ($innodb_status->{IB_fk_reason} || 'unknown'); + + # Display FK errors caused by invalid DML. + if ( $innodb_status->{IB_fk_txn} ) { + my $txn = $innodb_status->{IB_fk_txn}; + push @display_lines, + '', + "User $txn->{user} from $txn->{hostname}, thread $txn->{mysql_thread_id} was executing:", + '', no_ctrl_char($txn->{query_text}); + } + + my @fk_table = create_table2( + $tbl_meta{fk_error}->{visible}, + meta_to_hdr('fk_error'), + extract_values($innodb_status, $innodb_status, $innodb_status, 'fk_error'), + { just => '-', sep => ' '}); + push @display_lines, '', @fk_table; + + } + else { + push @display_lines, '', 'No foreign key error data.'; + } + draw_screen(\@display_lines, { raw => 1 } ); +} + +# display_I {{{3 +sub display_I { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + get_innodb_status(\@cxns); + + my @io_threads; + my @pending_io; + my @file_io_misc; + my @log_statistics; + my %rows_for = ( + io_threads => \@io_threads, + pending_io => \@pending_io, + file_io_misc => \@file_io_misc, + log_statistics => \@log_statistics, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + + if ( $set->{IB_io_complete} ) { + if ( $wanted{io_threads} ) { + my $cur_threads = $set->{IB_io_threads}; + my $pre_threads = $pre->{IB_io_threads} || $cur_threads; + foreach my $key ( sort keys %$cur_threads ) { + my $cur_thd = $cur_threads->{$key}; + my $pre_thd = $pre_threads->{$key} || $cur_thd; + my $hash = extract_values($cur_thd, $cur_thd, $pre_thd, 'io_threads'); + $hash->{cxn} = $cxn; + push @io_threads, $hash; + } + } + if ( $wanted{pending_io} ) { + push @pending_io, extract_values($set, $set, $pre, 'pending_io'); + } + if ( $wanted{file_io_misc} ) { + push @file_io_misc, extract_values( + $config{status_inc}->{val} ? inc(0, $cxn) : $set, + $set, $pre, 'file_io_misc'); + } + } + if ( $set->{IB_lg_complete} && $wanted{log_statistics} ) { + push @log_statistics, extract_values($set, $set, $pre, 'log_statistics'); + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_K {{{3 +sub display_K { + my @display_lines; + my @cxns = get_connections(); + + my %rows_for = ( + innodb_blocked_blocker => [], + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + # Get info on locks + if ( $wanted{innodb_blocked_blocker} ) { + my @rows = get_innodb_blocked_blocker(@cxns); + push @{$rows_for{innodb_blocked_blocker}}, map { extract_values($_, $_, $_, 'innodb_blocked_blocker') } @rows; + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + # Save queries in global variable for analysis. The rows in %rows_for have been + # filtered, etc as a side effect of set_to_tbl(), so they are the same as the rows + # that get pushed to the screen. + @current_queries = map { + my %hash; + @hash{ qw(cxn id user host db query time) } + = @{$_}{ qw(cxn blocking_thread blocking_user blocking_host blocking_db blocking_query blocking_age) }; + # time is in fuzzy-time format; convert into something ascii-sortable. + $hash{time} = sprintf('%012s', fuzzy_to_secs($hash{time})); + $hash{host} =~ s/:.*$// if $hash{host}; + \%hash; + } @{$rows_for{innodb_blocked_blocker}}; + + draw_screen(\@display_lines); +} + +# display_L {{{3 +sub display_L { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + get_innodb_status(\@cxns); + + my @innodb_locks; + my %rows_for = ( + innodb_locks => \@innodb_locks, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + # Get info on locks + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock} or next; + my $pre = $vars{$cxn}->{$clock-1} || $set; + + if ( $wanted{innodb_locks} && defined $set->{IB_tx_transactions} && @{$set->{IB_tx_transactions}} ) { + + my $cur_txns = $set->{IB_tx_transactions}; + my $pre_txns = $pre->{IB_tx_transactions} || $cur_txns; + my %cur_txns = map { $_->{mysql_thread_id} => $_ } grep { defined $_->{mysql_thread_id} } @$cur_txns; + my %pre_txns = map { $_->{mysql_thread_id} => $_ } grep { defined $_->{mysql_thread_id} } @$pre_txns; + foreach my $txn ( @$cur_txns ) { + foreach my $lock ( @{$txn->{locks}} ) { + my %hash = map { $_ => $txn->{$_} } qw(txn_id mysql_thread_id lock_wait_time active_secs); + map { $hash{$_} = $lock->{$_} } qw(lock_type space_id page_no n_bits index db table txn_id lock_mode special insert_intention waiting); + $hash{cxn} = $cxn; + push @innodb_locks, extract_values(\%hash, \%hash, \%hash, 'innodb_locks'); + } + } + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_M {{{3 +sub display_M { + my @display_lines; + my @cxns = get_connections(); + get_master_slave_status(@cxns); + get_status_info(@cxns); + + my @slave_sql_status; + my @slave_io_status; + my @master_status; + my %rows_for = ( + slave_sql_status => \@slave_sql_status, + slave_io_status => \@slave_io_status, + master_status => \@master_status, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + foreach my $cxn ( @cxns ) { + my $linecount=0; + my $sth = do_stmt($cxn, 'GET_CHANNELS'); + my ( $channel ); + $sth->execute(); + $sth->bind_columns( \$channel ); + while ( $sth->fetch() ) { + $linecount=$linecount+1; + if ( length $channel < 1 ) { + $channel = 'no_channels'; + } + my $chcxn = $channel . '=' . $cxn; + get_slave_status($cxn,$channel); + my $set = $config{status_inc}->{val} ? inc(0, $chcxn) : $vars{$chcxn}->{$clock}; + my $pre = $vars{$chcxn}->{$clock - 1} || $set; + if ( $wanted{slave_sql_status} ) { + push @slave_sql_status, extract_values($set, $set, $pre, 'slave_sql_status'); + } + if ( $wanted{slave_io_status} ) { + push @slave_io_status, extract_values($set, $set, $pre, 'slave_io_status'); + } + } + if ( $linecount < 1 ) { + $channel = 'no_channels'; + my $chcxn = $channel . '=' . $cxn; + get_slave_status($cxn,$channel); + my $set = $config{status_inc}->{val} ? inc(0, $chcxn) : $vars{$chcxn}->{$clock}; + my $pre = $vars{$chcxn}->{$clock - 1} || $set; + if ( $wanted{slave_sql_status} ) { + push @slave_sql_status, extract_values($set, $set, $pre, 'slave_sql_status'); + } + if ( $wanted{slave_io_status} ) { + push @slave_io_status, extract_values($set, $set, $pre, 'slave_io_status'); + } + } + my $set = $config{status_inc}->{val} ? inc(0, $cxn) : $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock - 1} || $set; + if ( $wanted{master_status} ) { + push @master_status, extract_values($set, $set, $pre, 'master_status'); + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_O {{{3 +sub display_O { + my @display_lines = (''); + my @cxns = get_connections(); + my @open_tables = get_open_tables(@cxns); + my @tables = map { extract_values($_, $_, $_, 'open_tables') } @open_tables; + push @display_lines, set_to_tbl(\@tables, 'open_tables'), get_cxn_errors(@cxns); + draw_screen(\@display_lines); +} + +# display_P {{{3 +sub display_P { + my @display_lines; + + my @table_statistics; + my @index_statistics; + my @index_table_statistics; + my %rows_for = ( + table_statistics => \@table_statistics, + index_statistics => \@index_statistics, + index_table_statistics => \@index_table_statistics, + ); + + my @visible = $opts{n} ? 'index_table_statistics' : get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + # Get the data + my @cxns = get_connections(); + + if ( $wanted{table_statistics} ) { + my @rows = get_table_statistics(@cxns); + push @table_statistics, map { extract_values($_, $_, $_, 'table_statistics') } @rows; + } + elsif ( $wanted{index_statistics} ) { + my @rows = get_index_statistics(@cxns); + push @index_statistics, map { extract_values($_, $_, $_, 'index_statistics') } @rows; + } + elsif ( $wanted{index_table_statistics} ) { + my @rows = get_index_table_statistics(@cxns); + push @index_table_statistics, map { extract_values($_, $_, $_, 'index_table_statistics') } @rows; + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + next unless $wanted{$tbl}; + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_Q {{{3 +sub display_Q { + my @display_lines; + + my @q_header; + my @processlist; + my %rows_for = ( + q_header => \@q_header, + processlist => \@processlist, + ); + + my @visible = $opts{n} ? 'processlist' : get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + # Get the data + my @cxns = get_connections(); + my @full_processlist = get_full_processlist(@cxns); + + # Create header + if ( $wanted{q_header} ) { + get_status_info(@cxns); + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + my $hash = extract_values($set, $set, $pre, 'q_header'); + $hash->{cxn} = $cxn; + $hash->{when} = 'Total'; + push @q_header, $hash; + + if ( exists $vars{$cxn}->{$clock - 1} ) { + my $inc = inc(0, $cxn); + my $hash = extract_values($inc, $set, $pre, 'q_header'); + $hash->{cxn} = $cxn; + $hash->{when} = 'Now'; + push @q_header, $hash; + } + } + } + + if ( $wanted{processlist} ) { + # TODO: save prev values + push @processlist, map { extract_values($_, $_, $_, 'processlist') } @full_processlist; + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + next unless $wanted{$tbl}; + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + # Save queries in global variable for analysis. The rows in %rows_for have been + # filtered, etc as a side effect of set_to_tbl(), so they are the same as the rows + # that get pushed to the screen. + @current_queries = map { + my %hash; + @hash{ qw(cxn id db query time user host) } + = @{$_}{ qw(cxn mysql_thread_id db info time user hostname) }; + # time is in seconds-to-time format; convert into something + # ascii-sortable. + $hash{time} = sprintf('%012s', $hash{time} =~ m/^([^.]*)/); + \%hash; + } @{$rows_for{processlist}}; + + draw_screen(\@display_lines); +} + +# display_R {{{3 +sub display_R { + my @display_lines; + my @cxns = get_connections(); + get_status_info(@cxns); + get_innodb_status(\@cxns); + + my @row_operations; + my @row_operation_misc; + my @semaphores; + my @wait_array; + my %rows_for = ( + row_operations => \@row_operations, + row_operation_misc => \@row_operation_misc, + semaphores => \@semaphores, + wait_array => \@wait_array, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + my $incvar = $config{status_inc}->{val}; + + foreach my $cxn ( @cxns ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + my $inc; # Only assigned to if wanted + + if ( $set->{IB_ro_complete} ) { + if ( $wanted{row_operations} ) { + $inc ||= $incvar ? inc(0, $cxn) : $set; + push @row_operations, extract_values($inc, $set, $pre, 'row_operations'); + } + if ( $wanted{row_operation_misc} ) { + push @row_operation_misc, extract_values($set, $set, $pre, 'row_operation_misc'), + } + } + + if ( $set->{IB_sm_complete} && $wanted{semaphores} ) { + $inc ||= $incvar ? inc(0, $cxn) : $set; + push @semaphores, extract_values($inc, $set, $pre, 'semaphores'); + } + + if ( $set->{IB_sm_wait_array_size} && $wanted{wait_array} ) { + foreach my $wait ( @{$set->{IB_sm_waits}} ) { + my $hash = extract_values($wait, $wait, $wait, 'wait_array'); + $hash->{cxn} = $cxn; + push @wait_array, $hash; + } + } + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + draw_screen(\@display_lines); +} + +# display_T {{{3 +sub display_T { + my @display_lines; + + my @t_header; + my @innodb_transactions; + my %rows_for = ( + t_header => \@t_header, + innodb_transactions => \@innodb_transactions, + ); + + my @visible = $opts{n} ? 'innodb_transactions' : get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + + my @cxns = get_connections(); + + get_status_info(@cxns); + + # If the header is to be shown, buffer pool data is required. + get_innodb_status( \@cxns, [ $wanted{t_header} ? qw(bp) : () ] ); + + foreach my $cxn ( get_connections() ) { + my $set = $vars{$cxn}->{$clock}; + my $pre = $vars{$cxn}->{$clock-1} || $set; + + next unless $set->{IB_tx_transactions}; + + if ( $wanted{t_header} ) { + my $hash = extract_values($set, $set, $pre, 't_header'); + push @t_header, $hash; + } + + if ( $wanted{innodb_transactions} ) { + my $cur_txns = $set->{IB_tx_transactions}; + my $pre_txns = $pre->{IB_tx_transactions} || $cur_txns; + my %cur_txns = map { $_->{mysql_thread_id} => $_ } grep { defined $_->{mysql_thread_id} } @$cur_txns; + my %pre_txns = map { $_->{mysql_thread_id} => $_ } grep { defined $_->{mysql_thread_id} } @$pre_txns; + foreach my $thd_id ( sort keys %cur_txns ) { + my $cur_txn = $cur_txns{$thd_id}; + my $pre_txn = $pre_txns{$thd_id} || $cur_txn; + my $hash = extract_values($cur_txn, $cur_txn, $pre_txn, 'innodb_transactions'); + $hash->{cxn} = $cxn; + push @innodb_transactions, $hash; + } + } + + } + + my $first_table = 0; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + + # Save queries in global variable for analysis. The rows in %rows_for have been + # filtered, etc as a side effect of set_to_tbl(), so they are the same as the rows + # that get pushed to the screen. + @current_queries = map { + my %hash; + @hash{ qw(cxn id db query time user host) } + = @{$_}{ qw(cxn mysql_thread_id db query_text active_secs user hostname) }; + \%hash; + } @{$rows_for{innodb_transactions}}; + + draw_screen(\@display_lines); +} + +# display_S {{{3 +sub display_S { + my $fmt = get_var_set('S_set'); + my $func = $config{S_func}->{val}; + my $inc = $func eq 'g' || $config{status_inc}->{val}; + + # The table's meta-data is generated from the compiled var_set. + my ( $cols, $visible ); + if ( $tbl_meta{var_status}->{fmt} && $fmt eq $tbl_meta{var_status}->{fmt} ) { + ( $cols, $visible ) = @{$tbl_meta{var_status}}{qw(cols visible)}; + } + else { + ( $cols, $visible ) = compile_select_stmt($fmt); + + # Apply missing values to columns. Always apply averages across all connections. + map { + $_->{agg} = 'avg'; + $_->{label} = $_->{hdr}; + } values %$cols; + + $tbl_meta{var_status}->{cols} = $cols; + $tbl_meta{var_status}->{visible} = $visible; + $tbl_meta{var_status}->{fmt} = $fmt; + map { $tbl_meta{var_status}->{cols}->{$_}->{just} = ''} @$visible; + } + + my @var_status; + my %rows_for = ( + var_status => \@var_status, + ); + + my @visible = get_visible_tables(); + my %wanted = map { $_ => 1 } @visible; + my @cxns = get_connections(); + + get_status_info(@cxns); + get_innodb_status(\@cxns); + + # Set up whether to pivot and how many sets to extract. + $tbl_meta{var_status}->{pivot} = $func eq 'v'; + + my $num_sets + = $func eq 'v' + ? $config{num_status_sets}->{val} + : 0; + foreach my $set ( 0 .. $num_sets ) { + my @rows; + foreach my $cxn ( @cxns ) { + my $vars = $inc ? inc($set, $cxn) : $vars{$cxn}->{$clock - $set}; + my $cur = $vars{$cxn}->{$clock-$set}; + my $pre = $vars{$cxn}->{$clock-$set-1} || $cur; + next unless $vars && %$vars; + my $hash = extract_values($vars, $cur, $pre, 'var_status'); + push @rows, $hash; + } + @rows = apply_group_by('var_status', [], @rows); + push @var_status, @rows; + } + + # Recompile the sort func. TODO: avoid recompiling at every refresh. + # Figure out whether the data is all numeric and decide on a sort type. + # my $cmp + # = scalar( + # grep { !defined $_ || $_ !~ m/^\d+$/ } + # map { my $col = $_; map { $_->{$col} } @var_status } + # $tbl_meta{var_status}->{sort_cols} =~ m/(\w+)/g) + # ? 'cmp' + # : '<=>'; + $tbl_meta{var_status}->{sort_func} = make_sort_func($tbl_meta{var_status}); + + # ################################################################ + # Now there is specific display code based on $config{S_func} + # ################################################################ + if ( $func =~ m/s|g/ ) { + my $min_width = 4; + + # Clear the screen if the display width changed. + if ( @last_term_size && $this_term_size[0] != $last_term_size[0] ) { + $lines_printed = 0; + $clear_screen_sub->(); + } + + if ( $func eq 's' ) { + # Decide how wide columns should be. + my $num_cols = scalar(@$visible); + my $width = $opts{n} ? 0 : max($min_width, int(($this_term_size[0] - $num_cols + 1) / $num_cols)); + my $g_format = $opts{n} ? ( "%s\t" x $num_cols ) : ( "%-${width}s " x $num_cols ); + + # Print headers every now and then. Headers can get really long, so compact them. + my @hdr = @$visible; + if ( $opts{n} ) { + if ( $lines_printed == 0 ) { + print join("\t", @hdr), "\n"; + $lines_printed++; + } + } + elsif ( $lines_printed == 0 || $lines_printed > $this_term_size[1] - 2 ) { + @hdr = map { donut(crunch($_, $width), $width) } @hdr; + print join(' ', map { sprintf( "%${width}s", donut($_, $width)) } @hdr) . "\n"; + $lines_printed = 1; + } + + # Design a column format for the values. + my $format + = $opts{n} + ? join("\t", map { '%s' } @$visible) . "\n" + : join(' ', map { "%${width}s" } @hdr) . "\n"; + + foreach my $row ( @var_status ) { + printf($format, map { defined $_ ? $_ : '' } @{$row}{ @$visible }); + $lines_printed++; + } + } + else { # 'g' mode + # Design a column format for the values. + my $num_cols = scalar(@$visible); + my $width = $opts{n} ? 0 : int(($this_term_size[0] - $num_cols + 1) / $num_cols); + my $format = $opts{n} ? ( "%s\t" x $num_cols ) : ( "%-${width}s " x $num_cols ); + $format =~ s/\s$/\n/; + + # Print headers every now and then. + if ( $opts{n} ) { + if ( $lines_printed == 0 ) { + print join("\t", @$visible), "\n"; + print join("\t", map { shorten($mvs{$_}) } @$visible), "\n"; + } + } + elsif ( $lines_printed == 0 || $lines_printed > $this_term_size[1] - 2 ) { + printf($format, map { donut(crunch($_, $width), $width) } @$visible); + printf($format, map { shorten($mvs{$_} || 0) } @$visible); + $lines_printed = 2; + } + + # Update the max ever seen, and scale by the max ever seen. + my $set = $var_status[0]; + foreach my $col ( @$visible ) { + $set->{$col} = 1 unless defined $set->{$col} && $set->{$col} =~ m/$num_regex/; + $set->{$col} = ($set->{$col} || 1) / ($set->{Uptime_hires} || 1); + $mvs{$col} = max($mvs{$col} || 1, $set->{$col}); + $set->{$col} /= $mvs{$col}; + } + printf($format, map { ( $config{graph_char}->{val} x int( $width * $set->{$_} )) || '.' } @$visible ); + $lines_printed++; + + } + } + else { # 'v' + my $first_table = 0; + my @display_lines; + foreach my $tbl ( @visible ) { + push @display_lines, '', set_to_tbl($rows_for{$tbl}, $tbl); + push @display_lines, get_cxn_errors(@cxns) + if ( $config{debug}->{val} || !$first_table++ ); + } + $clear_screen_sub->(); + draw_screen( \@display_lines ); + } +} + +# display_explain {{{3 +sub display_explain { + my $info = shift; + my $cxn = $info->{cxn}; + my $db = $info->{db}; + + my ( $mods, $query ) = rewrite_for_explain($info->{query}); + + my @display_lines; + + if ( $query ) { + + my $part = version_ge($dbhs{$cxn}->{dbh}, '5.1.5') ? 'PARTITIONS' : ''; + $query = "EXPLAIN $part\n" . $query; + + eval { + if ( $db ) { + do_query($cxn, "use $db"); + } + my $sth = do_query($cxn, $query); + + my $res; + while ( $res = $sth->fetchrow_hashref() ) { + map { $res->{$_} ||= '' } ( 'partitions', keys %$res); + my @this_table = create_caption("Sub-Part $res->{id}", + create_table2( + $tbl_meta{explain}->{visible}, + meta_to_hdr('explain'), + extract_values($res, $res, $res, 'explain'))); + @display_lines = stack_next(\@display_lines, \@this_table, { pad => ' ', vsep => 2 }); + } + }; + + if ( $EVAL_ERROR ) { + push @display_lines, + '', + "The query could not be explained. Only SELECT queries can be " + . "explained; innotop tries to rewrite certain REPLACE and INSERT queries " + . "into SELECT, but this doesn't always succeed."; + } + + } + else { + push @display_lines, '', 'The query could not be explained.'; + } + + if ( $mods ) { + push @display_lines, '', '[This query has been re-written to be explainable]'; + } + + unshift @display_lines, no_ctrl_char($query); + draw_screen(\@display_lines, { raw => 1 } ); +} + +# rewrite_for_explain {{{3 +sub rewrite_for_explain { + my $query = shift; + + my $mods = 0; + my $orig = $query; + $mods += $query =~ s/^\s*(?:replace|insert).*?select/select/is; + $mods += $query =~ s/^ + \s*create\s+(?:temporary\s+)?table + \s+(?:\S+\s+)as\s+select/select/xis; + $mods += $query =~ s/\s+on\s+duplicate\s+key\s+update.*$//is; + return ( $mods, $query ); +} + +# show_optimized_query {{{3 +sub show_optimized_query { + my $info = shift; + my $cxn = $info->{cxn}; + my $db = $info->{db}; + my $meta = $dbhs{$cxn}; + + my @display_lines; + + my ( $mods, $query ) = rewrite_for_explain($info->{query}); + + if ( $mods ) { + push @display_lines, '[This query has been re-written to be explainable]'; + } + + if ( $query ) { + push @display_lines, no_ctrl_char($info->{query}); + + eval { + if ( $db ) { + do_query($cxn, "use $db"); + } + do_query( $cxn, 'EXPLAIN EXTENDED ' . $query ) or die "Can't explain query"; + my $sth = do_query($cxn, 'SHOW WARNINGS'); + my $res = $sth->fetchall_arrayref({}); + + if ( $res ) { + foreach my $result ( @$res ) { + push @display_lines, 'Note:', no_ctrl_char($result->{message}); + } + } + else { + push @display_lines, '', 'The query optimization could not be generated.'; + } + }; + + if ( $EVAL_ERROR ) { + push @display_lines, '', "The optimization could not be generated: $EVAL_ERROR"; + } + + } + else { + push @display_lines, '', 'The query optimization could not be generated.'; + } + + draw_screen(\@display_lines, { raw => 1 } ); +} + +# display_help {{{3 +sub display_help { + my $mode = $config{mode}->{val}; + + # Get globally mapped keys, then overwrite them with mode-specific ones. + my %keys = map { + $_ => $action_for{$_}->{label} + } keys %action_for; + foreach my $key ( keys %{$modes{$mode}->{action_for}} ) { + $keys{$key} = $modes{$mode}->{action_for}->{$key}->{label}; + } + delete $keys{'?'}; + + # Split them into three kinds of keys: MODE keys, action keys, and + # magic (special character) keys. + my @modes = sort grep { m/[A-Z]/ } keys %keys; + my @actions = sort grep { m/[a-z]/ } keys %keys; + my @magic = sort grep { m/[^A-Z]/i } keys %keys; + + my @display_lines = ( '', 'Switch to a different mode:' ); + + # Mode keys + my @all_modes = map { "$_ $modes{$_}->{hdr}" } @modes; + my @col1 = splice(@all_modes, 0, ceil(@all_modes/3)); + my @col2 = splice(@all_modes, 0, ceil(@all_modes/2)); + my $max1 = max(map {length($_)} @col1); + my $max2 = max(map {length($_)} @col2); + while ( @col1 ) { + push @display_lines, sprintf(" %-${max1}s %-${max2}s %s", + (shift @col1 || ''), + (shift @col2 || ''), + (shift @all_modes || '')); + } + + # Action keys + my @all_actions = map { "$_ $keys{$_}" } @actions; + @col1 = splice(@all_actions, 0, ceil(@all_actions/2)); + $max1 = max(map {length($_)} @col1); + push @display_lines, '', 'Actions:'; + while ( @col1 ) { + push @display_lines, sprintf(" %-${max1}s %s", + (shift @col1 || ''), + (shift @all_actions || '')); + } + + # Magic keys + my @all_magic = map { + my $k = $action_for{$_} ? ($action_for{$_}->{key} || $_) : $_; + sprintf('%4s %s', $k, $keys{$_}); + } @magic; + @col1 = splice(@all_magic, 0, ceil(@all_magic/2)); + $max1 = max(map {length($_)} @col1); + push @display_lines, '', 'Other:'; + while ( @col1 ) { + push @display_lines, sprintf("%-${max1}s%s", + (shift @col1 || ''), + (shift @all_magic || '')); + } + + $clear_screen_sub->(); + draw_screen(\@display_lines, { show_all => 1 } ); + pause(); + $clear_screen_sub->(); +} + +# show_full_query {{{3 +sub show_full_query { + my $info = shift; + my @display_lines = no_ctrl_char($info->{query}); + draw_screen(\@display_lines, { raw => 1 }); +} + +# Formatting functions {{{2 + +# create_table2 {{{3 +# Makes a two-column table, labels on left, data on right. +# Takes refs of @cols, %labels and %data, %user_prefs +sub create_table2 { + my ( $cols, $labels, $data, $user_prefs ) = @_; + my @rows; + + if ( @$cols && %$data ) { + + # Override defaults + my $p = { + just => '', + sep => ':', + just1 => '-', + }; + if ( $user_prefs ) { + map { $p->{$_} = $user_prefs->{$_} } keys %$user_prefs; + } + + # Fix undef values + map { $data->{$_} = '' unless defined $data->{$_} } @$cols; + + # Format the table + my $max_l = max(map{ length($labels->{$_}) } @$cols); + my $max_v = max(map{ length($data->{$_}) } @$cols); + my $format = "%$p->{just}${max_l}s$p->{sep} %$p->{just1}${max_v}s"; + foreach my $col ( @$cols ) { + push @rows, sprintf($format, $labels->{$col}, $data->{$col}); + } + } + return @rows; +} + +# stack_next {{{3 +# Stacks one display section next to the other. Accepts left-hand arrayref, +# right-hand arrayref, and options hashref. Tries to stack as high as +# possible, so +# aaaaaa +# bbb +# can stack ccc next to the bbb. +# NOTE: this DOES modify its arguments, even though it returns a new array. +sub stack_next { + my ( $left, $right, $user_prefs ) = @_; + my @result; + + my $p = { + pad => ' ', + vsep => 0, + }; + if ( $user_prefs ) { + map { $p->{$_} = $user_prefs->{$_} } keys %$user_prefs; + } + + # Find out how wide the LHS can be and still let the RHS fit next to it. + my $pad = $p->{pad}; + my $max_r = max( map { length($_) } @$right) || 0; + my $max_l = $this_term_size[0] - $max_r - length($pad); + + # Find the minimum row on the LHS that the RHS will fit next to. + my $i = scalar(@$left) - 1; + while ( $i >= 0 && length($left->[$i]) <= $max_l ) { + $i--; + } + $i++; + my $offset = $i; + + if ( $i < scalar(@$left) ) { + # Find the max width of the section of the LHS against which the RHS + # will sit. + my $max_i_in_common = min($i + scalar(@$right) - 1, scalar(@$left) - 1); + my $max_width = max( map { length($_) } @{$left}[$i..$max_i_in_common]); + + # Append the RHS onto the LHS until one runs out. + while ( $i < @$left && $i - $offset < @$right ) { + my $format = "%-${max_width}s$pad%${max_r}s"; + $left->[$i] = sprintf($format, $left->[$i], $right->[$i - $offset]); + $i++; + } + while ( $i - $offset < @$right ) { + # There is more RHS to push on the end of the array + push @$left, + sprintf("%${max_width}s$pad%${max_r}s", ' ', $right->[$i - $offset]); + $i++; + } + push @result, @$left; + } + else { + # There is no room to put them side by side. Add them below, with + # a blank line above them if specified. + push @result, @$left; + push @result, (' ' x $this_term_size[0]) if $p->{vsep} && @$left; + push @result, @$right; + } + return @result; +} + +# create_caption {{{3 +sub create_caption { + my ( $caption, @rows ) = @_; + if ( @rows ) { + + # Calculate the width of what will be displayed, so it can be centered + # in that space. When the thing is wider than the display, center the + # caption in the display. + my $width = min($this_term_size[0], max(map { length(ref($_) ? $_->[0] : $_) } @rows)); + + my $cap_len = length($caption); + + # It may be narrow enough to pad the sides with underscores and save a + # line on the screen. + if ( $cap_len <= $width - 6 ) { + my $left = int(($width - 2 - $cap_len) / 2); + unshift @rows, + ("_" x $left) . " $caption " . ("_" x ($width - $left - $cap_len - 2)); + } + + # The caption is too wide to add underscores on each side. + else { + + # Color is supported, so we can use terminal underlining. + if ( $config{color}->{val} ) { + my $left = int(($width - $cap_len) / 2); + unshift @rows, [ + (" " x $left) . $caption . (" " x ($width - $left - $cap_len)), + 'underline', + ]; + } + + # Color is not supported, so we have to add a line underneath to separate the + # caption from whatever it's captioning. + else { + my $left = int(($width - $cap_len) / 2); + unshift @rows, ('-' x $width); + unshift @rows, (" " x $left) . $caption . (" " x ($width - $left - $cap_len)); + } + + # The caption is wider than the thing it labels, so we have to pad the + # thing it labels to a consistent width. + if ( $cap_len > $width ) { + @rows = map { + ref($_) + ? [ sprintf('%-' . $cap_len . 's', $_->[0]), $_->[1] ] + : sprintf('%-' . $cap_len . 's', $_); + } @rows; + } + + } + } + return @rows; +} + +# create_table {{{3 +# Input: an arrayref of columns, hashref of col info, and an arrayref of hashes +# Example: [ 'a', 'b' ] +# { a => spec, b => spec } +# [ { a => 1, b => 2}, { a => 3, b => 4 } ] +# The 'spec' is a hashref of hdr => label, just => ('-' or ''). It also supports min and max-widths +# vi the minw and maxw params. +# Output: an array of strings, one per row. +# Example: +# Column One Column Two +# ---------- ---------- +# 1 2 +# 3 4 +sub create_table { + my ( $cols, $info, $data, $prefs ) = @_; + $prefs ||= {}; + $prefs->{no_hdr} ||= ($opts{n} && $clock != 1); + + # Truncate rows that will surely be off screen even if this is the only table. + if ( !$opts{n} && !$prefs->{raw} && !$prefs->{show_all} && $this_term_size[1] < @$data-1 ) { + $data = [ @$data[0..$this_term_size[1] - 1] ]; + } + + my @rows = (); + + if ( @$cols && %$info ) { + + # Fix undef values, collapse whitespace. + foreach my $row ( @$data ) { + map { $row->{$_} = collapse_ws($row->{$_}) } @$cols; + } + + my $col_sep = $opts{n} ? "\t" : ' '; + + # Find each column's max width. + my %width_for; + if ( !$opts{n} ) { + %width_for = map { + my $col_name = $_; + if ( $info->{$_}->{dec} ) { + # Align along the decimal point + my $max_rodp = max(0, map { $_->{$col_name} =~ m/([^\s\d-].*)$/ ? length($1) : 0 } @$data); + foreach my $row ( @$data ) { + my $col = $row->{$col_name}; + my ( $l, $r ) = $col =~ m/^([\s\d]*)(.*)$/; + $row->{$col_name} = sprintf("%s%-${max_rodp}s", $l, $r); + } + } + my $max_width = max( length($info->{$_}->{hdr}), map { length($_->{$col_name}) } @$data); + if ( $info->{$col_name}->{maxw} ) { + $max_width = min( $max_width, $info->{$col_name}->{maxw} ); + } + if ( $info->{$col_name}->{minw} ) { + $max_width = max( $max_width, $info->{$col_name}->{minw} ); + } + $col_name => $max_width; + } @$cols; + } + + # The table header. + if ( !$config{hide_hdr}->{val} && !$prefs->{no_hdr} ) { + push @rows, $opts{n} + ? join( $col_sep, @$cols ) + : join( $col_sep, map { sprintf( "%-$width_for{$_}s", trunc($info->{$_}->{hdr}, $width_for{$_}) ) } @$cols ); + if ( $config{color}->{val} && $config{header_highlight}->{val} ) { + push @rows, [ pop @rows, $config{header_highlight}->{val} ]; + } + elsif ( !$opts{n} ) { + push @rows, join( $col_sep, map { "-" x $width_for{$_} } @$cols ); + } + } + + # The table data. + if ( $opts{n} ) { + foreach my $item ( @$data ) { + push @rows, join($col_sep, map { $item->{$_} } @$cols ); + } + } + else { + my $format = join( $col_sep, + map { "%$info->{$_}->{just}$width_for{$_}s" } @$cols ); + foreach my $item ( @$data ) { + my $row = sprintf($format, map { trunc($item->{$_}, $width_for{$_}) } @$cols ); + if ( $config{color}->{val} && $item->{_color} ) { + push @rows, [ $row, $item->{_color} ]; + } + else { + push @rows, $row; + } + } + } + } + + return @rows; +} + +# Aggregates a table. If $group_by is an arrayref of columns, the grouping key +# is the specified columns; otherwise it's just the empty string (e.g. +# everything is grouped as one group). +sub apply_group_by { + my ( $tbl, $group_by, @rows ) = @_; + my $meta = $tbl_meta{$tbl}; + my %is_group = map { $_ => 1 } @$group_by; + my @non_grp = grep { !$is_group{$_} } keys %{$meta->{cols}}; + + my %temp_table; + foreach my $row ( @rows ) { + my $group_key + = @$group_by + ? '{' . join('}{', map { defined $_ ? $_ : '' } @{$row}{@$group_by}) . '}' + : ''; + $temp_table{$group_key} ||= []; + push @{$temp_table{$group_key}}, $row; + } + + # Crush the rows together... + my @new_rows; + foreach my $key ( sort keys %temp_table ) { + my $group = $temp_table{$key}; + my %new_row; + @new_row{@$group_by} = @{$group->[0]}{@$group_by}; + foreach my $col ( @non_grp ) { + my $agg = $meta->{cols}->{$col}->{agg} || 'first'; + $new_row{$col} = $agg_funcs{$agg}->( map { $_->{$col} } @$group ); + } + push @new_rows, \%new_row; + } + return @new_rows; +} + +# set_to_tbl {{{3 +# Unifies all the work of filtering, sorting etc. Alters the input. +# TODO: pull all the little pieces out into subroutines and stick events in each of them. +sub set_to_tbl { + my ( $rows, $tbl ) = @_; + my $meta = $tbl_meta{$tbl} or die "No such table $tbl in tbl_meta"; + + # don't show / hide cxn if there's only one connection being displayed + my (@visible, @group_by); + my $num_cxn = scalar get_connections(); + if ($num_cxn <= 1) { + map { push @visible, $_ if $_ !~ /^cxn$/ } @{$meta->{visible}}; + $meta->{visible} = \@visible; + map { push @group_by, $_ if $_ !~ /^cxn$/ } @{$meta->{group_by}}; + $meta->{group_by} = \@group_by; + } + # if cxn is not visible and there is now more than one connection, + # make cxn visible again. assume it's not in group_by if it's not + # visible + else { + my $has_cxn = 0; + foreach my $column (@{$meta->{visible}}) { + if ($column eq "cxn") { + $has_cxn = 1; + last; + } + } + if (not $has_cxn) { + map { push @visible, $_ if $_ !~ /^cxn$/ } @{$meta->{visible}}; + $meta->{visible} = \@visible; + map { push @group_by, $_ if $_ !~ /^cxn$/ } @{$meta->{group_by}}; + $meta->{group_by} = \@group_by; + } + } + + if ( !$meta->{pivot} ) { + + # Hook in event listeners + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_filter}} ) { + $listener->set_to_tbl_pre_filter($rows, $tbl); + } + + # Apply filters. Note that if the table is pivoted, filtering and sorting + # are applied later. + foreach my $filter ( @{$meta->{filters}} ) { + eval { + @$rows = grep { $filters{$filter}->{func}->($_) } @$rows; + }; + if ( $EVAL_ERROR && $config{debug}->{val} ) { + die $EVAL_ERROR; + } + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_sort}} ) { + $listener->set_to_tbl_pre_sort($rows, $tbl); + } + + # Sort. Note that if the table is pivoted, sorting might have the wrong + # columns and it could crash. This will only be an issue if it's possible + # to toggle pivoting on and off, which it's not at the moment. + if ( @$rows && $meta->{sort_func} && !$meta->{aggregate} ) { + if ( $meta->{sort_dir} > 0 ) { + @$rows = $meta->{sort_func}->( @$rows ); + } + else { + @$rows = reverse $meta->{sort_func}->( @$rows ); + } + } + + } + + # Stop altering arguments now. + my @rows = @$rows; + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_group}} ) { + $listener->set_to_tbl_pre_group(\@rows, $tbl); + } + + # Apply group-by. + if ( $meta->{aggregate} ) { + @rows = apply_group_by($tbl, $meta->{group_by}, @rows); + + # Sort. Note that if the table is pivoted, sorting might have the wrong + # columns and it could crash. This will only be an issue if it's possible + # to toggle pivoting on and off, which it's not at the moment. + if ( @rows && $meta->{sort_func} ) { + if ( $meta->{sort_dir} > 0 ) { + @rows = $meta->{sort_func}->( @rows ); + } + else { + @rows = reverse $meta->{sort_func}->( @rows ); + } + } + + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_colorize}} ) { + $listener->set_to_tbl_pre_colorize(\@rows, $tbl); + } + + if ( !$meta->{pivot} ) { + # Colorize. Adds a _color column to rows. + if ( @rows && $meta->{color_func} ) { + eval { + foreach my $row ( @rows ) { + $row->{_color} = $meta->{color_func}->($row); + } + }; + if ( $EVAL_ERROR ) { + pause($EVAL_ERROR); + } + } + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_transform}} ) { + $listener->set_to_tbl_pre_transform(\@rows, $tbl); + } + + # Apply_transformations. + if ( @rows ) { + my $cols = $meta->{cols}; + foreach my $col ( keys %{$rows->[0]} ) { + # Don't auto-vivify $tbl_meta{tbl}-{cols}->{_color}->{trans} + next if $col eq '_color'; + foreach my $trans ( @{$cols->{$col}->{trans}} ) { + map { $_->{$col} = $trans_funcs{$trans}->($_->{$col}) } @rows; + } + } + } + + my ($fmt_cols, $fmt_meta); + + # Pivot. + if ( $meta->{pivot} ) { + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_pivot}} ) { + $listener->set_to_tbl_pre_pivot(\@rows, $tbl); + } + + my @vars = @{$meta->{visible}}; + my @tmp = map { { name => $_ } } @vars; + my @cols = 'name'; + foreach my $i ( 0..@$rows-1 ) { + my $col = "set_$i"; + push @cols, $col; + foreach my $j ( 0..@vars-1 ) { + $tmp[$j]->{$col} = $rows[$i]->{$vars[$j]}; + } + } + $fmt_meta = { map { $_ => { hdr => $_, just => '-' } } @cols }; + $fmt_cols = \@cols; + @rows = @tmp; + + # Hook in event listeners + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_filter}} ) { + $listener->set_to_tbl_pre_filter($rows, $tbl); + } + + # Apply filters. + foreach my $filter ( @{$meta->{filters}} ) { + eval { + @rows = grep { $filters{$filter}->{func}->($_) } @rows; + }; + if ( $EVAL_ERROR && $config{debug}->{val} ) { + die $EVAL_ERROR; + } + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_sort}} ) { + $listener->set_to_tbl_pre_sort($rows, $tbl); + } + + # Sort. + if ( @rows && $meta->{sort_func} ) { + if ( $meta->{sort_dir} > 0 ) { + @rows = $meta->{sort_func}->( @rows ); + } + else { + @rows = reverse $meta->{sort_func}->( @rows ); + } + } + + } + else { + # If the table isn't pivoted, just show all columns that are supposed to + # be shown; but eliminate aggonly columns if the table isn't aggregated. + my $aggregated = $meta->{aggregate}; + $fmt_cols = [ grep { $aggregated || !$meta->{cols}->{$_}->{aggonly} } @{$meta->{visible}} ]; + $fmt_meta = { map { $_ => $meta->{cols}->{$_} } @$fmt_cols }; + + # If the table is aggregated, re-order the group_by columns to the left of + # the display, and suppress 'agghide' columns. + if ( $aggregated ) { + my %is_group = map { $_ => 1 } @{$meta->{group_by}}; + $fmt_cols = [ @{$meta->{group_by}}, grep { !$is_group{$_} } @$fmt_cols ]; + $fmt_cols = [ grep { !$meta->{cols}->{$_}->{agghide} } @$fmt_cols ]; + } + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_pre_create}} ) { + $listener->set_to_tbl_pre_create(\@rows, $tbl); + } + + @rows = create_table( $fmt_cols, $fmt_meta, \@rows); + if ( !$meta->{hide_caption} && !$opts{n} && $config{display_table_captions}->{val} ) { + @rows = create_caption($meta->{capt}, @rows) + } + + foreach my $listener ( @{$event_listener_for{set_to_tbl_post_create}} ) { + $listener->set_to_tbl_post_create(\@rows, $tbl); + } + + return @rows; +} + +# meta_to_hdr {{{3 +sub meta_to_hdr { + my $tbl = shift; + my $meta = $tbl_meta{$tbl}; + my %labels = map { $_ => $meta->{cols}->{$_}->{hdr} } @{$meta->{visible}}; + return \%labels; +} + +# commify {{{3 +# From perlfaq5: add commas. +sub commify { + my ( $num ) = @_; + $num = 0 unless defined $num; + $num =~ s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g; + return $num; +} + +# set_precision {{{3 +# Trim to desired precision. +sub set_precision { + my ( $num, $precision ) = @_; + $num = 0 unless defined $num; + $precision = $config{num_digits}->{val} if !defined $precision; + if ( $num eq "" ) { + $num = int(0); + } + sprintf("%.${precision}f", $num); +} + +# percent {{{3 +# Convert to percent +sub percent { + my ( $num ) = @_; + $num = 0 unless defined $num; + if ( $num eq "" ) { + $num = int(0); + } + my $digits = $config{num_digits}->{val}; + return sprintf("%.${digits}f", $num * 100) + . ($config{show_percent}->{val} ? '%' : ''); +} + +# sparkify {{{3 +# Find the range (min to max) and divide it up. Each value then gets put into +# a bucket and represented by one of these characters: _.-=^ +sub sparkify { + my @vals = @_; + my @chars = qw(_ . - = ^); + my $min = min(@vals); + my $max = max(@vals); + my $range = ($max - $min) / 4; + return "_" x scalar(@vals) if !$min || !$max || $max == $min || !$range; + my $result = ""; + foreach my $v ( @vals ) { + $result .= $chars[ int(($v - $min) / $range) ]; + } + return $result; +} + +# shorten {{{3 +sub shorten { + my ( $num, $opts ) = @_; + + return $num if !defined($num) || $opts{n} || $num !~ m/$num_regex/; + + $opts ||= {}; + my $pad = defined $opts->{pad} ? $opts->{pad} : ''; + my $num_digits = defined $opts->{num_digits} + ? $opts->{num_digits} + : $config{num_digits}->{val}; + my $force = defined $opts->{force}; + + my $n = 0; + while ( $num >= 1_024 ) { + $num /= 1_024; + ++$n; + } + return $num =~ m/\./ || $n || $force + ? sprintf("%.${num_digits}f%s", $num, ($pad,'k','M','G','T')[$n]) + : $num; +} + +# Utility functions {{{2 +# unique {{{3 +sub unique { + my %seen; + return grep { !$seen{$_}++ } @_; +} + +# make_color_func {{{3 +sub make_color_func { + my ( $tbl ) = @_; + my @criteria; + foreach my $spec ( @{$tbl->{colors}} ) { + next unless exists $comp_ops{$spec->{op}}; + my $val = $spec->{op} =~ m/^(?:eq|ne|le|ge|lt|gt)$/ ? "'$spec->{arg}'" + : $spec->{op} =~ m/^(?:=~|!~)$/ ? "m/" . quotemeta($spec->{arg}) . "/" + : $spec->{arg}; + push @criteria, + "( defined \$set->{$spec->{col}} && \$set->{$spec->{col}} $spec->{op} $val ) { return '$spec->{color}'; }"; + } + return unless @criteria; + my $sub = eval 'sub { my ( $set ) = @_; if ' . join(" elsif ", @criteria) . '}'; + die if $EVAL_ERROR; + return $sub; +} + +# make_sort_func {{{3 +# Gets a list of sort columns from the table, like "+cxn -time" and returns a +# subroutine that will sort that way. +sub make_sort_func { + my ( $tbl ) = @_; + my @criteria; + + # Pivoted tables can be sorted by 'name' and set_x columns; others must be + # sorted by existing columns. TODO: this will crash if you toggle between + # pivoted and nonpivoted. I have several other 'crash' notes about this if + # this ever becomes possible. + + if ( $tbl->{pivot} ) { + # Sort type is not really possible on pivoted columns, because a 'column' + # contains data from an entire non-pivoted row, so there could be a mix of + # numeric and non-numeric data. Thus everything has to be 'cmp' type. + foreach my $col ( split(/\s+/, $tbl->{sort_cols} ) ) { + next unless $col; + my ( $dir, $name ) = $col =~ m/([+-])?(\w+)$/; + next unless $name && $name =~ m/^(?:name|set_\d+)$/; + $dir ||= '+'; + my $op = 'cmp'; + my $df = "''"; + push @criteria, + $dir eq '+' + ? "(\$a->{$name} || $df) $op (\$b->{$name} || $df)" + : "(\$b->{$name} || $df) $op (\$a->{$name} || $df)"; + } + } + else { + foreach my $col ( split(/\s+/, $tbl->{sort_cols} ) ) { + next unless $col; + my ( $dir, $name ) = $col =~ m/([+-])?(\w+)$/; + next unless $name && $tbl->{cols}->{$name}; + $dir ||= '+'; + my $op = $tbl->{cols}->{$name}->{num} ? "<=>" : "cmp"; + my $df = $tbl->{cols}->{$name}->{num} ? "0" : "''"; + push @criteria, + $dir eq '+' + ? "(\$a->{$name} || $df) $op (\$b->{$name} || $df)" + : "(\$b->{$name} || $df) $op (\$a->{$name} || $df)"; + } + } + return sub { return @_ } unless @criteria; + my $sub = eval 'sub { sort {' . join("||", @criteria) . '} @_; }'; + die if $EVAL_ERROR; + return $sub; +} + +# trunc {{{3 +# Shortens text to specified length. +sub trunc { + my ( $text, $len ) = @_; + if ( length($text) <= $len ) { + return $text; + } + return substr($text, 0, $len); +} + +# donut {{{3 +# Takes out the middle of text to shorten it. +sub donut { + my ( $text, $len ) = @_; + return $text if length($text) <= $len; + my $max = length($text) - $len; + my $min = $max - 1; + + # Try to remove a single "word" from somewhere in the center + if ( $text =~ s/_[^_]{$min,$max}_/_/ ) { + return $text; + } + + # Prefer removing the end of a "word" + if ( $text =~ s/([^_]+)[^_]{$max}_/$1_/ ) { + return $text; + } + + $text = substr($text, 0, int($len/2)) + . "_" + . substr($text, int($len/2) + $max + 1); + return $text; +} + +# crunch {{{3 +# Removes vowels and compacts repeated letters to shorten text. +sub crunch { + my ( $text, $len ) = @_; + return $text if $len && length($text) <= $len; + $text =~ s/^IB_\w\w_//; + $text =~ s/(?{val}; + if ( $charset && $charset eq 'unicode' ) { + $text =~ s/ + ("(?:(?!(?{val} ) { + unshift @$display_lines, create_statusbar(); + } + + foreach my $listener ( @{$event_listener_for{draw_screen}} ) { + $listener->draw_screen($display_lines); + } + + $clear_screen_sub->() + if $prefs->{clear} || !$modes{$config{mode}->{val}}->{no_clear_screen}; + if ( $opts{n} || $prefs->{raw} ) { + my $num_lines = 0; + my $ts = $opts{t} ? POSIX::strftime($config{timeformat}->{val}, localtime) : ''; + if ( $opts{t} ) { + if ( $opts{t} == 1 ) { + print "\n$ts\n\n"; + $ts = ""; # Prevent it from being written on every line. + $num_lines++; + } + else { + $ts .= " "; + } + } + print join("\n", + map { + $num_lines++; + ref $_ + ? colored($ts . $_->[0], $_->[1]) + : $ts . $_; + } + grep { !$opts{n} || $_ } # Suppress empty lines + @$display_lines); + if ( $opts{n} && $num_lines ) { + print "\n"; + } + } + else { + my $max_lines = $prefs->{show_all} + ? scalar(@$display_lines)- 1 + : min(scalar(@$display_lines), $this_term_size[1]); + print join("\n", + map { + ref $_ + ? colored(substr($_->[0], 0, $this_term_size[0]), $_->[1]) + : substr($_, 0, $this_term_size[0]); + } @$display_lines[0..$max_lines - 1]); + } +} + +# fuzzy_time {{{3 +sub fuzzy_time { + my ( $secs ) = @_; + return '' unless $secs; + return sprintf('%.2f', $secs) if $secs =~ m/^.\./; + $secs =~ s/\..*$//; + return $secs < 180 ? "${secs}s" + : $secs < 3600 ? sprintf("%dm", $secs / 60) + : $secs < 3600 * 3 ? sprintf("%dh%dm", $secs / 3600, ($secs % 3600) / 60) + : $secs < 86400 ? sprintf("%dh", $secs / 3600) + : $secs < 86400* 3 ? sprintf("%dd%dh", $secs / 86400, ($secs % 86400) / 3600) + : sprintf("%dd", $secs / 86400); +} + +sub fuzzy_to_secs { + my ($t) = @_; + return 0 unless $t; + my ($num, $suffix) = $t =~ m/(\d+)([a-z])?$/; + return $num unless $suffix; + return $suffix eq 's' ? $num # Seconds + : $suffix eq 'm' ? $num * 60 # Minutes + : $suffix eq 'h' ? $num * 3600 # Hours + : $num * 86400; # Days +} + +# distill {{{3 +sub distill { + my ( $query ) = @_; + return "" unless $query; + my $orig_query = $query; + + $query =~ m/\A\s*call\s+(\S+)\(/i && return "CALL $1"; + $query =~ m/\A\s*use\s+/ && return "USE"; + $query =~ m/\A\s*UNLOCK TABLES/i && return "UNLOCK"; + $query =~ m/\A\s*xa\s+(\S+)/i && return "XA_$1"; + + # Strip out comments + my $olc_re = qr/(?:--|#)[^'"\r\n]*(?=[\r\n]|\Z)/; # One-line comments + my $mlc_re = qr#/\*[^!].*?\*/#sm; # But not /*!version */ + my $vlc_re = qr#/\*.*?[0-9+].*?\*/#sm; # For SHOW + /*!version */ + my $vlc_rf = qr#^(SHOW).*?/\*![0-9+].*?\*/#sm; # Variation for SHOW + $query =~ s/$olc_re//go; + $query =~ s/$mlc_re//go; + if ( $query =~ m/$vlc_rf/i ) { # contains show + version + $query =~ s/$vlc_re//go; + } + + # Handle SHOW queries + if ( $query =~ m/\A\s*SHOW\s+/i ) { + $query = uc $query; + $query =~ s/\s+(?:GLOBAL|SESSION|FULL|STORAGE|ENGINE)\b/ /g; + $query =~ s/\s+COUNT[^)]+\)//g; + $query =~ s/\s+(?:FOR|FROM|LIKE|WHERE|LIMIT|IN)\b.+//ms; + $query =~ s/\A(SHOW(?:\s+\S+){1,2}).*\Z/$1/s; + $query =~ s/\s+/ /g; + } + + # Find verbs and tables. + my ($verbs, $table); + + # Handle DDL operations (dds) + my $tbl_ident = qr/(?:`[^`]+`|\w+)(?:\.(?:`[^`]+`|\w+))?/; + my $tbl_regex = qr{ + \b(?:FROM|JOIN|(? 1 ) { + # False-positive verbs after SELECT + my $union = grep { $_ eq 'UNION' } @verbs; + @verbs = $union ? qw(SELECT UNION) : qw(SELECT); + } + + my %seen; + $verbs = join(q{ }, grep { !$seen{$_}++ } @verbs); + } + + if ( $verbs && $verbs =~ m/^SHOW/ ) { + my %alias_for = qw( + SCHEMA DATABASE + KEYS INDEX + INDEXES INDEX + ); + map { $verbs =~ s/$_/$alias_for{$_}/ } keys %alias_for; + $query = $verbs; + } + else { + my @tables; + $query =~ s/ (?:LOW_PRIORITY|IGNORE|STRAIGHT_JOIN)//ig; + if ( $query =~ /^\s*LOCK\s+TABLES/i ) { + $query =~ s/^(\s*LOCK\s+TABLES\s+)//i; + $query =~ s/\s+(?:READ|WRITE|LOCAL)+\s*//gi; + $query = "FROM $query"; + } + $query =~ s/\\["']//g; # quoted strings + $query =~ s/".*?"/?/sg; # quoted strings + $query =~ s/'.*?'/?/sg; # quoted strings + + foreach my $tbls ( $query =~ m/$tbl_regex/gio ) { + next if $tbls =~ m/\ASELECT\b/i; + foreach my $tbl ( split(',', $tbls) ) { + $tbl =~ s/\s*($tbl_ident)(\s+.*)?/$1/gio; + if ( $tbl !~ m/[a-zA-Z]/ ) { + # Skip suspicious table name + next; + } + push @tables, $tbl; + } + } + + # If we have a bunch of tables like db1.tbl1 db1.tbl2, convert to + # db1.tbl1 -.tbl2 etc. Also remove repeated tables, and strip `quotes`. + $query = $verbs; + my $prev = ''; + foreach my $t ( @tables, $table ) { + next unless $t; + $t =~ s/`//g; + next if $t eq $prev; + my ($prefix, undef) = split(/\./, $prev); + $prev = $t; + if ( $prefix ) { + $t =~ s/^$prefix\./-./; + } + $query .= " " . $t; + } + } + + # die $orig_query if $query eq 'LOCK lock'; + return $query; +} + +# secs_to_time {{{3 +sub secs_to_time { + my ( $secs, $fmt ) = @_; + $secs ||= 0; + + # If the inbound value has a decimal point, then format the seconds with milliseconds. + my $hires = $secs =~ m/\./ ? '%06.3f' : '%02d'; + + if ( !$secs ) { + return sprintf("00:$hires", $secs); + } + + # Decide what format to use, if not given + $fmt ||= $secs >= 86_400 ? 'd' + : $secs >= 3_600 ? 'h' + : 'm'; + + return + $fmt eq 'd' ? sprintf( + "%d+%02d:%02d:$hires", + int($secs / 86_400), + int(($secs % 86_400) / 3_600), + int(($secs % 3_600) / 60), + $secs % 60 + ($secs - int($secs))) + : $fmt eq 'h' ? sprintf( + "%02d:%02d:$hires", + int(($secs % 86_400) / 3_600), + int(($secs % 3_600) / 60), + $secs % 60 + ($secs - int($secs))) + : sprintf( + "%02d:$hires", + int(($secs % 3_600) / 60), + $secs % 60 + ($secs - int($secs))); +} + +# dulint_to_int {{{3 +# Takes a number that InnoDB formats as two ulint integers, like transaction IDs +# and such, and turns it into a single integer +sub dulint_to_int { + my $num = shift; + return 0 unless $num; + my ( $high, $low ) = $num =~ m/^(\d+) (\d+)$/; + return $low unless $high; + return $low + ( $high * $MAX_ULONG ); +} + +# create_statusbar {{{3 +sub create_statusbar { + my $mode = $config{mode}->{val}; + my @cxns = sort { $a cmp $b } get_connections(); + + my $modeline = ( $config{readonly}->{val} ? '[RO] ' : '' ) + . $modes{$mode}->{hdr} . " (? for help)"; + my $mode_width = length($modeline); + my $remaining_width = $this_term_size[0] - $mode_width - 1; + my $result; + + # The thingie in top-right that says what we're monitoring. + my $cxn = ''; + + if ( 1 == @cxns && $dbhs{$cxns[0]} && $dbhs{$cxns[0]}->{dbh} ) { + $cxn = $dbhs{$cxns[0]}->{dbh}->{mariadb_serverinfo} || ''; + } + else { + if ( $modes{$mode}->{server_group} ) { + $cxn = "Servers: " . $modes{$mode}->{server_group}; + my $err_count = grep { $dbhs{$_} && $dbhs{$_}->{failed} } @cxns; + if ( $err_count ) { + $cxn .= "(" . ( scalar(@cxns) - $err_count ) . "/" . scalar(@cxns) . ")"; + } + } + else { + $cxn = join(' ', map { ($dbhs{$_}->{failed} ? '!' : '') . $_ } + grep { $dbhs{$_} } @cxns); + } + } + + if ( 1 == @cxns ) { + get_driver_status(@cxns); + my $vars = $vars{$cxns[0]}->{$clock}; + my $inc = inc(0, $cxns[0]); + + # Format server uptime human-readably, calculate QPS... + my $uptime = fuzzy_time( $vars->{Uptime_hires} ); + my $qps = ($inc->{Questions}||0) / ($inc->{Uptime_hires}||1); + my $ibinfo = ''; + + if ( exists $vars->{IB_last_secs} ) { + $ibinfo .= "InnoDB $vars->{IB_last_secs}s "; + if ( $vars->{IB_got_all} ) { + if ( ($mode eq 'T' || $mode eq 'W') + && $vars->{IB_tx_is_truncated} ) { + $ibinfo .= ':^|'; + } + else { + $ibinfo .= ':-)'; + } + } + else { + $ibinfo .= ':-('; + } + } + $result = sprintf( + "%-${mode_width}s %${remaining_width}s", + $modeline, + join(', ', grep { $_ } ( + $cxns[0], + $uptime, + $ibinfo, + shorten($qps) . " QPS", + ($vars->{Threads} || 0) . "/" . ($vars->{Threads_running} || 0) . "/" . ($vars->{Threads_cached} || 0) . " con/run/cac thds", + $cxn))); + } + else { + $result = sprintf( + "%-${mode_width}s %${remaining_width}s", + $modeline, + $cxn); + } + + return $config{color}->{val} ? [ $result, 'bold reverse' ] : $result; +} + +# Database connections {{{3 +sub add_new_dsn { + my ( $name, $dsn, $dl_table, $have_user, $user, $have_pass, $pass, $savepass ) = @_; + + if ( defined $name ) { + $name =~ s/[\s:;]//g; + } + + if ( !$name ) { + print word_wrap("Choose a name for the connection. It cannot contain " + . "whitespace, colons or semicolons."), "\n\n"; + do { + $name = prompt("Enter a name"); + $name =~ s/[\s:;]//g; + } until ( $name ); + } + + if ( !$dsn ) { + do { + $clear_screen_sub->(); + print "Typical DSN strings look like\n DBI:MariaDB:;host=hostname;port=port\n" + . "The db and port are optional and can usually be omitted.\n" + . "If you specify 'mariadb_read_default_group=mysql' many options can be read\n" + . "from your mysql options files (~/.my.cnf, /etc/my.cnf).\n\n"; + $dsn = prompt("Enter a DSN string", undef, "DBI:MariaDB:;mariadb_read_default_group=mysql;host=$name"); + } until ( $dsn ); + } + if ( !$dl_table ) { + $clear_screen_sub->(); + my $dl_table = prompt("Optional: enter a table (must not exist) to use when resetting InnoDB deadlock information", + undef, 'test.innotop_dl'); + } + + $connections{$name} = { + dsn => $dsn, + dl_table => $dl_table, + have_user => $have_user, + user => $user, + have_pass => $have_pass, + pass => $pass, + savepass => $savepass + }; +} + +sub add_new_server_group { + my ( $name ) = @_; + + if ( defined $name ) { + $name =~ s/[\s:;]//g; + } + + if ( !$name ) { + print word_wrap("Choose a name for the group. It cannot contain " + . "whitespace, colons or semicolons."), "\n\n"; + do { + $name = prompt("Enter a name"); + $name =~ s/[\s:;]//g; + } until ( $name ); + } + + my @cxns; + do { + $clear_screen_sub->(); + @cxns = select_cxn("Choose servers for $name", keys %connections); + } until ( @cxns ); + + $server_groups{$name} = \@cxns; + return $name; +} + +sub get_var_set { + my ( $name ) = @_; + while ( !$name || !exists($var_sets{$config{$name}->{val}}) ) { + $name = choose_var_set($name); + } + return $var_sets{$config{$name}->{val}}->{text}; +} + +sub add_new_var_set { + my ( $name ) = @_; + + if ( defined $name ) { + $name =~ s/\W//g; + } + + if ( !$name ) { + do { + $name = prompt("Enter a name"); + $name =~ s/\W//g; + } until ( $name ); + } + + my $variables; + do { + $clear_screen_sub->(); + $variables = prompt("Enter variables for $name", undef ); + } until ( $variables ); + + $var_sets{$name} = { text => $variables, user => 1 }; +} + +sub next_server { + my $mode = $config{mode}->{val}; + my @cxns = sort keys %connections; + my ($cur) = get_connections($mode); + $cur ||= $cxns[0]; + my $pos = grep { $_ lt $cur } @cxns; + my $newpos = ($pos + 1) % @cxns; + $modes{$mode}->{server_group} = ''; + $modes{$mode}->{connections} = [ $cxns[$newpos] ]; + $clear_screen_sub->(); +} + +sub next_server_group { + my $mode = shift || $config{mode}->{val}; + my @grps = sort keys %server_groups; + my $curr = $modes{$mode}->{server_group}; + + return unless @grps; + + if ( $curr ) { + # Find the current group's position. + my $pos = 0; + while ( $curr ne $grps[$pos] ) { + $pos++; + } + $modes{$mode}->{server_group} = $grps[ ($pos + 1) % @grps ]; + } + else { + $modes{$mode}->{server_group} = $grps[0]; + } +} + +# Get a list of connection names used in this mode. +sub get_connections { + if ( $file ) { + return qw(file); + } + my $mode = shift || $config{mode}->{val}; + my @connections = $modes{$mode}->{server_group} + ? @{$server_groups{$modes{$mode}->{server_group}}} + : @{$modes{$mode}->{connections}}; + if ( $modes{$mode}->{one_connection} ) { + @connections = @connections ? $connections[0] : (); + } + # If the connections are the same as a server group, we set the mode's + # group to that group. + if ( ! $modes{$mode}->{server_group} ) { + my $maybe_group = join(',', sort @connections); + foreach my $g ( keys %server_groups ) { + my $group_conns = join(',', sort @{$server_groups{$g}}); + if ( $maybe_group eq $group_conns ) { + $modes{$mode}->{server_group} = $g; + last; + } + } + } + return unique(@connections); +} + +# Get a list of tables used in this mode. If innotop is running non-interactively, just use the first. +sub get_visible_tables { + my $mode = shift || $config{mode}->{val}; + my @tbls = @{$modes{$mode}->{visible_tables}}; + if ( $opts{n} ) { + return $tbls[0]; + } + else { + return @tbls; + } +} + +# Choose from among available connections or server groups. +# If the mode has a server set in use, prefers that instead. +sub choose_connections { + $clear_screen_sub->(); + my $mode = $config{mode}->{val}; + my $meta = { map { $_ => $connections{$_}->{dsn} } keys %connections }; + foreach my $group ( keys %server_groups ) { + $meta->{"#$group"} = join(' ', @{$server_groups{$group}}); + } + + my $choices = prompt_list("Choose connections or a group for $mode mode", + undef, sub { return keys %$meta }, $meta); + + my @choices = unique(grep { $_ } $choices =~ m/(\S+)/g); + if ( @choices ) { + if ( $choices[0] =~ s/^#// && exists $server_groups{$choices[0]} ) { + $modes{$mode}->{server_group} = $choices[0]; + } + else { + $modes{$mode}->{connections} = [ grep { exists $connections{$_} } @choices ]; + } + } +} + +# Accepts a DB connection name and the name of a prepared query (e.g. status, kill). +# Also a list of params for the prepared query. This allows not storing prepared +# statements globally. Returns a $sth that's been executed. +# ERROR-HANDLING SEMANTICS: if the statement throws an error, propagate, but if the +# connection has gone away or can't connect, DO NOT. Just return undef. +sub do_stmt { + my ( $cxn, $stmt_name, @args ) = @_; + + return if $file; + + # Test if the cxn should not even be tried + return if $dbhs{$cxn} + && $dbhs{$cxn}->{failed} + && ( !$dbhs{$cxn}->{dbh} || !$dbhs{$cxn}->{dbh}->{Active} || $dbhs{$cxn}->{mode} eq $config{mode}->{val} ); + + my $sth; + my $retries = 1; + my $success = 0; + TRY: + while ( $retries-- >= 0 && !$success ) { + + eval { + my $dbh = connect_to_db($cxn); + + # If the prepared query doesn't exist, make it. + if ( !exists $dbhs{$cxn}->{stmts}->{$stmt_name} ) { + $dbhs{$cxn}->{stmts}->{$stmt_name} = $stmt_maker_for{$stmt_name}->($dbh); + } + + $sth = $dbhs{$cxn}->{stmts}->{$stmt_name}; + if ( $sth ) { + $sth->execute(@args); + } + $success = 1; + }; + if ( $EVAL_ERROR ) { + if ( $EVAL_ERROR =~ m/$nonfatal_errs/ ) { + handle_cxn_error($cxn, $EVAL_ERROR); + } + else { + die "$cxn $stmt_name: $EVAL_ERROR"; + } + if ( $retries < 0 ) { + $sth = undef; + } + } + } + + if ( $sth && $sth->{NUM_OF_FIELDS} ) { + sleep($stmt_sleep_time_for{$stmt_name}) if $stmt_sleep_time_for{$stmt_name}; + return $sth; + } +} + +# Marks a connection as failed. When we sleep between redraws, we try to +# reopen. +sub handle_cxn_error { + my ( $cxn, $err ) = @_; + my $meta = $dbhs{$cxn}; + $meta->{failed} = 1; + + # This is used so errors that have to do with permissions needed by the current + # mode will get displayed as long as we're in this mode, but get ignored if the + # mode changes. + $meta->{mode} = $config{mode}->{val}; + + # Strip garbage from the error text if possible. + $err =~ s/\s+/ /g; + if ( $err =~ m/failed: (.*?) at \S*innotop line/ ) { + $err = $1; + } + + $meta->{last_err} = $err; + if ( $config{show_cxn_errors}->{val} ) { + print STDERR "DB error: $cxn $err" if $config{debug}->{val}; + } +} + +# Accepts a DB connection name and a (string) query. Returns a $sth that's been +# executed. +sub do_query { + my ( $cxn, $query ) = @_; + + return if $file; + + # Test if the cxn should not even be tried + return if $dbhs{$cxn} + && $dbhs{$cxn}->{failed} + && ( !$dbhs{$cxn}->{dbh} || !$dbhs{$cxn}->{dbh}->{Active} || $dbhs{$cxn}->{mode} eq $config{mode}->{val} ); + + my $sth; + my $retries = 1; + my $success = 0; + TRY: + while ( $retries-- >= 0 && !$success ) { + + eval { + my $dbh = connect_to_db($cxn); + + $sth = $dbh->prepare($query); + $sth->execute(); + $success = 1; + }; + if ( $EVAL_ERROR ) { + if ( $EVAL_ERROR =~ m/$nonfatal_errs/ ) { + handle_cxn_error($cxn, $EVAL_ERROR); + } + else { + die $EVAL_ERROR; + } + if ( $retries < 0 ) { + $sth = undef; + } + } + } + + return $sth; +} + +sub get_uptime { + my ( $cxn ) = @_; + $dbhs{$cxn}->{start_time} ||= time(); + # Avoid dividing by zero + return (time() - $dbhs{$cxn}->{start_time}) || .001; +} + +sub connect_to_db { + my ( $cxn ) = @_; + + $dbhs{$cxn} ||= { + stmts => {}, # bucket for prepared statements. + start_time => 0, + dbh => undef, + }; + my $href = $dbhs{$cxn}; + + if ( !$href->{dbh} || ref($href->{dbh}) !~ m/DBI/ || !$href->{dbh}->ping ) { + my $dbh = get_new_db_connection($cxn); + @{$href}{qw(dbh failed start_time stmts)} = ($dbh, 0, 0, {}); + + # Derive and store the server's start time in hi-res + my $uptime = $dbh->selectrow_hashref("show status like 'Uptime'")->{value}; + $href->{start_time} = time() - $uptime; + + # Set timeouts so an unused connection stays alive. + # For example, a connection might be used in Q mode but idle in T mode. + if ( version_ge($dbh, '4.0.3')) { + my $timeout = $config{cxn_timeout}->{val}; + $dbh->do("set session wait_timeout=$timeout, interactive_timeout=$timeout"); + } + } + return $href->{dbh}; +} + +# Compares versions like 5.0.27 and 4.1.15-standard-log +sub version_ge { + my ( $dbh, $target ) = @_; + my $version = sprintf('%03d%03d%03d', $dbh->{mariadb_serverinfo} =~ m/^(\d+).(\d+).(\d+)/g); + return $version ge sprintf('%03d%03d%03d', $target =~ m/(\d+)/g); +} + +# Extracts status values that can be gleaned from the DBD driver without doing a whole query. +sub get_driver_status { + my @cxns = @_; + if ( !$info_gotten{driver_status}++ ) { + foreach my $cxn ( @cxns ) { + next unless $dbhs{$cxn} && $dbhs{$cxn}->{dbh} && $dbhs{$cxn}->{dbh}->{Active}; + $vars{$cxn}->{$clock} ||= {}; + my $vars = $vars{$cxn}->{$clock}; + my %res = map { $_ =~ s/ +/_/g; $_ } $dbhs{$cxn}->{dbh}->{mariadb_stat} =~ m/(\w[^:]+): ([\d\.]+)/g; + map { $vars->{$_} ||= $res{$_} } keys %res; + $vars->{Uptime_hires} ||= get_uptime($cxn); + $vars->{cxn} = $cxn; + } + } +} + +sub get_new_db_connection { + my ( $connection, $destroy ) = @_; + if ( $file ) { + die "You can't connect to a MariaDB server while monitoring a file. This is probably a bug."; + } + + my $dsn = $connections{$connection} + or die "No connection named '$connection' is defined in your configuration"; + + # don't ask for a username if mariadb_read_default_group=client is in the DSN + if ( !defined $dsn->{have_user} and $dsn->{dsn} !~ /mariadb_read_default_group=client/ ) { + my $answer = prompt("Do you want to specify a username for $connection?", undef, 'n'); + $dsn->{have_user} = $answer && $answer =~ m/1|y/i; + } + + # don't ask for a password if mariadb_read_default_group=client is in the DSN + if ( !defined $dsn->{have_pass} and $dsn->{dsn} !~ /mariadb_read_default_group=client/ ) { + my $answer = prompt("Do you want to specify a password for $connection?", undef, 'n'); + $dsn->{have_pass} = $answer && $answer =~ m/1|y/i; + } + + if ( !$dsn->{user} && $dsn->{have_user} ) { + my $user = $ENV{USERNAME} || $ENV{USER} || getlogin() || getpwuid($REAL_USER_ID) || undef; + $dsn->{user} = prompt("Enter username for $connection", undef, $user); + } + + if ( !defined $dsn->{user} ) { + $dsn->{user} = ''; + } + + if ( !$dsn->{pass} && !$dsn->{savepass} && $dsn->{have_pass} ) { + $dsn->{pass} = prompt_noecho("Enter password for '$dsn->{user}' on $connection"); + print "\n"; + if ( !defined($dsn->{savepass}) ) { + my $answer = prompt("Save password in plain text in the config file?", undef, 'y'); + $dsn->{savepass} = $answer && $answer =~ m/1|y/i; + } + } + + my $dbh = DBI->connect( + $dsn->{dsn}, $dsn->{user}, $dsn->{pass}, + { RaiseError => 1, PrintError => 0, AutoCommit => 1 }); + $dbh->{InactiveDestroy} = 1 unless $destroy; # Can't be set in $db_options + $dbh->{FetchHashKeyName} = 'NAME_lc'; # Lowercases all column names for fetchrow_hashref + return $dbh; +} + +sub get_cxn_errors { + my @cxns = @_; + return () unless $config{show_cxn_errors_in_tbl}->{val}; + return + map { [ $_ . ': ' . $dbhs{$_}->{last_err}, 'red' ] } + grep { $dbhs{$_} && $dbhs{$_}->{failed} && $dbhs{$_}->{mode} eq $config{mode}->{val} } + @cxns; +} + +# Setup and tear-down functions {{{2 + +# Takes a string and turns it into a hashref you can apply to %tbl_meta tables. The string +# can be in the form 'foo, bar, foo/bar, foo as bar' much like a SQL SELECT statement. +sub compile_select_stmt { + my ($str) = @_; + my @exps = $str =~ m/\s*([^,]+(?i:\s+as\s+[^,\s]+)?)\s*(?=,|$)/g; + my %cols; + my @visible; + foreach my $exp ( @exps ) { + my ( $text, $colname ); + if ( $exp =~ m/as\s+(\w+)\s*/ ) { + $colname = $1; + $exp =~ s/as\s+(\w+)\s*//; + $text = $exp; + } + else { + $text = $colname = $exp; + } + my ($func, $err) = compile_expr($text); + $cols{$colname} = { + src => $text, + hdr => $colname, + num => 0, + func => $func, + }; + push @visible, $colname; + } + return (\%cols, \@visible); +} + +# compile_filter {{{3 +sub compile_filter { + my ( $text ) = @_; + my ( $sub, $err ); + eval { $sub = sub { my $set = shift; $text } }; + if ( $EVAL_ERROR ) { + $EVAL_ERROR =~ s/at \(eval.*$//; + $sub = sub { return $EVAL_ERROR }; + $err = $EVAL_ERROR; + } + return ( $sub, $err ); +} + +# compile_expr {{{3 +sub compile_expr { + my ( $expr ) = @_; + # Leave built-in functions alone so they get called as Perl functions, unless + # they are the only word in $expr, in which case treat them as hash keys. + if ( $expr =~ m/\W/ ) { + $expr =~ s/(?{$1}"/eg; + } + else { + $expr = "\$set->{$expr}"; + } + my ( $sub, $err ); + my $quoted = quotemeta($expr); + eval qq{ + \$sub = sub { + my (\$set, \$cur, \$pre) = \@_; + my \$val = eval { $expr }; + if ( \$EVAL_ERROR && \$config{debug}->{val} ) { + \$EVAL_ERROR =~ s/ at \\(eval.*//s; + die "\$EVAL_ERROR in expression $quoted"; + } + return \$val; + } + }; + if ( $EVAL_ERROR ) { + if ( $config{debug}->{val} ) { + die $EVAL_ERROR; + } + $EVAL_ERROR =~ s/ at \(eval.*$//; + $sub = sub { return $EVAL_ERROR }; + $err = $EVAL_ERROR; + } + return ( $sub, $err ); +} + +# finish {{{3 +# This is a subroutine because it's called from a key to quit the program. +sub finish { + save_config(); + foreach my $cxn ( values %dbhs ) { + eval { + foreach my $sth ( values %{$cxn->{stmts}} ) { + $sth->finish; + } + $cxn->{dbh}->disconnect; + }; + # Ignore eval errors, we just don't care + } + ReadMode('normal') unless $opts{n}; + print "\n"; + exit(0); +} + +# core_dump {{{3 +sub core_dump { + my $msg = shift; + if ($config{debugfile}->{val} && $config{debug}->{val}) { + eval { + open my $file, '>>', $config{debugfile}->{val}; + if ( %vars ) { + print $file "Current variables:\n" . Dumper(\%vars); + } + close $file; + }; + } + print $msg; +} + +# migrate_config {{{3 +sub migrate_config { + + my ($old_filename, $new_filename) = @_; + + # don't proceed if old file doesn't exist + if ( ! -f $old_filename ) { + die "Error migrating '$old_filename': file doesn't exist.\n"; + } + # don't migrate files if new file exists + elsif ( -f $new_filename ) { + die "Error migrating '$old_filename' to '$new_filename': new file already exists.\n"; + } + # if migrating from one file to another in the same directory, just rename them + if (dirname($old_filename) eq dirname($new_filename)) { + rename($old_filename, $new_filename) + or die "Can't rename '$old_filename' to '$new_filename': $OS_ERROR"; + } + # otherwise, move the existing conf file to a temp file, make the necessary directory structure, + # and move the temp conf file to its new home + else { + my $tmp = File::Temp->new( TEMPLATE => 'innotopXXXXX', DIR => $homepath, SUFFIX => '.conf'); + my $tmp_filename = $tmp->filename; + my $dirname = dirname($new_filename); + rename($old_filename, $tmp_filename) + or die "Can't rename '$old_filename' to '$tmp_filename': $OS_ERROR"; + mkdir($dirname) or die "Can't create directory '$dirname': $OS_ERROR"; + mkdir("$dirname/plugins") or die "Can't create directory '$dirname/plugins': $OS_ERROR"; + rename($tmp_filename, $new_filename) + or die "Can't rename '$tmp_filename' to '$new_filename': $OS_ERROR"; + } +} + +# load_config {{{3 +sub load_config { + + my ($old_filename, $answer); + + if ( $opts{u} or $opts{p} or $opts{h} or $opts{P} or $opts{S} ) { + my @params = $dsn_parser->get_cxn_params(\%opts); # dsn=$params[0] + add_new_dsn($opts{h} || 'localhost', $params[0], 'test.innotop_dl', + $opts{u} ? 1 : 0, $opts{u}, $opts{p} ? 1 : 0, $opts{p}); + } + if ($opts{c}) { + $conf_file = $opts{c}; + } + # If we don't have a new config file but we do have an old one, + # innotop got upgraded and this is an old config file. Convert it, but + # don't overwrite something existing. + elsif ( ! -f $default_home_conf && ( -f "$homepath/.innotop" or -f "$homepath/.innotop/innotop.ini" ) ) { + $conf_file = $default_home_conf; + if ( -f "$homepath/.innotop") { + $old_filename = "$homepath/.innotop"; + } + elsif ( -f "$homepath/.innotop/innotop.ini" ) { + $old_filename = "$homepath/.innotop/innotop.ini"; + } + $answer = pause("Innotop's default config location has moved to '$conf_file'. Move old config file '$old_filename' there now? y/n"); + if ( lc $answer eq 'y' ) { + migrate_config($old_filename, $conf_file); + } + else { + print "\nInnotop will now exit so you can fix the config file.\n"; + exit(0); + } + } + elsif ( -f $default_home_conf ) { + $conf_file = $default_home_conf; + } + elsif ( -f $default_central_conf and not $opts{s} ) { + $conf_file = $default_central_conf; + } + else { + # If no config file was loaded, set readonly to 0 if the user wants to + # write a config + $config{readonly}->{val} = 0 if $opts{w}; + # If no connections have been defined, connect to a MySQL database + # on localhost using mariadb_read_default_group=client + if (!%connections) { + add_new_dsn('localhost', + 'DBI:MariaDB:;host=localhost;mariadb_read_default_group=client', + 'test.innotop_dl'); + } + } + + if ( -f "$conf_file" ) { + open my $file, "<", $conf_file or die("Can't open '$conf_file': $OS_ERROR"); + + # Check config file version. Just ignore if either innotop or the file has + # garbage in the version number. + if ( defined(my $line = <$file>) && $VERSION =~ m/\d/ ) { + chomp $line; + if ( my ($maj, $min, $rev) = $line =~ m/^version=(\d+)\.(\d+)(?:\.(\d+))?$/ ) { + $rev ||= 0; + my $cfg_ver = sprintf('%03d-%03d-%03d', $maj, $min, $rev); + ( $maj, $min, $rev ) = $VERSION =~ m/^(\d+)\.(\d+)(?:\.(\d+))?$/; + $rev ||= 0; + my $innotop_ver = sprintf('%03d-%03d-%03d', $maj, $min, $rev); + + if ( $cfg_ver gt $innotop_ver ) { + pause("The config file is for a newer version of innotop and may not be read correctly."); + } + else { + my @ver_history = @config_versions; + while ( my ($start, $end) = splice(@ver_history, 0, 2) ) { + # If the config file is between the endpoints and innotop is greater than + # the endpoint, innotop has a newer config file format than the file. + if ( $cfg_ver ge $start && $cfg_ver lt $end && $innotop_ver ge $end ) { + my $msg = "innotop's config file format has changed. Overwrite $conf_file? y or n"; + if ( pause($msg) eq 'n' ) { + $config{readonly}->{val} = 1; + print "\ninnotop will not save any configuration changes you make."; + pause(); + print "\n"; + } + close $file; + return; + } + } + } + } + } + + while ( my $line = <$file> ) { + chomp $line; + next unless $line =~ m/^\[([a-z_]+)\]$/; + if ( exists $config_file_sections{$1} ) { + $config_file_sections{$1}->{reader}->($file); + } + else { + warn "Unknown config file section '$1'"; + } + } + close $file or die("Can't close $conf_file: $OS_ERROR"); + } + +} + +# Do some post-processing on %tbl_meta: compile src properties into func etc. +sub post_process_tbl_meta { + foreach my $table ( values %tbl_meta ) { + foreach my $col_name ( keys %{$table->{cols}} ) { + my $col_def = $table->{cols}->{$col_name}; + my ( $sub, $err ) = compile_expr($col_def->{src}); + $col_def->{func} = $sub; + } + } +} + +# load_config_plugins {{{3 +sub load_config_plugins { + my ( $file ) = @_; + + # First, find a list of all plugins that exist on disk, and get information about them. + my $dir = $config{plugin_dir}->{val}; + foreach my $p_file (glob($dir."/*.pm")) { + my ($package, $desc); + eval { + open my $p_in, "<", $p_file or die $OS_ERROR; + while ( my $line = <$p_in> ) { + chomp $line; + if ( $line =~ m/^package\s+(.*?);/ ) { + $package = $1; + } + elsif ( $line =~ m/^# description: (.*)/ ) { + $desc = $1; + } + last if $package && $desc; + } + close $p_in; + }; + if ( $package ) { + $plugins{$package} = { + file => $p_file, + desc => $desc, + class => $package, + active => 0, + }; + if ( $config{debug}->{val} && $EVAL_ERROR ) { + die $EVAL_ERROR; + } + } + } + + # Now read which ones the user has activated. Each line simply represents an active plugin. + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + next unless $line && $plugins{$line}; + + my $obj; + eval { + require $plugins{$line}->{file}; + $obj = $line->new(%pluggable_vars); + foreach my $event ( $obj->register_for_events() ) { + my $queue = $event_listener_for{$event}; + if ( $queue ) { + push @$queue, $obj; + } + } + }; + if ( $config{debug}->{val} && $EVAL_ERROR ) { + die $EVAL_ERROR; + } + if ( $obj ) { + $plugins{$line}->{active} = 1; + $plugins{$line}->{object} = $obj; + } + } +} + +# save_config_plugins {{{3 +sub save_config_plugins { + my $file = shift; + foreach my $class ( sort keys %plugins ) { + next unless $plugins{$class}->{active}; + print $file "$class\n"; + } +} + +# load_config_active_server_groups {{{3 +sub load_config_active_server_groups { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $mode, $group ) = $line =~ m/^(.*?)=(.*)$/; + next unless $mode && $group + && exists $modes{$mode} && exists $server_groups{$group}; + $modes{$mode}->{server_group} = $group; + } +} + +# save_config_active_server_groups {{{3 +sub save_config_active_server_groups { + my $file = shift; + foreach my $mode ( sort keys %modes ) { + print $file "$mode=$modes{$mode}->{server_group}\n"; + } +} + +# load_config_server_groups {{{3 +sub load_config_server_groups { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $name, $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $name && $rest; + my @vars = unique(grep { $_ && exists $connections{$_} } split(/\s+/, $rest)); + next unless @vars; + $server_groups{$name} = \@vars; + } +} + +# save_config_server_groups {{{3 +sub save_config_server_groups { + my $file = shift; + foreach my $set ( sort keys %server_groups ) { + print $file "$set=", join(' ', @{$server_groups{$set}}), "\n"; + } +} + +# load_config_varsets {{{3 +sub load_config_varsets { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $name, $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $name && $rest; + $var_sets{$name} = { + text => $rest, + user => 1, + }; + } +} + +# save_config_varsets {{{3 +sub save_config_varsets { + my $file = shift; + foreach my $varset ( sort keys %var_sets ) { + next unless $var_sets{$varset}->{user}; + print $file "$varset=$var_sets{$varset}->{text}\n"; + } +} + +# load_config_group_by {{{3 +sub load_config_group_by { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $tbl , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $tbl && exists $tbl_meta{$tbl}; + my @parts = unique(grep { exists($tbl_meta{$tbl}->{cols}->{$_}) } split(/\s+/, $rest)); + $tbl_meta{$tbl}->{group_by} = [ @parts ]; + $tbl_meta{$tbl}->{cust}->{group_by} = 1; + } +} + +# save_config_group_by {{{3 +sub save_config_group_by { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + next if $tbl_meta{$tbl}->{temp}; + next unless $tbl_meta{$tbl}->{cust}->{group_by}; + my $aref = $tbl_meta{$tbl}->{group_by}; + print $file "$tbl=", join(' ', @$aref), "\n"; + } +} + +# load_config_filters {{{3 +sub load_config_filters { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key, $rest ) = $line =~ m/^(.+?)=(.*)$/; + next unless $key && $rest; + + my %parts = $rest =~ m/(\w+)='((?:(?!(? $sub, + text => $parts{text}, + user => 1, + name => $key, + note => 'User-defined filter', + tbls => \@tbls, + } + } +} + +# save_config_filters {{{3 +sub save_config_filters { + my $file = shift; + foreach my $key ( sort keys %filters ) { + next if !$filters{$key}->{user} || $filters{$key}->{quick}; + my $text = $filters{$key}->{text}; + $text =~ s/([\\'])/\\$1/g; + my $tbls = join(" ", @{$filters{$key}->{tbls}}); + print $file "$key=text='$text' tbls='$tbls'\n"; + } +} + +# load_config_visible_tables {{{3 +sub load_config_visible_tables { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $mode, $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $mode && exists $modes{$mode}; + $modes{$mode}->{visible_tables} = + [ unique(grep { $_ && exists $tbl_meta{$_} } split(/\s+/, $rest)) ]; + $modes{$mode}->{cust}->{visible_tables} = 1; + } +} + +# save_config_visible_tables {{{3 +sub save_config_visible_tables { + my $file = shift; + foreach my $mode ( sort keys %modes ) { + next unless $modes{$mode}->{cust}->{visible_tables}; + my $tables = $modes{$mode}->{visible_tables}; + print $file "$mode=", join(' ', @$tables), "\n"; + } +} + +# load_config_sort_cols {{{3 +sub load_config_sort_cols { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $key && exists $tbl_meta{$key}; + $tbl_meta{$key}->{sort_cols} = $rest; + $tbl_meta{$key}->{cust}->{sort_cols} = 1; + $tbl_meta{$key}->{sort_func} = make_sort_func($tbl_meta{$key}); + } +} + +# save_config_sort_cols {{{3 +sub save_config_sort_cols { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + next unless $tbl_meta{$tbl}->{cust}->{sort_cols}; + my $col = $tbl_meta{$tbl}->{sort_cols}; + print $file "$tbl=$col\n"; + } +} + +# load_config_active_filters {{{3 +sub load_config_active_filters { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $tbl , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $tbl && exists $tbl_meta{$tbl}; + my @parts = unique(grep { exists($filters{$_}) } split(/\s+/, $rest)); + @parts = grep { grep { $tbl eq $_ } @{$filters{$_}->{tbls}} } @parts; + $tbl_meta{$tbl}->{filters} = [ @parts ]; + $tbl_meta{$tbl}->{cust}->{filters} = 1; + } +} + +# save_config_active_filters {{{3 +sub save_config_active_filters { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + next if $tbl_meta{$tbl}->{temp}; + next unless $tbl_meta{$tbl}->{cust}->{filters}; + my $aref = $tbl_meta{$tbl}->{filters}; + print $file "$tbl=", join(' ', @$aref), "\n"; + } +} + +# load_config_active_columns {{{3 +sub load_config_active_columns { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $key && exists $tbl_meta{$key}; + my @parts = grep { exists($tbl_meta{$key}->{cols}->{$_}) } unique split(/ /, $rest); + $tbl_meta{$key}->{visible} = [ @parts ]; + $tbl_meta{$key}->{cust}->{visible} = 1; + } +} + +# save_config_active_columns {{{3 +sub save_config_active_columns { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + next unless $tbl_meta{$tbl}->{cust}->{visible}; + my $aref = $tbl_meta{$tbl}->{visible}; + print $file "$tbl=", join(' ', @$aref), "\n"; + } +} + +# save_config_tbl_meta {{{3 +sub save_config_tbl_meta { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + foreach my $col ( keys %{$tbl_meta{$tbl}->{cols}} ) { + my $meta = $tbl_meta{$tbl}->{cols}->{$col}; + next unless $meta->{user}; + print $file "$col=", join( + " ", + map { + # Some properties (trans) are arrays, others scalars + my $val = ref($meta->{$_}) ? join(',', @{$meta->{$_}}) : $meta->{$_}; + $val =~ s/([\\'])/\\$1/g; # Escape backslashes and single quotes + "$_='$val'"; # Enclose in single quotes + } + grep { $_ ne 'func' } + keys %$meta + ), "\n"; + } + } +} + +# save_config_config {{{3 +sub save_config_config { + my $file = shift; + foreach my $key ( sort keys %config ) { + eval { + if ( $key ne 'password' || $config{savepass}->{val} ) { + print $file "# $config{$key}->{note}\n" + or die "Cannot print to file: $OS_ERROR"; + my $val = $config{$key}->{val}; + $val = '' unless defined($val); + if ( ref( $val ) eq 'ARRAY' ) { + print $file "$key=" + . join( " ", @$val ) . "\n" + or die "Cannot print to file: $OS_ERROR"; + } + elsif ( ref( $val ) eq 'HASH' ) { + print $file "$key=" + . join( " ", + map { "$_:$val->{$_}" } keys %$val + ) . "\n"; + } + else { + print $file "$key=$val\n"; + } + } + }; + if ( $EVAL_ERROR ) { print "$EVAL_ERROR in $key"; }; + } + +} + +# load_config_config {{{3 +sub load_config_config { + my ( $file ) = @_; + + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $name, $val ) = $line =~ m/^(.+?)=(.*)$/; + next unless defined $name && defined $val; + + # Validate the incoming values... + if ( $name && exists( $config{$name} ) ) { + if ( !$config{$name}->{pat} || $val =~ m/$config{$name}->{pat}/ ) { + $config{$name}->{val} = $val; + $config{$name}->{read} = 1; + } + } + } +} + +# load_config_tbl_meta {{{3 +sub load_config_tbl_meta { + my ( $file ) = @_; + + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + # Each tbl_meta section has all the properties defined in %col_props. + my ( $col , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $col; + my %parts = $rest =~ m/(\w+)='((?:(?!(?{cols}->{$col} ||= {}; + + foreach my $prop ( keys %col_props ) { + if ( !defined($parts{$prop}) ) { + # Make it default to whatever's in col_props. + $parts{$prop} = $col_props{$prop}; + } + + # Un-escape escaping + $parts{$prop} =~ s/\\\\/\\/g; + $parts{$prop} =~ s/\\'/'/g; + + if ( ref $col_props{$prop} ) { + if ( $prop eq 'trans' ) { + $meta->{cols}->{$col}->{trans} + = [ unique(grep { exists $trans_funcs{$_} } split(',', $parts{$prop})) ]; + } + else { + $meta->{cols}->{$col}->{$prop} = [ split(',', $parts{$prop}) ]; + } + } + else { + $meta->{cols}->{$col}->{$prop} = $parts{$prop}; + } + } + + } +} + +# save_config {{{3 +sub save_config { + print "\n"; + return if $config{readonly}->{val}; + # return if no config file was loaded and -w wasn't specified + if (not $conf_file) { + if (not $opts{w}) { + return; + } + else { + # if no config was loaded but -w was specified, + # write to $default_home_conf + $conf_file = $default_home_conf; + } + } + elsif ($conf_file and $opts{w}) { + print "Loaded config file on start-up, so ignoring -w (see --help)\n" + } + + my $dirname = dirname($conf_file); + + # if directories don't exist, create them. This could cause errors + # or warnings if a central config doesn't have readonly=1, but being + # flexible requires giving the user enough rope to hang themselves with. + if ( ! -d $dirname ) { + mkdir $dirname + or die "Can't create directory '$dirname': $OS_ERROR"; + } + if ( ! -d "$dirname/plugins" ) { + mkdir "$dirname/plugins" + or warn "Can't create directory '$dirname/plugins': $OS_ERROR\n"; + } + + # Save to a temp file first, so a crash doesn't destroy the main config file + my $tmpfile = File::Temp->new( TEMPLATE => 'innotopXXXXX', DIR => $dirname, SUFFIX => '.conf.tmp'); + open my $file, "+>", $tmpfile + or die("Can't write to $tmpfile: $OS_ERROR"); + print $file "version=$VERSION\n"; + + foreach my $section ( @ordered_config_file_sections ) { + die "No such config file section $section" unless $config_file_sections{$section}; + print $file "\n[$section]\n\n"; + $config_file_sections{$section}->{writer}->($file); + print $file "\n[/$section]\n"; + } + + # Now clobber the main config file with the temp. + close $file or die("Can't close $tmpfile: $OS_ERROR"); + rename($tmpfile, $conf_file) or die("Can't rename $tmpfile to $conf_file: $OS_ERROR"); +} + +# load_config_connections {{{3 +sub load_config_connections { + return if $opts{u} or $opts{p} or $opts{h} or $opts{P}; # don't load connections if DSN or user/pass options used + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $key; + my %parts = $rest =~ m/(\S+?)=(\S*)/g; + my %conn = map { $_ => $parts{$_} || '' } @conn_parts; + $connections{$key} = \%conn; + } +} + +# save_config_connections {{{3 +sub save_config_connections { + my $file = shift; + foreach my $conn ( sort keys %connections ) { + my $href = $connections{$conn}; + my @keys = $href->{savepass} ? @conn_parts : grep { $_ ne 'pass' } @conn_parts; + print $file "$conn=", join(' ', map { "$_=$href->{$_}" } grep { defined $href->{$_} } @keys), "\n"; + } +} + +sub load_config_colors { + my ( $file ) = @_; + my %rule_set_for; + + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $tbl, $rule ) = $line =~ m/^(.*?)=(.*)$/; + next unless $tbl && $rule; + next unless exists $tbl_meta{$tbl}; + my %parts = $rule =~ m/(\w+)='((?:(?!(?{cols}->{$parts{col}}; + next unless $parts{op} && exists $comp_ops{$parts{op}}; + next unless defined $parts{arg}; + next unless defined $parts{color}; + my @colors = unique(grep { exists $ansicolors{$_} } split(/\W+/, $parts{color})); + next unless @colors; + + # Finally! Enough validation... + $rule_set_for{$tbl} ||= []; + push @{$rule_set_for{$tbl}}, \%parts; + } + + foreach my $tbl ( keys %rule_set_for ) { + $tbl_meta{$tbl}->{colors} = $rule_set_for{$tbl}; + $tbl_meta{$tbl}->{color_func} = make_color_func($tbl_meta{$tbl}); + $tbl_meta{$tbl}->{cust}->{colors} = 1; + } +} + +# save_config_colors {{{3 +sub save_config_colors { + my $file = shift; + foreach my $tbl ( sort keys %tbl_meta ) { + my $meta = $tbl_meta{$tbl}; + next unless $meta->{cust}->{colors}; + foreach my $rule ( @{$meta->{colors}} ) { + print $file "$tbl=", join( + ' ', + map { + my $val = $rule->{$_}; + $val =~ s/([\\'])/\\$1/g; # Escape backslashes and single quotes + "$_='$val'"; # Enclose in single quotes + } + qw(col op arg color) + ), "\n"; + } + } +} + +# load_config_active_connections {{{3 +sub load_config_active_connections { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $rest ) = $line =~ m/^(.*?)=(.*)$/; + next unless $key && exists $modes{$key}; + my @parts = grep { exists $connections{$_} } split(/ /, $rest); + $modes{$key}->{connections} = [ @parts ] if exists $modes{$key}; + } +} + +# save_config_active_connections {{{3 +sub save_config_active_connections { + my $file = shift; + foreach my $mode ( sort keys %modes ) { + my @connections = get_connections($mode); + print $file "$mode=", join(' ', @connections), "\n"; + } +} + +# load_config_stmt_sleep_times {{{3 +sub load_config_stmt_sleep_times { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $val ) = split('=', $line); + next unless $key && defined $val && $val =~ m/$num_regex/; + $stmt_sleep_time_for{$key} = $val; + } +} + +# save_config_stmt_sleep_times {{{3 +sub save_config_stmt_sleep_times { + my $file = shift; + foreach my $key ( sort keys %stmt_sleep_time_for ) { + print $file "$key=$stmt_sleep_time_for{$key}\n"; + } +} + +# load_config_mvs {{{3 +sub load_config_mvs { + my ( $file ) = @_; + while ( my $line = <$file> ) { + chomp $line; + next if $line =~ m/^#/; + last if $line =~ m/^\[/; + + my ( $key , $val ) = split('=', $line); + next unless $key && defined $val && $val =~ m/$num_regex/; + $mvs{$key} = $val; + } +} + +# save_config_mvs {{{3 +sub save_config_mvs { + my $file = shift; + foreach my $key ( sort keys %mvs ) { + print $file "$key=$mvs{$key}\n"; + } +} + +# edit_configuration {{{3 +sub edit_configuration { + my $key = ''; + while ( $key ne 'q' ) { + $clear_screen_sub->(); + my @display_lines = ''; + + if ( $key && $cfg_editor_action{$key} ) { + $cfg_editor_action{$key}->{func}->(); + } + + # Show help + push @display_lines, create_caption('What configuration do you want to edit?', + create_table2( + [ sort keys %cfg_editor_action ], + { map { $_ => $_ } keys %cfg_editor_action }, + { map { $_ => $cfg_editor_action{$_}->{note} } keys %cfg_editor_action }, + { sep => ' ' })); + + draw_screen(\@display_lines); + $key = pause(''); + } +} + +# edit_configuration_variables {{{3 +sub edit_configuration_variables { + $clear_screen_sub->(); + my $mode = $config{mode}->{val}; + + my %config_choices + = map { $_ => $config{$_}->{note} || '' } + # Only config values that are marked as applying to this mode. + grep { + my $key = $_; + $config{$key}->{conf} && + ( $config{$key}->{conf} eq 'ALL' + || grep { $mode eq $_ } @{$config{$key}->{conf}} ) + } keys %config; + + my $key = prompt_list( + "Enter the name of the variable you wish to configure", + '', + sub{ return keys %config_choices }, + \%config_choices); + + if ( exists($config_choices{$key}) ) { + get_config_interactive($key); + } +} + +# edit_color_rules {{{3 +sub edit_color_rules { + my ( $tbl ) = @_; + $clear_screen_sub->(); + $tbl ||= choose_visible_table(); + if ( $tbl && exists($tbl_meta{$tbl}) ) { + my $meta = $tbl_meta{$tbl}; + my @cols = ('', qw(col op arg color)); + my $info = { map { $_ => { hdr => $_, just => '-', } } @cols }; + $info->{label}->{maxw} = 30; + my $key; + my $selected_rule; + + # This loop builds a tabular view of the rules. + do { + + # Show help + if ( $key && $key eq '?' ) { + my @display_lines = ''; + push @display_lines, create_caption('Editor key mappings', + create_table2( + [ sort keys %color_editor_action ], + { map { $_ => $_ } keys %color_editor_action }, + { map { $_ => $color_editor_action{$_}->{note} } keys %color_editor_action }, + { sep => ' ' })); + draw_screen(\@display_lines); + pause(); + $key = ''; + } + else { + + # Do the action specified + $selected_rule ||= 0; + if ( $key && $color_editor_action{$key} ) { + $selected_rule = $color_editor_action{$key}->{func}->($tbl, $selected_rule); + $selected_rule ||= 0; + } + + # Build the table of rules. If the terminal has color, the selected rule + # will be highlighted; otherwise a > at the left will indicate. + my $data = $meta->{colors} || []; + foreach my $i ( 0..@$data - 1 ) { + $data->[$i]->{''} = $i == $selected_rule ? '>' : ''; + } + my @display_lines = create_table(\@cols, $info, $data); + + # Highlight selected entry + for my $i ( 0 .. $#display_lines ) { + if ( $display_lines[$i] =~ m/^>/ ) { + $display_lines[$i] = [ $display_lines[$i], 'reverse' ]; + } + } + + # Draw the screen and wait for a command. + unshift @display_lines, '', + "Editing color rules for $meta->{capt}. Press ? for help, q to " + . "quit.", ''; + draw_screen(\@display_lines); + print "\n\n", word_wrap('Rules are applied in order from top to ' + . 'bottom. The first matching rule wins and prevents the ' + . 'rest of the rules from being applied.'); + $key = pause(''); + } + } while ( $key ne 'q' ); + $meta->{color_func} = make_color_func($meta); + } +} + +# add_quick_filter {{{3 +sub add_quick_filter { + my $tbl = choose_visible_table(); + if ( $tbl && exists($tbl_meta{$tbl}) ) { + print "\n"; + my $response = prompt_list( + "Enter column name and filter text", + '', + sub { return keys %{$tbl_meta{$tbl}->{cols}} }, + () + ); + my ( $col, $text ) = split(/\s+/, $response, 2); + + # You can't filter on a nonexistent column. But if you filter on a pivoted + # table, the columns are different, so on a pivoted table, allow filtering + # on the 'name' column. + # NOTE: if a table is pivoted and un-pivoted, this will likely cause crashes. + # Currently not an issue since there's no way to toggle pivot/nopivot. + return unless $col && $text && + (exists($tbl_meta{$tbl}->{cols}->{$col}) + || ($tbl_meta{$tbl}->{pivot} && $col eq 'name')); + + my ( $sub, $err ) = compile_filter( "defined \$set->{$col} && \$set->{$col} =~ m/$text/" ); + return if !$sub || $err; + my $name = "quick_$tbl.$col"; + $filters{$name} = { + func => $sub, + text => $text, + user => 1, + quick => 1, + name => $name, + note => 'Quick-filter', + tbls => [$tbl], + }; + push @{$tbl_meta{$tbl}->{filters}}, $name; + } +} + +# clear_quick_filters {{{3 +sub clear_quick_filters { + my $tbl = choose_visible_table( + # Only tables that have quick-filters + sub { + my ( $tbl ) = @_; + return scalar grep { $filters{$_}->{quick} } @{ $tbl_meta{$tbl}->{filters} }; + } + ); + if ( $tbl && exists($tbl_meta{$tbl}) ) { + my @current = @{$tbl_meta{$tbl}->{filters}}; + @current = grep { !$filters{$_}->{quick} } @current; + $tbl_meta{$tbl}->{filters} = \@current; + } +} + +sub edit_plugins { + $clear_screen_sub->(); + + my @cols = ('', qw(class desc active)); + my $info = { map { $_ => { hdr => $_, just => '-', } } @cols }; + my @rows = map { $plugins{$_} } sort keys %plugins; + my $key; + my $selected; + + # This loop builds a tabular view of the plugins. + do { + + # Show help + if ( $key && $key eq '?' ) { + my @display_lines = ''; + push @display_lines, create_caption('Editor key mappings', + create_table2( + [ sort keys %plugin_editor_action ], + { map { $_ => $_ } keys %plugin_editor_action }, + { map { $_ => $plugin_editor_action{$_}->{note} } keys %plugin_editor_action }, + { sep => ' ' })); + draw_screen(\@display_lines); + pause(); + $key = ''; + } + + # Do the action specified + else { + $selected ||= 0; + if ( $key && $plugin_editor_action{$key} ) { + $selected = $plugin_editor_action{$key}->{func}->(\@rows, $selected); + $selected ||= 0; + } + + # Build the table of plugins. + foreach my $row ( 0.. $#rows ) { + $rows[$row]->{''} = $row eq $selected ? '>' : ' '; + } + my @display_lines = create_table(\@cols, $info, \@rows); + + # Highlight selected entry + for my $i ( 0 .. $#display_lines ) { + if ( $display_lines[$i] =~ m/^>/ ) { + $display_lines[$i] = [ $display_lines[$i], 'reverse' ]; + } + } + + # Draw the screen and wait for a command. + unshift @display_lines, '', + "Plugin Management. Press ? for help, q to quit.", ''; + draw_screen(\@display_lines); + $key = pause(''); + } + } while ( $key ne 'q' ); +} + +# edit_table {{{3 +sub edit_table { + $clear_screen_sub->(); + my ( $tbl ) = @_; + $tbl ||= choose_visible_table(); + if ( $tbl && exists($tbl_meta{$tbl}) ) { + my $meta = $tbl_meta{$tbl}; + my @cols = ('', qw(name hdr label src)); + my $info = { map { $_ => { hdr => $_, just => '-', } } @cols }; + $info->{label}->{maxw} = 30; + my $key; + my $selected_column; + + # This loop builds a tabular view of the tbl_meta's structure, showing each column + # in the entry as a row. + do { + + # Show help + if ( $key && $key eq '?' ) { + my @display_lines = ''; + push @display_lines, create_caption('Editor key mappings', + create_table2( + [ sort keys %tbl_editor_action ], + { map { $_ => $_ } keys %tbl_editor_action }, + { map { $_ => $tbl_editor_action{$_}->{note} } keys %tbl_editor_action }, + { sep => ' ' })); + draw_screen(\@display_lines); + pause(); + $key = ''; + } + else { + + # Do the action specified + $selected_column ||= $meta->{visible}->[0]; + if ( $key && $tbl_editor_action{$key} ) { + $selected_column = $tbl_editor_action{$key}->{func}->($tbl, $selected_column); + $selected_column ||= $meta->{visible}->[0]; + } + + # Build the pivoted view of the table's meta-data. If the terminal has color, + # The selected row will be highlighted; otherwise a > at the left will indicate. + my $data = []; + foreach my $row ( @{$meta->{visible}} ) { + my %hash; + @hash{ @cols } = @{$meta->{cols}->{$row}}{@cols}; + $hash{src} = '' if ref $hash{src}; + $hash{name} = $row; + $hash{''} = $row eq $selected_column ? '>' : ' '; + push @$data, \%hash; + } + my @display_lines = create_table(\@cols, $info, $data); + + # Highlight selected entry + for my $i ( 0 .. $#display_lines ) { + if ( $display_lines[$i] =~ m/^>/ ) { + $display_lines[$i] = [ $display_lines[$i], 'reverse' ]; + } + } + + # Draw the screen and wait for a command. + unshift @display_lines, '', + "Editing table definition for $meta->{capt}. Press ? for help, q to quit.", ''; + draw_screen(\@display_lines, { clear => 1 }); + $key = pause(''); + } + } while ( $key ne 'q' ); + } +} + +# choose_mode_tables {{{3 +# Choose which table(s), and in what order, to display in a given mode. +sub choose_mode_tables { + my $mode = $config{mode}->{val}; + my @tbls = @{$modes{$mode}->{visible_tables}}; + my $new = prompt_list( + "Choose tables to display", + join(' ', @tbls), + sub { return @{$modes{$mode}->{tables}} }, + { map { $_ => $tbl_meta{$_}->{capt} } @{$modes{$mode}->{tables}} } + ); + $modes{$mode}->{visible_tables} = + [ unique(grep { $_ && exists $tbl_meta{$_} } split(/\s+/, $new)) ]; + $modes{$mode}->{cust}->{visible_tables} = 1; +} + +# set_visible_table {{{3 +sub set_visible_table { + my ( $tbl ) = @_; + my $mode = $config{mode}->{val}; + my @tbls = grep { $_ eq $tbl } @{$modes{$mode}->{tables}}; + if ( @tbls == 1 ) { + $modes{$mode}->{visible_tables} = [ $tbl ]; + $modes{$mode}->{cust}->{visible_tables} = 1; + } +} + +# choose_visible_table {{{3 +sub choose_visible_table { + my ( $grep_cond ) = @_; + my $mode = $config{mode}->{val}; + my @tbls + = grep { $grep_cond ? $grep_cond->($_) : 1 } + @{$modes{$mode}->{visible_tables}}; + my $tbl = $tbls[0]; + if ( @tbls > 1 ) { + $tbl = prompt_list( + "Choose a table", + '', + sub { return @tbls }, + { map { $_ => $tbl_meta{$_}->{capt} } @tbls } + ); + } + return $tbl; +} + +sub toggle_aggregate { + my ( $tbl ) = @_; + $tbl ||= choose_visible_table(); + return unless $tbl && exists $tbl_meta{$tbl}; + my $meta = $tbl_meta{$tbl}; + $meta->{aggregate} ^= 1; +} + +sub choose_filters { + my ( $tbl ) = @_; + $tbl ||= choose_visible_table(); + return unless $tbl && exists $tbl_meta{$tbl}; + my $meta = $tbl_meta{$tbl}; + $clear_screen_sub->(); + + print "Choose filters for $meta->{capt}:\n"; + + my $ini = join(' ', @{$meta->{filters}}); + my $val = prompt_list( + 'Choose filters', + $ini, + sub { return keys %filters }, + { + map { $_ => $filters{$_}->{note} } + grep { grep { $tbl eq $_ } @{$filters{$_}->{tbls}} } + keys %filters + } + ); + + my @choices = unique($val =~ m/(\S+)/g); + foreach my $new ( grep { !exists($filters{$_}) } @choices ) { + my $answer = prompt("There is no filter called '$new'. Create it?", undef, 'y'); + if ( $answer eq 'y' ) { + create_new_filter($new, $tbl); + } + } + @choices = grep { exists $filters{$_} } @choices; + @choices = grep { grep { $tbl eq $_ } @{$filters{$_}->{tbls}} } @choices; + $meta->{filters} = [ @choices ]; + $meta->{cust}->{filters} = 1; +} + +sub choose_group_cols { + my ( $tbl ) = @_; + $tbl ||= choose_visible_table(); + return unless $tbl && exists $tbl_meta{$tbl}; + $clear_screen_sub->(); + my $meta = $tbl_meta{$tbl}; + my $curr = join(', ', @{$meta->{group_by}}); + my $val = prompt_list( + 'Group-by columns', + $curr, + sub { return keys %{$meta->{cols}} }, + { map { $_ => $meta->{cols}->{$_}->{label} } keys %{$meta->{cols}} }); + if ( $curr ne $val ) { + $meta->{group_by} = [ grep { exists $meta->{cols}->{$_} } $val =~ m/(\w+)/g ]; + $meta->{cust}->{group_by} = 1; + } +} + +sub choose_sort_cols { + my ( $tbl ) = @_; + $tbl ||= choose_visible_table(); + return unless $tbl && exists $tbl_meta{$tbl}; + $clear_screen_sub->(); + my $meta = $tbl_meta{$tbl}; + + my ( $cols, $hints ); + if ( $meta->{pivot} ) { + $cols = sub { qw(name set_0) }; + $hints = { name => 'name', set_0 => 'set_0' }; + } + else { + $cols = sub { return keys %{$meta->{cols}} }; + $hints = { map { $_ => $meta->{cols}->{$_}->{label} } keys %{$meta->{cols}} }; + } + + my $val = prompt_list( + 'Sort columns (reverse sort with -col)', + $meta->{sort_cols}, + $cols, + $hints ); + if ( $meta->{sort_cols} ne $val ) { + $meta->{sort_cols} = $val; + $meta->{cust}->{sort_cols} = 1; + $tbl_meta{$tbl}->{sort_func} = make_sort_func($tbl_meta{$tbl}); + } +} + +# create_new_filter {{{3 +sub create_new_filter { + my ( $filter, $tbl ) = @_; + $clear_screen_sub->(); + + if ( !$filter || $filter =~ m/\W/ ) { + print word_wrap("Choose a name for the filter. This name is not displayed, and is only used " + . "for internal reference. It can only contain lowercase letters, numbers, and underscores."); + print "\n\n"; + do { + $filter = prompt("Enter filter name"); + } while ( !$filter || $filter =~ m/\W/ ); + } + + my $completion = sub { keys %{$tbl_meta{$tbl}->{cols}} }; + my ( $err, $sub, $body ); + do { + $clear_screen_sub->(); + print word_wrap("A filter is a Perl subroutine that accepts a hashref of columns " + . "called \$set, and returns a true value if the filter accepts the row. Example:\n" + . " \$set->{active_secs} > 5\n" + . "will only allow rows if their active_secs column is greater than 5."); + print "\n\n"; + if ( $err ) { + print "There's an error in your filter expression: $err\n\n"; + } + $body = prompt("Enter subroutine body", undef, undef, $completion); + ( $sub, $err ) = compile_filter($body); + } while ( $err ); + + $filters{$filter} = { + func => $sub, + text => $body, + user => 1, + name => $filter, + note => 'User-defined filter', + tbls => [$tbl], + }; +} + +# get_config_interactive {{{3 +sub get_config_interactive { + my $key = shift; + $clear_screen_sub->(); + + # Print help first. + print "Enter a new value for '$key' ($config{$key}->{note}).\n"; + + my $current = ref($config{$key}->{val}) ? join(" ", @{$config{$key}->{val}}) : $config{$key}->{val}; + + my $new_value = prompt('Enter a value', $config{$key}->{pat}, $current); + $config{$key}->{val} = $new_value; +} + +sub edit_current_var_set { + my $mode = $config{mode}->{val}; + my $name = $config{"${mode}_set"}->{val}; + my $variables = $var_sets{$name}->{text}; + + my $new = $variables; + do { + $clear_screen_sub->(); + $new = prompt("Enter variables for $name", undef, $variables); + } until ( $new ); + + if ( $new ne $variables ) { + @{$var_sets{$name}}{qw(text user)} = ( $new, 1); + } +} + + +sub choose_var_set { + my ( $key ) = @_; + $clear_screen_sub->(); + + my $new_value = prompt_list( + 'Choose a set of values to display, or enter the name of a new one', + $config{$key}->{val}, + sub { return keys %var_sets }, + { map { $_ => $var_sets{$_}->{text} } keys %var_sets }); + + if ( !exists $var_sets{$new_value} ) { + add_new_var_set($new_value); + } + + $config{$key}->{val} = $new_value if exists $var_sets{$new_value}; +} + +sub switch_var_set { + my ( $cfg_var, $dir ) = @_; + my @var_sets = sort keys %var_sets; + my $cur = $config{$cfg_var}->{val}; + my $pos = grep { $_ lt $cur } @var_sets; + my $newpos = ($pos + $dir) % @var_sets; + $config{$cfg_var}->{val} = $var_sets[$newpos]; + $clear_screen_sub->(); +} + +# Online configuration and prompting functions {{{2 + +# edit_stmt_sleep_times {{{3 +sub edit_stmt_sleep_times { + $clear_screen_sub->(); + my $stmt = prompt_list('Specify a statement', '', sub { my @tmparray = sort keys %stmt_maker_for; return @tmparray }); + return unless $stmt && exists $stmt_maker_for{$stmt}; + $clear_screen_sub->(); + my $curr_val = $stmt_sleep_time_for{$stmt} || 0; + my $new_val = prompt('Specify a sleep delay after calling this SQL', $num_regex, $curr_val); + if ( $new_val ) { + $stmt_sleep_time_for{$stmt} = $new_val; + } + else { + delete $stmt_sleep_time_for{$stmt}; + } +} + +# edit_server_groups {{{3 +# Choose which server connections are in a server group. First choose a group, +# then choose which connections are in it. +sub edit_server_groups { + $clear_screen_sub->(); + my $mode = $config{mode}->{val}; + my $group = $modes{$mode}->{server_group}; + my %curr = %server_groups; + my $new = choose_or_create_server_group($group, 'to edit'); + $clear_screen_sub->(); + if ( exists $curr{$new} ) { + # Don't do this step if the user just created a new server group, + # because part of that process was to choose connections. + my $cxns = join(' ', @{$server_groups{$new}}); + my @conns = choose_or_create_connection($cxns, 'for this group'); + $server_groups{$new} = \@conns; + } +} + +# choose_server_groups {{{3 +sub choose_server_groups { + $clear_screen_sub->(); + my $mode = $config{mode}->{val}; + my $group = $modes{$mode}->{server_group}; + my $new = choose_or_create_server_group($group, 'for this mode'); + $modes{$mode}->{server_group} = $new if exists $server_groups{$new}; +} + +sub choose_or_create_server_group { + my ( $group, $prompt ) = @_; + my $new = ''; + + my @available = sort keys %server_groups; + + if ( @available ) { + print "You can enter the name of a new group to create it.\n"; + + $new = prompt_list( + "Choose a server group $prompt", + $group, + sub { return @available }, + { map { $_ => join(' ', @{$server_groups{$_}}) } @available }); + + $new =~ s/\s.*//; + + if ( !exists $server_groups{$new} ) { + my $answer = prompt("There is no server group called '$new'. Create it?", undef, "y"); + if ( $answer eq 'y' ) { + add_new_server_group($new); + } + } + } + else { + $new = add_new_server_group(); + } + return $new; +} + +sub choose_or_create_connection { + my ( $cxns, $prompt ) = @_; + print "You can enter the name of a new connection to create it.\n"; + + my @available = sort keys %connections; + my $new_cxns = prompt_list( + "Choose connections $prompt", + $cxns, + sub { return @available }, + { map { $_ => $connections{$_}->{dsn} } @available }); + + my @new = unique(grep { !exists $connections{$_} } $new_cxns =~ m/(\S+)/g); + foreach my $new ( @new ) { + my $answer = prompt("There is no connection called '$new'. Create it?", undef, "y"); + if ( $answer eq 'y' ) { + add_new_dsn($new); + } + } + + return unique(grep { exists $connections{$_} } split(/\s+/, $new_cxns)); +} + +# choose_servers {{{3 +sub choose_servers { + $clear_screen_sub->(); + my $mode = $config{mode}->{val}; + my $cxns = join(' ', get_connections()); + my @chosen = choose_or_create_connection($cxns, 'for this mode'); + $modes{$mode}->{connections} = \@chosen; + $modes{$mode}->{server_group} = ''; # Clear this because it overrides {connections} + get_connections(); # This will set the server group if it matches connections just chosen +} + +# display_license {{{3 +sub display_license { + $clear_screen_sub->(); + + print $innotop_license; + + pause(); +} + +# Data-retrieval functions {{{2 +# get_status_info {{{3 +# Get SHOW STATUS and SHOW VARIABLES together. +sub get_status_info { + my @cxns = @_; + if ( !$info_gotten{status}++ ) { + foreach my $cxn ( @cxns ) { + $vars{$cxn}->{$clock} ||= {}; + my $vars = $vars{$cxn}->{$clock}; + + my $sth = do_stmt($cxn, 'SHOW_STATUS') or next; + my $res = $sth->fetchall_arrayref(); + map { $vars->{$_->[0]} = $_->[1] || 0 } @$res; + + # Calculate hi-res uptime and add cxn to the hash. This duplicates get_driver_status, + # but it's most important to have consistency. + $vars->{Uptime_hires} ||= get_uptime($cxn); + $vars->{cxn} = $cxn; + + # Add SHOW VARIABLES to the hash. If we've gotten this info before, skip and re-use. + if ( $show_variables{$cxn} ) { + $res = $show_variables{$cxn}; + } + else { + $sth = do_stmt($cxn, 'SHOW_VARIABLES') or next; + $res = $sth->fetchall_arrayref(); + $res = {map { $_->[0] => $_->[1] || 0 } @$res}; + $show_variables{$cxn} = $res; + } + @{$vars}{keys %$res} = values %$res; + + # Create sparklines for QPS and Threads_running. As a consequence of + # this, we get QPS for free. TODO: remove QPS computation from + # elsewhere. + my $pre = $vars{$cxn}->{$clock - 1}; + if ( $pre && $pre->{Uptime_hires} ) { + my @prev_qps = ($pre->{SPARK_store_qps} || '') =~ m/(\S+)/g; + my @prev_run = ($pre->{SPARK_store_run} || '') =~ m/(\S+)/g; + + # Find out the values; throw away if too many; sparkify; store. + my $this_qps = (($vars->{Questions} || 0) - ($pre->{Questions} || 0))/ + ($vars->{Uptime_hires} - $pre->{Uptime_hires}); + push @prev_qps, $this_qps; + shift @prev_qps if @prev_qps > $config{spark}->{val}; + my $qps_spark = sparkify(@prev_qps); + $vars->{SPARK_qps} = $qps_spark; + $vars->{SPARK_store_qps} = join(' ', @prev_qps); + my $this_run = $vars->{Threads_running}; + push @prev_run, $this_run; + shift @prev_run if @prev_run > $config{spark}->{val}; + my $run_spark = sparkify(@prev_run); + $vars->{SPARK_run} = $run_spark; + $vars->{SPARK_store_run} = join(' ', @prev_run); + } + } + } +} + +# Chooses a thread for explaining, killing, etc... +# First arg is a func that can be called in grep. +sub choose_thread { + my ( $grep_cond, $prompt ) = @_; + + my %thread_for = map { + # Eliminate innotop's own threads. + $_ => $dbhs{$_}->{dbh} ? $dbhs{$_}->{dbh}->{mariadb_thread_id} : 0 + } keys %connections; + + my @candidates = grep { + $_->{id} != $thread_for{$_->{cxn}} && $grep_cond->($_) + } @current_queries; + return unless @candidates; + + # Find out which server. + my @cxns = unique map { $_->{cxn} } @candidates; + my ( $cxn ) = select_cxn('On which server', @cxns); + return unless $cxn && exists($connections{$cxn}); + + # Re-filter the list of candidates to only those on this server + @candidates = grep { $_->{cxn} eq $cxn } @candidates; + + # Find out which thread to do. + my $info; + if ( @candidates > 1 ) { + + # Sort longest-active first, then longest-idle. + my $sort_func = sub { + my ( $a, $b ) = @_; + return $a->{query} && !$b->{query} ? 1 + : $b->{query} && !$a->{query} ? -1 + : ($a->{time} || 0) cmp ($b->{time} || 0); + }; + my @threads = map { $_->{id} } reverse sort { $sort_func->($a, $b) } @candidates; + + print "\n"; + my $thread = prompt_list($prompt, + $threads[0], + sub { return @threads }); + return unless $thread && $thread =~ m/$int_regex/; + + # Find the info hash of that query on that server. + ( $info ) = grep { $thread == $_->{id} } @candidates; + } + else { + $info = $candidates[0]; + } + return $info; +} + +# analyze_query {{{3 +# Allows the user to show fulltext, explain, show optimized... +sub analyze_query { + my ( $action ) = @_; + + my $info = choose_thread( + sub { $_[0]->{query} }, + 'Select a thread to analyze', + ); + return unless $info; + + my %actions = ( + e => \&display_explain, + f => \&show_full_query, + o => \&show_optimized_query, + ); + do { + $actions{$action}->($info); + print "\n"; + $action = pause('Press e to explain, f for full query, o for optimized query'); + } while ( exists($actions{$action}) ); +} + +# inc {{{3 +# Returns the difference between two sets of variables/status/innodb stuff. +sub inc { + my ( $offset, $cxn ) = @_; + my $vars = $vars{$cxn}; + if ( $offset < 0 ) { + return $vars->{$clock}; + } + elsif ( exists $vars{$clock - $offset} && !exists $vars->{$clock - $offset - 1} ) { + return $vars->{$clock - $offset}; + } + my $cur = $vars->{$clock - $offset}; + my $pre = $vars->{$clock - $offset - 1}; + return { + # Numeric variables get subtracted, non-numeric get passed straight through. + map { + $_ => + ( (defined $cur->{$_} && $cur->{$_} =~ m/$num_regex/ && ($pre->{$_} || '') =~ m/$num_regex/ ) + ? $cur->{$_} - ($pre->{$_} || 0) + : $cur->{$_} ) + } keys %{$cur} + }; +} + +# extract_values {{{3 +# Arguments are a set of values (which may be incremental, derived from +# current and previous), current, and previous values. +# TODO: there are a few places that don't remember prev set so can't pass it. +sub extract_values { + my ( $set, $cur, $pre, $tbl ) = @_; + + # Hook in event listeners + foreach my $listener ( @{$event_listener_for{extract_values}} ) { + $listener->extract_values($set, $cur, $pre, $tbl); + } + + my $result = {}; + my $meta = $tbl_meta{$tbl}; + my $cols = $meta->{cols}; + foreach my $key ( keys %$cols ) { + my $info = $cols->{$key} + or die "Column '$key' doesn't exist in $tbl"; + die "No func defined for '$key' in $tbl" + unless $info->{func}; + eval { + $result->{$key} = $info->{func}->($set, $cur, $pre) + }; + if ( $EVAL_ERROR ) { + if ( $config{debug}->{val} ) { + die $EVAL_ERROR; + } + $result->{$key} = $info->{num} ? 0 : ''; + } + } + return $result; +} + +# get_processlist_stats {{{3 +# Inserts special values as though they are SHOW STATUS counters. +sub get_processlist_stats { + my @cxns = @_; + @current_queries = (); + if ( !$info_gotten{processlist_stats}++ ) { + foreach my $cxn ( @cxns ) { + my $max_query_time = 0; + my ($user_threads, $slaves, $longest_sql, $slave_sql, $locked); + $vars{$cxn}->{$clock} ||= {}; + my $vars = $vars{$cxn}->{$clock}; + $vars->{cxn} = $cxn; + my $stmt = do_stmt($cxn, 'PROCESSLIST_NO_IS') or next; + my $arr = $stmt->fetchall_arrayref({}); + my $cur = undef; + foreach my $thread ( @$arr ) { + if ( ($thread->{state} || '') =~ m/lock/i ) { + $locked++; + } + # Ignore non-user threads, but remember the SQL in case there is + # no user SQL. Ignore sleeping threads and SHOW PROCESSLIST + # threads. + if ( ($thread->{user} || '') =~ m/system user/ ) { + if ( $thread->{info} && $thread->{time} ) { + $slave_sql = $thread->{info}; + } + next; + } + next unless $thread->{command}; + if ( $thread->{command} eq 'Binlog Dump' ) { + $slaves++; + next; + } + next unless $thread->{command} eq 'Query'; + next unless $thread->{state} && $thread->{info}; + next if $thread->{info} =~ m#/\*innotop#; + $user_threads++; + if ( $thread->{time} > $max_query_time ) { + $max_query_time = $thread->{time}; + $longest_sql = $thread->{info}; + if ( $thread->{state} eq 'Checking table' ) { + $longest_sql = 'CHECK TABLE ' . $thread->{info}; + } + $cur = { + cxn => $cxn, + id => $thread->{id}, + db => $thread->{db}, + query => $thread->{info}, + time => $thread->{time}, + user => $thread->{user}, + host => $thread->{host}, + }; + $thread->{host} =~ s/:.*$//; + } + } + $vars->{Max_query_time} = $max_query_time; + $vars->{User_threads_running} = $user_threads; + $vars->{Slaves} = $slaves || 0; + $vars->{Longest_sql} = $longest_sql || $slave_sql || ''; + $vars->{Locked_count} = $locked || 0; + $vars->{Uptime_hires} ||= get_uptime($cxn); + push @current_queries, $cur if $cur; + } + } +} + +# get_full_processlist {{{3 +sub get_full_processlist { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'PROCESSLIST') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_open_tables {{{3 +sub get_open_tables { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'OPEN_TABLES') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_index_statistics {{{3 +sub get_index_statistics { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'INDEX_STATISTICS') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_index_table_statistics {{{3 +sub get_index_table_statistics { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'INDEX_TABLE_STATISTICS') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_table_statistics {{{3 +sub get_table_statistics { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'TABLE_STATISTICS') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_innodb_blocked_blocker {{{3 +sub get_innodb_blocked_blocker { + my @cxns = @_; + my @result; + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'INNODB_BLOCKED_BLOCKER') or next; + my $arr = $stmt->fetchall_arrayref({}); + push @result, map { $_->{cxn} = $cxn; $_ } @$arr; + } + return @result; +} + +# get_innodb_status {{{3 +sub get_innodb_status { + my ( $cxns, $addl_sections ) = @_; + if ( !$config{skip_innodb}->{val} && !$info_gotten{innodb_status}++ ) { + + # Determine which sections need to be parsed + my %sections_required = + map { $tbl_meta{$_}->{innodb} => 1 } + grep { $_ && $tbl_meta{$_}->{innodb} } + get_visible_tables(); + + # Add in any other sections the caller requested. + foreach my $sec ( @$addl_sections ) { + $sections_required{$sec} = 1; + } + + foreach my $cxn ( @$cxns ) { + my $innodb_status_text; + + if ( $file ) { # Try to fetch status text from the file. + my @stat = stat($file); + + # Initialize the file. + if ( !$file_mtime ) { + # Initialize to 130k from the end of the file (because the limit + # on the size of innodb status is 128k even with Google's patches) + # and try to grab the last status from the file. + sysseek($file, (-128 * 1_024), 2); + } + + # Read from the file. + my $buffer; + if ( !$file_mtime || $file_mtime != $stat[9] ) { + $file_data = ''; + while ( sysread($file, $buffer, 4096) ) { + $file_data .= $buffer; + } + $file_mtime = $stat[9]; + } + + # Delete everything but the last InnoDB status text from the file. + $file_data =~ s/\A.*(?=^=====================================\n...... ........ INNODB MONITOR OUTPUT)//ms; + $innodb_status_text = $file_data; + } + + else { + next if ($show_variables{$cxn}->{have_innodb} || 'YES') eq 'NO'; + my $stmt = do_stmt($cxn, 'INNODB_STATUS') or next; + $innodb_status_text = $stmt->fetchrow_hashref()->{status}; + } + + next unless $innodb_status_text + && substr($innodb_status_text, 0, 100) =~ m/INNODB MONITOR OUTPUT/; + + # Parse and merge into %vars storage + my %innodb_status = ( + $innodb_parser->get_status_hash( + $innodb_status_text, + $config{debug}->{val}, + \%sections_required, + 0, # don't parse full lock information + $show_variables{$cxn}->{version} + ) + ); + if ( !$innodb_status{IB_got_all} && $config{auto_wipe_dl}->{val} ) { + clear_deadlock($cxn); + } + + # Merge using a hash slice, which is the fastest way + $vars{$cxn}->{$clock} ||= {}; + my $hash = $vars{$cxn}->{$clock}; + @{$hash}{ keys %innodb_status } = values %innodb_status; + $hash->{cxn} = $cxn; + $hash->{Uptime_hires} ||= get_uptime($cxn); + } + } +} + +# clear_deadlock {{{3 +sub clear_deadlock { + my ( $cxn ) = @_; + return if $clearing_deadlocks++; + my $tbl = $connections{$cxn}->{dl_table}; + return unless $tbl; + + eval { + # disable binary logging for the session + do_query($cxn, "set SQL_LOG_BIN=0"); + + # Set up the table for creating a deadlock. + my $engine = version_ge($dbhs{$cxn}->{dbh}, '4.1.2') ? 'engine' : 'type'; + return unless do_query($cxn, "drop table if exists $tbl"); + return unless do_query($cxn, "create table $tbl(a int) $engine=innodb"); + return unless do_query($cxn, "delete from $tbl"); + return unless do_query($cxn, "insert into $tbl(a) values(0), (1)"); + return unless do_query($cxn, "commit"); # Or the children will block against the parent + + # Fork off two children to deadlock against each other. + my %children; + foreach my $child ( 0..1 ) { + my $pid = fork(); + if ( defined($pid) && $pid == 0 ) { # I am a child + deadlock_thread( $child, $tbl, $cxn ); + } + elsif ( !defined($pid) ) { + die("Unable to fork for clearing deadlocks!\n"); + } + # I already exited if I'm a child, so I'm the parent. + $children{$child} = $pid; + } + + # Wait for the children to exit. + foreach my $child ( keys %children ) { + my $pid = waitpid($children{$child}, 0); + } + + # Clean up. + do_query($cxn, "drop table $tbl"); + + # enable binary logging for the session again + # the session by itself will not be used anymore, but this is clean :) + do_query($cxn, "set SQL_LOG_BIN=1"); + + }; + if ( $EVAL_ERROR ) { + print $EVAL_ERROR; + pause(); + } + + $clearing_deadlocks = 0; +} + +sub get_master_logs { + my @cxns = @_; + my @result; + if ( !$info_gotten{master_logs}++ ) { + foreach my $cxn ( @cxns ) { + my $stmt = do_stmt($cxn, 'SHOW_MASTER_LOGS') or next; + push @result, @{$stmt->fetchall_arrayref({})}; + } + } + return @result; +} + +# get_master_slave_status {{{3 +# Inserts special counters as though they are SHOW STATUS counters. +sub get_master_slave_status { + my @cxns = @_; + if ( !$info_gotten{replication_status}++ ) { + foreach my $cxn ( @cxns ) { + $vars{$cxn}->{$clock} ||= {}; + my $vars = $vars{$cxn}->{$clock}; + $vars->{cxn} = $cxn; + $vars->{Uptime_hires} ||= get_uptime($cxn); + + my $stmt = do_stmt($cxn, 'SHOW_MASTER_STATUS') or next; + my $res = $stmt->fetchall_arrayref({})->[0]; + @{$vars}{ keys %$res } = values %$res; + + } + } +} + +# get_slave_status {{{3 +# Separated handling of slave status to support 5.7 and replication channels +sub get_slave_status { + my ($cxn, $channel) = @_; + my $chcxn = $channel . '=' . $cxn; + $vars{$chcxn}->{$clock} ||= {}; + my $vars = $vars{$chcxn}->{$clock}; + $vars->{chcxn} = $chcxn; + $vars->{Uptime_hires} ||= get_uptime($chcxn); + + if ( $channel =~ /no_channels/ ) { + my $stmt = do_stmt($cxn, 'SHOW_SLAVE_STATUS') or next; + my $res = $stmt->fetchall_arrayref({}); + if ( $res && @$res ) { + $res = $res->[0]; + @{$vars}{ keys %$res } = values %$res; + $vars->{Slave_ok} = + (($res->{slave_sql_running} || 'Yes') eq 'Yes' + && ($res->{slave_io_running} || 'Yes') eq 'Yes') ? 'Yes' : 'No'; + } + else { + $vars->{Slave_ok} = 'Off'; + } + } else { + my $dbh = connect_to_db($cxn); + my $sql = 'SHOW SLAVE STATUS FOR CHANNEL \'' . $channel . '\''; + my $stmt = $dbh->prepare($sql ) ; + $stmt->execute(); + my $res = $stmt->fetchall_arrayref({}); + if ( $res && @$res ) { + $res = $res->[0]; + @{$vars}{ keys %$res } = values %$res; + $vars->{Slave_ok} = + (($res->{slave_sql_running} || 'Yes') eq 'Yes' + && ($res->{slave_io_running} || 'Yes') eq 'Yes') ? 'Yes' : 'No'; + } + else { + $vars->{Slave_ok} = 'Off'; + } + } + } + + + + +sub is_func { + my ( $word ) = @_; + return defined(&$word) + || eval { my $x = sub { $word }; 1 } + || $EVAL_ERROR !~ m/^Bareword/; +} + +# Documentation {{{1 +# ############################################################################ +# I put this last as per the Dog book. +# ############################################################################ +=pod + +=head1 NAME + +innotop - MySQL and InnoDB transaction/status monitor. + +=head1 SYNOPSIS + +To monitor servers normally: + + innotop + +To monitor InnoDB status information from a file: + + innotop /var/log/mysql/mysqld.err + +To run innotop non-interactively in a pipe-and-filter configuration: + + innotop --count 5 -d 1 -n + +To monitor a database on another system using a particular username and password: + + innotop -u -p -h + +=head1 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. + +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">. Press '?' at any time while running innotop for +context-sensitive help. + +=head1 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 "innotop" and press +Enter; otherwise, you will need to change to innotop's directory and type "perl +innotop". + +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. + +After you've connected, innotop should show you something like the following: + + [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 ( + + +(This sample is truncated at the right so it will fit on a terminal when running +'man innotop') + +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 ([RO]), 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. + +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 TAB and other keys to auto-complete and edit input. + +To quit innotop, press the 'q' key. + +=head1 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<"MONITORING A FILE"> for more +details. + +You can negate some options by prefixing the option name with --no. For +example, --noinc (or --no-inc) negates L<"--inc">. + +=over + +=item --color + +Enable or disable terminal coloring. Corresponds to the L<"color"> config file +setting. + +=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. + +=item --count + +Refresh only the specified number of times (ticks) before exiting. Each refresh +is a pause for L<"interval"> seconds, followed by requesting data from MySQL +connections and printing it to the terminal. + +=item --delay + +Specifies the amount of time to pause between ticks (refreshes). Corresponds to +the configuration option L<"interval">. + +=item --help + +Print a summary of command-line usage and exit. + +=item --host + +Host to connect to. + +=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">. + +=item --mode + +Specifies the mode in which innotop should start. Corresponds to the +configuration option L<"mode">. + +=item --nonint + +Enable non-interactive operation. See L<"NON-INTERACTIVE OPERATION"> for more. + +=item --password + +Password to use for connection. + +=item --port + +Port to use for connection. + +=item --skipcentral + +Don't read the central configuration file. + +=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. + +=item --user + +User to use for connection. + +=item --version + +Output version information and exit. + +=item --write + +Sets the configuration option L<"readonly"> to 0, making innotop write the +running configuration to ~/.innotop/innotop.conf on exit, if no configuration +file was loaded at start-up. + +=back + +=head1 HOTKEYS + +innotop is interactive, and you control it with key-presses. + +=over + +=item * + +Uppercase keys switch between modes. + +=item * + +Lowercase keys initiate some action within the current mode. + +=item * + +Other keys do something special like change configuration or show the +innotop license. + +=back + +Press '?' at any time to see the currently active keys and what they do. + +=head1 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: + +=over + +=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. + +=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 SHOW INNODB STATUS. + +This mode contains the L<"buffer_pool">, L<"page_statistics">, +L<"insert_buffers">, and L<"adaptive_hash_index"> tables by default. + +=item C: Command Summary + +This mode is similar to mytop's Command Summary mode. It shows the +L<"cmd_summary"> table, which looks something like the following: + + 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% + +The command summary table is built by extracting variables from +L<"STATUS_VARIABLES">. The variables must be numeric and must match the prefix +given by the L<"cmd_filter"> 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. + +The example shows what you see if the prefix is "Select_". The default +prefix is "Com_". You can choose a prefix with the 's' key. + +It's rather like running SHOW VARIABLES LIKE "prefix%" with memory and +nice formatting. + +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. + +=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. + +InnoDB puts deadlock information before some other information in the SHOW +INNODB STATUS 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 SHOW INNODB +STATUS 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. + +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<"SERVER +CONNECTIONS">). + +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">). + +This mode displays the L<"deadlock_transactions"> and L<"deadlock_locks"> tables +by default. + +=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. + +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 ++so much code devoted to parsing this messy, unparsable 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. + +This mode displays the L<"fk_error"> table by default. + +=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">, +L<"pending_io">, L<"file_io_misc">, and L<"log_statistics"> tables by default. + +=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 L<"innodb_blocked_blocker>" table. + +=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 TRANSACTIONS 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 "hot spot" for +locks. If your server is running pretty well, this mode should show nothing. + +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 (L). It's +not documented in the MySQL manual, but creating the lock monitor with the +following statement also affects the output of SHOW INNODB STATUS, which innotop +uses: + + CREATE TABLE innodb_lock_monitor(a int) ENGINE=INNODB; + +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 SHOW INNODB STATUS output +include lock information, which innotop can parse and display (that's the +undocumented feature). + +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. + +This mode displays the L<"innodb_locks"> table by default. Here's a sample of +the screen when one connection is waiting for locks another connection holds: + + _________________________________ 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 + +You can see the first connection, ID 12, is waiting for a lock on the PRIMARY +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. + +=item M: Master/Slave Replication Status + +This mode shows the output of SHOW SLAVE STATUS and SHOW MASTER STATUS in three +tables. The first two divide the slave's status into SQL 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. + +This mode displays the L<"slave_sql_status">, L<"slave_io_status">, and +L<"master_status"> tables by default. + +=item O: Open Tables + +This section comes from MySQL's SHOW OPEN TABLES 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. + +This mode displays the L<"open_tables"> mode by default. + +=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 "user statistics." This feature gathers stats +on clients, threads, users, tables, and indexes and makes them available as +INFORMATION_SCHEMA tables. These are invaluable for understanding what your +server is doing. They are also available in MariaDB. + +The statistics supported so far are only from the TABLE_STATISTICS and +INDEX_STATISTICS 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. + +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. + +=item Q: Query List + +This mode displays the output from SHOW FULL PROCESSLIST, much like B's +query list mode. This mode does B show InnoDB-related information. This +is probably one of the most useful modes for general usage. + +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. + +You can EXPLAIN a query from this mode with the 'e' key. This displays the +query's full text, the results of EXPLAIN, and in newer MySQL versions, even +the optimized query resulting from EXPLAIN EXTENDED. innotop also tries to +rewrite certain queries to make them EXPLAIN-able. For example, INSERT/SELECT +statements are rewritable. + +This mode displays the L<"q_header"> and L<"processlist"> tables by default. + +=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">, +L<"row_operation_misc">, L<"semaphores">, and L<"wait_array"> tables by default. + +=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. + +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 B. The 'g' +key changes the view to a graph of the same numbers, sort of like B. +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"> +configuration variable. + +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. + +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"> table +definition for this. + +=item T: InnoDB Transactions + +This mode shows transactions from the InnoDB monitor's output, in B-like +format. This mode is the reason I wrote innotop. + +You can kill queries or processes with the 'k' and 'x' keys, and EXPLAIN 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. + +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. + +This mode displays the L<"t_header"> and L<"innodb_transactions"> tables by +default. + +=back + +=head1 INNOTOP STATUS + +The first line innotop displays is a "status bar" of sorts. What it contains +depends on the mode you're in, and what servers you're monitoring. The first +few words are always [RO] (if readonly is set to 1), the innotop mode, such as +"InnoDB Txns" for T mode, followed by a reminder to press '?' for help at any +time. + +=head2 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. + +If you're in an InnoDB mode, such as T or B, the next word is "InnoDB" followed +by some information about the SHOW INNODB STATUS output used to render the +screen. The first word is the number of seconds since the last SHOW INNODB +STATUS, 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">). + +The next two words indicate the server's queries per second (QPS) and how many +threads (connections) exist. Finally, the server's version number is the last +thing on the line. + +=head2 MULTIPLE SERVERS + +If you are monitoring multiple servers (see L<"SERVER CONNECTIONS">), 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. + +If you are monitoring a group of servers (see L<"SERVER GROUPS">), 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. + +See L<"ERROR HANDLING"> for more details about innotop's error handling. + +=head2 MONITORING A FILE + +If you give a filename on the command line, innotop will not connect to ANY +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. + +=head1 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. + +You can kill a connection, or in newer versions of MySQL kill a query but not a +connection, from L<"Q: Query List"> and L<"T: InnoDB Transactions"> modes. +Press 'k' to issue a KILL command, or 'x' to issue a KILL QUERY command. +innotop will prompt you for the server and/or connection ID 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'. + +In L<"M: Master/Slave Replication Status"> 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 START SLAVE or STOP SLAVE +for you, but you can actually edit the command and send anything you wish, such +as SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1 to make the slave skip one binlog event +when it starts. + +You can also ask innotop to calculate the earliest binlog in use by any slave +and issue a PURGE MASTER LOGS 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 PURGE MASTER LOGS. + +in L<"U: User Statistics"> mode, you can use the 's' key to start and stop +the collection of the statistics data for TABLE_STATISTICS and similar. + +=head1 SERVER CONNECTIONS + +When you create a server connection using '@', innotop asks you for a series of +inputs, as follows: + +=over + +=item DSN + +A DSN is a Data Source Name, which is the initial argument passed to the DBI +module for connecting to a server. It is usually of the form + + DBI:MariaDB:;mariadb_read_default_group=mysql;host=HOSTNAME + +Since this DSN is passed to the DBD::MariaDB driver, you should read the driver's +documentation at L for +the exact details on all the options you can pass the driver in the DSN. You +can read more about DBI at L, and especially at +L. + +The mariadb_read_default_group=mysql option lets the DBD 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. + +=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">). 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. + +=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. + +The username defaults to your login name on the system you're running innotop on. + +=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. + +=back + +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<"SWITCHING BETWEEN CONNECTIONS">. + +=head1 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. + +You can choose which group to monitor with the '#' key, and you can press the +TAB key to switch to the next group. If you're not currently monitoring a +group, pressing TAB selects the first group. + +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. + +=head1 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. + +You can quickly switch to the 'next' connection in alphabetical order with the +'n' key. If you're monitoring a server group (see L<"SERVER GROUPS">) this will +switch to the first connection. + +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 +"server1 server2." Again, if you type the name of a connection that doesn't +exist, innotop will prompt you for connection information and create the +connection. + +Another way to monitor multiple connections at once is with server groups. You +can use the TAB key to switch to the 'next' group in alphabetical order, or if +you're not monitoring any groups, TAB will switch to the first group. + +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. + +When you monitor more than one connection, innotop's status bar changes. See +L<"INNOTOP STATUS">. + +=head1 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! + +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. + +Since errors might only happen in certain modes because of the SQL 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. + +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"> configuration option, which is enabled by default. +If the L<"debug"> option is enabled, innotop will display the error at the +bottom of every table, not just the first. And if L<"show_cxn_errors"> is +enabled, innotop will print the error text to STDOUT 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. + +=head1 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"<--nonint"> command-line option. +This changes innotop's behavior in the following ways: + +=over + +=item * + +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. + +=item * + +innotop does not clear the screen after each tick. + +=item * + +innotop does not persist any changes to the configuration file. + +=item * + +If L<"--count"> is given and innotop is in incremental mode (see L<"status_inc"> +and L<"--inc">), 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. + +=item * + +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<"TABLES">. Since L<"Q: Query +List"> mode is so important, innotop automatically disables the L<"q_header"> +table. This ensures you'll see the L<"processlist"> table, even if you have +innotop configured to show the q_header table during interactive operation. +Similarly, in L<"T: InnoDB Transactions"> mode, the L<"t_header"> table is +suppressed so you see only the L<"innodb_transactions"> table. + +=item * + +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. + +=item * + +innotop only prints column headers once instead of every tick (see +L<"hide_hdr">). innotop does not print table captions (see +L<"display_table_captions">). innotop ensures there are no empty lines in the +output. + +=item * + +innotop does not honor the L<"shorten"> transformation, which normally shortens +some numbers to human-readable formats. + +=item * + +innotop does not print a status line (see L<"INNOTOP STATUS">). + +=back + +=head1 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. + +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: + +=over + +=item S: Statement Sleep Times + +Edits SQL statement sleep delays, which make innotop pause for the specified +amount of time after executing a statement. See L<"SQL STATEMENTS"> for a +definition of each statement and what it does. By default innotop does not +delay after any statements. + +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 SHOW GLOBAL STATUS. If innotop calls +SHOW FULL PROCESSLIST immediately afterward, the processlist contains more +queries than the machine actually averages at any given moment. Configuring +innotop to pause briefly after calling SHOW GLOBAL STATUS alleviates this +effect. + +Sleep times are stored in the L<"stmt_sleep_times"> section of the configuration +file. Fractional-second sleeps are supported, subject to your hardware's +limitations. + +=item c: Edit Columns + +Starts the table editor on one of the displayed tables. See L<"TABLE EDITOR">. +An alternative way to start the table editor without entering the configuration +dialog is with the '^' key. + +=item g: General Configuration + +Starts the configuration editor to edit global and mode-specific configuration +variables (see L<"MODES">). innotop prompts you to choose a variable from among +the global and mode-specific ones depending on the current mode. + +=item k: Row-Coloring Rules + +Starts the row-coloring rules editor on one of the displayed table(s). See +L<"COLORS"> for details. + +=item p: Manage Plugins + +Starts the plugin configuration editor. See L<"PLUGINS"> for details. + +=item s: Server Groups + +Lets you create and edit server groups. See L<"SERVER GROUPS">. + +=item t: Choose Displayed Tables + +Lets you choose which tables to display in this mode. See L<"MODES"> and +L<"TABLES">. + +=back + +=head1 CONFIGURATION FILE + +innotop's default configuration file locations are $HOME/.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"> 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. + +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. + +A configuration file is read-only be default. You can override that with +L<"--write">. See L<"readonly">. + +The configuration file is arranged into sections like an INI 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. + +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. + +The following list describes each section of the configuration file and the data +it contains: + +=over + +=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. + +=over + +=item S_func + +Controls S mode presentation (see L<"S: Variables & Status">). If g, values are +graphed; if s, values are like vmstat; if p, values are in a pivoted table. + +=item S_set + +Specifies which set of variables to display in L<"S: Variables & Status"> mode. +See L<"VARIABLE SETS">. + +=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. + +=item charset + +Specifies what kind of characters to allow through the L<"no_ctrl_char"> +transformation. This keeps non-printable characters from confusing a +terminal when you monitor queries that contain binary data, such as images. + +The default is 'ascii', which considers anything outside normal ASCII 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 ALL text fields in queries. + +=item cmd_filter + +This is the prefix that filters variables in L<"C: Command Summary"> mode. + +=item color + +Whether terminal coloring is permitted. + +=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. + +=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"> when there is a +crash. + +=item debugfile + +A file to which innotop will write information when there is a crash. See +L<"FILES">. + +=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. + +=item global + +Whether to show GLOBAL variables and status. innotop only tries to do this on +servers which support the GLOBAL option to SHOW VARIABLES and SHOW STATUS. 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. + +I can no longer find or reproduce the situation where GLOBAL wasn't allowed, but +I know there was one. + +=item graph_char + +Defines the character to use when drawing graphs in L<"S: Variables & Status"> +mode. + +=item header_highlight + +Defines how to highlight column headers. This only works if Term::ANSIColor is +available. Valid values are 'bold' and 'underline'. + +=item hide_hdr + +Hides column headers globally. + +=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. + +This variable accepts fractions of a second. + +=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<"MODES">. + +=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"> +mode with the '+' and '-' keys. It is used in the L<"set_precision">, +L<"shorten">, and L<"percent"> transformations. + +=item num_status_sets + +Controls how many sets of status variables to display in pivoted L<"S: Variables +& Status"> 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. + +=item plugin_dir + +Specifies where plugins can be found. By default, innotop stores plugins in the +'plugins' subdirectory of your innotop configuration directory. + +=item readonly + +Whether the configuration file is readonly. This cannot be set interactively. + +=item show_cxn_errors + +Makes innotop print connection errors to STDOUT. See L<"ERROR HANDLING">. + +=item show_cxn_errors_in_tbl + +Makes innotop display connection errors as rows in the first table on screen. +See L<"ERROR HANDLING">. + +=item show_percent + +Adds a '%' character after the value returned by the L<"percent"> +transformation. + +=item show_statusbar + +Controls whether to show the status bar in the display. See L<"INNOTOP +STATUS">. + +=item skip_innodb + +Disables fetching SHOW INNODB STATUS, 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 SUPER privilege, required to run SHOW INNODB STATUS. + +=item spark + +Specifies how wide a spark chart is. There are two ASCII spark charts in A +mode, showing QPS and User_threads_running. + +=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. + +=item timeformat + +The C-style strftime()-compatible format for the timestamp line to be printed +in -n mode when -t is set. + +=back + +=item plugins + +This section holds a list of package names of active plugins. If the plugin +exists, innotop will activate it. See L<"PLUGINS"> for more information. + +=item filters + +This section holds user-defined filters (see L<"FILTERS">). Each line is in the +format filter_name=text='filter text' tbls='table list'. + +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. + +=item active_filters + +This section stores which filters are active on each table. Each line is in the +format table_name=filter_list. + +=item tbl_meta + +This section stores user-defined or user-customized columns (see L<"COLUMNS">). +Each line is in the format col_name=properties, where the properties are a +name=quoted-value list. + +=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 DSN, username, or password +command-line options are used. See L<"SERVER CONNECTIONS">. + +=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. + +=item server_groups + +This section holds server groups. Each line is in the format +name=connection_list. See L<"SERVER GROUPS">. + +=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. + +=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"> mode. Each line is in the format +name=value. + +=item active_columns + +This section holds table column lists. Each line is in the format +tbl_name=column_list. See L<"COLUMNS">. + +=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<"SORTING">. + +=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<"TABLES">. + +=item varsets + +This section defines variable sets for use in L<"S: Status & Variables"> mode. +Each line is in the format name=variable_list. See L<"VARIABLE SETS">. + +=item colors + +This section defines colorization rules. Each line is in the format +tbl_name=property_list. See L<"COLORS">. + +=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">. + +=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<"GROUPING">. + +=back + +=head1 CUSTOMIZING + +You can customize innotop a great deal. For example, you can: + +=over + +=item * + +Choose which tables to display, and in what order. + +=item * + +Choose which columns are in those tables, and create new columns. + +=item * + +Filter which rows display with built-in filters, user-defined filters, and +quick-filters. + +=item * + +Sort the rows to put important data first or group together related rows. + +=item * + +Highlight rows with color. + +=item * + +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). + +=item * + +Design your own expressions to extract and combine data as you need. This gives +you unlimited flexibility. + +=back + +All these and more are explained in the following sections. + +=head2 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. + +Internally, table meta-data is defined in a data structure called %tbl_meta. +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<"TABLE EDITOR">). + +You can choose which tables to show by pressing the '$' key. See L<"MODES"> and +L<"TABLES">. + +The table life-cycle is as follows: + +=over + +=item * + +Each table begins with a data source, which is an array of hashes. See below +for details on data sources. + +=item * + +Each element of the data source becomes a row in the final table. + +=item * + +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 +$set. The values innotop extracts are determined by the table's columns. Each +column has an extraction subroutine, compiled from an expression (see +L<"EXPRESSIONS">). The resulting row is a hash whose keys are named the same as +the column name. + +=item * + +innotop filters the rows, removing those that don't need to be displayed. See +L<"FILTERS">. + +=item * + +innotop sorts the rows. See L<"SORTING">. + +=item * + +innotop groups the rows together, if specified. See L<"GROUPING">. + +=item * + +innotop colorizes the rows. See L<"COLORS">. + +=item * + +innotop transforms the column values in each row. See L<"TRANSFORMATIONS">. + +=item * + +innotop optionally pivots the rows (see L<"PIVOTING">), then filters and sorts +them. + +=item * + +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. + +=back + +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 SQL, 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. + +Each built-in table is described below: + +=over + +=item adaptive_hash_index + +Displays data about InnoDB's adaptive hash index. Data source: +L<"STATUS_VARIABLES">. + +=item buffer_pool + +Displays data about InnoDB's buffer pool. Data source: L<"STATUS_VARIABLES">. + +=item cmd_summary + +Displays weighted status variables. Data source: L<"STATUS_VARIABLES">. + +=item deadlock_locks + +Shows which locks were held and waited for by the last detected deadlock. Data +source: L<"DEADLOCK_LOCKS">. + +=item deadlock_transactions + +Shows transactions involved in the last detected deadlock. Data source: +L<"DEADLOCK_TRANSACTIONS">. + +=item explain + +Shows the output of EXPLAIN. Data source: L<"EXPLAIN">. + +=item file_io_misc + +Displays data about InnoDB's file and I/O operations. Data source: +L<"STATUS_VARIABLES">. + +=item fk_error + +Displays various data about InnoDB's last foreign key error. Data source: +L<"STATUS_VARIABLES">. + +=item health_dashboard + +Displays an overall summary of servers, one server per line, for monitoring. +Data source: L<"STATUS_VARIABLES">, L<"MASTER_SLAVE">, L<"PROCESSLIST_STATS">. + +=item index_statistics + +Displays data from the INDEX_STATISTICS table in Percona-enhanced servers. + +=item index_table_statistics + +Displays data from the INDEX_STATISTICS and TABLE_STATISTICS 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"> 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. + +=item innodb_blocked_blocker + +Displays InnoDB locks and lock waits. Data source: L<"INNODB_BLOCKED_BLOCKER">. + +=item innodb_locks + +Displays InnoDB locks. Data source: L<"INNODB_LOCKS">. + +=item innodb_transactions + +Displays data about InnoDB's current transactions. Data source: +L<"INNODB_TRANSACTIONS">. + +=item insert_buffers + +Displays data about InnoDB's insert buffer. Data source: L<"STATUS_VARIABLES">. + +=item io_threads + +Displays data about InnoDB's I/O threads. Data source: L<"IO_THREADS">. + +=item log_statistics + +Displays data about InnoDB's logging system. Data source: L<"STATUS_VARIABLES">. + +=item master_status + +Displays replication master status. Data source: L<"STATUS_VARIABLES">. + +=item open_tables + +Displays open tables. Data source: L<"OPEN_TABLES">. + +=item page_statistics + +Displays InnoDB page statistics. Data source: L<"STATUS_VARIABLES">. + +=item pending_io + +Displays InnoDB pending I/O operations. Data source: L<"STATUS_VARIABLES">. + +=item processlist + +Displays current MySQL processes (threads/connections). Data source: +L<"PROCESSLIST">. + +=item q_header + +Displays various status values. Data source: L<"STATUS_VARIABLES">. + +=item row_operation_misc + +Displays data about InnoDB's row operations. Data source: +L<"STATUS_VARIABLES">. + +=item row_operations + +Displays data about InnoDB's row operations. Data source: +L<"STATUS_VARIABLES">. + +=item semaphores + +Displays data about InnoDB's semaphores and mutexes. Data source: +L<"STATUS_VARIABLES">. + +=item slave_io_status + +Displays data about the slave I/O thread. Data source: +L<"STATUS_VARIABLES">. + +=item slave_sql_status + +Displays data about the slave SQL thread. Data source: L<"STATUS_VARIABLES">. + +=item table_statistics + +Displays data from the TABLE_STATISTICS table in Percona-enhanced servers. + +=item t_header + +Displays various InnoDB status values. Data source: L<"STATUS_VARIABLES">. + +=item var_status + +Displays user-configurable data. Data source: L<"STATUS_VARIABLES">. + +=item wait_array + +Displays data about InnoDB's OS wait array. Data source: L<"OS_WAIT_ARRAY">. + +=back + +=head2 COLUMNS + +Columns belong to tables. You can choose a table's columns by pressing the '^' +key, which starts the L<"TABLE EDITOR"> and lets you choose and edit columns. +Pressing 'e' from within the table editor lets you edit the column's properties: + +=over + +=item * + +hdr: a column header. This appears in the first row of the table. + +=item * + +just: justification. '-' means left-justified and '' means right-justified, +just as with printf formatting codes (not a coincidence). + +=item * + +dec: whether to further align the column on the decimal point. + +=item * + +num: whether the column is numeric. This affects how values are sorted +(lexically or numerically). + +=item * + +label: a small note about the column, which appears in dialogs that help the +user choose columns. + +=item * + +src: an expression that innotop uses to extract the column's data from its +source (see L<"DATA SOURCES">). See L<"EXPRESSIONS"> for more on expressions. + +=item * + +minw: specifies a minimum display width. This helps stabilize the display, +which makes it easier to read if the data is changing frequently. + +=item * + +maxw: similar to minw. + +=item * + +trans: a list of column transformations. See L<"TRANSFORMATIONS">. + +=item * + +agg: an aggregate function. See L<"GROUPING">. The default is L<"first">. + +=item * + +aggonly: controls whether the column only shows when grouping is enabled on the +table (see L<"GROUPING">). 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"> and L<"innodb_transactions">, so you don't see a count when the +grouping isn't enabled, but you do when it is. + +=item * + +agghide: the reverse of aggonly. The column is hidden when grouping is enabled. + +=back + +=head2 FILTERS + +Filters remove rows from the display. They behave much like a WHERE clause in +SQL. 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. + +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. + +=head3 USER-DEFINED FILTERS + +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 $set. + +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 TAB to initiate your +terminal's auto-completion. You'll see the names of the columns in the +L<"processlist"> table (innotop generally tries to help you with auto-completion +lists). You want to filter on the 'time' column. Type the text "$set->{time} > +300" to return true when the query is more than five minutes old. That's all +you need to do. + +In other words, the code you're typing is surrounded by an implicit context, +which looks like this: + + sub filter { + my ( $set ) = @_; + # YOUR CODE HERE + } + +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"> to make innotop throw an error instead. + +=head3 QUICK-FILTERS + +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 "search for." For example, to filter the L<"processlist"> table on queries +that refer to the products table, type '/' and then 'info product'. Internally, +the filter is compiled into a subroutine like this: + + sub filter { + my ( $set ) = @_; + $set->{info} =~ m/product/; + } + +The filter text can actually be any Perl regular expression, but of course a +literal string like 'product' works fine as a regular expression. + +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: + + 1. / + 2. cmd ^(?!Gandalf) + +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. + +To clear quick-filters, press the '\' key and innotop will clear them all at +once. + +=head2 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. + +To start the sort dialog, start the L<"TABLE EDITOR"> 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. + +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. + +=head2 GROUPING + +innotop can group, or aggregate, rows together (the terms are used +interchangeably). This is quite similar to an SQL GROUP BY 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 SQL so far, but unlike SQL, +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. + +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. + +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. + +Two tables have default group_by lists and a count column built in: +L<"processlist"> and L<"innodb_transactions">. 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. + +By default, the table shown in L<"S: Variables & Status"> mode also uses +grouping so you can monitor variables and status across many servers. The +default aggregation function in this mode is 'avg'. + +Valid grouping functions are defined in the %agg_funcs hash. They include + +=over + +=item first + +Returns the first element in the group. + +=item count + +Returns the number of elements in the group, including undefined elements, much +like SQL's COUNT(*). + +=item avg + +Returns the average of defined elements in the group. + +=item sum + +Returns the sum of elements in the group. + +=back + +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"> mode. Press '=' to toggle grouping (if necessary, select the +L<"processlist"> table when prompted). + +Your display might now look like the following: + + 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 + +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). + +=head2 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: + + foo bar + === === + 1 3 + 2 4 + +After pivoting, the table will look like this: + + name set0 set1 + ==== ==== ==== + foo 1 2 + bar 3 4 + +To get reasonable results, you might need to group as well as pivoting. +innotop currently does this for L<"S: Variables & Status"> mode. + +=head2 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. + +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: + + 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 + +This is the default rule set for the L<"processlist"> table. In order of +priority, these rules make locked queries black on a red background, "gray out" +connections from replication and sleeping queries, and make queries turn from +cyan to red as they run longer. + +(For some reason, the ANSI color code "white" is actually a light gray. Your +terminal's display may vary; experiment to find colors you like). + +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. + +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. + +=head2 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<"TABLES">. Expressions are used in the earliest step, where it extracts +values from a data source to form rows. + +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. + +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. + +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 $set 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: + + sub compute_column_value { + my ( $set, $cur, $pre ) = @_; + my $val = # EXPANDED STRING GOES HERE + return $val; + } + +Here's a concrete example, taken from the header table L<"q_header"> in L<"Q: +Query List"> mode. This expression calculates the qps, or Queries Per Second, +column's values, from the values returned by SHOW STATUS: + + Questions/Uptime_hires + +innotop decides both words are barewords, and transforms this expression into +the following Perl code: + + $set->{Questions}/$set->{Uptime_hires} + +When surrounded by the rest of the subroutine's code, this is executable Perl +that calculates a high-resolution queries-per-second value. + +The arguments to the subroutine are named $set, $cur, and $pre. In most cases, +$set and $cur will be the same values. However, if L<"status_inc"> is set, $cur +will not be the same as $set, because $set will already contain values that are +the incremental difference between $cur and $pre. + +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. + +=head2 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: + +=over + +=item commify + +Adds commas to large numbers every three decimal places. + +=item distill + +Distills SQL into verb-noun-noun format for quick comprehension. + +=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. + +=item fuzzy_time + +Converts a number of seconds into a friendly, readable value like "1h35m". + +=item no_ctrl_char + +Removes quoted control characters from the value. This is affected by the +L<"charset"> configuration variable. + +This transformation only operates within quoted strings, for example, values to +a SET clause in an UPDATE statement. It will not alter the UPDATE statement, +but will collapse the quoted string to [BINARY] or [TEXT], depending on the +charset. + +=item percent + +Converts a number to a percentage by multiplying it by two, formatting it with +L<"num_digits"> digits after the decimal point, and optionally adding a percent +sign (see L<"show_percent">). + +=item secs_to_time + +Formats a number of seconds as time in days+hours:minutes:seconds format. + +=item set_precision + +Formats numbers with L<"num_digits"> number of digits after the decimal point. + +=item shorten + +Formats a number as a unit of 1024 (k/M/G/T) and with L<"num_digits"> number of +digits after the decimal point. + +=back + +=head2 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: + + 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'l Pool Additional pool alloca IB_bp_add_poo + +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. + +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<"EXPRESSIONS">). + +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. + +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. + +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: + +=over + +=item * + +The column name: this needs to be a word without any funny characters, e.g. just +letters, numbers and underscores. + +=item * + +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. + +=item * + +The column's data source: this is an expression that determines what data from +the source (see L<"TABLES">) 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<"EXPRESSIONS">. + +=back + +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. + +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: "The total +number of times since startup that the replication slave SQL thread has retried +transactions. This variable was added in version 5.0.4." This is appropriate to +add to the L<"slave_sql_status"> table. + +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. + +=head1 VARIABLE SETS + +Variable sets are used in L<"S: Variables & Status"> 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 SQL SELECT list. + +The data source for variable sets, and indeed the entire S mode, is the +combination of SHOW STATUS, SHOW VARIABLES, and SHOW INNODB STATUS. 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: + + Questions, Uptime, Questions/Uptime as QPS + +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 "variable set," or a "list of variables you want to monitor." + +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. + +You may want to use some of the functions listed in L<"TRANSFORMATIONS"> to help +format the results. In particular, L<"set_precision"> is often useful to limit +the number of digits you see. Extending the above example, here's how: + + Questions, Uptime, set_precision(Questions/Uptime) as QPS + +Actually, this still needs a little more work. If your L<"interval"> is less +than one second, you might be dividing by zero because Uptime is incremental in +this mode by default. Instead, use Uptime_hires: + + Questions, Uptime, set_precision(Questions/Uptime_hires) as QPS + +This example is simple, but it shows how easy it is to choose which variables +you want to monitor. + +=head1 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. + +An innotop plugin is a Perl module (.pm) file placed in innotop's L<"plugin_dir"> +directory. On UNIX systems, you can place a symbolic link to the module instead +of putting the actual file there. innotop automatically discovers files named C<*.pm>. If +there is a corresponding entry in the L<"plugins"> configuration file section, +innotop loads and activates the plugin. + +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. + +=head2 Package Source Convention + +innotop inspects the plugin module's source to determine the Perl package name. +It looks for a line of the form "package Foo;" 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. + +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 "# +description: Foo", where "Foo" is the text innotop will consider to be the +plugin's description. + +=head2 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 + +=over + +=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">). It must return a reference +to the newly created plugin object. + +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"> section in +the config file. + +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. + +=item register_for_events() + +This method must return a list of events in which the plugin is interested, if +any. See L<"Plugin Events"> for the defined events. If the plugin returns an +event that's not defined, the event is ignored. + +=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 +register_for_events(), it must have foo() and bar() methods. These methods are +callbacks for the events. See L<"Plugin Events"> for more details about each +event. + +=back + +=head2 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 +%pluggable_vars, and are as follows: + +=over + +=item action_for + +A hashref of key mappings. These are innotop's global hot-keys. + +=item agg_funcs + +A hashref of functions that can be used for grouping. See L<"GROUPING">. + +=item config + +The global configuration hash. + +=item connections + +A hashref of connection specifications. These are just specifications of how to +connect to a server. + +=item dbhs + +A hashref of innotop's database connections. These are actual DBI connection +objects. + +=item filters + +A hashref of filters applied to table rows. See L<"FILTERS"> for more. + +=item modes + +A hashref of modes. See L<"MODES"> for more. + +=item server_groups + +A hashref of server groups. See L<"SERVER GROUPS">. + +=item tbl_meta + +A hashref of innotop's table meta-data, with one entry per table (see +L<"TABLES"> for more information). + +=item trans_funcs + +A hashref of transformation functions. See L<"TRANSFORMATIONS">. + +=item var_sets + +A hashref of variable sets. See L<"VARIABLE SETS">. + +=back + +=head2 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 %event_listener_for variable, and are as follows: + +=over + +=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. + +=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. + +=item draw_screen($lines) + +This event occurs inside the subroutine that prints the lines to the screen. +$lines is an arrayref of strings. + +=back + +=head2 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). + + use strict; + use warnings FATAL => 'all'; + + package Innotop::Plugin::Example; + # description: Adds an 'example' column to every table + + sub new { + my ( $class, %vars ) = @_; + # Store reference to innotop's variables in $self + my $self = bless { %vars }, $class; + + # Design the example column + my $col = { + hdr => 'Example', + just => '', + dec => 0, + num => 1, + label => 'Example', + src => 'example', # Get data from this column in the data source + tbl => '', + 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}}, 'example'; + } + + # Be sure to return a reference to the object. + return $self; + } + + # I'd 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's data source to the value 1. + foreach my $row ( @$rows ) { + $row->{example} = 1; + } + } + + 1; + +=head2 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. + +=head1 SQL STATEMENTS + +innotop uses a limited set of SQL 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, INNODB_STATUS +executes "SHOW ENGINE INNODB STATUS", while on earlier versions it executes +"SHOW INNODB STATUS". The statements are as follows: + + 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 + +=head1 DATA SOURCES + +Each time innotop extracts values to create a table (see L<"EXPRESSIONS"> and +L<"TABLES">), it does so from a particular data source. Largely because of the +complex data extracted from SHOW INNODB STATUS, this is slightly messy. SHOW +INNODB STATUS contains a mixture of single values and repeated values that form +nested data sets. + +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"> setting is sub-second. + +Here are the kinds of data sources from which data is extracted: + +=over + +=item STATUS_VARIABLES + +This is the broadest category, into which the most kinds of data fall. It +begins with the combination of SHOW STATUS and SHOW VARIABLES, but other sources +may be included as needed, for example, SHOW MASTER STATUS and SHOW SLAVE +STATUS, as well as many of the non-repeated values from SHOW INNODB STATUS. + +=item DEADLOCK_LOCKS + +This data is extracted from the transaction list in the LATEST DETECTED DEADLOCK +section of SHOW INNODB STATUS. It is nested two levels deep: transactions, then +locks. + +=item DEADLOCK_TRANSACTIONS + +This data is from the transaction list in the LATEST DETECTED DEADLOCK +section of SHOW INNODB STATUS. It is nested one level deep. + +=item EXPLAIN + +This data is from the result set returned by EXPLAIN. + +=item INNODB_BLOCKED_BLOCKER + +This data is from the INFORMATION_SCHEMA tables related to InnoDB locks and +the processlist. + +=item INNODB_TRANSACTIONS + +This data is from the TRANSACTIONS section of SHOW INNODB STATUS. + +=item IO_THREADS + +This data is from the list of threads in the FILE I/O section of SHOW INNODB +STATUS. + +=item INNODB_LOCKS + +This data is from the TRANSACTIONS section of SHOW INNODB STATUS and is nested +two levels deep. + +=item MASTER_SLAVE + +This data is from the combination of SHOW MASTER STATUS and SHOW SLAVE STATUS. + +=item OPEN_TABLES + +This data is from SHOW OPEN TABLES. + +=item PROCESSLIST + +This data is from SHOW FULL PROCESSLIST. + +=item PROCESSLIST_STATS + +This data is from SHOW FULL PROCESSLIST and computes stats such as the maximum time +a user query has been running, and how many user queries are running. A "user +query" excludes replication threads. + +=item OS_WAIT_ARRAY + +This data is from the SEMAPHORES section of SHOW INNODB STATUS and is nested one +level deep. It comes from the lines that look like this: + + --Thread 1568861104 has waited at btr0cur.c line 424 .... + +=back + +=head1 MYSQL PRIVILEGES + +=over + +=item * + +You must connect to MySQL as a user who has the SUPER privilege for many of the +functions. + +=item * + +If you don't have the SUPER privilege, you can still run some functions, but you +won't necessarily see all the same data. + +=item * + +You need the PROCESS privilege to see the list of currently running queries in Q +mode. + +=item * + +You need special privileges to start and stop slave servers. + +=item * + +You need appropriate privileges to create and drop the deadlock tables if needed +(see L<"SERVER CONNECTIONS">). + +=back + +=head1 SYSTEM REQUIREMENTS + +You need Perl to run innotop, of course. You also need a few Perl modules: DBI, +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 CPAN. +Term::ReadKey in particular has been known to cause problems if installed from +CPAN. + +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. + +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 OSX. I +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. + +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. + +=head1 FILES + +$HOMEDIR/.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"> is +enabled, and the plugins/ subdirectory. + +=head1 GLOSSARY OF TERMS + +=over + +=item tick + +A tick is a refresh event, when innotop re-fetches data from connections and +displays it. + +=back + +=head1 ACKNOWLEDGEMENTS + +The following people and organizations are acknowledged for various reasons. +Hopefully no one has been forgotten. + +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 AB, +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. + +(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). + +=head1 COPYRIGHT, LICENSE AND WARRANTY + +This program is copyright (c) 2006 Baron Schwartz. +Feedback and improvements are welcome. + +THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, version 2; OR the Perl Artistic License. On UNIX and similar +systems, you can issue `man perlgpl' or `man perlartistic' to read these +licenses. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1335 USA. + +Execute innotop and press '!' to see this information at any time. + +=head1 AUTHOR + +Originally written by Baron Schwartz; currently maintained by Aaron Racine. + +=head1 BUGS + +You can report bugs, ask for improvements, and get other help and support at +L. 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. + +=cut diff --cc debian/additions/innotop/innotop.1 index 62a9aed69,000000000..b0e21b5c3 mode 100644,000000..100644 --- a/debian/additions/innotop/innotop.1 +++ b/debian/additions/innotop/innotop.1 @@@ -1,2200 -1,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 \-p \-h +.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 ++so much code devoted to parsing this messy, unparsable 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 (). 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 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 , and especially at +. +.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 +. 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. diff --cc debian/additions/mariadb.conf.d/50-mysqld_safe.cnf index 000000000,000000000..e24f96a9e new file mode 100644 --- /dev/null +++ b/debian/additions/mariadb.conf.d/50-mysqld_safe.cnf @@@ -1,0 -1,0 +1,28 @@@ ++# NOTE: THIS FILE IS READ ONLY BY THE TRADITIONAL SYSV INIT SCRIPT, NOT SYSTEMD. ++# MARIADB SYSTEMD DOES _NOT_ UTILIZE MYSQLD_SAFE NOR READ THIS FILE. ++# ++# For similar behavior, systemd users should create the following file: ++# /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf ++# ++# To achieve the same result as the default 50-mysqld_safe.cnf, please create ++# /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf ++# with the following contents: ++# ++# [Service] ++# User = mysql ++# StandardOutput = syslog ++# StandardError = syslog ++# SyslogFacility = daemon ++# SyslogLevel = err ++# SyslogIdentifier = mysqld ++# ++# For more information, please read https://mariadb.com/kb/en/mariadb/systemd/ ++ ++[mysqld_safe] ++# This will be passed to all mysql clients ++# It has been reported that passwords should be enclosed with ticks/quotes ++# especially if they contain "#" chars... ++ ++nice = 0 ++skip_log_error ++syslog diff --cc debian/additions/mariadb.conf.d/50-server.cnf index 90ecafc72,000000000..1fca97aed mode 100644,000000..100644 --- a/debian/additions/mariadb.conf.d/50-server.cnf +++ b/debian/additions/mariadb.conf.d/50-server.cnf @@@ -1,113 -1,0 +1,119 @@@ +# +# These groups are read by MariaDB server. +# Use it for options that only the server (but not clients) should see + +# this is read by the standalone daemon and embedded servers +[server] + +# this is only for the mariadbd daemon +[mariadbd] + +# +# * Basic Settings +# + +#user = mysql +pid-file = /run/mysqld/mysqld.pid +basedir = /usr +#datadir = /var/lib/mysql +#tmpdir = /tmp + +# Broken reverse DNS slows down connections considerably and name resolve is +# safe to skip if there are no "host by domain name" access grants +#skip-name-resolve + +# Instead of skip-networking the default is now to listen only on +# localhost which is more compatible and is not less secure. +bind-address = 127.0.0.1 + +# +# * Fine Tuning +# + +#key_buffer_size = 128M +#max_allowed_packet = 1G +#thread_stack = 192K +#thread_cache_size = 8 +# This replaces the startup script and checks MyISAM tables if needed +# the first time they are touched +#myisam_recover_options = BACKUP +#max_connections = 100 +#table_cache = 64 + +# +# * Logging and Replication +# + ++# Note: The configured log file or its directory need to be created ++# and be writable by the mysql user, e.g.: ++# $ sudo mkdir -m 2750 /var/log/mysql ++# $ sudo chown mysql /var/log/mysql ++ +# Both location gets rotated by the cronjob. +# Be aware that this log type is a performance killer. +# Recommend only changing this at runtime for short testing periods if needed! +#general_log_file = /var/log/mysql/mysql.log +#general_log = 1 + - # Error logging goes via stdout/stderr, which on systemd systems goes to - # journald. ++# When running under systemd, error logging goes via stdout/stderr to journald ++# and when running legacy init error logging goes to syslog due to ++# /etc/mysql/conf.d/mariadb.conf.d/50-mysqld_safe.cnf +# Enable this if you want to have error logging into a separate file +#log_error = /var/log/mysql/error.log +# Enable the slow query log to see queries with especially long duration +#log_slow_query_file = /var/log/mysql/mariadb-slow.log +#log_slow_query_time = 10 +#log_slow_verbosity = query_plan,explain +#log-queries-not-using-indexes +#log_slow_min_examined_row_limit = 1000 + +# The following can be used as easy to replay backup logs or for replication. +# note: if you are setting up a replica, see README.Debian about other +# settings you may need to change. +#server-id = 1 +#log_bin = /var/log/mysql/mysql-bin.log +expire_logs_days = 10 +#max_binlog_size = 100M + +# +# * SSL/TLS +# + +# For documentation, please read +# https://mariadb.com/kb/en/securing-connections-for-client-and-server/ +#ssl-ca = /etc/mysql/cacert.pem +#ssl-cert = /etc/mysql/server-cert.pem +#ssl-key = /etc/mysql/server-key.pem +#require-secure-transport = on + +# +# * Character sets +# + - # MariaDB default is Latin1, but in Debian we rather default to the full ++# MySQL/MariaDB default is Latin1, but in Debian we rather default to the full +# utf8 4-byte character set. See also client.cnf +character-set-server = utf8mb4 +character-set-collations = utf8mb4=uca1400_ai_ci + +# +# * InnoDB +# + +# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. +# Read the manual for more InnoDB related options. There are many! +# Most important is to give InnoDB 80 % of the system RAM for buffer use: +# https://mariadb.com/kb/en/innodb-system-variables/#innodb_buffer_pool_size +#innodb_buffer_pool_size = 8G + +# this is only for embedded server +[embedded] + +# This group is only read by MariaDB servers, not by MySQL. +# If you use the same .cnf file for MySQL and MariaDB, +# you can put MariaDB-only options here +[mariadbd] + +# This group is only read by MariaDB-11.4 servers. +# If you use the same .cnf file for MariaDB of different versions, +# use this group for options that older servers don't understand +[mariadb-11.4] diff --cc debian/changelog index b9dc6a54d,000000000..027596014 mode 100644,000000..100644 --- a/debian/changelog +++ b/debian/changelog @@@ -1,5 -1,0 +1,2542 @@@ - mariadb (1:11.4.0) unstable; urgency=medium ++mariadb (1:11.4.2-4) unstable; urgency=medium + - * Initial Release ++ * Revert move of 'mysqld_safe' to compat package to avoid breaking pdns + - -- Vicențiu Ciorbaru Thu, 18 Jun 2021 16:08:00 +0300 ++ -- Otto Kekäläinen Fri, 12 Jul 2024 20:52:32 -0700 ++ ++mariadb (1:11.4.2-3) unstable; urgency=medium ++ ++ * Make compile_time_assert compatible with x32 (Closes: #1063738) ++ * Revert "Stop building the embedded server to save disk space" ++ (Closes: #1074670) ++ ++ -- Otto Kekäläinen Sun, 07 Jul 2024 21:59:40 -0700 ++ ++mariadb (1:11.4.2-2) unstable; urgency=medium ++ ++ * Disable the 'mysql*' command deprecation warning ++ * Revert move of 'mysqldump' to compat package to avoid breaking dependencies ++ * Revert move of 'mysqladmin' to compat package to avoid breaking dependencies ++ * Use correct 1:11.0.0 version in Breaks/Replaces (Closes: #1074566) ++ ++ -- Otto Kekäläinen Mon, 01 Jul 2024 15:41:57 -0700 ++ ++mariadb (1:11.4.2-1) unstable; urgency=medium ++ ++ * New upstream major version 11.4.2. Includes new features as noted at ++ https://mariadb.com/kb/en/mariadb-11-4-2-release-notes/ for this ++ minor release that got announced for General Availabily and ++ https://mariadb.com/kb/en/changes-improvements-in-mariadb-11-4/ ++ for an overview of what the MariaDB 11.4 series brings. ++ * Use new '/usr/share/mariadb' path instead of deprecated 'mysql' equivalent ++ * Use new 'mariadb-test' path and name instead of deprecated 'mysql-test' ++ * Use command 'mariadb' instead of deprecated 'mysql' ++ * Don't stop autopkgtest configuration-tracing on errors early ++ * Update server trace to include new parameters and values ++ * Add build/test dependency libnet-ssleay-perl ++ * Partially sync debian/ with upstream MariaDB 11.4.2 ++ * Fix all Lintian errors, and more, for MariaDB 11.4.2 ++ * Make transitional mariadb-server-10.5 package compatible with 11.4 ++ * Stop building the embedded server to save disk space ++ * When shutting down 'mariadbd', fallback to 'mysqld' ++ ++ -- Otto Kekäläinen Sun, 23 Jun 2024 21:46:13 -0700 ++ ++mariadb (1:10.11.8-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.11.8. Includes fixes for several severe regressions ++ as noted at https://mariadb.com/kb/en/mariadb-10-11-8-release-notes/ as well ++ as security issues: ++ - CVE-2024-21096 ++ * Add CMake flag to ignore libfmt exit code so cross-building works ++ * Extend skip test list for latest failures in reproducible builds on armhf ++ * Disable tests that fail on armhf when full test suite is run ++ * Remove temporary exceptions for bugs that should by now be fixed ++ * MDEV-31530 Localizations for Swahili language ++ * Update Innotop to be compatible with MariaDB 11.x series ++ * Replace use of trailing line `| \` with just `|` in Bash scripts ++ * Remove libmariadb file no longer present in MariaDB Connector C v3.3 ++ * Replace autopkgtest smoke test dependency hack with arch list ++ * Update client program 'mariadb' trace to match new libmariadb v3.3 ++ - New parameter 'sandbox' to fix a vulnerability and new mariadb-dump ++ output that always has the sandbox header and is backwards incompatible ++ * Update server trace to include new parameters innodb-log-spin-wait-delay ++ and innodb-snapshot-isolation ++ [ Michael Biebl ] ++ * Ensure debconf database is purged after it has been used in postrm ++ ++ [ Svante Signell ] ++ * Make hurd-i386 build fully pass (Closes: #1069094) ++ ++ ++ -- Otto Kekäläinen Thu, 16 May 2024 22:02:04 -0700 ++ ++mariadb (1:10.11.7-4) unstable; urgency=medium ++ ++ [ Michael Biebl ] ++ * Drop unnecessary mariadb-server.prerm (Closes: #1067491) ++ * Rely on dh_installsystemd to stop the service in postrm ++ ++ [ Otto Kekäläinen ] ++ * Remove direct dependencies on libcurl4 (Closes: #1068403, #1068404) ++ * Make tests compatible with OpenSSL 3.2.0 ++ ++ -- Otto Kekäläinen Sat, 13 Apr 2024 11:07:08 -0700 ++ ++mariadb (1:10.11.7-3) unstable; urgency=medium ++ ++ * Add 'dpkg-dev (>= 1.22.5)' to Build-Depends for time_t transition ++ (Closes: #1065275) ++ ++ -- Otto Kekäläinen Sat, 02 Mar 2024 08:26:26 -0800 ++ ++mariadb (1:10.11.7-2) unstable; urgency=medium ++ ++ [ Graham Inggs ] ++ * Rename libraries for 64-bit time_t transition (Closes: #1062841) ++ ++ [ Otto Kekäläinen ] ++ * Salsa-CI: Adopt new libmariadbd19t64 library name in CI ++ * Remove obsolete Lintian override: ++ package-supports-alternative-init-but-no-init.d-script ++ * Disable more tests not passing for sparc64 on Debian ++ * Add patch to fix hurd-i386 build failure (Closes: #1063739) ++ * Add patch to partially revert upstream c432c9ef (Closes: #1063738) ++ * Disable table_value_constr failing on armhf on Launchpad ++ * Backport patch for MDEV-32975 (collation fix for PHP connector) ++ ++ -- Otto Kekäläinen Fri, 01 Mar 2024 17:43:11 -0800 ++ ++mariadb (1:10.11.7-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.11.7. Includes fixes for several regressions ++ as noted at https://mariadb.com/kb/en/mariadb-10-11-7-release-notes/ ++ * Add missing ${misc:Depends} to Depends for mariadb-server-10.5 ++ * Re-export upstream signing key without extra signatures ++ * Remove field Priority on binary package mariadb-server-10.5 that duplicates ++ source ++ * Update debian/copyright for 2024 ++ * Delete test plugin pam_mariadb_mtr.so to keep mariadb-test-data clean ++ * Clean away unused Lintian overrides ++ * Remove unneeded CMAKE_SYSTEM_PROCESSOR from debian/rules ++ * Add patch to skip building AUTH_SOCKET on Hurd (Related: #1006531) ++ * Use Pre-Depends to ensure init-system-helpers is present ++ ++ [ Michael Biebl ] ++ * Install PAM module and systemd files into /usr (Closes: #1061348) ++ * Install .service files via .install and let dh_installinit/dh_systemd ++ generate the maintscript code ++ * Switch to dh_installsystemd and debhelper compat 13 ++ ++ -- Otto Kekäläinen Tue, 06 Feb 2024 20:14:49 -0800 ++ ++mariadb (1:10.11.6-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Make the transitional dummy package description explicit ++ * Ensure 'clean' target works ++ * Use upstream patch to fix subselect test regressions (Closes: #1059904) ++ * Disable innodb_ext_key crashing on ppc64el (Related: #1059904) ++ * Apply upstream patch to use RDTIME in RISC-V (Closes: #1060007) ++ -- Otto Kekäläinen Fri, 05 Jan 2024 16:32:12 +0800 ++ ++mariadb (1:10.11.6-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.11.6. Includes fixes for several severe regressions ++ as noted at https://mariadb.com/kb/en/mariadb-10-11-6-release-notes/ as well ++ as security issues: ++ - CVE-2023-22084 ++ * Upstream MariaDB Server 10.11.6 included fix for fmtlib 10 compatibility ++ (Closes: #1056387) ++ * Drop STACK_DIRECTION customization as upstream CMake code now handles it ++ * Update traces to match these changes in MariaDB 10.11.6: ++ - New option 'ALL' to multiple parameters as a way to define that all ++ possible values/options are selected ++ - New variables log-slow-max-warnings, note-verbosity and ++ optimizer-max-sel-args ++ - Default value for innodb-purge-batch-size increased to 1000 ++ - Support for TLSv1.1 has been dropped ++ ++ [ Guillem Jover ] ++ * Remove tilegx support removed from dpkg 1.22.0 (Closes: #1056748) ++ ++ -- Otto Kekäläinen Sun, 26 Nov 2023 18:54:33 -0800 ++ ++mariadb (1:10.11.5-3) unstable; urgency=medium ++ ++ * Bugfix: Rewrite 0300a91 again to retain original autopkgtest behavior ++ * Disable more tests not passing on Debian post-build test or Launchpad ++ * Fix misc spelling ++ ++ -- Otto Kekäläinen Fri, 13 Oct 2023 21:48:03 -0700 ++ ++mariadb (1:10.11.5-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Make SysV init more verbose in case of MariaDB start failures ++ * Test & QA related changes: ++ * Bugfix: Rewrite 0300a9157cc to retain original autopkgtest behavior ++ * Switch autopkgtest upstream job to use '--skip-rpl --suite=main' again ++ * Include type_test.so and others in mariadb-test package ++ * Revert "Skip upstream MTR run on armel/armhf where lxcfs upgrade broke CPU check" ++ * Partially revert fc1358087b3 about MDEV-30728 to see if it still occurs ++ * Remove overrides for test failures that should be fixed now ++ * Add patch to fix disk.disk{_notembedded} tests and re-enable them ++ * Disable tests not passing on Debian CI, Salsa CI or Launchpad builds ++ ++ -- Otto Kekäläinen Sat, 07 Oct 2023 16:00:43 -0700 ++ ++mariadb (1:10.11.5-1) unstable; urgency=medium ++ ++ [ Helmut Grohne ] ++ * Fix FTCBFS: Do not pass host CFLAGS to the native build. (Closes: #1051222) ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.11.5. Includes fixes for several severe regressions ++ as noted at https://mariadb.com/kb/en/mariadb-10-11-5-release-notes/ such as ++ - MDEV-31642: Upgrade may crash if innodb_log_file_buffering=OFF ++ (Closes: #1040784) ++ * Update configuration tracing to match what is expected for 10.11.5 ++ * Include trailing slash in watch file to be compatible with latest uscan ++ * Re-apply "Limit check of running mysqld/mariadbd to system users (Closes: #1032047)" ++ * Re-apply "Add patches to fix spelling in MariaDB and components (Closes: #1032860)" ++ * Sync downstream (where applicable) with upstream 10.11 debian/* contents ++ * Complement upstream commits with more complete mysql->mariadb conversion ++ * Misc fixes to Debian scripts to satisfy Shellcheck ++ * Fix blocksize check to use $mysql_datadir/$datadir correctly ++ * Make sure that datadir always has some value and exists ++ ++ [ Tuukka Pasanen ] ++ * MDEV-30951: Fix small perlcritic and enable modern Perl ++ * Remove usage of AWK from Debian init and postinst scripts ++ ++ [ Anel Husakovic ] ++ * MDEV-31358: Update description for MariaDB deb packages ++ ++ -- Otto Kekäläinen Tue, 03 Oct 2023 20:59:30 -0700 ++ ++mariadb (1:10.11.4-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.11.4. Includes fixes for several severe regressions, ++ see details at https://mariadb.com/kb/en/mariadb-10-11-4-release-notes/ ++ ++ [ Andreas Beckmann ] ++ * Introduce transitional mariadb-server-10.5 (Closes: #1035949) ++ ++ -- Otto Kekäläinen Sun, 04 Jun 2023 11:22:27 -0700 ++ ++mariadb (1:10.11.3-1) unstable; urgency=medium ++ ++ * New upstream version 10.11.3. Includes security fixes for ++ - CVE-2022-47015 (Closes: #1034889) ++ * This is the first bug fixing maintenance release from upstream in the 10.11 ++ series as the 10.11.2 release was the first one announced GA (general ++ availability). For a full list of all bug fixes see release notes at ++ https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/. ++ * Update libmariadb3.symbols to include new ABI changes in 3.3.5 ++ and fix DPKG_GENSYMBOLS_CHECK_LEVEL so it actually takes effect and in ++ build will properly fail if there are unaccounted symbol changes in ++ future upstream maintenance releases ++ * Update Lintian overrides after 10.11.3 import ++ * Use new log_slow_* configuration variable names in configuration examples ++ to be aligned with upstream and have least amount of surprises for users ++ of MariaDB 10.11 where these variables changed names ++ * Clean away unnecessary mariadb-test.links, no functional effect ++ * Delete all embedded zlib copies to fix crossbuilds and improve security ++ * Use native zlib to make crossbuilds work again after recent zlib 1.2.13 ++ update regressed crossbuilds ++ * Revert fixes from February/March 2023 that the Debian release team ++ deemed unfit/too late for Bookworm (Bug#1033811): ++ - Revert "Add patch to fix upgrades from MySQL 5.7 to MariaDB 10.11..." ++ - Revert "Limit check of running mysqld/mariadbd to system users..." ++ - Revert "MDEV-21303: Fix man page packaging for new mariadb-* named..." ++ - Revert "Add patches to fix spelling in MariaDB and components..." ++ - Revert "Add patch to better diagnose failures in main.order_by_innodb..." ++ - Revert "Add patch to fix misc compiler warnings in upstream build" ++ - Revert "Add patch to emit warnings if mariadb-upgrade was not run..." ++ ++ [ Mathias Gibbens ] ++ * Silence superfluous warnings in mariadb-server preinst (Closes: #1034684) ++ ++ -- Otto Kekäläinen Sat, 27 May 2023 23:16:42 -0700 ++ ++mariadb (1:10.11.2-3) unstable; urgency=medium ++ ++ * Fix typo in autopkgtests configuration-tracing affecting armhf and armel ++ * Revert: Sync downstream (where applicable) with upstream 10.11 debian/* ++ contents so that using diff/meld to compare changes are easier ++ - Revert on suggestion by Debian release managers the changes done by ++ upstreams devs in https://github.com/MariaDB/server/commit/952af4a1 ++ for MariaDB 10.5.19, 10.6.12, 10.11.2 etc. It was deemed too invasive ++ for the Debian 12 "Bookworm" release this late in the release cycle. ++ ++ -- Otto Kekäläinen Thu, 20 Apr 2023 21:48:51 -0700 ++ ++mariadb (1:10.11.2-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * SUMMARY: This version has a lot of bug fixes, quality fixes, documentation ++ and translation updates and it is tailored for the Debian 12 "Bookworm" ++ release and all potentially functional changes have been left out and ++ are pending review and merge post-Bookworm release at ++ https://salsa.debian.org/mariadb-team/mariadb-server/-/merge_requests, ++ where contributions both as reviews and new submissions are welcome! ++ * Update NEWS to summarize what is new in MariaDB 10.11 (compared to 10.6) ++ * Update and activate configuration tracing in autopkgtests to ensure that ++ for the Debian 12 "Bookworm" release cycle no upstream server config change ++ would slip in unnoticed ++ * Enable mariadb-plugin-rocksdb for riscv64 (fixes autopkgtests for riscv64) ++ * Sync downstream (where applicable) with upstream 10.11 debian/* contents ++ so that using diff/meld to compare changes are easier ++ * Add important upstream 10.11.2+ fixes as packes: ++ * Stack overflow in pinbox allocator (PR#2541) ++ * Upgrades from MySQL 5.7 to MariaDB 10.11 (MDEV-30483) (Closes: #866751) ++ * Misc compiler warnings in upstream build ++ * Incomplete stack traces if MariaDB crashes ++ * Make mariadbd emit warnings if mariadb-upgrade was not run ++ * Binlog failures due to 'character_set_client' (MDEV-30824) ++ * Prevent mariadb-test-run from using native I/O on ppc64el and s390x due to ++ Linux kernel bug (Related: #1031656) ++ * Add patch to better diagnose potential failures in main.order_by_innodb ++ * Add patch to fix cross-compilation failure on uca-dump (Closes: #1029165) ++ * Update mariadb-test-run skip test lists to not run tests that are known ++ to be broken or unstable, and that have been reported upstream ++ * Limit check of running mysqld/mariadbd to system users (Closes: #1032047) ++ * Make error more helpful in case server restart fails (Related: #1033234) ++ * Update Lintian overrides after rigorous review of all Lintian issues ++ * Remove incorrect Multi-Arch definitions ++ * Fix man pages syntax issues (Closes: #1032861) ++ * Fix spelling in MariaDB and components (Closes: #1032860) ++ * Refresh patches metadata ++ * Update upstream signing key ++ * Fix dependency of obsolete libncurses5-dev ++ ++ [ Ekaterine Papava ] ++ * Add Georgian translation (error messages) ++ ++ [ Tuukka Pasanen ] ++ * Update README files to correct versions ++ ++ -- Otto Kekäläinen Sat, 25 Mar 2023 23:26:42 -0700 ++ ++mariadb (1:10.11.2-1) unstable; urgency=medium ++ ++ * New upstream release MariaDB 10.11.2 has been announced GA ++ (general availability) with long-term support and security updates ++ until spring 2028 ++ * Autopkgetest improvements ++ - Fix incomplete variable rename in a3b6f3d7f4b ++ - Extend tracing to include MariaDB client and move traces to subdirectory ++ ++ -- Otto Kekäläinen Thu, 16 Feb 2023 23:53:02 -0800 ++ ++mariadb (1:10.11.1-5) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Packages mariadb-plugin-provider-* must depend at least on MariaDB 10.11 ++ * Make postinstall check work with more than one result (Closes: #1031244) ++ * Revert "Compression plugins as Depends for mariadb-server" (Closes: #1031116) ++ to not break the Cacti autopkgtests and allow the mariadb-10.6 autopkgtest ++ to fail instead (re-introducing Bug#1031116) ++ ++ [ Bubu ] ++ * Update French translation of debconf messages (Closes: #1030581) ++ ++ [ Adriano Rafael Gomes ] ++ * Update Brazilian translation of debconf messages (Closes: #1030908) ++ ++ -- Otto Kekäläinen Wed, 15 Feb 2023 22:57:46 -0800 ++ ++mariadb (1:10.11.1-4) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Have all compression plugins as Depends for mariadb-server (Closes: #1030604) ++ * Update existing patch with latest upstream PR#2448 version 0284207 ++ * Temporarily disable MTR on s390x as Debian buildd seems unstable ++ (Related: #1030510) ++ * Add upstream patch to fix build failure on HPPA (Closes: #1006529) ++ * Refresh patches and include references to Debian bugs they should fix ++ ++ [ Gianfranco Costamagna ] ++ * Drop riscv64 rules latomic hack, use upstream PR#2477 instead ++ (Related: #1024041) ++ ++ -- Otto Kekäläinen Thu, 09 Feb 2023 08:40:34 -0800 ++ ++mariadb (1:10.11.1-3) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Customize dh_installinit to keep service enabled (Closes: #1029136) ++ * Fix alpha compilation error in GPREL16/wsrep_* (Closes: #1024040) ++ * Skip tests that have bug reports and known to fail on 1:10.11.1-2 ++ * Review and polish autopkgtests ++ ++ [ Tianyu Chen ] ++ * Add simplified Chinese translation of debconf messages ++ ++ -- Otto Kekäläinen Sun, 05 Feb 2023 15:21:04 -0800 ++ ++mariadb (1:10.11.1-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Add upstream patch for main.explain_json_format_partitions (MDEV-30411) ++ (Closes: 1029163) ++ * Fix riscv64 compilation error in RocksDB atomic functions (Closes: #1024041) ++ * Stop skipping tests that are marked fixed upstream ++ * Don't ship any mysql-tests/unstable-tests as neither does upstream ++ * Skip test main.func_json_notembedded on s390x due to MDEV-30518 ++ * Implement configuration tracing as an autopkgtest test ++ * Drop obsolete dependency on package lsb-release ++ * Clean away outdated mentions of mariadb-10.6 and even mysql-dfsg-5.1 ++ * Update more Lintian overrides syntax to follow latest Lintian 2.115 ++ * Update standards version to 4.6.2, no changes needed ++ * Update watch file format version to 4 ++ ++ [ MichaIng ] ++ * Do not create /var/log/mysql in postinst ++ ++ [ Salman Mohammadi ] ++ * mariadb-plugin-connect: introduce curl as recommends ++ ++ [ Remus-Gabriel Chelu ] ++ * Update Romanian translation of debconf messages ++ ++ [ Faustin Lammler ] ++ * Cover the full-upgrade scenario in CI ++ ++ [ Pablo ] ++ * Update Galician translation of debconf messages ++ ++ -- Otto Kekäläinen Tue, 31 Jan 2023 00:19:17 -0800 ++ ++mariadb (1:10.11.1-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New major upstream release: 10.11 ++ - Introduce new packages called 'providers', each one providing ++ a particular features, though so far only various compression ++ methods. ++ - New plugin package for Hashicorp Vault ++ - Upstream 10.11 series is intended to be a long-term supported ++ version with 5 years of security releases ++ - The other major versions 10.7/8/9/10 releases after 10.6 ++ are all short-term releases, and thus not suitable for inclusion ++ in Debian but still worth noting as a guide on how to read ++ upstream relases notes, as all apply for what is now new in ++ Debian with the introduction of this 10.11 ++ * Remove version suffix from Debian packages and rename source ++ package to just 'mariadb', dropping the 10.6 suffix. ++ * Emit warning from SysV init script if mysqld_safe is missing ++ * Ignore some EXPLAIN JSON test failures on armel/armhf (MDEV-30411) ++ * Add custom dh_installinit to keep /etc/init.d/mariadb enabled ++ when upgrading from mariadb-server-10.6 to mariadb-server (10.11) ++ ++ [ Sunil Mohan Adapa ] ++ * Workaround failure to create DB with libpam-tmpdir (Closes: #1022994) ++ ++ -- Otto Kekäläinen Sun, 15 Jan 2023 14:45:21 -0800 ++ ++mariadb-10.6 (1:10.6.11-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Standardize on using capitalized 'ON' in CMake build options ++ * Fix Breaks/Replaces for smoother upgrades from MySQL 5.5 ++ and update maintainer documentation on how to do comprehensive ++ upgrade testing ++ * Enable automatic datadir move also on upgrades from MySQL.com packages ++ and make upgrades from MySQL Community (Cluster) 8.0 not get ++ stuck on dpkg and server restart ++ ++ [ Eric Lindblad ] ++ * Fix typos ++ ++ -- Otto Kekäläinen Mon, 02 Jan 2023 22:42:46 -0800 ++ ++mariadb-10.6 (1:10.6.11-1) unstable; urgency=medium ++ ++ * New upstream version 10.6.11. ++ * Align with upstream 10.6 debian/ contents ++ ++ -- Otto Kekäläinen Sun, 13 Nov 2022 22:27:08 -0800 ++ ++mariadb-10.6 (1:10.6.10-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.6.10. Includes several important fixes for ++ issues that regressed in previous release. See details in: ++ https://mariadb.org/regressions-in-recent-mariadb-server-releases/ ++ * Update Lintian overrides syntax to follow latest Lintian 2.115 ++ - Biggest change in Lintian 2.115 is a new syntax to use brackets in file ++ paths. ++ ++ -- Otto Kekäläinen Sun, 25 Sep 2022 15:43:39 -0700 ++ ++mariadb-10.6 (1:10.6.9-1) unstable; urgency=medium ++ ++ * New upstream version 10.6.8. Includes security fixes for ++ - CVE-2018-25032 ++ - CVE-2022-32081 ++ - CVE-2022-32082 ++ - CVE-2022-32084 ++ - CVE-2022-32089 ++ - CVE-2022-32091 ++ ++ -- Otto Kekäläinen Wed, 17 Aug 2022 07:28:05 -0700 ++ ++mariadb-10.6 (1:10.6.8-1) unstable; urgency=medium ++ ++ * New upstream version 10.6.8. Includes security fixes for ++ - CVE-2021-46669 ++ - CVE-2022-27376 ++ - CVE-2022-27377 ++ - CVE-2022-27378 ++ - CVE-2022-27379 ++ - CVE-2022-27380 ++ - CVE-2022-27381 ++ - CVE-2022-27382 ++ - CVE-2022-27383 ++ - CVE-2022-27384 ++ - CVE-2022-27386 ++ - CVE-2022-27387 ++ - CVE-2022-27444 ++ - CVE-2022-27445 ++ - CVE-2022-27446 ++ - CVE-2022-27447 ++ - CVE-2022-27448 ++ - CVE-2022-27449 ++ - CVE-2022-27451 ++ - CVE-2022-27452 ++ - CVE-2022-27455 ++ - CVE-2022-27456 ++ - CVE-2022-27457 ++ - CVE-2022-27458 ++ - CVE-2022-32085 ++ - CVE-2022-32086 ++ - CVE-2022-32087 ++ - CVE-2022-32088 ++ ++ [ Daniel Black ] ++ * Move client programs to client package from MariaDB server package ++ ++ [ Tuukka Pasanen ] ++ * MDEV-12275: Add switch '--silent' to SySV init upgrade ++ * Allow to use Perl DBD::mysl with mariadb-report (MDEV-28376) ++ ++ [ Andreas Hasenack ] ++ * Disable LTO on Ubuntu ++ ++ [ Faustin Lammler ] ++ * Use archive.mariadb.org as official watch source ++ ++ [ Laurent Bigonville ] ++ * Fix pmem availability check (Closes: #1006530) ++ ++ [ Otto Kekäläinen ] ++ * Update breaks/replaces to accommodate the moved mariadb-binlog et al ++ * Use pmem also on riscv64 ++ * Add Bulgarian and Chinese translations for error messages ++ * Use proper pid namespace ++ * Add upstream PR#2129 to fix wsrep_sst_backup packaging ++ * Deb: Move my_print_defaults to MariaDB client core package ++ * Deb: Ensure the not-installed list is up-to-date ++ * Install all available man pages in appropriate packages ++ ++ -- Otto Kekäläinen Sun, 22 May 2022 16:44:02 -0700 ++ ++mariadb-10.6 (1:10.6.7-3) unstable; urgency=medium ++ ++ * Fix syntax error in unstable tests lists ++ * Forward patches upstream and update metadata for them ++ * Bugfix: Include missing sql_parse.cc in ER_KILL_DENIED_ERROR patch ++ * Fix mysql_install_db by reverting recent addition (MDEV-27980) ++ * Fix htm use on PowerPC to fix build failure (might close #1006527) ++ * Revert "Strip path from Mroonga to make the build reproducible" ++ ++ -- Otto Kekäläinen Wed, 09 Mar 2022 22:26:32 -0800 ++ ++mariadb-10.6 (1:10.6.7-2) unstable; urgency=medium ++ ++ * Backport OpenSSL 3.0 support for MariaDB 10.6 series (Closes: #1005950) ++ * Clean away most Lintian overrides and unstable-tests to see full ++ QA results in Debian experimental ++ * Add upstream PR#2028 to fix main.grant_kill test failure ++ * Update unstable-tests skip lists after review of 1:10.6.7-2~exp1 builds ++ * Fix more spelling errors ++ * Fix misc Lintian issues and add overrides ++ ++ -- Otto Kekäläinen Tue, 01 Mar 2022 20:40:07 -0800 ++ ++mariadb-10.6 (1:10.6.7-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.6.7. Includes security fixes for ++ - CVE-2021-46661 ++ - CVE-2021-46663 ++ - CVE-2021-46664 ++ - CVE-2021-46665 ++ - CVE-2021-46668 ++ * New upstream version 10.6.6. Includes security fixes for ++ - CVE-2021-46659 ++ - CVE-2022-24048 ++ - CVE-2022-24050 ++ - CVE-2022-24051 ++ - CVE-2022-24052 ++ * Previous release 10.6.5 included security fixes for: ++ - CVE-2021-46662 ++ - CVE-2021-46667 ++ * Notable upstream functional changes in 10.6.6 and 10.6.7: ++ - New default value for innodb_change_buffering is 'none' instead of old ++ value 'all' (MDEV-27734). This change should improve crash safety but ++ might cause performance regressions on systems that use old spinning disks ++ (HDD) where seek latency is higher. ++ - New default value for innodb_read_only_compressed is 'OFF' instead of ++ 'ON'. Upstream originally intended to deprecate ROW_FORMAT=COMPRESSED but ++ abandoned the plan. ++ - New default minimum value for innodb_buffer_pool_size is 20 MB (from 2 MB) ++ * Drop MIPS and CTE patches applied now upstream ++ * Add upstream patch to make Mroonga builds reproducible (Closes: #976984) ++ * Add patch for potential kfreebsd-amd64 build failure (Closes: #994665) ++ * Remove useless libaio-dev dependency from d/control (Closes: #1001649) ++ ++ [ Faustin Lammler ] ++ * Salsa-CI: use a mirror redirector for the CI ++ ++ [ Bas Couwenberg ] ++ * Don't require debian.cnf to be executable in logrotate (Closes: #1005186) ++ ++ [ Tuukka Pasanen ] ++ * Remove unneeded path from MariaDB server postinst script ++ ++ -- Otto Kekäläinen Sat, 19 Feb 2022 16:00:00 -0800 ++ ++mariadb-10.6 (1:10.6.5-2) unstable; urgency=medium ++ ++ * Fix misc failures in 10.6 detected by Debian QA systems ++ - Revert systemd extra and socket files to fix build=all ++ - Backport fix for test cte_nonrecursive failure ++ - Disable test main.func_math on more platforms ++ ++ -- Otto Kekäläinen Tue, 14 Dec 2021 20:05:25 -0800 ++ ++mariadb-10.6 (1:10.6.5-1) unstable; urgency=medium ++ ++ * New upstream version 10.6.5. ++ * Drop MIPS and libatomic patches applied now upstream ++ * Enable Numa support (Closes: #861553) ++ ++ -- Otto Kekäläinen Sat, 27 Nov 2021 13:48:25 -0800 ++ ++mariadb-10.6 (1:10.6.4-1) unstable; urgency=medium ++ ++ [ Bas Couwenberg ] ++ * Don't require debian.cnf to be executable in logrotate (Closes: #994284) ++ ++ [ Otto Kekäläinen ] ++ * Add new overrides to be clean on Lintian v2.105.0 ++ * Salsa-CI: Add workarounds for Stretch->Bookworm upgrade bugs ++ * Salsa-CI: Add testing for Bullseye upgrades and backports ++ * Extend README.Contributor to include more QA and debugging tips ++ * Make RocksDB plugin depend on python3:any to be Lintian clean ++ * Adopt DEP-14 for the git repository layout ++ * Import new upstream major release MariaDB 10.6.4 ++ * Update Debian packaging for MariaDB 10.6 series ++ * Clean up d/copyright and remove obsolete licence-reconcile config ++ * Extend Breaks/Replaces to cover all known MySQL variants ++ * Skip upstream tests that are permanently broken ++ ++ -- Otto Kekäläinen Thu, 21 Oct 2021 11:02:17 +0300 ++ ++mariadb-10.5 (1:10.5.12-1) unstable; urgency=medium ++ ++ * New upstream version 10.5.12. Includes security fixes for: ++ - CVE-2021-2389 ++ - CVE-2021-2372 ++ * Drop patches applied upstream in MariaDB S3 plugin ++ ++ -- Otto Kekäläinen Sun, 08 Aug 2021 20:33:47 -0700 ++ ++mariadb-10.5 (1:10.5.11-1) unstable; urgency=medium ++ ++ * New upstream version 10.5.11. Includes several important bug fixes, ++ including a replication hang (Closes: #991399, Closes: #989400) ++ * Cleanup, documentation and testing: ++ * Drop backported patch for armfh build now in 10.5.11 from upstream. ++ * Drop patch no longer needed with latest gcc-10 (Closes: #972564) ++ * Save autopkgtests results as JUnit-compatible XML-report ++ * Salsa-CI: Verify wrap-and-sort usage and correctness of patches/series ++ * Remove rocksdb_build_git_date from RocksDB binaries to make them ++ build in a reproducible way, thus making the entire MariaDB finally ++ reproducible (Closes: #976985) ++ ++ [ Andreas Beckmann ] ++ * Ease switching from galera-3 to galera-4 on upgrades from buster ++ (Closes: #990708, Closes: #976147, Closes: #977137) ++ ++ -- Otto Kekäläinen Sun, 25 Jul 2021 15:38:34 -0700 ++ ++mariadb-10.5 (1:10.5.10-2) unstable; urgency=medium ++ ++ * Bugfix: Revert upstream code change to fix armhf build (Closes: #988629) ++ ++ -- Otto Kekäläinen Sun, 23 May 2021 21:04:38 -0700 ++ ++mariadb-10.5 (1:10.5.10-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.5.10. Includes security fixes for (Closes: #988428): ++ - CVE-2021-2154 ++ - CVE-2021-2166 ++ * Previous release 10.5.9 included security fixes additionally for: ++ - CVE-2021-27928 ++ * Previous release 10.5.7 included security fixes additionally for: ++ - CVE-2021-2194 ++ * Previous release 10.5.5 included security fixes additionally for: ++ - CVE-2021-2022 ++ * Update symbols to include new one from MariaDB Client 3.1.13 ++ * Misc Salsa-CI fixes for better QA ++ * Innotop: Add support for MariaDB 10.5+ (Closes: #941986) ++ * Bugfix: Ensure upstream 1556 patch is included fully (Closes: 987231) ++ * Bugfix: Don't create /usr/share/mysql/*.flag files (Closes: #985870) ++ * Misc spelling fixes ++ ++ [ Glenn Strauss ] ++ * Mark systemd files [linux-any] in debian/*.install ++ ++ [ Arnaud Rebillout ] ++ * Fix postinst trigger when systemd is not running (Closes: #983563) ++ ++ [ Faustin Lammler ] ++ * GitLab CI now supports timeout for specific jobs ++ ++ -- Otto Kekäläinen Sun, 16 May 2021 11:36:38 -0700 ++ ++mariadb-10.5 (1:10.5.9-1) unstable; urgency=medium ++ ++ * New upstream version 10.5.9 ++ * Remove transitional libmariadbclient-dev empty metapackage ++ ++ -- Otto Kekäläinen Mon, 22 Feb 2021 21:32:47 +0200 ++ ++mariadb-10.5 (1:10.5.8-3) unstable; urgency=medium ++ ++ * Re-introduce deprecated transitional libmariadbclient-dev package ++ so that the libmariadbclient-dev from 10.5 can replace the existing ++ libmariadbclient-dev form 10.3 and thus allow MariaDB 10.5 to ++ migrate from Debian unstable to testing. ++ ++ -- Otto Kekäläinen Mon, 23 Nov 2020 22:14:57 +0200 ++ ++mariadb-10.5 (1:10.5.8-2) unstable; urgency=medium ++ ++ * Fix FTBFS on mipsel/mips64el due to test main.drop failure ++ ++ -- Otto Kekäläinen Tue, 17 Nov 2020 17:07:55 +0200 ++ ++mariadb-10.5 (1:10.5.8-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Revert back to 1fc0f45a as the armhf build failure was due to GCC bug ++ * Salsa-CI: salsa-ci-team/pipeline#173 seems fixed, stop allowing failure ++ * Filter out extra 3rd party sources directly when importing new upstream ++ * New upstream version 10.5.7. Includes security fixes for: ++ - CVE-2020-28912 ++ - CVE-2020-14812 ++ - CVE-2020-14789 ++ - CVE-2020-14776 ++ - CVE-2020-14765 ++ * Clean away from d/copyright files that are no longer in the sources ++ * Sync debian/* changes from upstream 10.5.7 release ++ * Clean away columnstore sources during build and ignore all CS issues ++ * New upstream version 10.5.8 ++ - Includes criticat fix for arbitrary InnoDB buffer pool and data file ++ corruption issue (MDEV-24096) ++ * Add patch to workaround armhf build failure due to gcc segfault ++ ++ [ Helmut Grohne ] ++ * Fix FTCBFS: Add native libssl-dev to Build-Depends (Closes: #973388) ++ ++ -- Otto Kekäläinen Fri, 13 Nov 2020 09:20:28 +0200 ++ ++mariadb-10.5 (1:10.5.6-2) unstable; urgency=medium ++ ++ [ Miroslav Kure ] ++ * Update Czech translation of debconf messages (Closes: #972441) ++ ++ [ Otto Kekäläinen ] ++ * Salsa-CI: Circumvent Bug#972552 so upgrade tests work again ++ * Salsa-CI: Install more packages to cover more in upgrade tests ++ * Automatically remove /etc/logrotate.d/mysql-server (Closes: #971399) ++ * Fix debci: Skip main.failed_auth_unixsocket on armhf and i386 ++ * Revert "Allow libnuma-dev on armhf as well" ++ * Switch to using system OpenSSL (Closes: #787118) ++ ++ -- Otto Kekäläinen Mon, 26 Oct 2020 14:13:56 +0200 ++ ++mariadb-10.5 (1:10.5.6-1) unstable; urgency=medium ++ ++ * New upstream version 10.5.6. Includes security fixes for: ++ - CVE-2020-15180 ++ * Include debian/ when importing new upstream releases ++ - This will help to follow upstream packaging changes and prevent ++ divergence in packaging code upstream vs. downstream. ++ * Unify config file syntax style ++ * Allow libnuma-dev on armhf as well ++ ++ -- Otto Kekäläinen Thu, 15 Oct 2020 11:55:14 +0300 ++ ++mariadb-10.5 (1:10.5.5-3) unstable; urgency=medium ++ ++ [ Helmut Grohne ] ++ * Fix cross-compilation, amend commit f0ba31e1 ++ ++ [ Aurelien Jarno ] ++ * Correctly link pthread so riscv64 builds pass (Closes: #933151) ++ ++ [ Otto Kekäläinen ] ++ * Revert "Automatically use libatomics on 64-bit archs (Closes: #933151)" ++ * Update MTR test skip lists after full test runs in Debian experimental ++ * Clean up d/rules and patches for issues that to best knowledge were ++ temporary and not needed anymore in MariaDB 10.5.5 ++ ++ -- Otto Kekäläinen Fri, 09 Oct 2020 10:06:04 +0300 ++ ++mariadb-10.5 (1:10.5.5-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Salsa-CI: Extend feature tests to ensure TLS connections work at v1.2 ++ * Fix x32 compilation issue (Closes: #970662) ++ * Implement unified logrotate from upstream PR#1556 (Closes: #971399) ++ * Fix upgrade from Percona.com by ensuring server uses mariadb.cnf ++ * Revert emptying /etc/mysql/debian.cnf (Closes: #971256) ++ * Use build flag to enforce default charset as utf8mb4 (Closes: #933063) ++ * Remove "Multi-Arch: same" from libmariadbd-dev ++ * Disable flaky MTR tests to get builds pass ++ * Automatically use libatomics on 64-bit archs (Closes: #933151) ++ ++ [ Daniel Black ] ++ * Fix upgrade from MySQL.com with a new 'auth_socket' rename ++ ++ [ Helmut Grohne ] ++ * Fix FTCBFS so cross-compiling works (Closes: #971579) ++ - Add native dependencies on gnutls, libedit and ncurses. ++ - Use a native perl interpreter during build. ++ - Let dh_auto_configure pass -DCMAKE_SYSTEM_NAME to cmake. ++ - Keep default CMAKE_BUILD_TYPE=RelWithDebInfo instead of debhelper's None. ++ - Cache the per-architecture stack direction. ++ ++ -- Otto Kekäläinen Tue, 06 Oct 2020 14:44:39 +0300 ++ ++mariadb-10.5 (1:10.5.5-1) unstable; urgency=medium ++ ++ * New upstream version 10.5.5 (Closes: #968895) ++ - Drop patches that are obsolete or applied upstream in 10.5 ++ - Rename most occurrences of 10.4 to 10.5 after importing 10.5 series ++ - Add Breaks/Replaces for 10.5 on previous 10.4 versions ++ - Stop suggesting tinyca, upstream project does not exist anymore ++ - Sync some changes from upstream MariaDB 10.5 debian/ directory ++ - Update d/copyright for MariaDB 10.5 ++ - Disable ColumnStore, not mature enough for Debian yet ++ - Remove mariadb-plugin-tokudb as upstream TokuDB is not maintained anymore ++ - Introduce new package mariadb-plugin-s3 new in MariaDB 10.5 ++ - Include caching_sha2_password.so plugin for libmariadb3 (Closes: #962597) ++ - Remove unnecessary charset stanza from client config (Closes: #879099) ++ * Remove deprecated transitional libmariadbclient-dev package ++ * Correct documentation about systemd using debian-start (Closes: #866782) ++ * Add NEWS item about MySQL 8.0 in-place binary incompatibility ++ * Add Provides: libmysqld-dev now as the mysql-8.0 stopped providing it ++ * Install Spider with a simple spider.cnf (Closes: #917818) ++ * Remove faulty encryption.preset file installed in subdirectory ++ * Salsa-CI: Refactor common parts into reusable sections ++ ++ -- Otto Kekäläinen Fri, 25 Sep 2020 19:56:59 +0300 ++ ++mariadb-10.4 (1:10.4.14-1~exp1) experimental; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.4.14 ++ - Includes fix for RocksDB build failure on arch riscv64 ++ * Add Breaks/Replaces for mysql-client-core-8.0 that ships myisam_ftdump ++ ++ [ Christian Göttsche ] ++ * Prevent executable stack due to objects compiled from assembly ++ ++ -- Otto Kekäläinen Sun, 23 Aug 2020 13:20:04 +0300 ++ ++mariadb-10.4 (1:10.4.13-1~exp1) experimental; urgency=medium ++ ++ * New upstream version 10.4.13. Includes security fixes for: ++ - CVE-2020-2752 ++ - CVE-2020-2760 ++ - CVE-2020-2812 ++ - CVE-2020-2814 ++ - CVE-2020-13249 ++ - Includes fix for MDEV-21586: Server does not start if lc_messages setting ++ was not English (Closes: #951059) ++ * Restructure and extend d/copyright to cover libmariadb (Closes: #962541) ++ * Simplify autopkgtest 'smoke' to be easier to debug ++ * Add patch to fix RocksDB detection of ZSTD ++ * Update libmariadb symbols for upstream release 3.1.8 ++ ++ -- Otto Kekäläinen Mon, 29 Jun 2020 09:47:07 +0300 ++ ++mariadb-10.4 (1:10.4.12-1~exp3) experimental; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Make mariadb-client-10.4 Recommends libdbd-mariadb-perl as primary option ++ * Detect MySQL 8.0 based on undo_001 file as *.flag is buggy in mysql-8.0 ++ ++ [ Faustin Lammler ] ++ * Fix systemd aliases (Closes: #932289) ++ ++ -- Otto Kekäläinen Fri, 10 Apr 2020 11:03:02 +0300 ++ ++mariadb-10.4 (1:10.4.12-1~exp2) experimental; urgency=medium ++ ++ [ Christian Göttsche ] ++ * Prevent executable stack due to objects compiled from assembly ++ ++ [ Bastian Germann ] ++ * Link with libedit instead of readline5 (Closes: #940879) ++ ++ [ Otto Kekäläinen ] ++ * Fix mysqld crash on s390x that stemmed from WolfSSL ++ * Extend contributor README with debugging tips ++ * Clean up -dev packages from excess private files ++ * Make full contents, also header files, explicit in -dev packages ++ * Remove entire sql-bench in debian/rules to simplify not-installed listings ++ * Remove obsolete AUTH_SOCKET build flag ++ * Add missing mariadb-ldb to mariadb-plugin-rocksdb ++ * Install files that belong to mariadb-test instead of not-installed ++ * Ignore mariadb-config.1 since there is no mariadb-config binary ++ * Enforce --fail-missing in debian/rules to not miss any uninstalled files ++ * Unify server preinst and postrm server stopping function ++ * Move mariadb-upgrade to same package as mysql-upgrade and manpage ++ * Update package to use debhelper level 10 ++ * Install arch dependent mariadb.pc in lib/ with patch from upstream ++ * Move binary mariadb-tzinfo-to-sql to server package like upstream has ++ * Don't install useless extra logrotate script or test config helper ++ * Add patch for man page fixes from upstream 10.5 pull request ++ * Add patch to backport spelling fixes from upstream 10.5 pull request ++ * Include new man pages for mytop and myrocks_hotbackup in packaging ++ * Use https protected nluug.nl server for upstream repo to watch ++ ++ -- Otto Kekäläinen Tue, 17 Mar 2020 15:05:39 +0200 ++ ++mariadb-10.4 (1:10.4.12-1~exp1) experimental; urgency=medium ++ ++ * New upstream version 10.4.12 ++ - Drop patches applied upstream in 10.4 ++ - Sync debian/* improvements done in upstream MariaDB 10.4 release ++ - Update Galera to version 4 ++ - Update debian/copyright for MariaDB 10.4 ++ - Sync non-functional delta from upstream 10.4 ++ - Sync AppArmor profile handling from MariaDB 10.4 ++ - Sync server stopping logic from MariaDB 10.4 preinst/postinst/postrm ++ - Package PAM tool and user map introduced in upstream MariaDB 10.4 ++ - Clean away versioned breaks/replaces on older generation packages ++ - Update maintainer and contributor docs for MariaDB 10.4 ++ - Add patch from MDEV-21691 so mysql-test-run works out-of-source tree ++ - Upstream release 10.4.12 included security fixes for: ++ - CVE-2020-2574 ++ - CVE-2020-7221 ++ - Previous version 10.4.9 included security fixes for: ++ - CVE-2020-2780 ++ - Previous version 10.4.7 included security fixes for: ++ - CVE-2020-2922 ++ ++ -- Otto Kekäläinen Tue, 18 Feb 2020 20:24:40 +0200 ++ ++mariadb-10.3 (1:10.3.22-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.22. Includes security fixes for: ++ - CVE-2020-2574 ++ * Update conflicts/breaks/replaces for MySQL 8.0 ++ * Add Rules-Requires-Root definition to control file ++ * Activate NO_UPDATE_BUILD_VERSION to make RocksDB build reproducible ++ * Strip path from Mroonga to make the build reproducible ++ * Update Debian Policy version ++ * Simplify and extend Gitlab-CI testing by using more of Salsa-CI features ++ * Prefer salsa-ci.yml naming over gitlab-ci.yml since we inherit Salsa-CI ++ * Add Breaks/Replaces for mysql-client-5.7 that ships myisam_ftdump ++ ++ [ Christian Göttsche ] ++ * Set correct SELinux contexts on package installation (Closes: #948424) ++ ++ -- Otto Kekäläinen Tue, 28 Jan 2020 22:12:28 +0200 ++ ++mariadb-10.3 (1:10.3.21-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Update Python dependencies and recommends to Python 3 (Closes: #945697) ++ * Remove deprecated basedir config from debian.cnf (Closes: #947553) ++ ++ [ James Clarke ] ++ * Fix RocksDB on GNU/kFreeBSD (Closes: #920994) ++ * Use versioned symbols on GNU/kFreeBSD ++ ++ -- Otto Kekäläinen Tue, 07 Jan 2020 09:01:10 +0200 ++ ++mariadb-10.3 (1:10.3.21-1) unstable; urgency=low ++ ++ [ Faustin Lammler ] ++ * Remove no more needed lintian overrides ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.21 ++ ++ -- Otto Kekäläinen Wed, 11 Dec 2019 18:01:43 +0200 ++ ++mariadb-10.3 (1:10.3.20-1) unstable; urgency=high ++ ++ * New upstream version 10.3.20. Includes fix for regression: ++ - MDEV-20987: InnoDB fails to start when FTS table has FK relation ++ * Remove obsolete fields Name, Contact from debian/upstream/metadata ++ * Gitlab-CI: Print artifact sizes to ensure it stays under 100 MB ++ * Gitlab-CI: Adapt CI jobs for Debian Sid work ++ * Update README.Maintainer with current Debian and Ubuntu release statuses ++ ++ -- Otto Kekäläinen Mon, 11 Nov 2019 23:55:37 +0200 ++ ++mariadb-10.3 (1:10.3.19-1) unstable; urgency=high ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.17. Includes security fixes for: ++ - CVE-2019-2938 ++ - CVE-2019-2974 ++ * Update symbols to match latest libmariadb_3 ++ * Drop systemd service patch applied upstream ++ ++ [ Faustin Lammler ] ++ * Fix typo in Readme ++ ++ -- Otto Kekäläinen Thu, 07 Nov 2019 21:26:49 +0200 ++ ++mariadb-10.3 (1:10.3.18-1) unstable; urgency=medium ++ ++ * New upstream version 10.3.18. Fixes regression introduced in 10.3.17 ++ (MDEV-20247: Replication hangs with "preparing" and never starts) ++ (Closes: #939819) ++ * Minort Gitlab-CI improvements ++ ++ -- Otto Kekäläinen Thu, 12 Sep 2019 15:51:04 +0300 ++ ++mariadb-10.3 (1:10.3.17-1) unstable; urgency=high ++ ++ * New upstream version 10.3.17. Includes security fixes for: ++ - CVE-2019-2737 ++ - CVE-2019-2739 ++ - CVE-2019-2740 ++ - CVE-2019-2758 ++ - CVE-2019-2805 ++ * Multiple Gitlab-CI/Salsa-CI improvements ++ * Dependency in resolveip is still included (Closes: #910902) ++ * Update libmariadb3 symbols to match MariaDB Connector C 3.1 API ++ * Add Lintian override for new test binary wsrep_check_version ++ * Gitlab-CI: Clean away one excess comment left from b9d633b38 ++ ++ -- Otto Kekäläinen Fri, 02 Aug 2019 17:53:22 +0100 ++ ++mariadb-10.3 (1:10.3.16-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.16 ++ * Make libzstd dependency versioned as RocksDB need at least 1.3.3. ++ This fixes build errors across different build environments. ++ * Update Gitlab CI for better quality control and long-term maintenance. ++ ++ [ Helmut Grohne ] ++ * Improve cross building (Closes: #930314) ++ ++ -- Otto Kekäläinen Sat, 22 Jun 2019 16:45:18 +0200 ++ ++mariadb-10.3 (1:10.3.15-2) unstable; urgency=medium ++ ++ [ Julien Muchembled ] ++ * Fixup RocksDB test on s390x, not available there ++ ++ [ Otto Kekäläinen ] ++ * Purge deleted translations from debian/po ++ * Rename 'mariadbcheck' to 'mariadb-check' as upstream is doing in 10.4 ++ ++ -- Otto Kekäläinen Fri, 07 Jun 2019 09:13:35 +0300 ++ ++mariadb-10.3 (1:10.3.15-1) unstable; urgency=high ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.15. Includes security fixes for (Closes: #928393): ++ - CVE-2019-2628 ++ - CVE-2019-2627 ++ - CVE-2019-2614 ++ * Includes upstream fix for MDEV-18721: Host option in configuration file is ++ ignored (Closes: #921599) ++ ++ [ Gregor Riepl ] ++ * Extend mariadb/mysql_config to support --libmysqld-libs (Closes: #928230) ++ ++ [ Julien Muchembled ] ++ * Enable LZ4&Snappy for InnoDB and LZ4&Snappy&ZSTD for RocksDB ++ ++ -- Otto Kekäläinen Tue, 21 May 2019 10:45:37 +0300 ++ ++mariadb-10.3 (1:10.3.14-1) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Rename and re-organize gitlab-ci.yml stages ++ * Refactor gitlab-ci.yml to be optimal for a life in Buster ++ * Ensure cmake builds also apply CPPFLAGS flags for hardening to fully work ++ * New upstream version 10.3.14. Includes MariaDB Connector C 3.0.10 which ++ includes an improved impelemntation of mysql_real_connect() that respects ++ the my.cnf "host" option (Closes: #921599). This upstream release also ++ fixes an indexes problem on import dump SQL (MDEV-18577) and many other ++ InnoDB corruption issues (Closes: #924498). ++ * Enable automatic restarts from maint scripts in gitlab-ci.yml ++ * Automate renaming MySQL auth_socket correctly in mysql_upgrade ++ (Closes: #926231) ++ ++ [ Andreas Beckmann ] ++ * Use piuparts with --testdebs-repo so dependencies of each install resolve ++ ++ -- Otto Kekäläinen Fri, 19 Apr 2019 14:38:26 +0300 ++ ++mariadb-10.3 (1:10.3.13-2) unstable; urgency=medium ++ ++ [ Olaf ] ++ * Use upstream conf defaults (Closes: #905599). This is critically important ++ so that nothing defined in the configuration would hold back upstream ++ improvements in default option values. ++ ++ [ Otto Kekäläinen ] ++ * Extend gitlab-ci.yml to include MySQL to MariaDB upgrade testing and also ++ refine automatic testing in many ways to ensure as little regressions as ++ possible. ++ * Automatically rename 'auth_socket' to 'unix_socket' when upgrading from ++ MySQL 5.7 which otherwise would completely fail. ++ * Drop the transitional libmariadbclient18 package (Closes: #925117) ++ * Move resolveip from mariadb-server-10.3 to -core-10.3 (Closes: #910902) ++ * Move all mariadb-server-x.x *.sql files to mariadb-server-core-x.x package ++ ++ -- Otto Kekäläinen Mon, 01 Apr 2019 23:05:31 +0300 ++ ++mariadb-10.3 (1:10.3.13-1) unstable; urgency=medium ++ ++ * New upstream version 10.3.13 ++ * Includes fixes for the following security vulnerabilities ++ (Closes: #920933): ++ - CVE-2019-2537 ++ - CVE-2019-2529 ++ * Update symbols list to match latest MariaDB Connector C release ++ * Use bundled SSL libraries instead of system OpenSSL (Closes: #921488) ++ * Fix 'Multi-Arch: same' stanzas (Closes: #920364) ++ * Implement proper version detection in maintainer scripts (Closes: #920415) ++ * Make libmariadb-dev depend on libgnutls28-dev (Closes: #917135) ++ * Extend Gitlab-CI significantly and update READMEs ++ ++ -- Otto Kekäläinen Sun, 24 Feb 2019 21:14:15 +0200 ++ ++mariadb-10.3 (1:10.3.12-2) unstable; urgency=medium ++ ++ [ Adrian Bunk ] ++ * mariadb-plugin-tokudb: Properly generate the libjemalloc dependency ++ ++ [ Otto Kekäläinen ] ++ * Re-enable jemalloc as Debian#843926 is now fixed (Closes: #918798) ++ * Update gitlab-ci.yml ++ * Follow upstream 'build' and 'lintian' steps ++ * Extend upgrade testing to upgrade from buster->sid (10.1 -> 10.3) ++ * Make libmariadb-dev-compat also Breaks+Replaces old libmariadbclient-dev ++ (Closes: #863675) ++ * Revert "Update libmariadb-dev.links to restore /usr/include/mysql.." ++ ++ [ Andreas Beckmann ] ++ * Reintroduce libmariadbclient-dev as a transitional package ++ * Drop obsolete libmariadbclient18 symbols file ++ * Add Build-Depends-Package field to symbols file ++ * Minimize the upstream signing key by dropping all signatures ++ * Fix multiple Lintian issues ++ ++ -- Otto Kekäläinen Thu, 24 Jan 2019 20:56:46 +0200 ++ ++mariadb-10.3 (1:10.3.12-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * New upstream version 10.3.12 ++ * Create the mysqlclient.pc symlink at correct path with /pkgconfig/ ++ (Closes: #878340) ++ * Add libjemalloc2 as alternative dep for mariadb-plugin-tokudb ++ * Prevent mysql_upgrade from being triggered on every server restart ++ * Automate VERSION variable in mariadb-server installer scripts ++ * Improve logging and tag syslog messages with postinstall filename ++ * Make libmariadbclient18 Breaks old libpam-mysql and libdbd-mysql-perl ++ ++ [ Samuel Thibault ] ++ * Do not try to install disks.so file not built on non-Linux ++ * Tune symbol visibility on GNU/Hurd too ++ ++ -- Otto Kekäläinen Tue, 08 Jan 2019 22:52:16 +0100 ++ ++mariadb-10.3 (1:10.3.11-3) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Use sst_dump from package rocksdb-tools (Closes: #886853) ++ * Remove wsrep_sst_xtrabackup(-v2) already deprecated in upstream ++ * Make gitlab-ci.yml upgrade test specifically run mariadb-server-10.1->10.3 ++ * Fix upstream RocksDB patch to fix Lintian complaints about source code ++ * Drop the MIPS Innobase patch that it is already fixed upstream ++ * Extend gitlab-ci.yml to test libmysql* interactions ++ * Ensure libmariadbd19 does not breaks/replace anything ++ * Make libmariadb-dev-compat break what is replaces ++ * Make libmariadb-dev breaks/replaces libmysqlclient-dev (Closes: #863675) ++ * Update Dutch translation by Frans Spiesschaert (Closes: #895461) ++ ++ [ Faustin Lammler ] ++ * Fix 2 typo error in README contributor ++ * Lintian some complaints ++ ++ [ Helge Deller ] ++ * Skip failing test on HPPA, it's not too important (Closes: #917395) ++ ++ [ Scott Kitterman ] ++ * Update libmariadb-dev.links to restore /usr/include/mysql compatibility ++ symlinks lost when the default switched from 10.1 to 10.3 (Closes: #917266) ++ ++ -- Otto Kekäläinen Mon, 31 Dec 2018 16:39:33 +0200 ++ ++mariadb-10.3 (1:10.3.11-2) unstable; urgency=low ++ ++ [ Vicențiu Ciorbaru ] ++ * Update c11_atomics patch to include mysys. This should fix both ++ mips and armel build failures. ++ ++ [ Otto Kekäläinen ] ++ * Make libmariadb-dev depend on libssl-dev (Closes: #917135) ++ * Remove "Conflicts: libmariadbclient18 (<< 10.2.0)" (Closes: #917075) ++ ++ -- Otto Kekäläinen Mon, 24 Dec 2018 18:50:31 +0200 ++ ++mariadb-10.3 (1:10.3.11-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Import to Debian latest major release of MariaDB (Closes: #867892) ++ * Packaging carries on all impromevements done on to the latest MariaDB ++ 10.1.x packages in Debian unstable up until Dec 15th 2018. ++ * Drop the Hurd socket patch that it is already applied upstream ++ * Update SSL/TLS keys as OpenSSL since 1.1.0 rejects weak keys by default ++ * Remove innodb_* options from server config that are default in 10.3 ++ * Remove --skip-auth-anonymous-user deprecated in 10.3 ++ * Include also arch specific skiplists in CI tests ++ * Make TokuDB explicitly depend on libjemalloc1 ++ * Follow Salsa-CI changes and update build image name to 'dockerbuilder' ++ * Extend gitlab-ci to test installation and upgrade of MariaDB ++ ++ [ Vicențiu Ciorbaru ] ++ * Refresh c11_atomics patch for 10.3 ++ * Fix MEMORY storage engine test ++ ++ -- Otto Kekäläinen Thu, 20 Dec 2018 21:52:42 +0200 ++ ++mariadb-10.1 (1:10.1.37-3) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Update translation templates ++ * Fix typo in commit 33d853128 so skip list is not reset when adding lines ++ ++ [ Vicențiu Ciorbaru ] ++ * Fix mips compilation failure (__bss_start symbol missing) ++ ++ -- Otto Kekäläinen Sat, 08 Dec 2018 18:50:43 +0200 ++ ++mariadb-10.1 (1:10.1.37-2) unstable; urgency=low ++ ++ [ Samuel Thibault ] ++ * Do not depend on libsystemd-dev on non-Linux ++ * On non-Linux, do not install files not built there ++ * Add hurd cmake configuration (Closes: #912902) ++ ++ [ Otto Kekäläinen ] ++ * Add Gitlab-CI definition file that can test each commit to this repository ++ * Utilize upstream unstable-tests list in tests/upstream mysql-test-run. ++ This will make ci.debian.net pass as it will correctly ignore tests. ++ * Disable test unit.pcre_test on s390x that was failing in stretch-security ++ ++ -- Otto Kekäläinen Sat, 01 Dec 2018 18:17:18 +0200 ++ ++mariadb-10.1 (1:10.1.37-1) unstable; urgency=high ++ ++ * New upstream version 10.1.37. Includes security fixes for: ++ - CVE-2018-3282 ++ - CVE-2018-3251 ++ - CVE-2018-3174 ++ - CVE-2018-3156 ++ - CVE-2018-3143 ++ - CVE-2016-9843 ++ * Update README.Contributor based on recent feedback ++ * Update README.Maintainer to match current best practices ++ * Move my_print_defaults to mariadb-server-core (Closes: #898367) ++ * Update Debian standards version to 4.2.1 (no changes) ++ * Fix minor Lintian complaints ++ * Add (and rename) new man pages ++ ++ -- Otto Kekäläinen Sun, 04 Nov 2018 19:11:19 +0200 ++ ++mariadb-10.1 (1:10.1.35-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.35. Includes security fixes for: ++ - CVE-2018-3066 ++ - CVE-2018-3064 ++ - CVE-2018-3063 ++ - CVE-2018-3058 ++ * Fix wrong-path-for-interpreter in innotop script ++ * Update Debian standards version ++ * Revert "Remove the mariadb-test-* packages" (Closes: #888956) ++ * Omit test plugins as they are not used by the tests and already deleted ++ * Define autopkgtest with isolation-container (Closes: #870408) ++ * Ship config examples et al in /usr/share/mysql (Closes: #878223) ++ * Extend the server README to clarify misunderstandings (Closes: #878215) ++ * Introduce mariadb-backup as a separate binary package, just like in upstream ++ * Fix bash syntax issues detected by Shellcheck ++ * Fix 'max key length is 767 bytes' errors (Closes: #886756) ++ * Remove GNU Hurd FTBFS patch that's been applied upstream (Closes: #882062) ++ ++ -- Otto Kekäläinen Tue, 07 Aug 2018 22:18:20 +0300 ++ ++mariadb-10.1 (1:10.1.34-1) unstable; urgency=medium ++ ++ * New upstream release 10.1.34. ++ * Previous upstream version 10.1.33 included fixes for the following ++ security vulnerabilities: ++ - CVE-2018-2819 ++ - CVE-2018-2817 ++ - CVE-2018-2813 ++ - CVE-2018-2787 ++ - CVE-2018-2784 ++ - CVE-2018-2782 ++ - CVE-2018-2781 ++ - CVE-2018-2771 ++ - CVE-2018-2766 ++ - CVE-2018-2761 ++ - CVE-2018-2755 ++ * Previous upstream version 10.1.31 included fixes for the following ++ security vulnerabilities: ++ - CVE-2018-2668 ++ - CVE-2018-2665 ++ - CVE-2018-2640 ++ - CVE-2018-2622 ++ - CVE-2018-2612 ++ - CVE-2018-2562 ++ * Previous upstream version 10.1.30 included fixes for the following ++ security vulnerabilities: ++ - CVE-2017-15365 ++ ++ [ Otto Kekäläinen ] ++ * Update VCS-* links to point to the new source repository ++ * Delete unnecessary systemd files introduced by upstream ++ * Add new files introduced by upstream to correct packages ++ * Mark selected tests as unstable so they don't stop the whole upload in vain ++ * Update d/control Uploaders to match current affairs ++ * Various minor Lintian fixes ++ [ Otto Kekäläinen ] ++ * Use the ccache symlinks made by update-ccache-symlinks, if available ++ ++ [ Vicențiu Ciorbaru ] ++ * Extend libmariadbclient-rename.patch to cover TokuDB as well ++ * Disable disks.disks test ++ ++ [ Rui Branco ] ++ * Updated Portuguese translation by Rui Branco (Closes: #871052) ++ ++ [ Takuma Yamada ] ++ Updated Japanese translation by Takuma Yamada (Closes: #859481) ++ ++ -- Otto Kekäläinen Tue, 31 Jul 2018 21:52:16 +0800 ++ ++mariadb-10.1 (1:10.1.29-6) unstable; urgency=high ++ ++ * Ignore failed tests on more non-release platforms (kfreebsd-i386, ++ kfreebsd-amd64 and sparc64) ++ ++ -- Ondřej Surý Thu, 23 Nov 2017 07:03:47 +0000 ++ ++mariadb-10.1 (1:10.1.29-5) unstable; urgency=high ++ ++ * Update the -O3 -> -O2 patch to include more cmake files ++ ++ -- Ondřej Surý Wed, 22 Nov 2017 22:48:13 +0000 ++ ++mariadb-10.1 (1:10.1.29-4) unstable; urgency=high ++ ++ * Change the default optimization from -O3 to -O2 in mysql_release.cmake ++ BUILD_CONFIG profile ++ ++ -- Ondřej Surý Wed, 22 Nov 2017 20:33:17 +0000 ++ ++mariadb-10.1 (1:10.1.29-3) unstable; urgency=medium ++ ++ * Change the default optimization level to -O2 to fix arm64 build ++ ++ -- Ondřej Surý Wed, 22 Nov 2017 15:33:21 +0000 ++ ++mariadb-10.1 (1:10.1.29-2) unstable; urgency=medium ++ ++ [ Otto Kekäläinen ] ++ * Update the d/changelog with CVEs ++ ++ [ Ondřej Surý ] ++ * Revert to using system pcre library (Closes: #882329) ++ * Bump the epoch to fix the mess created by mariadb-10.2 upload ++ (Closes: #881898) ++ ++ [ Christian Ehrhardt ] ++ * d/t/upstream: skip func_regexp_pcre on s390x ++ ++ -- Ondřej Surý Wed, 22 Nov 2017 06:03:17 +0000 ++ ++mariadb-10.1 (10.1.29-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.29, includes fixes for the following ++ security vulnerabilities: ++ - [CVE-2017-10378]: Optimizer component to cause denial of service ++ conditions ++ - [CVE-2017-10268]: Replication component to access data ++ - [MDEV-13819]: Server crashes in Item_func_in::val_int or Assertion ++ `in_item' failed in virtual longlong Item_func_in::val_int ++ * Remove the mariadb-test-* packages as they are now provided by ++ mariadb-10.2 (Closes: #881898) ++ * Rebase patches for new upstream version. ++ ++ -- Ondřej Surý Thu, 16 Nov 2017 15:24:36 +0000 ++ ++mariadb-10.1 (10.1.28-2) unstable; urgency=high ++ ++ * Add libconfig-inifiles-perl to mariadb-client-10.1 depends to fix ++ mytop (Closes: #875708) ++ * Add mips64el to the list of platforms that are allowed to fail test ++ suite (Closes: #879637) ++ ++ -- Ondřej Surý Sun, 12 Nov 2017 11:03:20 +0000 ++ ++mariadb-10.1 (10.1.28-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.28 ++ * Rebase patches on top of MariaDB 10.1.28 ++ * Add extra symbols aliases for libmariadbclient_16 ++ ++ -- Ondřej Surý Mon, 09 Oct 2017 22:07:43 +0000 ++ ++mariadb-10.1 (10.1.26-1) unstable; urgency=medium ++ ++ * Ignore upstream debian/ directory when importing upstream tarball ++ * New upstream version 10.1.26 ++ * Refresh patches for MariaDB 10.1.26 ++ * Remove unstable tests patches for unstable build, so we see what is ++ really failing and what is not ++ ++ -- Ondřej Surý Thu, 10 Aug 2017 20:41:46 +0200 ++ ++mariadb-10.1 (10.1.25-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.25 ++ * Update quilt patches on top of mariadb-10.1.25 release ++ * Explicitly add dh_systemd_start snippets to mariadb-server-10.1 ++ because it's all messed up with different name for sysvinit ('mysql') ++ and systemd ('mariadb') (Closes: #865870) ++ * Don't disable PIE, it's enabled by upstream anyway (Closes: #865737) ++ * Add default socket location for client (Closes: #864662) ++ ++ -- Ondřej Surý Sun, 30 Jul 2017 14:15:48 +0200 ++ ++mariadb-10.1 (10.1.24-6) unstable; urgency=medium ++ ++ * Run invoke-rc.d mysql maintscript snippets only when running under ++ sysvinit (Closes: #864593) ++ ++ -- Ondřej Surý Wed, 21 Jun 2017 11:12:16 +0200 ++ ++mariadb-10.1 (10.1.24-5) unstable; urgency=medium ++ ++ * Add @SYSTEMD_EXECSTARTPOST@ replacement token to mariadb@.service, so ++ the /var/run/mysqld directory is created even for multi-server setup ++ (Closes: #865083) ++ ++ -- Ondřej Surý Mon, 19 Jun 2017 08:52:26 +0200 ++ ++mariadb-10.1 (10.1.24-4) unstable; urgency=medium ++ ++ [ James Cowgill ] ++ * Disable jemalloc on mips*. (Closes: #864340) ++ * Update C11 atomics to have correct semantics (Closes: #864774) ++ ++ [ Ondřej Surý ] ++ * Refresh patches after C11 atomics patch update ++ * Merge mytop script improvements from src:mytop package (Original ++ patches by Philipp Matthias Hahn, Werner Detter, Olaf van der Spek, ++ and Steffen Zieger) (Closes: #864762) ++ ++ [ Svante Signell ] ++ * Fix FTBFS on Debian GNU/Hurd (Closes: #861166) ++ ++ -- Ondřej Surý Mon, 19 Jun 2017 07:09:50 +0200 ++ ++mariadb-10.1 (10.1.24-3) unstable; urgency=medium ++ ++ * Team upload. ++ * Add mips-innobase-atomic.patch, fixing FTBFS on 32-bit mips*, thanks to ++ James Cowgill. (Closes: #864298) ++ ++ -- Andreas Beckmann Wed, 07 Jun 2017 02:23:44 +0200 ++ ++mariadb-10.1 (10.1.24-2) unstable; urgency=medium ++ ++ * Add Breaks: cqrlog (<< 1.9.0-5~) to ensure correct upgrade order ++ (Closes: #864159) ++ ++ -- Ondřej Surý Tue, 06 Jun 2017 14:29:52 +0200 ++ ++mariadb-10.1 (10.1.24-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.24, includes fixes for the following ++ high-priority regression fixes: ++ + MDEV-11842: Fail to insert on a table where a field has no default ++ + MDEV-12075: innodb_use_fallocate does not work in MariaDB ++ Server 10.1.21 ++ * Refresh patches on top of MariaDB 10.1.24 ++ * Fix FTBFS in tests: Add cracklib-runtime to Build-Depends ++ ++ -- Ondřej Surý Tue, 06 Jun 2017 09:25:19 +0200 ++ ++mariadb-10.1 (10.1.23-9+deb9u1) stretch; urgency=medium ++ ++ [ Ondřej Surý ] ++ * Add Breaks: cqrlog (<< 1.9.0-5~) to ensure correct upgrade order ++ (Closes: #864159) ++ ++ -- Andreas Beckmann Wed, 07 Jun 2017 21:11:23 +0200 ++ ++mariadb-10.1 (10.1.23-9) unstable; urgency=medium ++ ++ * Fix the invalid location of insserv configuration snippet ++ (Thanks Michael Biebl for catching that) ++ ++ -- Ondřej Surý Fri, 26 May 2017 09:26:33 +0200 ++ ++mariadb-10.1 (10.1.23-8) unstable; urgency=medium ++ ++ * Use /etc/insserv.conf.d/mariadb to provide $database system facility ++ (Closes: #862447) ++ ++ -- Ondřej Surý Sat, 13 May 2017 11:08:43 +0200 ++ ++mariadb-10.1 (10.1.23-7) unstable; urgency=medium ++ ++ * Remove hard Breaks/Replaces with mysql-server and mysql-client ++ * Move virtual packages from Breaks to Conflicts (Debian Policy 7.6.2) ++ ++ -- Ondřej Surý Fri, 12 May 2017 12:21:33 +0200 ++ ++mariadb-10.1 (10.1.23-6) unstable; urgency=medium ++ ++ * Also fix the same assertion failure in xtradb (Closes: #862103) ++ ++ -- Ondřej Surý Mon, 08 May 2017 19:51:47 +0200 ++ ++mariadb-10.1 (10.1.23-5) unstable; urgency=medium ++ ++ * Add upstream patch to fix assertion failure in InnoDB storage engine ++ (Closes: #862103) ++ ++ -- Ondřej Surý Mon, 08 May 2017 17:21:55 +0200 ++ ++mariadb-10.1 (10.1.23-4) unstable; urgency=medium ++ ++ * Properly declare conflict on mytop (Closes: #861913) ++ ++ -- Ondřej Surý Mon, 08 May 2017 11:31:13 +0200 ++ ++mariadb-10.1 (10.1.23-3) unstable; urgency=medium ++ ++ * Remove two internal symbols (ll2str and longlong2str) from ++ kfrebsd-amd64 symbols file ++ ++ -- Ondřej Surý Thu, 04 May 2017 13:19:00 +0200 ++ ++mariadb-10.1 (10.1.23-2) unstable; urgency=medium ++ ++ * Add CVE list for 10.1.23 release ++ * Fix FTBFS on kfrebsd-any due missing .service files ++ ++ -- Ondřej Surý Thu, 04 May 2017 10:55:06 +0200 ++ ++mariadb-10.1 (10.1.23-1) unstable; urgency=medium ++ ++ * New upstream version 10.1.23, includes fixes for the following ++ security vulnerabilities: ++ - [CVE-2017-3302]: use-after-free in C client library for MySQL ++ - [CVE-2017-3313]: unauthorized (local) access to critical data or ++ complete access to all MySQL Server accessible data ++ - [CVE-2017-3308]: unauthorized (network) ability to cause a hang or ++ frequently repeatable crash ++ - [CVE-2017-3309]: unauthorized (network) ability to cause a hang or ++ frequently repeatable crash ++ - [CVE-2017-3453]: unauthorized (network) ability to cause a hang or ++ frequently repeatable crash ++ - [CVE-2017-3456]: unauthorized (network) ability to cause a hang or ++ frequently repeatable crash ++ - [CVE-2017-3464]: unauthorized update, insert or delete access to some ++ of MySQL Server accessible data ++ * Refresh debian/patches on top of MariaDB 10.1.23 release ++ * debian/gbp.conf: Filter most common cruft in the orig tarball ++ * debian/rules: Use --fail-missing to catch extra upstream files ++ * debian/*.manpages: Merge into debian/*.install ++ * debian/*.install: Add few missing binaries into various packages ++ * Declare mariadb-plugin-tokudb as available only on (linux-)amd64 ++ to fix FTBFS on kfreebsd-amd64 ++ * Remove the extra sanity check as it is already there via standard ++ dh_installinit (|| exit 0) (Closes: #861782) ++ * Stop /usr/sbin/mysqld in prerm script even with systemd ++ * Move mariadb.pc into proper multiarch directory (Closes: #852621) ++ * Add libarchive-dev needed by mariabackup to Build-Depends ++ * debian/control: run wrap-and-sort -a ++ * Move mysql_install_db from mariadb-server-10.1 to ++ mariadb-server-core-10.1 (Closes: #840646) ++ * Add Provides: $database to mysql.init - this partially addresses ++ #852776 ++ * Call dh_systemd_start with --no-restart-after-upgrade ++ (Closes: #853137) ++ * d/rules: Remove dh_prep override (legacy cruft) ++ ++ -- Ondřej Surý Thu, 04 May 2017 07:23:23 +0200 ++ ++mariadb-10.1 (10.1.22-4) unstable; urgency=medium ++ ++ * Fix small typo in d/rules that caused MySQL version suffix to not ++ contain information about Debian build ++ ++ -- Ondřej Surý Sat, 29 Apr 2017 21:56:23 +0200 ++ ++mariadb-10.1 (10.1.22-3) unstable; urgency=medium ++ ++ * Use pidof instead of pgrep, so we don't have to depend on procps ++ * Stop stopping mariadb server that many times and just add a simple ++ check to preinst that it has been really stopped (Closes: #852495) ++ * Fix small typo in gettid patch ++ * Disable TokuDB on kfreebsd-amd64 ++ ++ -- Ondřej Surý Tue, 28 Mar 2017 22:59:06 +0200 ++ ++mariadb-10.1 (10.1.22-2) unstable; urgency=medium ++ ++ [ Ondřej Surý ] ++ * Add correct kfreebsd-i386 symbols file (but this needs to be fixed in ++ how upstream uses linker) ++ * Update italian translation (Closes: #858300) ++ ++ [ Otto Kekäläinen ] ++ * Add Vietnamese translation by Trần Ngọc Quân ++ * Add Finnish translation by Antti Järvinen ++ ++ [ Ondřej Surý ] ++ * Disable test suite on hppa, don't fail test suite on more unstable ++ platforms: alpha, powerpc, and x32 ++ * Add swedish debconf translation (Closes: #858536) ++ * Add Catalan debconf translation (Closes: #858632) ++ * Use thr_self() as gettid implementation onf __FreeBSD_kernel__ ++ * Make mariadb-server-10.1 installable on kFreeBSD and Hurd (Closes: #851687) ++ * Update Turkish debconf translation (Closes: #858340) ++ * Disable specific tests on hppa to make the build succeed (Courtesy of ++ John David Anglin) (Closes: #858869) ++ ++ -- Ondřej Surý Tue, 28 Mar 2017 22:59:01 +0200 ++ ++mariadb-10.1 (10.1.22-1) unstable; urgency=high ++ ++ [ Otto Kekäläinen ] ++ * New upstream release 10.1.22. Includes fixes for the following ++ security vulnerabilities: ++ - CVE-2017-3313 ++ - CVE-2017-3302 ++ * New upstream also includes fix to logrotate so that it no longer ++ risks interrupting binary/relay log processing on the server. ++ https://github.com/MariaDB/server/commit/156cf86defdc59353f37f6 ++ * Add a NEWS.Debian item with same contents as the Stretch release notes ++ ++ [ Ondřej Surý ] ++ * Add myself to Uploaders ++ * Use https URI for Homepage ++ * Use /usr/share/dpkg/default.mk to define dpkg-architecture and other ++ build variables ++ * Install and use non-versioned symbols files for kFreeBSD and Hurd ++ architectures ++ * Make mysql_config and mariadb.pc return -lmariadbclient instead of ++ missing -lmysqlclient ++ * Add mysqlclient.pc -> mariadb.pc symlink into ++ libmariadbclient-dev-compat package ++ * MDEV-11884: Fix logrotate failing if mysqld is not running (Closes: #830976) ++ ++ -- Ondřej Surý Sun, 19 Mar 2017 15:23:26 +0100 ++ ++mariadb-10.1 (10.1.21-5) unstable; urgency=low ++ ++ [ James Clarke ] ++ * Make debian/mariadb-server-10.1.install executable (Closes: #852728) ++ * Allow mariadb-plugin-tokudb/mroonga on non-linux and non-release arches ++ * Detect whether libatomic is needed rather than hard-coding for mips ++ * Use host architecture, not build architecture, and clean up variables ++ * General clean-up in d/rules ++ ++ -- Otto Kekäläinen Fri, 27 Jan 2017 20:42:36 +0200 ++ ++mariadb-10.1 (10.1.21-4) unstable; urgency=low ++ ++ * Hotfix to full build failure: Add missing galera_new_cluster.1 to patch ++ ++ -- Otto Kekäläinen Thu, 26 Jan 2017 23:33:32 +0200 ++ ++mariadb-10.1 (10.1.21-3) unstable; urgency=low ++ ++ [ Ian Gilfillan ] ++ * Extend WSREP and Galera man pages patch to cover all commands ++ ++ [ Dieter Adriaenssens ] ++ * Specify Architecture for mariadb-plugin-mroonga and mariadb-plugin-tokudb ++ (Closes: #852709) ++ ++ [ James Clarke ] ++ * Fix FTBFS on non-Linux architectures (Closes: #852728) ++ ++ -- Otto Kekäläinen Thu, 26 Jan 2017 22:18:26 +0200 ++ ++mariadb-10.1 (10.1.21-2) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Implement systemd packaging the Debian way ++ * Extend README.Debian regarding new systemd files ++ * Add config file comments about SysV init and systemd differences ++ * Extend Debian.README with section about mixing with packages MariaDB.org ++ * Update /etc/init.d/mysql after comparison with upstream MariaDB 10.1.21 ++ * Run chown much faster on the datadir during install/update ++ * Check if /var/lib/mysql exists before running 'find' on it ++ * Skip mysqld stopping if no mysqld process is running at all ++ * Update French debconf translation by Baptiste Jammet (Closes: #850066) ++ * Remove unnecessary XS-Testsuite field (as instructed by Lintian) ++ * Add a modified version of upstream autobake-deb script to utilize CI tools ++ * Fix server config example on how to enable SSL with YaSSL (Closes: #851132) ++ * Make commands mariadb and mariadbcheck available with symlinks ++ ++ [ Jean Weisbuch ] ++ * Update Innotop to latest version ++ ++ [ Ian Gilfillan ] ++ * Add wsrep_* man pages ++ ++ -- Otto Kekäläinen Wed, 25 Jan 2017 10:42:45 +0200 ++ ++mariadb-10.1 (10.1.21-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * New upstream release 10.0.28. Includes fixes for the following ++ security vulnerabilities (Closes: #851759, Closes: ##849435): ++ - CVE-2017-3318 ++ - CVE-2017-3317 ++ - CVE-2017-3312 ++ - CVE-2017-3291 ++ - CVE-2017-3265 ++ - CVE-2017-3258 ++ - CVE-2017-3257 ++ - CVE-2017-3244 ++ - CVE-2017-3243 ++ - CVE-2017-3238 ++ - CVE-2016-6664 ++ * Add new program introduced in upstream 10.1.21: mysqld_safe_helper ++ * Deb-CI: remove parameter --skip-ndbcluster not available in 10.1 any more ++ * Make libmariadbclient18 depend on mysql-common only (Closes: #850216) ++ * Fix misleading config file comment (Closes: #677223) ++ * Update preinst variable $this_version from 10.0 to 10.1 (Closes: #851257) ++ ++ [ Kristian Nielsen ] ++ * Re-implement passwordless root login (Closes: #851131) ++ ++ -- Otto Kekäläinen Thu, 19 Jan 2017 11:33:01 +0200 ++ ++mariadb-10.1 (10.1.20-3) unstable; urgency=low ++ ++ [ Vicențiu Ciorbaru ] ++ * Update debian rules to also account for mipsel ++ ++ -- Otto Kekäläinen Sat, 24 Dec 2016 20:23:23 +0200 ++ ++mariadb-10.1 (10.1.20-2) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Upload to unstable ++ * Previous version string should had been ~exp1, thus this ++ first upload to unstable is -2 and not -1 as normal ++ * Disable test suite temporairly due to false regressions ++ ++ [ Dieter Adriaenssens ] ++ * fix Vcs-git link format and repo name ++ * update 10.0 to 10.1 in README files ++ ++ [ Vicențiu Ciorbaru ] ++ * Fix mips missing atomics primitives ++ ++ -- Otto Kekäläinen Sat, 24 Dec 2016 09:54:59 +0200 ++ ++mariadb-10.1 (10.1.20-1) experimental; urgency=low ++ ++ * Upgrade package to new MariaDB 10.1.x series: ++ - New upstream release 10.1.20 ++ - Refresh patches after 10.1.20 import ++ - Update strings 10.0 -> 10.1 after importing 10.1.20 ++ - Refresh patches after 10.1.20 import ++ - Update d/control after 10.1 import ++ - Use https protected git url in d/control ++ - Backwards compatible XS-Testsuite syntax in d/control ++ - Import debian/* changes done in upstream 10.1 ++ - Replace deprecated iproute with iproute2 ++ - Remove unnecessary dependencies as packages are Essential anyway ++ - Remove unnecessary and big file mysql_embedded ++ - Switch to 10.1 style build flag for unix socket auth module in d/rules ++ - Update d/copyright after 10.1 import ++ - Add missing aria_add_gis_sp.sql to mariadb-server-10.1 ++ - Ship SELinux and AppArmor files with the server, but as inactive ++ - New package from upstream 10.1: GSS API (Kerberos) client and server ++ - Extend GSSAPI plugin descriptions to satisfy Lintian ++ - New plugin from upstream 10.1: Cracklib password validation ++ ++ -- Otto Kekäläinen Tue, 20 Dec 2016 22:46:59 +0200 ++ ++mariadb-10.0 (10.0.28-3) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Move libmariadbd and -dev next to each other for a more logical flow in d/control ++ * Move mariadb-test to last in file for a more logical flow in d/control ++ * Clean away unused Lintian overrides ++ * Add Lintian override for impossible mysql_config multi-arch requirement ++ * Update Debian copyright based on the 2016 git log author list ++ * Remove unnecessary /var/lib/mysql-upgrade (Closes: #848620) ++ ++ [ Vicențiu Ciorbaru ] ++ * Fix connect.upd test in armhf ++ * Fix mroonga/storage.index_read_multiple_double test in armhf ++ ++ -- Otto Kekäläinen Tue, 20 Dec 2016 21:59:47 +0200 ++ ++mariadb-10.0 (10.0.28-2) unstable; urgency=low ++ ++ [ Samuel Thibault ] ++ * patches/hurd_socket.patch: Also avoid non-working socket path length check ++ on hurd-i386. ++ * rules: Drop symbols on hurd-i386 too (Closes: #842696). ++ ++ [ Daniel Black ] ++ * Don't install private mysql header files in libmariadbclient-dev ++ ++ [ Otto Kekäläinen ] ++ * Update libmariadbd18 description and contents to match latest upstream ++ * Mark missing Multi-Arch as suggested by Multiarch hinter ++ * Move plugins to $ARCH/*/mariadb18 to meet multiarch needs (Closes: #739452) ++ ++ -- Otto Kekäläinen Fri, 11 Nov 2016 22:03:33 +0200 ++ ++mariadb-10.0 (10.0.28-1) unstable; urgency=low ++ ++ [ Vicențiu Ciorbaru ] ++ * Fix tokudb jemalloc linking ++ ++ [ Otto Kekäläinen ] ++ * New upstream release 10.0.28. Includes fixes for the following ++ security vulnerabilities: ++ - CVE-2016-8283 ++ - CVE-2016-7440 ++ - CVE-2016-6663 ++ - CVE-2016-5629 ++ - CVE-2016-5626 ++ - CVE-2016-5624 ++ - CVE-2016-5616 ++ - CVE-2016-5584 ++ - CVE-2016-3492 ++ * Drop 4 patches that have been applied upstream. ++ * Delete runnable files from mariadb-test-data as they were only ++ needed at build time to generate tests. ++ ++ -- Otto Kekäläinen Fri, 28 Oct 2016 22:51:14 +0300 ++ ++mariadb-10.0 (10.0.27-2) unstable; urgency=low ++ ++ [ Dieter Adriaenssens ] ++ * Fix typo in README.Contributor ++ * Improve documentation on how to clean the build env ++ ++ [ James Cowgill ] ++ * Mips build and testsuite fixes (Closes: #838557, Closes: #838914) ++ - Permit 93 as a valid value of the ENOTEMPTY error in the testsuite ++ - Correctly fix mips64 multiplication in taocrypt ++ - Ensure groonga is built with libatomic ++ - Handle unaligned buffers in connect's TYPBLK class ++ - Fix DEFAULT_MACHINE on mips ++ - Remove various tests from unstable-tests which now pass on MIPS ++ - Update debian/unstable-tests.mips* ++ ++ [ Kristian Nielsen ] ++ * Fix missing path for perl in autopkgtest (Closes: #809022) ++ * Fix test failures on hppa due to wrong enoempty (Closes: #837369) ++ ++ -- Otto Kekäläinen Sun, 02 Oct 2016 09:22:59 +0300 ++ ++mariadb-10.0 (10.0.27-1) unstable; urgency=low ++ ++ * New upstream release 10.0.27 ++ * Remove 3 patches after 10.0.27 import as they have been applied ++ upstream. ++ ++ -- Otto Kekäläinen Wed, 07 Sep 2016 23:05:28 +0300 ++ ++mariadb-10.0 (10.0.26-3) unstable; urgency=low ++ ++ [ Dieter Adriaenssens ] ++ * Add DEP-12 formatted upstream metadata file (Closes: #808421) ++ ++ [ Vicențiu Ciorbaru ] ++ * Update innodb_xtradb patch to introduce memory barrier after lock ++ * Fix failing shutdown with gcc v6 ++ ++ [ Otto Kekäläinen ] ++ * Extend commit d5af196 with old name of package libmariadb-dev-compat ++ * Extend commit 8d2a7c9 and actually install the tokuftdump man page ++ * Update mariadb-test dependencies to include also libmariadbclient18 ++ * Add path to fix for sporadically failing test main.information_schema_stats ++ * d/rules: NUMJOBS must have a default value ++ ++ -- Otto Kekäläinen Wed, 17 Aug 2016 00:31:02 +0300 ++ ++mariadb-10.0 (10.0.26-2) unstable; urgency=low ++ ++ [ Vicențiu Ciorbaru ] ++ * Add patch to correctly revert changes from 10.0.26 that caused ++ build failure regression on PPC64el ++ ++ [ Paul Gevers ] ++ * Add autopkg tests for MariaDB 10.0 (Closes: #809022) ++ ++ [ Axel Beckert ] ++ * Extend mariadb-server to purge gracefully if datadir is a mountpoint ++ (Closes: #829491) ++ ++ [ Ian Gilfillan ] ++ * Add a patch to provide a man page for tokuftdump ++ ++ [ Robie Basak ] ++ * Re-add libmariadbclient18 and libmariadbclient-dev ++ * Add libmariadbclient-dev-compat package ++ ++ [ Otto Kekäläinen ] ++ * d/control: libmariadbclient18 must be 'Multi-Arch: same' ++ * Make libmariadbclient-dev-compat conflict with libmariadb-dev-compat ++ (Closes: #831229) ++ * Add libmariadbclient-dev as dependency for libmariadbd-dev ++ * Replace hacky sed of libmysqlclient->libmariadbclient with proper patch ++ * Update symbols file to match newest libmariadbclient18 ++ * Updated Danish translation by Joe Hansen (Closes: #830592) ++ * Remove mariadb-plugin-cassandra until libthrif-dev lands in unstable ++ * Make libdbd-mysql-perl and friends Recommends instead of strict Depends ++ (Closes: #793787) ++ * Documentation and spelling fixes ++ * Remove mysqlbug binary as it is not used for MariaDB ++ * Update default config files with more secure TLS examples ++ ++ -- Otto Kekäläinen Fri, 29 Jul 2016 21:42:50 +0300 ++ ++mariadb-10.0 (10.0.26-1) unstable; urgency=low ++ ++ * Updated French translation by Baptiste Jammet (Closes: #826879) ++ * New upstream release 10.0.26. Includes fixes for the following ++ security vulnerabilities: ++ - CVE-2016-5440 ++ - CVE-2016-3615 ++ - CVE-2016-3521 ++ - CVE-2016-3477 ++ * Updated old changelog entries to include new CVE identifiers. ++ * Refresh patches after 10.0.26 import ++ ++ -- Otto Kekäläinen Fri, 24 Jun 2016 17:05:44 +0300 ++ ++mariadb-10.0 (10.0.25-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Revert previous changes tailored for Ubuntu 16.04 compatibility. ++ * New upstream release 10.0.25. Includes fixes for the following ++ security vulnerabilities (Closes: #823325): ++ - CVE-2016-0666 ++ - CVE-2016-0655 ++ - CVE-2016-0648 ++ - CVE-2016-0647 ++ - CVE-2016-0643 ++ - CVE-2016-5444 ++ - CVE-2016-3459 ++ - CVE-2016-3452 ++ * Updated old changelog entries to include new CVE identifiers. ++ * Upstream included changes to logrotate script that supports systems that ++ has multiple mysqld processes running (Closes: #810968). ++ * Updated Dutch translation by Frans Spiesschaert (Closes: #822894). ++ * Updated Spanish translation by Javier Fernández-Sanguino Peña ++ (Closes: #823099). ++ * Updated Russian translation by Yuri Kozlov (Closes: #823422). ++ * Updated German translation by Chris Leick (Closes: #824487). ++ * Updated Brazilian Portuguese translation (Closes: #824644). ++ * Updated Turkish translation by Atila KOÇ (Closes: #825802). ++ * Add patch to provide passwordless root accounts for test suite. ++ * Updated Japanese translation by Takuma Yamada (Closes: #825813). ++ ++ [ Vicențiu Ciorbaru ] ++ * Backport upstream MDEV-9479 fix: oqgraph fails to build with boost 1.60 ++ ++ -- Otto Kekäläinen Mon, 30 May 2016 22:43:30 +0300 ++ ++mariadb-10.0 (10.0.24-7) unstable; urgency=low ++ ++ * Temporarily remove mariadb-plugin-cassandra as Debian FTP bot thinks ++ it wasn't there before 10.0.24-6 and put the package in the NEW queue. ++ ++ -- Otto Kekäläinen Wed, 13 Apr 2016 13:24:28 +0300 ++ ++mariadb-10.0 (10.0.24-6) unstable; urgency=low ++ ++ * Move mysql_embedded from client package to client-core package, ++ equally as is in mysql-client-core-5.6 and -5.7 (LP: #1568077). ++ * Add breaks/replaces for mariadb-client to accommodate the above. ++ * Add conflicts/breaks/replaces for MySQL 5.7 series packages now ++ when mysql-5.7 entered the Ubuntu repositories (LP: #1568285). ++ * Detect properly if there is an incompatible data directory from 5.7, ++ save it to another location and initialize a new data directory so that the ++ installation can complete properly without leaving dpkg in an inconsistent ++ state. ++ * Remove all old passwordless root account lines to close a potential ++ security vulnerability (LP: #1561062). ++ ++ -- Otto Kekäläinen Wed, 13 Apr 2016 10:56:10 +0300 ++ ++mariadb-10.0 (10.0.24-5) unstable; urgency=low ++ ++ * Disable sporadically failing rpl_binlog_index test on PowerPC. ++ * Disable another sporadic on amd64 and update all Jira links. ++ * Fix typo in Mroonga prerm script. ++ ++ -- Otto Kekäläinen Sat, 12 Mar 2016 10:08:23 +0200 ++ ++mariadb-10.0 (10.0.24-4) unstable; urgency=low ++ ++ * Update contributor documentation to match git-buildpackage version in sid. ++ * Add libxml and unixOBDC as build-depends for ConnectSE as done by in ++ upstream (Closes: #814944). ++ * Upload to via NEW as mariadb-10.0 was accidentally removed from Debian ++ unstable archives. ++ ++ -- Otto Kekäläinen Thu, 10 Mar 2016 18:40:51 +0200 ++ ++mariadb-10.0 (10.0.24-3) unstable; urgency=low ++ ++ * Fix typo in rules file about Mroonga control section ++ * Add main.delayed test exception to more platforms ++ * Install mysql_embedded man page correctly ++ ++ -- Otto Kekäläinen Sun, 06 Mar 2016 22:20:52 +0200 ++ ++mariadb-10.0 (10.0.24-2) unstable; urgency=low ++ ++ * Make new plugin packages breaks+replaces mariadb-server-10.0 as ++ the files used to reside there (Closes: #815377). ++ * Disable main.delayed that has been confirmed to be a false positive ++ caused by built platform resource limits. ++ * Disable multiple s390x tests that only fail on Ubuntu/Launchpad and ++ cannot be reproduced anywhere else. ++ ++ -- Otto Kekäläinen Fri, 04 Mar 2016 08:38:25 +0200 ++ ++mariadb-10.0 (10.0.24-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * New upstream release 10.0.24 ++ - Drop auth_socket patches as MDEV-8375 was partially fixed upstream ++ - Refresh other patches ++ * New upstream release includes fixes for the following security ++ vulnerabilities: ++ - CVE-2016-0668 ++ - CVE-2016-0650 ++ - CVE-2016-0649 ++ - CVE-2016-0646 ++ - CVE-2016-0644 ++ - CVE-2016-0641 ++ - CVE-2016-0640 ++ * Update filenames in d/copyright ++ ++ [ Ian Gilfillan ] ++ * Add missing mysql_embedded man page ++ ++ -- Otto Kekäläinen Sat, 20 Feb 2016 14:23:50 +0200 ++ ++mariadb-10.0 (10.0.23-3) unstable; urgency=low ++ ++ * Add Lintian overrides for TokuDB sources that indeed need autotools files ++ * Split TokuDB, Mroonga, Spider and Cassandra into their own packages and ++ start using new naming scheme 'mariadb-plugin-xzy' and rename existing ++ Connect and OQGraph packages accordingly (Closes: #773727) ++ * There is no need for mariadb-test packages to contain the version in the ++ package name, so remove it. It only makes sense to keep the version number ++ in the client and server packages, which users actually want to pin to. ++ * Update standards version ++ ++ -- Otto Kekäläinen Tue, 26 Jan 2016 11:34:48 +0200 ++ ++mariadb-10.0 (10.0.23-2) unstable; urgency=low ++ ++ * Skip unstable Spider tests on Launchpad s390x builds ++ * Extend install lists with missing files after reviewing the list ++ of files produced by the build process ++ * Update server README.Debian to match current unix socekt authentication ++ * Lintian fixes and more updates to TokuDB plugin copyright paths ++ * Move mysql_upgrade to server core package so that Akonadi and similar ++ core package consumers can upgrade the database. Also update control file ++ with breaks/replaces to allow smooth upgrades (Closes: #793977). ++ * Update slow_query_log_file configuration syntax to match upstream's. Also ++ fixes #677222 in MariaDB packages. ++ * Rename and install Apport hook correctly ++ * Remove Taocrypt workaround fixed upstream long since #627208 ++ * Removed CFLAGS and CXXFLAGS as suggested by Lars Tangvald and also done ++ in mysql-5.6 packaging commit id 16a64e810e28f1d0b66ede274cd4c2b1a425fecb ++ * Unmask the systemd mysql.service if left behind by a mysql-server-5.6 ++ installation, otherwise the MariaDB service would remain masked too. ++ * Add gdb to build-deps as suggested in #627208 to get automatic stack traces ++ * Updated Turkish translation by Atila KOÇ (Closes: #811414) ++ ++ -- Otto Kekäläinen Sat, 23 Jan 2016 23:07:15 +0200 ++ ++mariadb-10.0 (10.0.23-1) unstable; urgency=low ++ ++ * New upstream release 10.0.23. Includes fixes for the following ++ security vulnerabilities: ++ - CVE-2016-2047 ++ - CVE-2016-0651 ++ - CVE-2016-0642 ++ - CVE-2016-0616 ++ - CVE-2016-0609 ++ - CVE-2016-0608 ++ - CVE-2016-0606 ++ - CVE-2016-0600 ++ - CVE-2016-0598 ++ - CVE-2016-0597 ++ - CVE-2016-0596 ++ - CVE-2016-0546 ++ - CVE-2016-0505 ++ * Ignore test suite exit code on unstable platforms (mips, mipsel) ++ * Update TokuDB plugin install and copyright paths to match latest ++ release done under Percona ownership ++ ++ -- Otto Kekäläinen Sun, 20 Dec 2015 14:18:33 +0200 ++ ++mariadb-10.0 (10.0.22-6) unstable; urgency=low ++ ++ * Add patches to make passwordless root login default on all new ++ installs in all situations. Make auth_socket a built-in plugin. ++ * Clean up previous passwordless root implementation so that it ++ applies only to new installs and existing databases continue ++ to operate with the passwords defined in their user tables ++ * As disabled.def intrepreted test names in a special way, switch ++ back to using --skip-test-list option ++ * Make the watch file to make it better suited for the ++ git-buildpackage workflow and remove call to uupdate ++ ++ -- Otto Kekäläinen Sat, 19 Dec 2015 22:28:23 +0200 ++ ++mariadb-10.0 (10.0.22-5) unstable; urgency=low ++ ++ * Fix non-working path of unstable-test in d/rules ++ * Add unstable test for amd64 to fix reproducible builds ++ ++ -- Otto Kekäläinen Thu, 17 Dec 2015 13:31:56 +0200 ++ ++mariadb-10.0 (10.0.22-4) unstable; urgency=low ++ ++ * Upload to unstable ++ ++ -- Otto Kekäläinen Mon, 14 Dec 2015 00:49:14 +0200 ++ ++mariadb-10.0 (10.0.22-4~exp1) experimental; urgency=low ++ ++ * Rewrite unstable tests section in d/rules that was not working ++ ++ -- Otto Kekäläinen Sun, 13 Dec 2015 21:36:48 +0200 ++ ++mariadb-10.0 (10.0.22-3) unstable; urgency=low ++ ++ * Fix typo in d/rules ++ * Extend list of unstable tests for arch mips, mipsel64 and alpha ++ ++ -- Otto Kekäläinen Fri, 11 Dec 2015 21:57:23 +0200 ++ ++mariadb-10.0 (10.0.22-2) unstable; urgency=low ++ ++ * Escape d/rules file correctly to avoid parse error. ++ * Remove patches/os_sync_Free patch that is not intended for production use. ++ ++ -- Otto Kekäläinen Fri, 20 Nov 2015 23:11:09 +0200 ++ ++mariadb-10.0 (10.0.22-2~exp2) experimental; urgency=low ++ ++ [ Alexander Barkov ] ++ * Backport patch from upstream to fix MDEV-9091: mysqld crashes on shutdown ++ after running TokuDB tests on Ubuntu ++ * Backport patch from upstream to fix MDEV-8692: prefschema test failures ++ ++ [ Otto Kekäläinen ] ++ * Replace old 'make test' structure with direct call on mysql-test-run and ++ parallelize the test suite run in the Debian build. ++ * Print in build log env info to help debug builds on different platforms. ++ * Keep a list of unstable tests that are to be skipped on official builds. ++ ++ -- Otto Kekäläinen Fri, 13 Nov 2015 22:08:49 +0200 ++ ++mariadb-10.0 (10.0.22-2~exp1) experimental; urgency=low ++ ++ * Add diagnostics to find out the problem in os_sync_free() ++ * Backport fix for TokuDB crashes in build tests on Launchpad ++ and enable TokuDB builds ++ ++ -- Otto Kekäläinen Fri, 13 Nov 2015 08:54:05 +0200 ++ ++mariadb-10.0 (10.0.22-1) unstable; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * New upstream release. Includes fixes for the following security ++ vulnerabilities (Closes: #802874): ++ - CVE-2016-0610 ++ - CVE-2016-3471 ++ - CVE-2015-7744 ++ - CVE-2015-4802 ++ - CVE-2015-4807 ++ - CVE-2015-4815 ++ - CVE-2015-4826 ++ - CVE-2015-4830 ++ - CVE-2015-4836 ++ - CVE-2015-4858 ++ - CVE-2015-4861 ++ - CVE-2015-4870 ++ - CVE-2015-4913 ++ - CVE-2015-4792 ++ * New release includes updated man pages (Closes: #779992) ++ * Update the most recent patches with proper DEP-3 compliant headers ++ * Add CVE IDs to previous changelog entries ++ ++ [ Jean Weisbuch ] ++ * Update mysqlreport to version 4.0 ++ ++ [ Otto Kekäläinen ] ++ ++ -- Otto Kekäläinen Fri, 30 Oct 2015 11:42:30 +0200 ++ ++mariadb-10.0 (10.0.21-3) unstable; urgency=low ++ ++ * Updated Brazilian Portuguese translation (Closes: #798048) ++ * Upload 10.0.21 and all changes tested initially in experimental ++ to unstable. Now sensible as mysql-5.6 has entered testing. ++ ++ -- Otto Kekäläinen Fri, 18 Sep 2015 23:04:53 +0300 ++ ++mariadb-10.0 (10.0.21-2) experimental; urgency=low ++ ++ * Update gdb.conf to have tags signed by default ++ * Add CVE IDs to previous changelog entries ++ * Pass DEB_BUILD_ARCH to CMake options to enhance buils on some platforms ++ * Test suite failures are now fatal on all platforms and not ignored anywhere ++ * Revert most of commit 579282f and re-enable Mroonga ++ ++ -- Otto Kekäläinen Wed, 26 Aug 2015 18:20:54 +0300 ++ ++mariadb-10.0 (10.0.21-1) experimental; urgency=low ++ ++ [ Otto Kekäläinen ] ++ * Created libmariadbd18 and moved .so file from libmariadbd-dev there ++ * Reproducible build improvement: Add LC_ALL=C to mysql.sym sort command ++ * New upstream release. ++ - Upstream added skip_log_error to mysqld_safe config (Closes: #781945) ++ - Diffie-Helman modulus increased to 2048-bits (Closes: #788905) ++ * New upstream release fixes the following security vulnerabilities: ++ - CVE-2015-4816 ++ - CVE-2015-4819 ++ - CVE-2015-4879 ++ - CVE-2015-4895 ++ * Split mariadb-test-data-10.0 out of the main test package. This will save ++ disk space in Debian archives as the arch independent data files are ++ in one single package that can be used on all platforms and the package ++ that is built on multiple platform shrinks significantly. ++ ++ [ Jean Weisbuch ] ++ * The MYCHECK_RCPT variable can now be set from the default file. ++ * The check_for_crashed_tables() function on the debian-start script has been ++ fixed to be able to log (and email) the errors it encountered : Errors are ++ sent to stderr by the CLI while only stdout was captured by the function. ++ * The same function now also checks Aria tables along with MyISAM ones. ++ ++ -- Otto Kekäläinen Thu, 13 Aug 2015 10:08:38 +0200 ++ ++mariadb-10.0 (10.0.20-3) unstable; urgency=medium ++ ++ [ Andreas Beckmann ] ++ * mariadb-common: Depend on a version of mysql-common that ships ++ /usr/share/mysql-common/configure-symlinks. (Closes: #787533) ++ * mariadb-common.postinst: Drop fallback my.cnf symlink management. ++ * mariadb-common.preinst: Clean up my.cnf/my.cnf.old from the fallback. ++ ++ [ Otto Kekäläinen ] ++ * Clean up old cruft from rules file after review by Sergei Golubchik ++ * Unified config file layout with upstream .cnf layout ++ * Recover mysql-upgrade dir/link handlig wrongly removed in f7caa041db ++ * Minor Lintian and documentation fixes ++ * Switch 'nm -n' to 'nm --defined-only' to improve reproducible builds ++ ++ [ Olaf van der Spek ] ++ * Minor spell checking (Closes: #792123) ++ ++ [ Israel Tsadok ] ++ * Fix mariadb-server-10.0.preinst script that failed to save a new ++ /var/lib/mysql-upgrade/DATADIR.link if a previous DATADIR.link existed and ++ the /var/lib/mysql directory was a symbolic link with an absolute path ++ as target (Closes: #792918) ++ ++ [ Jean Weisbuch ] ++ * Added a Debian default file for the mariadb-server-10.0 package which allows ++ one to set the MYSQLD_STARTUP_TIMEOUT variable used in the init script ++ ++ -- Otto Kekäläinen Fri, 24 Jul 2015 23:00:00 +0300 ++ ++mariadb-10.0 (10.0.20-2) unstable; urgency=low ++ ++ * Fix bash test logic in postinstall (Closes: #789589) ++ * Add extra sort in d/rules mysqld.sym.gz command to satisfy Debian ++ reproducible build requirements ++ * Switch to utf8mb4 as default character set ++ ++ -- Otto Kekäläinen Fri, 03 Jul 2015 17:11:01 +0300 ++ ++mariadb-10.0 (10.0.20-1) unstable; urgency=low ++ ++ * New upstream release. Includes fixes for the following security ++ vulnerabilities: ++ - CVE-2015-2582 ++ - CVE-2015-2620 ++ - CVE-2015-2643 ++ - CVE-2015-2648 ++ - CVE-2015-3152: Client command line option --ssl-verify-server-cert (and ++ MYSQL_OPT_SSL_VERIFY_SERVER_CERT option of the client API) when used ++ together with --ssl will ensure that the established connection is ++ SSL-encrypted and the MariaDB server has a valid certificate. ++ - CVE-2015-4752 ++ - CVE-2015-4864 ++ * New release includes fix for memory corruption on arm64 (Closes: #787221) ++ * Added patch to enhance build reproducibility regarding the file INFO_BIN ++ ++ -- Otto Kekäläinen Fri, 19 Jun 2015 13:01:56 +0300 ++ ++mariadb-10.0 (10.0.19-1) unstable; urgency=low ++ ++ * New upstream release. Fixed the server crash caused by mysql_upgrade ++ (MDEV-8115). ++ * Upload to unstable from master branch as Jessie is not released. ++ ++ -- Otto Kekäläinen Sat, 09 May 2015 22:24:03 +0300 ++ ++mariadb-10.0 (10.0.18-1~exp1) experimental; urgency=low ++ ++ * New upstream release. Includes fixes for the following security ++ vulnerabilities: ++ - CVE-2015-4866 ++ - CVE-2014-8964 bundled PCRE contained heap-based buffer overflow ++ vulnerability that allowed the server to crash or have other unspecified ++ impact via a crafted regular expression made possible with the ++ REGEXP_SUBSTR function (MDEV-8006). ++ - CVE-2015-0501 ++ - CVE-2015-2571 ++ - CVE-2015-0505 ++ - CVE-2015-0499 ++ - CVE-2015-4757 ++ - CVE-2015-4866 ++ * Cleanup in d/copyright ++ * Make the mariadb-common depends versioned to guarantee that latest ++ config files are installed ++ ++ -- Otto Kekäläinen Thu, 07 May 2015 23:21:20 +0300 ++ ++mariadb-10.0 (10.0.17-1~exp2) experimental; urgency=low ++ ++ * d/control: Related to innochecksum manpage move, also break/replace ++ the mysql-client-5.5/6 packages (Closes: #779873) ++ * Add automatic fallback to the new /etc/mysql/my.cnf management scheme ++ for cases where mysql-common/configure-symlinks is not yet available ++ and users complain the installation ends up broken. ++ * New release confirmed to build with GCC-5 (Closes: #777996) ++ ++ -- Otto Kekäläinen Fri, 06 Mar 2015 16:42:21 +0200 ++ ++mariadb-10.0 (10.0.17-1~exp1) experimental; urgency=low ++ ++ [ Jan Wagner ] ++ * Adding mysqld_multi.server_lsb-header.patch, provides LSB headers for ++ example initscript (Closes: #778762) ++ * Adding mysqld_multi_confd.patch, makes mysqld_multi reading conf.d ++ (Closes: #778761) ++ ++ [ Robie Basak ] ++ * Move innochecksum back to mariadb-server-core-10.0 to align with other ++ variants (LP: #1421520). ++ * Fix typo in mariadb-server-10.0.postinst. ++ * Fix typo in postinst mktemp call (LP: #1420831). ++ ++ [ Arnaud Fontaine ] ++ * d/control: innochecksum manpage has been moved to mariadb-client-10.0 in ++ 10.0.13-1 (ba97056), thus add Breaks/Replaces in mariadb-client-10.0 ++ against mariadb-server-10.0 << 10.0.13-1~. ++ ++ [ Otto Kekäläinen ] ++ * Follow to new /etc/mysql/my.cnf management scheme ++ * Remove the my.cnf move command as it increases complexity too much and might ++ emit an error code if mariadb-common is upgraded before mysql-common is. ++ * Add patch to enhance build reproducibility ++ * Remove /var/log/mysql.log from logrotate. Everything should be inside ++ the mysql directory (/var/log/mysql/) and not directly on plain /var/log ++ * New upstream release. Includes fixes for the following security ++ vulnerabilities (changelog updated post release): ++ - CVE-2015-2568 ++ - CVE-2015-2573 ++ - CVE-2015-0433 ++ - CVE-2015-0441 ++ ++ -- Otto Kekäläinen Mon, 02 Mar 2015 20:01:13 +0200 ++ ++mariadb-10.0 (10.0.16-1~exp3) experimental; urgency=low ++ ++ * Update the mail.ssl test to match new cacert.pem ++ * Stop asking and setting a database root user password. Instead enable ++ the auth_socket plugin and let unix user root access MariaDB without ++ a separate password. Admins using sudo or cron scripts can use the ++ same access too, and there is no debian-sys-maint password either anymore. ++ ++ -- Otto Kekäläinen Fri, 30 Jan 2015 18:52:55 +0200 ++ ++mariadb-10.0 (10.0.16-1~exp2) experimental; urgency=low ++ ++ * Fix typo in preinstall script (Closes: #776494). ++ * Backported new cacert.pem etc from 5.5 the replace the expired ones. ++ ++ -- Otto Kekäläinen Wed, 28 Jan 2015 20:57:23 +0200 ++ ++mariadb-10.0 (10.0.16-1~exp1) experimental; urgency=low ++ ++ * New upstream release. Includes fixes for the following security ++ vulnerabilities: ++ - CVE-2015-0411 ++ - CVE-2015-0382 ++ - CVE-2015-0381 ++ - CVE-2015-0432 ++ - CVE-2014-6568 ++ - CVE-2015-0374 ++ ++ -- Otto Kekäläinen Tue, 27 Jan 2015 17:04:21 +0200 ++ ++mariadb-10.0 (10.0.15-2~exp1) experimental; urgency=low ++ ++ * Fix mariadb-server-10.0.postinst so that the flag removal will not emit ++ an error code if there are no previous debian-*.flag files. This will ++ fix a dpkg issue caught by piuparts testing. ++ * Increase the debconf downgrade warning dialog priority to critical to make ++ sure all users see it and understand why their system broke after downgrade. ++ * Attempt to fix FTBFS on mips, mipsel, powerpc introduced by upstream ++ release 10.0.15 (Closes: #772964). ++ ++ -- Otto Kekäläinen Fri, 12 Dec 2014 14:07:50 +0200 ++ ++mariadb-10.0 (10.0.15-1) unstable; urgency=low ++ ++ [ Arnaud Fontaine ] ++ * Bump libpcre3-dev Build-Depends to >= 2:8.35-3.2~ (Closes: #767903). ++ ++ [ Otto Kekäläinen } ++ * New upstream release, includes fixes for the following security issues: ++ - CVE-2014-6507 ++ - CVE-2014-6491 ++ - CVE-2014-6500 ++ - CVE-2014-6469 ++ - CVE-2014-6555 ++ - CVE-2014-6559 ++ - CVE-2014-6494 ++ - CVE-2014-6496 ++ - CVE-2014-6464 ++ * Disable on non-amd64 platforms the new Mroonga storage engine which ++ was introduced in the new upstream release. ++ * Allow mariadb-server-10.0 to overwrite file man1/mysql_plugin.1.gz in ++ mysql-client-5.5 with breaks and replaces (Closes: #771213). ++ * Clean up old debian-*.flag files from datadir to avoid unexpected ++ behavior at later upgrades (Closes: #770177). ++ ++ -- Otto Kekäläinen Tue, 25 Nov 2014 21:45:43 +0200 ++ ++mariadb-10.0 (10.0.14-4) unstable; urgency=low ++ ++ * Updated patch d/username-in-tests-replace.patch to fix the ++ obfuscation done by anti-spam measures in the MariaDB ++ commit message view (Closes: #769865). ++ * Unified indentantion to two spaces in init file for easier ++ debugging of #609537 ++ ++ -- Otto Kekäläinen Mon, 17 Nov 2014 11:45:11 +0200 ++ ++mariadb-10.0 (10.0.14-3) unstable; urgency=low ++ ++ * Added patch d/username-in-tests-replace.patch to fix ++ test failure (Closes: #769212). ++ * Added versioned dependency on libpcre3 (Closes: #767903). ++ ++ -- Otto Kekäläinen Wed, 12 Nov 2014 15:00:11 +0300 ++ ++mariadb-10.0 (10.0.14-2) unstable; urgency=low ++ ++ [ Tobias Frost ] ++ * Fix two lintian warnings in d/copyright (missing "-" between GPL and 2) ++ * Always be verbose when building the package and show compiler args ++ ++ [ Otto Kekäläinen ] ++ * Upload to unstable ++ * Updated German translation by Chris Leick and Holger Wansing ++ (Closes: #763952) ++ * Updated Dutch translation by Frans Spiesschaert (Closes: #764013) ++ * Removed libssl-dev from build dependencies in favour of using ++ bundled YaSSL instead (Closes: #761911) ++ * Fixed debconf value saving (Closes: #761452) ++ * Re-enabled TokuDB after backporting upstream fix in MDEV-6815 ++ * Removed libmariadbclient packages that provided the Debian-only ++ libmariadbclient.so library that nobody used. Instead developers are ++ encouraged to use the libraries from the package libmariadb-client-lgpl ++ instead (Closes: #739452) (Closes: #742172). ++ ++ -- Otto Kekäläinen Sat, 18 Oct 2014 19:00:11 +0300 ++ ++mariadb-10.0 (10.0.14-1) experimental; urgency=low ++ ++ * New upstream release. (Closes: #757026) ++ * d/control: Removed Provides: libmysqlclient-dev (Closes: #759309) ++ * d/control: Removed Provides: libmysqld-dev with same motivation ++ * Updated Swedish translation by Martin Bagge ++ and Anders Jonsson (Closes: #762795) ++ * Updated Spanish translation by Javier Fernandez-Sanguino (Closes: #762751) ++ * Updated Portuguese translation by Miguel Figueiredo (Closes: #763194) ++ * Updated Czech translation by Miroslav Kure (Closes: #763309) ++ ++ -- Otto Kekäläinen Thu, 28 Aug 2014 00:39:02 +0300 ++ ++mariadb-10.0 (10.0.10-1) experimental; urgency=low ++ ++ * Initial Upload (Closes: #740473) ++ ++ -- Otto Kekäläinen Tue, 01 Apr 2014 09:56:38 +0300 diff --cc debian/control index 945a11a3c,000000000..009841c7b mode 100644,000000..100644 --- a/debian/control +++ b/debian/control @@@ -1,1306 -1,0 +1,1155 @@@ +Source: mariadb +Section: database +Priority: optional - Maintainer: MariaDB Developers - Build-Depends: bison, - cmake, - cracklib-runtime , - debhelper (>= 11), - default-jdk, - dh-exec, - flex [amd64], - gdb , - libaio-dev [linux-any], - libboost-atomic-dev [amd64], - libboost-chrono-dev [amd64], - libboost-date-time-dev [amd64], - libboost-dev, - libboost-filesystem-dev [amd64], - libboost-regex-dev [amd64], - libboost-system-dev [amd64], - libboost-thread-dev [amd64], - libbz2-dev, - libcrack2-dev (>= 2.9.0), - libcurl4-openssl-dev | libcurl4-dev, - libedit-dev, - libedit-dev:native, - libfmt-dev (>= 7.0.0), - libjemalloc-dev [linux-any], - libjudy-dev, - libkrb5-dev, - liblz4-dev, - liblzma-dev, - liblzo2-dev, - libncurses-dev, - libnuma-dev [linux-any], - libpam0g-dev, - libpcre2-dev, - libsnappy-dev, - libssl-dev, - libssl-dev:native, - libsystemd-dev [linux-any], - liburing-dev [linux-any], - libxml2-dev, - libzstd-dev (>= 1.1.3), - lsb-release, - perl:any, - po-debconf, - psmisc, - unixodbc-dev, - uuid-dev, - zlib1g-dev (>= 1:1.1.3-5~) ++Maintainer: Debian MySQL Maintainers ++Uploaders: ++ Otto Kekäläinen , ++Build-Depends: ++ bison, ++ cmake, ++ cracklib-runtime , ++ debhelper-compat (= 13), ++ default-jdk, ++ dh-exec, ++ dpkg-dev (>= 1.22.5), ++ gdb , ++ libboost-dev, ++ libbz2-dev, ++ libcrack2-dev (>= 2.9.0), ++ libcurl4-openssl-dev | libcurl4-dev, ++ libedit-dev, ++ libedit-dev:native, ++ libfmt-dev (>= 10.2.2) | libfmt-dev (<< 10), ++ libjemalloc-dev [linux-any], ++ libjudy-dev, ++ libkrb5-dev, ++ liblz4-dev, ++ liblzma-dev, ++ liblzo2-dev, ++ libncurses-dev, ++ libnet-ssleay-perl , ++ libnuma-dev [linux-any], ++ libpam0g-dev, ++ libpcre2-dev, ++ libpmem-dev [amd64 arm64 ppc64el riscv64], ++ libsnappy-dev, ++ libssl-dev, ++ libssl-dev:native, ++ libsystemd-dev [linux-any], ++ liburing-dev [linux-any], ++ libxml2-dev, ++ libzstd-dev (>= 1.3.3), ++ lsb-release, ++ perl:any, ++ po-debconf, ++ psmisc, ++ unixodbc-dev, ++ uuid-dev, ++ zlib1g-dev (>= 1:1.1.3-5~), ++ zlib1g-dev:native, +Rules-Requires-Root: no - Standards-Version: 4.5.0 ++Standards-Version: 4.6.2 +Homepage: https://mariadb.org/ - Vcs-Browser: https://github.com/MariaDB/server/ - Vcs-Git: https://github.com/MariaDB/server.git ++Vcs-Browser: https://salsa.debian.org/mariadb-team/mariadb-server ++Vcs-Git: https://salsa.debian.org/mariadb-team/mariadb-server.git + +Package: libmariadb-dev +Architecture: any +Section: libdevel - Depends: libmariadb3 (= ${binary:Version}), - libssl-dev, - zlib1g-dev, - ${misc:Depends}, - ${shlibs:Depends} - Conflicts: libmariadb-dev-compat (<< 3.0.0), - libmariadbclient-dev, - libmariadbclient16-dev - Provides: libmariadbclient-dev - Breaks: libmariadb-client-lgpl-dev, - libmysqlclient-dev (<< ${source:Version}), - libmysqld-dev (<< ${source:Version}) - Replaces: libmariadb-client-lgpl-dev, - libmariadb-dev-compat (<< 3.0.0), - libmariadbclient-dev, - libmysqlclient-dev (<< ${source:Version}), - libmysqld-dev (<< ${source:Version}) ++Depends: ++ libmariadb3 (= ${binary:Version}), ++ libssl-dev, ++ zlib1g-dev, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ libmariadb-client-lgpl-dev, ++ libmariadb-dev-compat (<< ${source:Version}), ++ libmariadbclient-dev (<< 1:10.3), ++ libmysqlclient-dev, ++ libmysqld-dev (<< ${source:Version}), ++Replaces: ++ libmariadb-client-lgpl-dev, ++ libmariadb-dev-compat (<< ${source:Version}), ++ libmariadbclient-dev (<< 1:10.3), ++ libmysqlclient-dev, ++ libmysqld-dev (<< ${source:Version}), ++Conflicts: ++ libmariadbclient16-dev, ++ libmysqlclient-dev, +Description: MariaDB database development files + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . - This package includes development libraries and header files to allow sources ++ This package includes development libraries and header files. To allow sources + expecting the MariaDB Connector/C to build. Sources that expect the MySQL - client libraries should use files from the libmariadb-dev-compat package. ++ Client libraries should use files from the libmariadb-dev-compat package. + +Package: libmariadb-dev-compat +Architecture: any - Multi-Arch: same +Section: libdevel - Depends: libmariadb-dev (= ${binary:Version}), - ${misc:Depends} - Conflicts: libmariadb-client-lgpl-dev, - libmariadb-client-lgpl-dev-compat, - libmariadbclient-dev (<< ${source:Version}), - libmariadbclient-dev-compat, - libmysqlclient-dev, - libmysqlclient10-dev, - libmysqlclient12-dev, - libmysqlclient14-dev, - libmysqlclient15-dev, - libmysqlclient16-dev - Provides: libmariadb-client-lgpl-dev-compat, - libmariadbclient-dev-compat, - libmysqlclient-dev - Breaks: libmariadb-dev (<< ${source:Version}) - Replaces: libmariadb-client-lgpl-dev, - libmariadb-client-lgpl-dev-compat, - libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmariadbclient-dev-compat, - libmysqlclient-dev ++Depends: ++ libmariadb-dev (= ${binary:Version}), ++ ${misc:Depends}, ++Conflicts: ++ libmariadb-client-lgpl-dev-compat, ++ libmariadbclient-dev-compat, ++ libmysqlclient-dev, ++Provides: ++ libmariadb-client-lgpl-dev-compat, ++ libmariadbclient-dev-compat, ++Breaks: ++ libmariadb-client-lgpl-dev-compat, ++ libmariadbclient-dev (<< 1:10.3), ++ libmariadbclient-dev-compat, ++ libmysqlclient-dev, ++Replaces: ++ libmariadb-client-lgpl-dev-compat, ++ libmariadbclient-dev (<< 1:10.3), ++ libmariadbclient-dev-compat, ++ libmysqlclient-dev, +Description: MariaDB Connector/C, compatibility symlinks + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes compatibility symlinks to allow sources expecting the + MySQL client libraries to be built against MariaDB Connector/C. + +Package: libmariadb3 +Architecture: any +Multi-Arch: same +Section: libs - Depends: mariadb-common, - ${misc:Depends}, - ${shlibs:Depends} - Conflicts: libmariadbclient18 (<< 10.2.0), - mariadb-galera-server-10.0, - mariadb-galera-server-5.5, - mariadb-server-10.0, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5 - Breaks: libmariadbclient18 (<< ${source:Version}) - Replaces: libmariadbclient18 (<< ${source:Version}) ++Depends: ++ mariadb-common, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ mariadb-galera-server-10.0, ++ mariadb-galera-server-5.5, ++ mariadb-server-10.0, ++ mariadb-server-5.1, ++ mariadb-server-5.2, ++ mariadb-server-5.3, ++ mariadb-server-5.5, ++Breaks: ++ libmariadbclient18, ++Replaces: ++ libmariadbclient18, +Description: MariaDB database client library + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the client library. + - Package: libmariadb3-compat - Architecture: any - Section: libs - Depends: libmariadb3, - mariadb-common, - ${misc:Depends} - Breaks: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 - Replaces: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 - Provides: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 - Description: MariaDB database client library MySQL compat package - MariaDB is a fast, stable and true multi-user, multi-threaded SQL database - server. SQL (Structured Query Language) is the most popular database query - language in the world. The main goals of MariaDB are speed, robustness and - ease of use. - . - This package includes the client runtime libraries that simulate and replace - the equivalents found in MySQL 5.6, 5.7 and 8.0 (mysqlclient19, 20 and 21). - - Package: libmariadbclient18 - Section: libs - Architecture: any - Depends: libmariadb3 (= ${binary:Version}), - ${misc:Depends} - Replaces: libmariadbclient18 - Provides: libmariadbclient18 - Description: Virtual package to satisfy external libmariadbclient18 depends - MariaDB is a fast, stable and true multi-user, multi-threaded SQL database - server. SQL (Structured Query Language) is the most popular database query - language in the world. The main goals of MariaDB are speed, robustness and - ease of use. - . - This package provides compatibility symlinks for binaries that expect to find - libmariadbclient.so.18 will automatically use libmariadb.so.3 instead. - - Package: libmysqlclient18 - Section: libs - Architecture: any - Depends: libmariadb3 (= ${binary:Version}), - ${misc:Depends} - Replaces: libmysqlclient18 - Provides: libmysqlclient18 - Description: Virtual package to satisfy external libmysqlclient18 depends - MariaDB is a fast, stable and true multi-user, multi-threaded SQL database - server. SQL (Structured Query Language) is the most popular database query - language in the world. The main goals of MariaDB are speed, robustness and - ease of use. - . - This package provides compatibility symlinks for binaries that expect to find - libmysqlclient.so.18 will automatically use libmariadb.so.3 instead. - - Package: libmariadbd19 ++Package: libmariadbd19t64 ++Provides: ++ ${t64:Provides}, ++Replaces: ++ libmariadbd19, ++Breaks: ++ libmariadbd19 (<< ${source:Version}), +Architecture: any +Section: libs - Depends: ${misc:Depends}, - ${shlibs:Depends} - Breaks: libmariadbd-dev (<< ${source:Version}) - Replaces: libmariadbd-dev (<< ${source:Version}) ++Depends: ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Multi-Arch: same +Description: MariaDB embedded database, shared library + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes a shared library for embedded MariaDB applications. + +Package: libmariadbd-dev +Architecture: any +Section: libdevel - Provides: libmysqld-dev - Pre-Depends: ${misc:Pre-Depends} - Depends: libmariadb-dev (= ${binary:Version}), - libmariadbd19 (= ${binary:Version}), - ${misc:Depends} - Breaks: libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmysqld-dev - Replaces: libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmysqld-dev - Description: MariaDB embedded database, development files package - MariaDB is a fast, stable and true multi-user, multi-threaded SQL database - server. SQL (Structured Query Language) is the most popular database query - language in the world. The main goals of MariaDB are speed, robustness and - ease of use. - . - This package includes the MariaDB embedded server library development and header files. - - Package: mysql-common - Architecture: all - Depends: ${misc:Depends} - Description: MariaDB client common configuration files package (e.g. /etc/mysql/my.cnf) ++Provides: ++ libmysqld-dev, ++Pre-Depends: ++ ${misc:Pre-Depends}, ++Depends: ++ libmariadb-dev (= ${binary:Version}), ++ libmariadbd19t64 (= ${binary:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ libmariadb-dev (<< 1:10.4), ++ libmysqld-dev, ++Replaces: ++ libmariadb-dev (<< 1:10.4), ++ libmysqld-dev, ++Description: MariaDB embedded database, development files + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . - This package includes files needed by all versions of the client library - (e.g. /etc/mysql/my.cnf). ++ This package includes the MariaDB embedded server library development and ++ header files. + +Package: mariadb-common +Architecture: all - Depends: mysql-common (>= 5.6.25), - ${misc:Depends} ++Depends: ++ mysql-common (>= 5.6.25), ++ ${misc:Depends}, +Multi-Arch: foreign - Description: MariaDB database common files (e.g. /etc/mysql/mariadb.conf.d/) ++Description: MariaDB database common config files (/etc/mysql/mariadb.conf.d/) + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes configuration files common to all MariaDB programs. + +Package: mariadb-client-core +Architecture: any - Depends: libmariadb3 (>= 10.5.4), - mariadb-common (>= ${source:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Conflicts: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - virtual-mysql-client-core - Breaks: mariadb-client (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-cluster-community-client-plugins, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-server-server-5.7, - percona-server-server-8.0, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - percona-xtradb-cluster-server-8.0 - Replaces: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-cluster-community-client-plugins, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-server-server-5.7, - percona-server-server-8.0, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - percona-xtradb-cluster-server-8.0, - virtual-mysql-client-core - Provides: default-mysql-client-core, - virtual-mysql-client-core ++Depends: ++ libmariadb3 (>= 10.5.4), ++ mariadb-common (>= ${source:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-client-5.7, ++ mysql-client-8.0, ++ virtual-mysql-client-core, ++Breaks: ++ mariadb-client-10.0, ++ mariadb-client-core-10.0, ++ mariadb-client-core-10.1, ++ mariadb-client-core-10.2, ++ mariadb-client-core-10.3, ++ mariadb-client-core-10.4, ++ mariadb-client-core-10.5, ++ mariadb-client-core-10.6, ++ mariadb-client-core-5.5, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-core (<< ${source:Version}), ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mysql-client-core-5.5, ++ mysql-client-core-5.6, ++ mysql-client-core-5.7, ++ mysql-client-core-8.0, ++ mysql-cluster-community-client-plugins, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-server-server-5.7, ++ percona-server-server-8.0, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ percona-xtradb-cluster-server-8.0, ++Replaces: ++ mariadb-client-10.0, ++ mariadb-client-core-10.0, ++ mariadb-client-core-10.1, ++ mariadb-client-core-10.2, ++ mariadb-client-core-10.3, ++ mariadb-client-core-10.4, ++ mariadb-client-core-10.5, ++ mariadb-client-core-10.6, ++ mariadb-client-core-5.5, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-core (<< ${source:Version}), ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mysql-client-core-5.5, ++ mysql-client-core-5.6, ++ mysql-client-core-5.7, ++ mysql-client-core-8.0, ++ mysql-cluster-community-client-plugins, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-server-server-5.7, ++ percona-server-server-8.0, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ percona-xtradb-cluster-server-8.0, ++ virtual-mysql-client-core, ++Provides: ++ virtual-mysql-client-core, +Description: MariaDB database core client binaries + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the core client files, as used by Akonadi. + +Package: mariadb-client +Architecture: any - Depends: debianutils (>=1.6), - libconfig-inifiles-perl, - mariadb-client-core (>= ${source:Version}), - mariadb-common, - ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} - Conflicts: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mytop, - virtual-mysql-client - Breaks: mariadb-client-core (<< ${source:Version}), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 - Replaces: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core (<< ${source:Version}), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - mytop, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-client - Provides: default-mysql-client, - virtual-mysql-client - Recommends: libdbd-mariadb-perl | libdbd-mysql-perl, - libdbi-perl, - libterm-readkey-perl, - mariadb-client-compat ++Depends: ++ debianutils (>=1.6), ++ libconfig-inifiles-perl, ++ mariadb-client-core (>= ${source:Version}), ++ ${misc:Depends}, ++ ${perl:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ mysql-client-core-5.5, ++ mysql-client-core-5.6, ++ mysql-client-core-5.7, ++ mysql-client-core-8.0, ++ mytop, ++ virtual-mysql-client, ++Breaks: ++ mariadb-client-10.0, ++ mariadb-client-10.1, ++ mariadb-client-10.2, ++ mariadb-client-10.3, ++ mariadb-client-10.4, ++ mariadb-client-10.5, ++ mariadb-client-10.6, ++ mariadb-client-5.5, ++ mariadb-client-compat (<< ${source:Version}), ++ mariadb-client-core (<< ${source:Version}), ++ mariadb-client-core-10.0, ++ mariadb-client-core-10.1, ++ mariadb-client-core-10.2, ++ mariadb-client-core-10.3, ++ mariadb-client-core-10.4, ++ mariadb-client-core-10.5, ++ mariadb-client-core-10.6, ++ mariadb-server (<< ${source:Version}), ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-10.6, ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-client-5.7, ++ mysql-client-8.0, ++ mysql-server-5.5, ++ mysql-server-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++Replaces: ++ mariadb-client-10.0, ++ mariadb-client-10.1, ++ mariadb-client-10.2, ++ mariadb-client-10.3, ++ mariadb-client-10.4, ++ mariadb-client-10.5, ++ mariadb-client-10.6, ++ mariadb-client-5.5, ++ mariadb-client-compat (<< ${source:Version}), ++ mariadb-client-core (<< ${source:Version}), ++ mariadb-client-core-10.0, ++ mariadb-client-core-10.1, ++ mariadb-client-core-10.2, ++ mariadb-client-core-10.3, ++ mariadb-client-core-10.4, ++ mariadb-client-core-10.5, ++ mariadb-client-core-10.6, ++ mariadb-server (<< ${source:Version}), ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-10.6, ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-client-5.7, ++ mysql-client-8.0, ++ mysql-server-5.5, ++ mysql-server-5.7, ++ mysql-server-core-8.0, ++ mytop, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ virtual-mysql-client, ++Provides: ++ virtual-mysql-client, ++Recommends: ++ libdbd-mariadb-perl | libdbd-mysql-perl, ++ libdbi-perl, ++ libterm-readkey-perl, +Description: MariaDB database client binaries + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the client binaries and the additional tools + innotop and mariadb-report (mysqlreport). + +Package: mariadb-client-compat +Architecture: all - Depends: mariadb-client (>= ${source:Version}) - Conflicts: mariadb-client (<< 11.0.0), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core (<< 11.0.0), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mariadb-server (<< 11.0.0), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< 11.0.0), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-server-5.7, - mysql-server-core-8.0, - percona-server-server, - percona-server-server-5.6, - percona-xtradb-cluster-server, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 ++Depends: ++ mariadb-client (>= ${source:Version}), ++ ${misc:Depends}, ++Breaks: ++ mariadb-client (<< 1:11.0.0), ++ mariadb-client-core (<< 1:11.0.0), ++ mariadb-server (<< 1:11.0.0), ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-core (<< 1:11.0.0), ++ mysql-client (<< 5.0.51), ++ mysql-server-5.5, ++Replaces: ++ mariadb-client (<< 1:11.0.0), ++ mariadb-client-core (<< 1:11.0.0), ++ mariadb-server (<< 1:11.0.0), ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-core (<< 1:11.0.0), ++ mysql-client (<< 5.0.51), ++ mysql-server-5.5, ++Conflicts: ++ mariadb-client-10.0, ++ mariadb-client-10.1, ++ mariadb-client-10.2, ++ mariadb-client-10.3, ++ mariadb-client-10.4, ++ mariadb-client-10.5, ++ mariadb-client-10.6, ++ mariadb-client-10.7, ++ mariadb-client-10.8, ++ mariadb-client-5.1, ++ mariadb-client-5.2, ++ mariadb-client-5.3, ++ mariadb-client-5.5, ++ mariadb-client-core-10.0, ++ mariadb-client-core-10.1, ++ mariadb-client-core-10.2, ++ mariadb-client-core-10.3, ++ mariadb-client-core-10.4, ++ mariadb-client-core-10.5, ++ mariadb-client-core-10.6, ++ mariadb-client-core-10.7, ++ mariadb-client-core-10.8, ++ mariadb-client-core-5.1, ++ mariadb-client-core-5.2, ++ mariadb-client-core-5.3, ++ mariadb-client-core-5.5, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.6, ++ mariadb-server-10.7, ++ mariadb-server-10.8, ++ mariadb-server-core-10.0, ++ mariadb-server-core-10.1, ++ mariadb-server-core-10.2, ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mariadb-server-core-10.7, ++ mariadb-server-core-10.8, ++ mysql-client-5.0, ++ mysql-client-5.1, ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-client-5.7, ++ mysql-client-8.0, ++ mysql-client-core-5.0, ++ mysql-client-core-5.1, ++ mysql-client-core-5.5, ++ mysql-client-core-5.6, ++ mysql-client-core-5.7, ++ mysql-client-core-8.0, ++ mysql-server-5.7, ++ mysql-server-core-8.0, ++ percona-server-server, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, +Multi-Arch: foreign - Description: MySQL compatibility links to mariadb-client binaries/scripts. ++Description: MySQL compatibility links to mariadb-client binaries/scripts + The package contains links and binaries that are needed by MySQL centric + tools which also works with MariaDB. + . - This package is also useful for users with strong background in MySQL - maintenance, but wants to switch to MariaDB ++ This package is also useful for users with long background in MySQL ++ maintenance who wants to switch to MariaDB but wants to continue using ++ familiar 'mysql' command-line tools instead of their MariaDB equivalents. + +Package: mariadb-server-core +Architecture: any - Depends: mariadb-common (>= ${source:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Conflicts: mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-server-5.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - virtual-mysql-server-core - Breaks: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 - Replaces: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-client-5.5, - mysql-server-5.0, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-server-core - Provides: default-mysql-server-core, - virtual-mysql-server-core ++Depends: ++ mariadb-common (>= ${source:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ mariadb-galera-server-5.5, ++ mysql-server-5.5, ++ mysql-server-5.6, ++ mysql-server-5.7, ++ mysql-server-8.0, ++ virtual-mysql-server-core, ++Breaks: ++ mariadb-client-10.1, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-core-10.0, ++ mariadb-server-core-10.1, ++ mariadb-server-core-10.2, ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mariadb-server-core-5.5, ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++Replaces: ++ mariadb-client-10.1, ++ mariadb-server (<< ${source:Version}), ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-10.6, ++ mariadb-server-core-10.0, ++ mariadb-server-core-10.1, ++ mariadb-server-core-10.2, ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mariadb-server-core-5.5, ++ mysql-client-5.5, ++ mysql-client-5.6, ++ mysql-client-5.7, ++ mysql-client-8.0, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ virtual-mysql-server-core, ++Provides: ++ virtual-mysql-server-core, +Description: MariaDB database core server files + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the core server files, as used by Akonadi. + +Package: mariadb-server +Architecture: any - Suggests: mailx, - mariadb-test, - netcat-openbsd - Recommends: libhtml-template-perl, - mariadb-server-compat, - pv - Pre-Depends: adduser (>= 3.40), - debconf, - mariadb-common (>= ${source:Version}) - Depends: galera-4 (>= 26.4), - gawk, - iproute2 [linux-any], - libdbi-perl, - lsof [linux-any], - mariadb-client (>= ${source:Version}), - mariadb-server-core (>= ${source:Version}), - passwd, - perl (>= 5.6), - procps, - psmisc, - rsync, - socat, - ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} - Conflicts: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-8.0, - mysql-server, - mysql-server-4.1, - mysql-server-5.0, - mysql-server-5.1, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - virtual-mysql-server - Breaks: handlersocket-mysql-5.5, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 - Replaces: handlersocket-mysql-5.5, - libmariadbclient-dev (<< 5.5.0), - libmariadbclient16, - mariadb-client (<< ${source:Version}), - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-8.0, - mysql-server, - mysql-server-4.1, - mysql-server-5.0, - mysql-server-5.1, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-server - Provides: default-mysql-server, - virtual-mysql-server ++Suggests: ++ mailx, ++ mariadb-test, ++ netcat-openbsd, ++Recommends: ++ libhtml-template-perl, ++ mariadb-plugin-provider-bzip2, ++ mariadb-plugin-provider-lz4, ++ mariadb-plugin-provider-lzma, ++ mariadb-plugin-provider-lzo, ++ mariadb-plugin-provider-snappy, ++ pv, ++Pre-Depends: ++ adduser (>= 3.40), ++ debconf, ++ mariadb-common (>= ${source:Version}), ++ ${misc:Pre-Depends}, ++Depends: ++ galera-4 (>= 26.4), ++ gawk, ++ iproute2 [linux-any], ++ libdbi-perl, ++ lsof [linux-any], ++ mariadb-client (>= ${source:Version}), ++ mariadb-server-core (>= ${server:Version}), ++ passwd, ++ perl (>= 5.6), ++ procps, ++ psmisc, ++ rsync, ++ socat, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ handlersocket-mysql-5.5, ++ mariadb-tokudb-engine-10.0, ++ mariadb-tokudb-engine-10.1, ++ mariadb-tokudb-engine-5.5, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ virtual-mysql-server, ++Breaks: ++ cqrlog (<< 1.9.0-5~), ++ galera-3 (<< 26.4), ++ handlersocket-mysql-5.5, ++ mariadb-galera-server, ++ mariadb-galera-server-10.0, ++ mariadb-galera-server-5.5, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-10.6, ++ mariadb-server-5.5, ++ mariadb-tokudb-engine-10.0, ++ mariadb-tokudb-engine-10.1, ++ mariadb-tokudb-engine-5.5, ++ mysql-client-5.5, ++ mysql-client-5.7, ++ mysql-client-core-8.0, ++ mysql-server-5.5, ++ mysql-server-5.6, ++ mysql-server-5.7, ++ mysql-server-8.0, ++Replaces: ++ handlersocket-mysql-5.5, ++ mariadb-galera-server, ++ mariadb-galera-server-10.0, ++ mariadb-galera-server-5.5, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-10.6, ++ mariadb-server-5.5, ++ mariadb-tokudb-engine-10.0, ++ mariadb-tokudb-engine-10.1, ++ mariadb-tokudb-engine-5.5, ++ mysql-client-5.5, ++ mysql-client-5.7, ++ mysql-client-core-8.0, ++ mysql-server-5.5, ++ mysql-server-5.6, ++ mysql-server-5.7, ++ mysql-server-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ virtual-mysql-server, ++Provides: ++ virtual-mysql-server, +Description: MariaDB database server binaries + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the server binaries. + +Package: mariadb-server-compat +Architecture: all - Depends: mariadb-server (>= ${source:Version}) - Conflicts: mariadb-server (<< 11.0.0), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mariadb-server-core (<< 11.0.0), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-server-5.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server, - percona-server-server-5.6, - percona-server-server-5.7, - percona-xtradb-cluster-server, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 ++Depends: ++ mariadb-server (>= ${source:Version}), ++ ${misc:Depends}, ++Breaks: ++ mariadb-server (<< 1:11.0.0), ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-core (<< 1:11.0.0), ++ mysql-server-5.5, ++ mysql-server-5.7, ++Replaces: ++ mariadb-server (<< 1:11.0.0), ++ mariadb-server-10.5 (<< 1:10.11), ++ mariadb-server-core (<< 1:11.0.0), ++ mysql-server-5.5, ++ mysql-server-5.7, ++Conflicts: ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++ mariadb-server-10.2, ++ mariadb-server-10.3, ++ mariadb-server-10.4, ++ mariadb-server-10.6, ++ mariadb-server-10.7, ++ mariadb-server-10.8, ++ mariadb-server-5.1, ++ mariadb-server-5.2, ++ mariadb-server-5.3, ++ mariadb-server-5.5, ++ mariadb-server-core-10.0, ++ mariadb-server-core-10.1, ++ mariadb-server-core-10.2, ++ mariadb-server-core-10.3, ++ mariadb-server-core-10.4, ++ mariadb-server-core-10.5, ++ mariadb-server-core-10.6, ++ mariadb-server-core-10.7, ++ mariadb-server-core-10.8, ++ mariadb-server-core-5.1, ++ mariadb-server-core-5.2, ++ mariadb-server-core-5.3, ++ mariadb-server-core-5.5, ++ mysql-server-5.0, ++ mysql-server-core-5.0, ++ mysql-server-core-5.1, ++ mysql-server-core-5.5, ++ mysql-server-core-5.6, ++ mysql-server-core-5.7, ++ mysql-server-core-8.0, ++ percona-server-server, ++ percona-server-server-5.6, ++ percona-server-server-5.7, ++ percona-xtradb-cluster-server, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, +Multi-Arch: foreign - Description: MySQL compatibility links to mariadb-server binaries/scripts. ++Description: MySQL compatibility links to mariadb-server binaries/scripts + The package contains links and binaries that are needed by MySQL centric + tools which also works with MariaDB. + . - This package is also useful for users with strong background in MySQL - maintenance, but wants to switch to MariaDB ++ This package is also useful for users with long background in MySQL ++ maintenance who wants to switch to MariaDB but wants to continue using ++ familiar 'mysql' commands instead of their MariaDB equivalents. ++ ++Package: mariadb-server-10.5 ++Architecture: any ++Depends: ++ mariadb-server (>= 1:11.4), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Description: MariaDB database server binaries (transitional dummy package) ++ MariaDB is a fast, stable and true multi-user, multi-threaded SQL database ++ server. SQL (Structured Query Language) is the most popular database query ++ language in the world. The main goals of MariaDB are speed, robustness and ++ ease of use. ++ . ++ This package is a transitional dummy package designed to make upgrades ++ from previous MariaDB versions seamless. + +Package: mariadb-backup +Architecture: any - Breaks: mariadb-backup-10.1, - mariadb-backup-10.2, - mariadb-backup-10.3, - mariadb-client-10.1 - Replaces: mariadb-backup-10.1, - mariadb-backup-10.2, - mariadb-backup-10.3, - mariadb-client-10.1 - Depends: mariadb-client-core (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends} ++Breaks: ++ mariadb-backup-10.1, ++ mariadb-backup-10.2, ++ mariadb-backup-10.3, ++ mariadb-client-10.1, ++Replaces: ++ mariadb-backup-10.1, ++ mariadb-backup-10.2, ++ mariadb-backup-10.3, ++ mariadb-client-10.1, ++Depends: ++ mariadb-client-core (= ${binary:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: Backup tool for MariaDB server + Based on Xtrabackup, but improved to work with MariaDB server. + This backup tool is guaranteed to be compatible with MariaDB server. + . + Please refer to the MariaDB Knowledge Base on more information on + how to use this tool. + +Package: mariadb-plugin-connect +Architecture: any - Depends: libxml2, - mariadb-server (= ${server:Version}), - unixodbc, - ${misc:Depends}, - ${shlibs:Depends} - Recommends: curl - Breaks: mariadb-connect-engine-10.0, - mariadb-connect-engine-10.1, - mariadb-connect-engine-10.2, - mariadb-connect-engine-10.3, - mariadb-connect-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 - Replaces: mariadb-connect-engine-10.0, - mariadb-connect-engine-10.1, - mariadb-connect-engine-10.2, - mariadb-connect-engine-10.3, - mariadb-connect-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 - Suggests: mariadb-plugin-connect-jdbc ++Depends: ++ libxml2, ++ mariadb-server (= ${server:Version}), ++ unixodbc, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Recommends: ++ curl, ++Conflicts: ++ mariadb-connect-engine-10.0, ++ mariadb-connect-engine-10.1, ++Breaks: ++ mariadb-connect-engine-10.0, ++ mariadb-connect-engine-10.1, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++Replaces: ++ mariadb-connect-engine-10.0, ++ mariadb-connect-engine-10.1, ++ mariadb-server-10.0, ++ mariadb-server-10.1, +Description: Connect storage engine for MariaDB server + Connect engine supports a number of file formats (dbf, xml, txt, bin, etc), + connections to ODBC tables and remote MySQL tables, as well as a number of + other interesting features. + This package contains the Connect plugin for MariaDB server. + +Package: mariadb-plugin-connect-jdbc - Architecture: any - Depends: default-jre-headless - Suggests: libcsvjdbc-java, - libmariadb-java, - libpostgis-java, - libpostgresql-jdbc-java, - libxerial-sqlite-jdbc-java - Enhances: mariadb-plugin-connect - Description: Connect storage engine JDBC interface for MariaDB server. ++Architecture: all ++Depends: ++ default-jre-headless, ++ ${misc:Depends}, ++Suggests: ++ libcsvjdbc-java, ++ libmariadb-java, ++ libpostgis-java, ++ libpostgresql-jdbc-java, ++ libxerial-sqlite-jdbc-java, ++Enhances: ++ mariadb-plugin-connect, ++Description: Connect storage engine JDBC interface for MariaDB server + To connect to remote DBMS using Connect Storage Engine (SE) and JDBC driver, + there is need for JDBC interface byte code. + The JDBC driver for the remote DBMS connection is required. - This package contains the Connect SE plugin JDBC interface file for MariaDB server. ++ This package contains the Connect SE plugin JDBC interface file for MariaDB ++ server. + +Package: mariadb-plugin-s3 +Architecture: any - Depends: libcurl4, - mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (= ${server:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: Amazon S3 archival storage engine for MariaDB + The S3 storage engine allows one to archive MariaDB tables in Amazon S3 (or any + third-party public or private cloud that implements S3 API), but still have + them accessible in MariaDB in read-only mode. + +Package: mariadb-plugin-rocksdb - Architecture: amd64 arm64 mips64el ppc64el - Depends: mariadb-server (= ${server:Version}), - python3:any, - rocksdb-tools, - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-rocksdb-engine-10.2, - mariadb-rocksdb-engine-10.3, - mariadb-rocksdb-engine-10.4 - Replaces: mariadb-rocksdb-engine-10.2, - mariadb-rocksdb-engine-10.3, - mariadb-rocksdb-engine-10.4 - Recommends: python3-mysqldb ++Architecture: amd64 arm64 mips64el ppc64el riscv64 ++Depends: ++ mariadb-server (= ${server:Version}), ++ python3:any, ++ rocksdb-tools, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-rocksdb-engine-10.2, ++ mariadb-rocksdb-engine-10.3, ++Replaces: ++ mariadb-rocksdb-engine-10.2, ++ mariadb-rocksdb-engine-10.3, ++Recommends: ++ python3-mysqldb, +Description: RocksDB storage engine for MariaDB server + The RocksDB storage engine is a high performance storage engine, aimed + at maximising storage efficiency while maintaining InnoDB-like performance. + This package contains the RocksDB plugin for MariaDB server. + +Package: mariadb-plugin-oqgraph +Architecture: any - Depends: libjudydebian1, - mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-oqgraph-engine-10.0, - mariadb-oqgraph-engine-10.1, - mariadb-oqgraph-engine-10.2, - mariadb-oqgraph-engine-10.3, - mariadb-oqgraph-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 - Replaces: mariadb-oqgraph-engine-10.0, - mariadb-oqgraph-engine-10.1, - mariadb-oqgraph-engine-10.2, - mariadb-oqgraph-engine-10.3, - mariadb-oqgraph-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 ++Depends: ++ libjudydebian1, ++ mariadb-server (= ${server:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: ++ mariadb-oqgraph-engine-10.0, ++ mariadb-oqgraph-engine-10.1, ++Breaks: ++ mariadb-oqgraph-engine-10.0, ++ mariadb-oqgraph-engine-10.1, ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++Replaces: ++ mariadb-oqgraph-engine-10.0, ++ mariadb-oqgraph-engine-10.1, ++ mariadb-server-10.0, ++ mariadb-server-10.1, +Description: OQGraph storage engine for MariaDB server + The OQGraph engine is a computation engine plugin for handling hierarchies + (trees) and graphs (friend-of-a-friend, etc) cleanly through standard SQL. + This package contains the OQGraph plugin for MariaDB server. + +Package: mariadb-plugin-mroonga - Architecture: any-alpha any-amd64 any-arm any-arm64 any-i386 any-ia64 any-mips64el any-mips64r6el any-mipsel any-mipsr6el any-nios2 any-powerpcel any-ppc64el any-sh3 any-sh4 any-tilegx - Depends: mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 - Replaces: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 ++Architecture: any-alpha any-amd64 any-arm any-arm64 any-i386 any-ia64 any-mips64el any-mips64r6el any-mipsel any-mipsr6el any-nios2 any-powerpcel any-ppc64el any-sh3 any-sh4 ++Depends: ++ mariadb-server (= ${server:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++Replaces: ++ mariadb-server-10.0, ++ mariadb-server-10.1, +Description: Mroonga storage engine for MariaDB server + Mroonga (formerly named Groonga Storage Engine) is a storage engine that + provides fast CJK-ready full text searching using column store. + This package contains the Mroonga plugin for MariaDB server. + +Package: mariadb-plugin-spider +Architecture: any - Depends: mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 - Replaces: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 ++Depends: ++ mariadb-server (= ${server:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-server-10.0, ++ mariadb-server-10.1, ++Replaces: ++ mariadb-server-10.0, ++ mariadb-server-10.1, +Description: Spider storage engine for MariaDB server + The Spider storage engine with built-in sharding features. It supports + partitioning and xa transactions, and allows tables of different MariaDB server + instances to be handled as if they were on the same instance. It refers to one + possible implementation of ISO/IEC 9075-9:2008 SQL/MED. + +Package: mariadb-plugin-gssapi-server +Architecture: any - Depends: libgssapi-krb5-2, - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-gssapi-server-10.1, - mariadb-gssapi-server-10.2, - mariadb-gssapi-server-10.3, - mariadb-gssapi-server-10.4, - mariadb-server-10.0, - mariadb-server-10.1 - Replaces: mariadb-gssapi-server-10.1, - mariadb-gssapi-server-10.2, - mariadb-gssapi-server-10.3, - mariadb-gssapi-server-10.4, - mariadb-server-10.0, - mariadb-server-10.1 ++Depends: ++ libgssapi-krb5-2, ++ mariadb-server, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-gssapi-server-10.1, ++ mariadb-gssapi-server-10.2, ++Replaces: ++ mariadb-gssapi-server-10.1, ++ mariadb-gssapi-server-10.2, +Description: GSSAPI authentication plugin for MariaDB server + This plugin includes support for Kerberos on Unix, but can also be used for + Windows authentication with or without domain environment. + . + This package contains the server parts. + +Package: mariadb-plugin-gssapi-client +Architecture: any - Multi-Arch: same - Depends: libgssapi-krb5-2, - mariadb-client (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends} - Breaks: mariadb-gssapi-client-10.1, - mariadb-gssapi-client-10.2, - mariadb-gssapi-client-10.3, - mariadb-gssapi-client-10.4 - Replaces: mariadb-gssapi-client-10.1, - mariadb-gssapi-client-10.2, - mariadb-gssapi-client-10.3, - mariadb-gssapi-client-10.4 ++Depends: ++ libgssapi-krb5-2, ++ mariadb-client (= ${binary:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-gssapi-client-10.1, ++ mariadb-gssapi-client-10.2, ++Replaces: ++ mariadb-gssapi-client-10.1, ++ mariadb-gssapi-client-10.2, +Description: GSSAPI authentication plugin for MariaDB client + This plugin includes support for Kerberos on Unix, but can also be used for + Windows authentication with or without domain environment. + . + This package contains the client parts. + +Package: mariadb-plugin-cracklib-password-check +Architecture: any - Depends: libcrack2 (>= 2.9.0), - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ libcrack2 (>= 2.9.0), ++ mariadb-server (= ${server:Version}), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: CrackLib Password Validation Plugin for MariaDB server + This password validation plugin uses cracklib to allow only + sufficiently secure (as defined by cracklib) user passwords in MariaDB server. + . - Install and configure this to enforce stronger passwords for MariaDB server users. ++ Install and configure this to enforce stronger passwords for MariaDB server ++ users. + +Package: mariadb-plugin-hashicorp-key-management +Architecture: any - Depends: libcurl4, - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server, ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: Hashicorp Key Management plugin for MariaDB + This encryption plugin uses Hashicorp Vault for storing encryption + keys for MariaDB Data-at-Rest encryption. + +Package: mariadb-plugin-provider-bzip2 +Architecture: any - Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (>= 1:10.11.1-1), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: BZip2 compression support in the server and storage engines + The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, + can use different compression libraries. + . + Plugin provides BZip2 (https://sourceware.org/bzip2/) compression + . + Note that these affect InnoDB and Mroonga only; + RocksDB still uses the compression algorithms from its own library + +Package: mariadb-plugin-provider-lz4 +Architecture: any - Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (>= 1:10.11.1-1), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: LZ4 compression support in the server and storage engines + The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, + can use different compression libraries. + . + Plugin provides LZ4 (http://lz4.github.io/lz4/) compression + . + Note that these affect InnoDB and Mroonga only; + RocksDB still uses the compression algorithms from its own library + +Package: mariadb-plugin-provider-lzma +Architecture: any - Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (>= 1:10.11.1-1), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: LZMA compression support in the server and storage engines + The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, + can use different compression libraries. + . + Plugin provides LZMA (https://tukaani.org/lzma/) compression + . + Note that these affect InnoDB and Mroonga only; + RocksDB still uses the compression algorithms from its own library + +Package: mariadb-plugin-provider-lzo +Architecture: any - Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (>= 1:10.11.1-1), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: LZO compression support in the server and storage engines + The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, + can use different compression libraries. + . + Plugin provides LZO (http://www.oberhumer.com/opensource/lzo/) compression + . + Note that these affect InnoDB and Mroonga only; + RocksDB still uses the compression algorithms from its own library + +Package: mariadb-plugin-provider-snappy +Architecture: any - Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} ++Depends: ++ mariadb-server (>= 1:10.11.1-1), ++ ${misc:Depends}, ++ ${shlibs:Depends}, +Description: Snappy compression support in the server and storage engines + The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, + can use different compression libraries. + . + Plugin provides Snappy (https://github.com/google/snappy) compression + . + Note that these affect InnoDB and Mroonga only; + RocksDB still uses the compression algorithms from its own library + +Package: mariadb-test +Architecture: any - Depends: libnet-ssleay-perl, - mariadb-client (= ${binary:Version}), - mariadb-server (= ${server:Version}), - mariadb-test-data (= ${source:Version}), - virtual-mysql-testsuite, - ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} - Conflicts: mariadb-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0 - Breaks: mariadb-server-5.5, - mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-10.3, - mariadb-test-10.4, - mariadb-test-5.5, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 - Replaces: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-10.3, - mariadb-test-10.4, - mariadb-test-5.5, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-testsuite - Provides: virtual-mysql-testsuite - Suggests: patch ++Depends: ++ libnet-ssleay-perl, ++ mariadb-client (= ${binary:Version}), ++ mariadb-server (= ${server:Version}), ++ mariadb-test-data (= ${source:Version}), ++ virtual-mysql-testsuite, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-test-10.0, ++ mariadb-test-10.1, ++ mariadb-test-5.5, ++ mysql-client-5.5, ++ mysql-server-5.5, ++ mysql-server-5.7, ++ mysql-server-core-8.0, ++ mysql-testsuite, ++ mysql-testsuite-5.5, ++ mysql-testsuite-5.6, ++ mysql-testsuite-5.7, ++ mysql-testsuite-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++Replaces: ++ mariadb-test-10.0, ++ mariadb-test-10.1, ++ mariadb-test-5.5, ++ mysql-client-5.5, ++ mysql-server-5.5, ++ mysql-server-5.7, ++ mysql-server-core-8.0, ++ mysql-testsuite, ++ mysql-testsuite-5.5, ++ mysql-testsuite-5.6, ++ mysql-testsuite-5.7, ++ mysql-testsuite-8.0, ++ percona-server-server-5.6, ++ percona-xtradb-cluster-server-5.6, ++ percona-xtradb-cluster-server-5.7, ++ virtual-mysql-testsuite, ++Provides: ++ virtual-mysql-testsuite, ++Suggests: ++ patch, +Description: MariaDB database regression test suite + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package includes the regression test suite. + +Package: mariadb-test-data +Architecture: all +Multi-Arch: foreign - Depends: ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} - Breaks: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-5.5, - mariadb-test-data-10.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0 - Replaces: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-5.5, - mariadb-test-data-10.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0 ++Depends: ++ ${misc:Depends}, ++ ${perl:Depends}, ++ ${shlibs:Depends}, ++Breaks: ++ mariadb-test-10.0, ++ mariadb-test-10.1, ++ mariadb-test-5.5, ++ mariadb-test-data-10.0, ++ mysql-testsuite, ++ mysql-testsuite-5.5, ++ mysql-testsuite-5.6, ++ mysql-testsuite-5.7, ++ mysql-testsuite-8.0, ++Replaces: ++ mariadb-test-10.0, ++ mariadb-test-10.1, ++ mariadb-test-5.5, ++ mariadb-test-data-10.0, ++ mysql-testsuite, ++ mysql-testsuite-5.5, ++ mysql-testsuite-5.6, ++ mysql-testsuite-5.7, ++ mysql-testsuite-8.0, +Description: MariaDB database regression test suite - data files + MariaDB is a fast, stable and true multi-user, multi-threaded SQL database + server. SQL (Structured Query Language) is the most popular database query + language in the world. The main goals of MariaDB are speed, robustness and + ease of use. + . + This package has the architecture independent data files for the test suite. diff --cc debian/copyright index a35a25dcd,000000000..380cac364 mode 100644,000000..100644 --- a/debian/copyright +++ b/debian/copyright @@@ -1,60 -1,0 +1,1040 @@@ ++Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ ++Upstream-Name: MariaDB Server ++Upstream-Contact: https://jira.mariadb.org ++Source: https://github.com/MariaDB/server ++Comment: ++ Originally produced by a modified version of licensecheck2dep5 ++ from CDBS by Clint Byrum . Hand modified to reduce ++ redundancy in the output and add appropriate license text. The file ++ has been rechecked against the source using the development version ++ of license-reconcile, see #686485. ++ . ++ Also, MySQL carries the "FOSS License Exception" specified in README ++ . ++ Quoting from README: ++ . ++ MySQL FOSS License Exception We want free and open source ++ software applications under certain licenses to be able to use ++ specified GPL-licensed MySQL client libraries despite the fact ++ that not all such FOSS licenses are compatible with version ++ 2 of the GNU General Public License. Therefore there are ++ special exceptions to the terms and conditions of the GPLv2 ++ as applied to these client libraries, which are identified ++ and described in more detail in the FOSS License Exception at ++ . ++ . ++ The text of the Above URL is quoted below, as of Aug 17, 2011. ++ . ++ > FOSS License Exception ++ > . ++ > Updated July 1, 2010 ++ > . ++ > What is the FOSS License Exception? Oracle's Free and Open Source ++ > Software ("FOSS") License Exception (formerly known as the FLOSS ++ > License Exception) allows developers of FOSS applications to include ++ > Oracle's MySQL Client Libraries (also referred to as "MySQL Drivers" ++ > or "MySQL Connectors") with their FOSS applications. MySQL Client ++ > Libraries are typically licensed pursuant to version 2 of the General ++ > Public License ("GPL"), but this exception permits distribution of ++ > certain MySQL Client Libraries with a developer's FOSS applications ++ > licensed under the terms of another FOSS license listed below, ++ > even though such other FOSS license may be incompatible with the GPL. ++ > . ++ > The following terms and conditions describe the circumstances under ++ > which Oracle's FOSS License Exception applies. ++ > . ++ > Oracle's FOSS License Exception Terms and Conditions Definitions. ++ > "Derivative Work" means a derivative work, as defined under applicable ++ > copyright law, formed entirely from the Program and one or more ++ > FOSS Applications. ++ > . ++ > "FOSS Application" means a free and open source software application ++ > distributed subject to a license listed in the section below titled ++ > "FOSS License List." ++ > . ++ > "FOSS Notice" means a notice placed by Oracle or MySQL in a copy ++ > of the MySQL Client Libraries stating that such copy of the MySQL ++ > Client Libraries may be distributed under Oracle's or MySQL's FOSS ++ > (or FLOSS) License Exception. ++ > . ++ > "Independent Work" means portions of the Derivative Work that are not ++ > derived from the Program and can reasonably be considered independent ++ > and separate works. ++ > . ++ > "Program" means a copy of Oracle's MySQL Client Libraries that ++ > contains a FOSS Notice. ++ > . ++ > A FOSS application developer ("you" or "your") may distribute a ++ > Derivative Work provided that you and the Derivative Work meet all ++ > of the following conditions: You obey the GPL in all respects for ++ > the Program and all portions (including modifications) of the Program ++ > included in the Derivative Work (provided that this condition does not ++ > apply to Independent Works); The Derivative Work does not include any ++ > work licensed under the GPL other than the Program; You distribute ++ > Independent Works subject to a license listed in the section below ++ > titled "FOSS License List"; You distribute Independent Works in ++ > object code or executable form with the complete corresponding ++ > machine-readable source code on the same medium and under the same ++ > FOSS license applying to the object code or executable forms; All ++ > works that are aggregated with the Program or the Derivative Work ++ > on a medium or volume of storage are not derivative works of the ++ > Program, Derivative Work or FOSS Application, and must reasonably ++ > be considered independent and separate works. Oracle reserves all ++ > rights not expressly granted in these terms and conditions. If all ++ > of the above conditions are not met, then this FOSS License Exception ++ > does not apply to you or your Derivative Work. ++ > . ++ > FOSS License List ++ > . ++ > License Name Version(s)/Copyright Date ++ > Release Early Certified Software ++ > Academic Free License 2.0 ++ > Apache Software License 1.0/1.1/2.0 ++ > Apple Public Source License 2.0 ++ > Artistic license From Perl 5.8.0 ++ > BSD license "July 22 1999" ++ > Common Development and Distribution License (CDDL) 1.0 ++ > Common Public License 1.0 ++ > Eclipse Public License 1.0 ++ > European Union Public License (EUPL)[1] 1.1 ++ > GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1/3.0 ++ > GNU General Public License (GPL) 3.0 ++ > IBM Public License 1.0 ++ > Jabber Open Source License 1.0 ++ > MIT License (As listed in file MIT-License.txt) - ++ > Mozilla Public License (MPL) 1.0/1.1 ++ > Open Software License 2.0 ++ > OpenSSL license (with original SSLeay license) "2003" ("1998") ++ > PHP License 3.0/3.01 ++ > Python license (CNRI Python License) - ++ > Python Software Foundation License 2.1.1 ++ > Sleepycat License "1999" ++ > University of Illinois/NCSA Open Source License - ++ > W3C License "2001" ++ > X11 License "2001" ++ > Zlib/libpng License - ++ > Zope Public License 2.0 ++ > [1] When an Independent Work is licensed under a "Compatible License" ++ > pursuant to the EUPL, the Compatible License rather than the EUPL is ++ > the applicable license for purposes of these FOSS License Exception ++ > Terms and Conditions. ++ . ++ The above text is subject to this copyright notice: ++ © 2010, Oracle and/or its affiliates. + - == MariaDB == ++Files: * ++Copyright: ++ 2000-2016, Oracle and/or its affiliates. All rights reserved. ++ 2008-2013 Monty Program AB ++ 2008-2014 SkySQL Ab ++ 2013-2016 MariaDB Corporation ++ 2012-2016 MariaDB Foundation ++License: GPL-2 ++ ++Files: debian/* ++Copyright: ++ 1997-1998, Scott Hanson ++ 1997 Christian Schwarz ++ 1999-2007, 2009, Christian Hammers ++ 2000-2001, Christopher C. Chimelis ++ 2001 Matthew Wilcox ++ 2005-2007, Sean Finney ++ 2006 Adam Conrad ++ 2007-2011, Norbert Tretkowski ++ 2007-2008, Monty Taylor ++ 2008 Devin Carraway ++ 2008 Steffen Joeris ++ 2009 Canonical Ltd ++ 2010 Xavier Oswald ++ 2011 Clint Byrum ++ 2011 Ondřej Surý ++ 2012 Nicholas Bamber ++ 2013,2016 Kristian Nielsen ++ 2013-2024 Otto Kekäläinen ++ 2014 Daniel Schepler ++ 2014 Julien Muchembled ++ 2014 Tobias Frost ++ 2015 Andreas Beckmann ++ 2015-2016 Arnaud Fontaine ++ 2015-2016 Daniel Black ++ 2015 Israel Tsadok ++ 2015 Jan Wagner ++ 2015 Jean Weisbuch ++ 2015 Olaf van der Spek ++ 2015-2106 Robie Basak ++ 2016 Axel Beckert ++ 2016 Dieter Adriaenssens ++ 2016 Ian Gilfillan ++ 2016 James Cowgill ++ 2016 Paul Gevers ++ 2016 Samuel Thibault ++ 2016 Vicențiu Ciorbaru ++License: GPL-2+ ++ ++Files: plugin/feedback/* ++Copyright: 2010 Sergei Golubchik and Monty Program Ab ++License: GPL-2 ++ ++Files: debian/additions/mariadb-report* ++Copyright: 2006-2008 Daniel Nichter ++ 2012-2015 Jean Weisbuch ++License: GPL-2+ ++ ++Files: ++ dbug/example1.c ++ dbug/example2.c ++ dbug/example3.c ++ dbug/factorial.c ++ dbug/main.c ++ dbug/my_main.c ++ dbug/remove_function_from_trace.pl ++ dbug/tests.c ++ dbug/tests-t.pl ++ mysql-test/* ++ support-files/binary-configure.sh ++ support-files/mysqld_multi.server.sh ++ Docs/* ++Copyright: UNKNOWN ++Comment: These files fall under the blanket license specified in the file ++ COPYING and README ++ GPLv2 Disclaimer: ++ For the avoidance of doubt, except that if any license choice ++ other than GPL or LGPL is available it will apply instead, ++ Oracle elects to use only the General Public License version 2 ++ (GPLv2) at this time for any software where a choice of GPL ++ license versions is made available with the language indicating ++ that GPLv2 or any later version may be used, or where a choice ++ of which version of the GPL is applied is otherwise unspecified. ++License: GPL-2 ++ ++Files: BUILD/* ++ client/* ++ cmake/* ++ dbug/dbug_add_tags.pl ++ extra/* ++ include/* ++ libmysqld/* ++ libservices/* ++ mysql-test/include/have_perfschema.inc ++ mysql-test/lib/mtr_cases.pm ++ mysql-test/lib/mtr_gprof.pl ++ mysql-test/lib/mtr_io.pl ++ mysql-test/lib/mtr_match.pm ++ mysql-test/lib/mtr_process.pl ++ mysql-test/lib/mtr_report.pm ++ mysql-test/lib/mtr_results.pm ++ mysql-test/lib/mtr_stress.pl ++ mysql-test/lib/mtr_unique.pm ++ mysql-test/lib/My/Config.pm ++ mysql-test/lib/My/CoreDump.pm ++ mysql-test/lib/My/File/* ++ mysql-test/lib/My/Find.pm ++ mysql-test/lib/My/Handles.pm ++ mysql-test/lib/My/Options.pm ++ mysql-test/lib/My/Platform.pm ++ mysql-test/lib/My/SafeProcess/Base.pm ++ mysql-test/lib/My/SafeProcess/safe_kill_win.cc ++ mysql-test/lib/My/SafeProcess/safe_process.cc ++ mysql-test/lib/My/SafeProcess/safe_process_win.cc ++ mysql-test/lib/My/SysInfo.pm ++ mysql-test/lib/My/Test.pm ++ mysql-test/lib/t/* ++ mysql-test/lib/v1/mtr_cases.pl ++ mysql-test/lib/v1/mtr_gcov.pl ++ mysql-test/lib/v1/mtr_gprof.pl ++ mysql-test/lib/v1/mtr_im.pl ++ mysql-test/lib/v1/mtr_io.pl ++ mysql-test/lib/v1/mtr_match.pl ++ mysql-test/lib/v1/mtr_process.pl ++ mysql-test/lib/v1/mtr_report.pl ++ mysql-test/lib/v1/mtr_stress.pl ++ mysql-test/lib/v1/mtr_timer.pl ++ mysql-test/lib/v1/mtr_unique.pl ++ mysql-test/lib/v1/My/* ++ mysql-test/lib/v1/mysql-test-run.pl ++ mysql-test/lib/v1/mtr_misc.pl ++ mysql-test/mariadb-stress-test.pl ++ mysql-test/mariadb-test-run.pl ++ mysql-test/std_data/* ++ mysql-test/suite/perfschema/include/* ++ mysql-test/suite/perfschema_stress/include/* ++ mysys/* ++ win/packaging/ca/* ++ plugin/audit_null/* ++ plugin/auth_* ++ plugin/daemon_example/* ++ plugin/fulltext/* ++ scripts/* ++ sql/* ++ sql-common/* ++ storage/* ++ strings/* ++ support-files/MacOSX/* ++ support-files/compiler_warnings.supp ++ support-files/mysql.* ++ support-files/dtrace/* ++ tests/* ++ unittest/* ++ vio/* ++Copyright: 1979-2009 MySQL AB ++ 1995-2010 Sun Microsystems Inc ++ 1994-1997,2000-2014 Oracle and/or its affiliates ++ 2010 Kristian Nielsen ++ 2012 MariaDB Services ++ 2013 MariaDB Foundation ++ 2010,2013 Sergei Golubchik ++ 1985,1995,2008-2011,2012-2014 Monty Program AB ++ 2008-2014 SykSQL Ab ++ 1993-2014 Olivier Bertrand ++ 2008-2014 Kentoku Shiba ++ 2013 Sergey Vojtovich and MariaDB Foundation ++ 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB ++ 2012 Michael Widenius ++ 2010-2011 DeNA Co.,Ltd. ++ 2011 Kentoku SHIBA ++License: GPL-2 ++ ++Files: include/maria.h include/myisamchk.h ++Copyright: 2006-2008 MySQL AB ++ 2008-2009 Sun Microsystems, Inc ++ 2009, 2013, Monty Program Ab ++License: GPL-2+ ++ ++Files: plugin/auth_pam/testing/pam_mariadb_mtr.c ++Copyright: none ++License: public-domain ++ ++Files: plugin/locale_info/locale_info.cc ++Copyright: 2013, Spaempresarial - Brazil, Roberto Spadim ++License: BSD-3-clause ++ ++Files: plugin/qc_info/qc_info.cc ++Copyright: 2008, Roland Bouman ++License: BSD-3-clause ++ ++Files: tests/async_queries.c tests/nonblock-wrappers.h ++Copyright: 2011 Kristian Nielsen and Monty Program Ab ++License: LGPL-2.1+ ++ ++Files: include/ma_dyncol.h include/queues.h mysys/ma_dyncol.c mysys/queues.c ++ unittest/mysys/ma_dyncol-t.c ++Copyright: 2010,2011,2013 Monty Program Ab ++ 2011,2012 Oleksandr Byelkin ++License: BSD-2-clause ++ ++Files: mysys/my_port.c ++Copyright: 2002 MySQL AB ++License: LGPL-2 ++ ++Files: mysys/my_safehash.* ++Copyright: 2003-2007 MySQL AB ++License: GPL-2+ ++ ++Files: strings/bmove_upp.c strings/is_prefix.c strings/llstr.c ++ strings/longlong2str.c strings/strcont.c strings/strfill.c strings/strmov.c ++ strings/strnmov.c strings/bchange.c strings/int2str.c strings/my_strtoll10.c ++ strings/str2int.c strings/strappend.c strings/strcend.c ++Copyright: 2009-2013, Monty Program Ab ++ 2000,2003 TXT DataKonsult Ab & Monty Program Ab ++License: BSD-2-clause ++ ++Files: strings/strxmov.c ++ strings/strxnmov.c ++ strings/strnlen.c ++Copyright: 2009-2011, Monty Program Ab ++ 2000 TXT DataKonsult Ab & Monty Program Ab ++ Richard A. O'Keefe ++License: BSD-2-clause ++ ++Files: client/async_example.c ++Copyright: 2011 Kristian Nielsen and Monty Program Ab ++License: LGPL-2.1+ ++ ++Files: storage/oqgraph/* ++Copyright: ++ 2007-2013 Arjen G Lentz & Antony T Curtis for Open Query ++ 2000-2006 MySQL AB ++License: GPL-2+ ++ ++Files: storage/connect/connect.cc ++Copyright: 2004-2012 Olivier Bertrand ++License: GPL-2+ ++ ++Files: storage/oqgraph/ha_oqgraph.* ++ storage/oqgraph/oqgraph_probes.d ++Copyright: ++ 2007-2013 Arjen G Lentz & Antony T Curtis for Open Query ++ 2000-2006 MySQL AB ++License: GPL-2 ++ ++Files: extra/*/INSTALL ++Copyright: 1994-1996, 1999-2002, 2004-2006, Free Software Foundation, Inc. ++License: unlimited-free-doc ++ This file is free documentation; the Free Software Foundation gives ++ unlimited permission to copy, distribute and modify it. ++ ++Files: mysql-test/lib/mtr_misc.pl ++ mysql-test/lib/My/SafeProcess.pm ++Copyright: 2004, 2007, 2011, Oracle and/or its affiliates ++License: LGPL ++ ++Files: ++ storage/myisam/ft_update.c ++ storage/myisam/fulltext.h ++ storage/myisam/ft_boolean_search.c ++ storage/myisam/ft_stopwords.c ++ storage/myisam/ft_nlq_search.c ++ storage/myisam/ft_parser.c ++ storage/myisam/myisam_ftdump.c ++Copyright: ++ 2000, 2001, 2010, 2011, Oracle and/or its affiliates ++ Sergei A. Golubchik ++License: GPL-2 ++ ++Files: storage/myisam/ft_myisam.c ++Copyright: 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB ++License: GPL-2+ ++ ++Files: storage/innobase/* ++Copyright: ++ 1994-2011 Sergei A. Golubchik ++ 1996 Michael Widenius ++ 1994-2014 Oracle and/or its affiliates ++ 2008-2009 Google Inc ++ 2009 Sun Microsystems, Inc ++ 2009 Percona Inc ++ 2013, 2014 SkySQL Ab ++ 2012 Facebook Inc ++License: GPL-2 ++ ++Files: storage/maria/* ++Copyright: ++ 2008-2009 Sun Microsystems, Inc ++ 2008 Sun AB ++ 2006 MySQL Finland AB ++ 2006 TCX DataKonsult AB ++ 2003-2008 MySQL AB ++ 2007-2008 Michael Widenius ++ 2007 Guilhem Bichot ++ 2006 Sergei A. Golubchik ++ 2007 Sanja Belkin ++ 2006 Ramil Kalimullin ++ 2006 Alexey Botchkov ++ 2008-2011 Monty Program Ab ++ 2004-2008 MySQL AB & MySQL Finland AB & TCX DataKonsult AB ++License: GPL-2 ++ ++Files: storage/sphinx/* ++Copyright: 2001-2014 Andrew Aksyonoff ++ 2008-2014 Sphinx Technologies Inc ++License: GPL-2 ++ ++Files: extra/readline/* ++Copyright: 1987-2006 Free Software Foundation Inc ++License: GPL-2+ ++ ++Files: sql-bench/*.sh ++Copyright: 2009 Sun Microsystems, Inc ++ 2000-2007 MySQL AB ++License: LGPL ++ ++Files: client/completion_hash.h ++ scripts/mysqlaccess.sh ++ scripts/mysql_fix_extensions.sh ++ scripts/mysql_setpermission.sh ++ storage/myisam/ftbench/ft-test-run.sh ++ storage/myisam/mi_test_all.sh ++ strings/ctype-uca.c ++ strings/ctype-ucs2.c ++ strings/ctype-utf8.c ++ support-files/MacOSX/postflight.sh ++ support-files/MacOSX/preflight.sh ++ mysql-test/lib/My/ConfigFactory.pm ++ BUILD/*.sh ++ BUILD/compile-solaris-amd64 ++ BUILD/compile-amd64-valgrind-max ++ BUILD/compile-pentium64-max ++ BUILD/compile-pentium64 ++ scripts/mysqlhotcopy.sh ++ scripts/mysqld_multi.sh ++ mysql-test/std_data/checkDBI_DBD-MariaDB.pl ++Copyright: 2000-2013 Oracle and/or its affiliates ++ 2000-2007 MySQL AB ++ 2009 Sun Microsystems Inc ++License: LGPL ++ ++Files: BUILD/util.sh ++Copyright: 2010 Kristian Nielsen and Monty Program AB ++License: GPL-2 ++ ++Files: sql-bench/innotest1.sh ++ sql-bench/innotest1a.sh ++ sql-bench/innotest1b.sh ++ sql-bench/innotest2.sh ++ sql-bench/innotest2a.sh ++ sql-bench/innotest2b.sh ++Copyright: 2000-2002 Innobase Oy & MySQL AB ++Comment: These files fall under the blanket license specified in the file COPYING ++License: GPL-2 ++ ++Files: storage/myisam/rt_index.h ++ storage/myisam/rt_key.* ++ storage/myisam/rt_mbr.* ++ storage/myisam/sp_defs.h ++Copyright: ++ 2000,2002-2007 MySQL AB ++ Ramil Kalimullin ++License: GPL-2 ++ ++Files: strings/ctype-bin.c ++ strings/ctype-eucjpms.c ++ strings/ctype-ujis.c ++Copyright: ++ 2000,2002,2005-2011 Oracle and/or its affiliates ++ tommy@valley.ne.jp ++License: LGPL + - The Debian package of MySQL was first debianzed on 1997-04-12 by Christian - Schwarz and is maintained since 1999-04-20 by - Christian Hammers . ++Files: scripts/mysqld_safe.sh ++ support-files/mysql-multi.server.sh ++ support-files/mysql.server.sh ++Copyright: 1996 Abandoned TCX DataKonsult AB & Monty Program KB & Detron HB ++License: public-domain + - The MariaDB packages were initially made by http://ourdelta.org/, and - are now managed by the MariaDB development team, developers@lists.mariadb.org ++Files: storage/innobase/include/pars0grm.h storage/innobase/pars/pars0grm.cc ++Copyright: 1995-2009 Innobase Oy. ++ 1984,1989-1990,2000-2004 Free Software Foundation Inc. ++License: GPL-2+-with-bison-exception ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2, or (at your option) ++ any later version. ++ . ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ . ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ Boston, MA 02110-1301, USA. ++ . ++ As a special exception, you may create a larger work that contains ++ part or all of the Bison parser skeleton and distribute that work ++ under terms of your choice, so long as that work isn't itself a ++ parser generator using the skeleton or a modified version thereof ++ as a parser skeleton. Alternatively, if you modify or redistribute ++ the parser skeleton itself, you may (at your option) remove this ++ special exception, which will cause the skeleton and the resulting ++ Bison output files to be licensed under the GNU General Public ++ License without this special exception. ++ . ++ This special exception was added by the Free Software Foundation in ++ version 2.2 of Bison. + - MariaDB can be downloaded from https://downloads.mariadb.org/ ++Files: storage/innobase/fts/fts0pars.cc ++ storage/innobase/include/fts0pars.h ++Copyright: 1984, 1989-1990, 2000-2006 Free Software Foundation, Inc. ++License: GPL-3+-with-bison-exception + ++License: GPL-3+-with-bison-exception ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ . ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ . ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ . ++ As a special exception, you may create a larger work that contains ++ part or all of the Bison parser skeleton and distribute that work ++ under terms of your choice, so long as that work isn't itself a ++ parser generator using the skeleton or a modified version thereof ++ as a parser skeleton. Alternatively, if you modify or redistribute ++ the parser skeleton itself, you may (at your option) remove this ++ special exception, which will cause the skeleton and the resulting ++ Bison output files to be licensed under the GNU General Public ++ License without this special exception. ++ . ++ This special exception was added by the Free Software Foundation in ++ version 2.2 of Bison. ++ ++ ++Files: include/t_ctype.h ++ strings/t_ctype.h ++Copyright: 2000 MySQL AB ++ 1998 Theppitak Karoonboonyanan ++ 1998-1999 Pruet Boonma ++License: GPL-2 ++ ++Files: strings/strend.c ++Copyright: Richard A. O'Keefe. ++ 2000 TXT DataKonsult Ab & Monty Program Ab ++ 2009-2011, Monty Program Ab ++License: BSD-2-clause ++ ++Files: dbug/dbug.c ++ dbug/dbug_long.h ++Copyright: 1987 Abandoned Fred Fish ++License: public-domain ++ ++Files: scripts/dheadgen.pl ++Copyright: 2008-2009 Sun Microsystems Inc ++License: BSD-3-clause ++ ++Files: plugin/handler_socket/* ++Copyright: ++ 2010 DeNA Co.,Ltd. ++License: BSD-3-clause ++ ++Files: plugin/auth_gssapi/* ++Copyright: 2015 Shuang Qiu ++ 2015 Robbie Harwood ++License: BSD-2-clause ++ ++Files: plugin/file_key_management/* ++Copyright: 2002-2012 eperi GmbH ++License: GPL-2 ++ ++Files: storage/mroonga/* ++Copyright: 2011-2015 Kouhei Sutou ++ 2011-2013 Kentoku SHIBA ++ 2010 Tetsuro IKEDA ++ 2014 Kenji Maruyama ++ 2014-2015 Naoya Murakami ++License: LGPL-2.1+ ++ ++Files: storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/* ++Copyright: 2009-2015 Brazil ++License: LGPL-2.1+ ++ ++Files: storage/spider/* ++Copyright: 2008-2015 Kentoku Shiba ++License: GPL-2 ++ ++Files: strings/ctype-win1250ch.c ++Copyright: 2002-2010 Oracle and/or its affiliates. ++ 2001 Jan Pazdziora ++License: GPL-2 ++ ++Files: strings/ctype-tis620.c ++Copyright: 1998 Theppitak Karoonboonyanan ++ 1989-1991 Samphan Raruenrom ++ 2000-2010 Oracle and/or its affiliates. ++ 2003 Sathit Jittanupat ++ 2001 Korakot Chaovavanich and ++ 1998-1999 Pruet Boonma ++License: GPL-2 ++ ++Files: storage/innobase/handler/ha_innodb.h ++Copyright: 2000-2010 MySQL AB & Innobase Oy. ++License: GPL-2 ++ ++Files: strings/dtoa.c ++Copyright: 2007-2012 Oracle and/or its affiliates. ++ 1991,2000-2001 Lucent Technologies ++License: LGPL ++ ++Files: scripts/mysqldumpslow.sh ++Copyright: ++ 2000-2002,2005-2008 MySQL AB ++ 2008-2009 Sun Microsystems Inc ++License: LGPL ++ ++Files: libmysqld/lib_sql.cc ++Copyright: 2000 SWsoft company ++License: SWsoft ++ This material is provided "as is", with absolutely no warranty expressed ++ or implied. Any use is at your own risk. ++ . ++ Permission to use or copy this software for any purpose is hereby granted ++ without fee, provided the above notices are retained on all copies. ++ Permission to modify the code and to distribute modified code is granted, ++ provided the above notices are retained, and a notice that the code was ++ modified is included with the above copyright notice. ++ ++Files: tests/mail_to_db.pl ++Copyright: 1998 Abandoned TCX DataKonsult AB & Monty Program KB & Detron HB ++License: public-domain ++ ++Files: scripts/mysqlaccess.conf ++Copyright: 1997, Yves.Carlier@rug.ac.be ++License: GPL-2 ++ ++Files: debian/additions/innotop/* ++Copyright: 2006-2009, Baron Schwartz ++License: GPL-2 or Artistic ++ ++Files: include/mysql_version.h.in ++Copyright: 1996, 1999, 2001 MySQL AB ++License: public-domain ++ ++Files: storage/federatedx/* ++Copyright: ++ 2007 Antony T Curtis ++ 2008-2009 Patrick Galbraith ++License: BSD-3-clause ++ ++Files: cmake/systemd.cmake ++ scripts/mariadb-service-convert ++Copyright: 2015 Daniel Black ++License: GPL-2 ++ ++Files: wsrep-lib/* ++ sql/wsrep_* ++ scripts/wsrep_* ++Copyright: 2008-2019 Codership Oy ++License: GPL-2 ++ ++Files: libmariadb/* ++Copyright: ++ 2000-2012 MySQL AB & MySQL Finland AB & TCX DataKonsult AB ++ 2006-2011 The PHP Group ++ 2012-2013 Monty Program AB ++ 2014-2020 MariaDB Corporation Ab ++ 2014 Kristian Nielsen & MariaDB Corporation ++License: LGPL-2+ ++ ++Files: libmariadb/libmariadb/mariadb_dyncol.* ++Copyright: ++ 2011-2012 Oleksandr Byelkin ++ 2011-2013 Monty Program Ab ++License: BSD-2-clause ++ ++Files: libmariadb/libmariadb/ma_dtoa.* +Copyright: ++ 1991, 2000-2001, Lucent Technologies ++ 2007, 2012, Oracle and/or its affiliates. ++License: LGPL ++ ++Files: libmariadb/unittest/libmariadb/getopt.* ++Copyright: ++ 1989-1994, Free Software Foundation, Inc ++License: LGPL-2+ ++ ++Files: libmariadb/cmake/FindIconv.cmake ++Copyright: ++ 2010, Michael Bell ++License: BSD-2-Clause ++ ++Files: storage/archive/azio.c ++ storage/archive/azlib.h ++ zlib/* ++Copyright: ++ 1995-2005 Jean-loup Gailly ++ 1995-2005 Mark Adler ++License: zlib/libpng ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ . ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ . ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++Files: mysys/CMakeLists.txt ++Copyright: 2006, 2014, Oracle and/or its affiliates ++License: GPL-2 ++ ++Files: plugin/server_audit/CMakeLists.txt ++Copyright: 2013 Alexey Botchkov and SkySQL Ab ++License: GPL-2 ++ ++Files: zlib/CMakeLists.txt ++Copyright: 2006, 2014, Oracle and/or its affiliates ++License: GPL-2 ++ ++License: GPL-2 ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; version 2 of the License. ++ . ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ . ++ On Debian and systems the full text of the GNU General Public ++ License version 2 can be found in the file ++ `/usr/share/common-licenses/GPL-2` ++ . ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . + - According to the file "COPYING" all parts of this package are licenced - under the terms of the GNU GPL Version 2 of which a copy is available - in /usr/share/common-licenses. ++License: GPL-2+ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ . ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ . ++ On Debian and systems the full text of the GNU General Public ++ License version 2 can be found in the file ++ `/usr/share/common-licenses/GPL-2` ++ . ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . + - To allow free software with other licences than the GPL to link against the - shared library, special terms for "derived works" are granted in the README file of MySQL 5.5, as follows: ++License: LGPL ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; version 2 ++ of the License. ++ . ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ . ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ++ MA 02110-1301, USA ++ . ++ On Debian and systems the full text of the GNU Library General Public ++ License version 2 can be found in the file ++ `/usr/share/common-licenses/LGPL-2` + - > MySQL FOSS License Exception - > We want free and open source software applications under certain - > licenses to be able to use specified GPL-licensed MySQL client - > libraries despite the fact that not all such FOSS licenses are - > compatible with version 2 of the GNU General Public License. - > Therefore there are special exceptions to the terms and conditions - > of the GPLv2 as applied to these client libraries, which are - > identified and described in more detail in the FOSS License - > Exception at - > . ++License: LGPL-2 ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; version 2 ++ of the License. ++ . ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ . ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ++ MA 02110-1301, USA ++ . ++ On Debian and systems the full text of the GNU Library General Public ++ License version 2 can be found in the file ++ `/usr/share/common-licenses/LGPL-2` + - The manual had to be removed as it is not free in the sense of the - Debian Free Software Guidelines (DFSG). ++License: LGPL-2+ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ . ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ . ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not see ++ or write to the Free Software Foundation, Inc., ++ 51 Franklin St., Fifth Floor, Boston, MA 02110, USA ++ . ++ On Debian systems, the complete text of the GNU Library General Public ++ License version 2 can be found in "/usr/share/common-licenses/LGPL-2". + ++License: LGPL-2.1+ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1, or (at your option) ++ any later version. ++ . ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ . ++ You should have received a copy of the GNU Lesser General Public License along ++ with this program; if not, write to the Free Software Foundation, ++ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ++ . ++ On Debian and systems the full text of the GNU Library General Public ++ License version 2.1 can be found in the file ++ `/usr/share/common-licenses/LGPL-2.1` + - == innotop == ++License: BSD-2-clause ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions are ++ met: ++ . ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ . ++ 2. Redistributions in binary form must the following disclaimer in ++ the documentation and/or other materials provided with the ++ distribution. + - Copyright 2006-2009, Baron Schwartz - URL: http://innotop.sourceforge.net ++License: BSD-3-clause ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ 3. Neither the name of the University nor the names of its contributors ++ may be used to endorse or promote products derived from this software ++ without specific prior written permission. ++ . ++ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. + - License: - > This software is dual licensed, either GPL version 2 or Artistic License. - > - > This package is free software; you can redistribute it and/or modify - > it under the terms of the GNU General Public License as published by - > the Free Software Foundation; either version 2 of the License, or - > (at your option) any later version. - > - > This package is distributed in the hope that it will be useful, - > but WITHOUT ANY WARRANTY; without even the implied warranty of - > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - > GNU General Public License for more details. - > - > You should have received a copy of the GNU General Public License - > along with this package; if not, write to the Free Software - > Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA ++License: Artistic ++ The "Artistic License" ++ . ++ Preamble ++ . ++ The intent of this document is to state the conditions under which a ++ Package may be copied, such that the Copyright Holder maintains some ++ semblance of artistic control over the development of the package, ++ while giving the users of the package the right to use and distribute ++ the Package in a more-or-less customary fashion, plus the right to make ++ reasonable modifications. ++ . ++ Definitions: ++ . ++ "Package" refers to the collection of files distributed by the ++ Copyright Holder, and derivatives of that collection of files ++ created through textual modification. ++ . ++ "Standard Version" refers to such a Package if it has not been ++ modified, or has been modified in accordance with the wishes ++ of the Copyright Holder as specified below. ++ . ++ "Copyright Holder" is whoever is named in the copyright or ++ copyrights for the package. ++ . ++ "You" is you, if you're thinking about copying or distributing ++ this Package. ++ . ++ "Reasonable copying fee" is whatever you can justify on the ++ basis of media cost, duplication charges, time of people involved, ++ and so on. (You will not be required to justify it to the ++ Copyright Holder, but only to the computing community at large ++ as a market that must bear the fee.) ++ . ++ "Freely Available" means that no fee is charged for the item ++ itself, though there may be fees involved in handling the item. ++ It also means that recipients of the item may redistribute it ++ under the same conditions they received it. ++ . ++ 1. You may make and give away verbatim copies of the source form of the ++ Standard Version of this Package without restriction, provided that you ++ duplicate all of the original copyright notices and associated disclaimers. ++ . ++ 2. You may apply bug fixes, portability fixes and other modifications ++ derived from the Public Domain or from the Copyright Holder. A Package ++ modified in such a way shall still be considered the Standard Version. ++ . ++ 3. You may otherwise modify your copy of this Package in any way, provided ++ that you insert a prominent notice in each changed file stating how and ++ when you changed that file, and provided that you do at least ONE of the ++ following: ++ . ++ a) place your modifications in the Public Domain or otherwise make them ++ Freely Available, such as by posting said modifications to Usenet or ++ an equivalent medium, or placing the modifications on a major archive ++ site such as uunet.uu.net, or by allowing the Copyright Holder to include ++ your modifications in the Standard Version of the Package. ++ . ++ b) use the modified Package only within your corporation or organization. ++ . ++ c) rename any non-standard executables so the names do not conflict ++ with standard executables, which must also be provided, and provide ++ a separate manual page for each non-standard executable that clearly ++ documents how it differs from the Standard Version. ++ . ++ d) make other distribution arrangements with the Copyright Holder. ++ . ++ 4. You may distribute the programs of this Package in object code or ++ executable form, provided that you do at least ONE of the following: ++ . ++ a) distribute a Standard Version of the executables and library files, ++ together with instructions (in the manual page or equivalent) on where ++ to get the Standard Version. ++ . ++ b) accompany the distribution with the machine-readable source of ++ the Package with your modifications. ++ . ++ c) give non-standard executables non-standard names, and clearly ++ document the differences in manual pages (or equivalent), together ++ with instructions on where to get the Standard Version. ++ . ++ d) make other distribution arrangements with the Copyright Holder. ++ . ++ 5. You may charge a reasonable copying fee for any distribution of this ++ Package. You may charge any fee you choose for support of this ++ Package. You may not charge a fee for this Package itself. However, ++ you may distribute this Package in aggregate with other (possibly ++ commercial) programs as part of a larger (possibly commercial) software ++ distribution provided that you do not advertise this Package as a ++ product of your own. You may embed this Package's interpreter within ++ an executable of yours (by linking); this shall be construed as a mere ++ form of aggregation, provided that the complete Standard Version of the ++ interpreter is so embedded. ++ . ++ 6. The scripts and library files supplied as input to or produced as ++ output from the programs of this Package do not automatically fall ++ under the copyright of this Package, but belong to whoever generated ++ them, and may be sold commercially, and may be aggregated with this ++ Package. If such scripts or library files are aggregated with this ++ Package via the so-called "undump" or "unexec" methods of producing a ++ binary executable image, then distribution of such an image shall ++ neither be construed as a distribution of this Package nor shall it ++ fall under the restrictions of Paragraphs 3 and 4, provided that you do ++ not represent such an executable image as a Standard Version of this ++ Package. ++ . ++ 7. C subroutines (or comparably compiled subroutines in other ++ languages) supplied by you and linked into this Package in order to ++ emulate subroutines and variables of the language defined by this ++ Package shall not be considered part of this Package, but are the ++ equivalent of input as in Paragraph 6, provided these subroutines do ++ not change the language in any way that would cause it to fail the ++ regression tests for the language. ++ . ++ 8. Aggregation of this Package with a commercial distribution is always ++ permitted provided that the use of this Package is embedded; that is, ++ when no overt attempt is made to make this Package's interfaces visible ++ to the end user of the commercial distribution. Such use shall not be ++ construed as a distribution of this Package. ++ . ++ 9. The name of the Copyright Holder may not be used to endorse or promote ++ products derived from this software without specific prior written permission. ++ . ++ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR ++ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ . ++ The End + - On Debian systems, the complete text of the GNU General Public License and the - Artistic License can be found in `/usr/share/common-licenses/'. ++License: public-domain ++ The work is public domain (no license). diff --cc debian/gbp.conf index a5af3e1f7,000000000..fd0fdf630 mode 100644,000000..100644 --- a/debian/gbp.conf +++ b/debian/gbp.conf @@@ -1,5 -1,0 +1,21 @@@ +[DEFAULT] +# Ignore requirement to use branch name 'master' to make it easier +# for contributors to work with feature and bugfix branches - # to Debian packaging +ignore-branch = True ++ ++# Always use pristine tar ++pristine-tar = True ++ ++# Always sign everything ++sign-tags = True ++upstream-signatures = on ++ ++# DEP-14 format ++debian-branch = debian/latest ++upstream-branch = upstream/latest ++ ++# Upstream tag format ++upstream-vcs-tag = mariadb-%(version)s ++ ++# MariaDB has submodules ++submodules = True diff --cc debian/libmariadb-dev.install index 48120822f,000000000..8bf8245e7 mode 100644,000000..100644 --- a/debian/libmariadb-dev.install +++ b/debian/libmariadb-dev.install @@@ -1,35 -1,0 +1,35 @@@ +usr/bin/mariadb-config +usr/bin/mariadb_config +usr/include/mariadb/errmsg.h +usr/include/mariadb/ma_list.h +usr/include/mariadb/ma_pvio.h +usr/include/mariadb/ma_tls.h - usr/include/mariadb/mariadb/ +usr/include/mariadb/mariadb/ma_io.h +usr/include/mariadb/mariadb_com.h +usr/include/mariadb/mariadb_ctype.h +usr/include/mariadb/mariadb_dyncol.h +usr/include/mariadb/mariadb_rpl.h +usr/include/mariadb/mariadb_stmt.h +usr/include/mariadb/mariadb_version.h +usr/include/mariadb/my_alloca.h +usr/include/mariadb/my_config.h +usr/include/mariadb/my_global.h +usr/include/mariadb/my_sys.h +usr/include/mariadb/mysql.h +usr/include/mariadb/mysql/ +usr/include/mariadb/mysql/client_plugin.h +usr/include/mariadb/mysql/plugin_auth.h +usr/include/mariadb/mysql_com.h +usr/include/mariadb/mysql_version.h +usr/include/mariadb/mysqld_error.h +usr/lib/*/libmariadb.a +usr/lib/*/libmariadb.so +usr/lib/*/libmariadbclient.a +usr/lib/*/libmariadbclient.so +usr/lib/*/libmysqlservices.a +usr/lib/*/pkgconfig/libmariadb.pc ++usr/lib/*/pkgconfig/mariadb.pc +usr/share/aclocal/mysql.m4 +usr/share/man/man1/mariadb_config.1 +usr/share/man/man1/mysql_config.1 +usr/share/man/man3/*.3 diff --cc debian/libmariadb-dev.lintian-overrides index 6a162120f,000000000..1a3c0d5f4 mode 100644,000000..100644 --- a/debian/libmariadb-dev.lintian-overrides +++ b/debian/libmariadb-dev.lintian-overrides @@@ -1,2 -1,0 +1,7 @@@ +# This is how upstream does it, wont' fix - arch-dependent-file-not-in-arch-specific-directory usr/bin/mariadb_config ++repeated-path-segment mariadb [usr/include/mariadb/mariadb/] ++# Man page syntax needs to be fixed upstream ++groff-message an.tmac::*: warning: tbl preprocessor failed, or it or soelim was not run; table(s) likely not rendered (TE macro called with TW register undefined) [usr/share/man/* ++groff-message troff::*: warning: cannot select font 'C' [usr/share/man/*] ++# mysql_config and mariadb_config location is this by old convention ++development-package-ships-elf-binary-in-path [usr/bin/mariadb_config] diff --cc debian/libmariadb3.lintian-overrides index 000000000,000000000..f7ebae378 new file mode 100644 --- /dev/null +++ b/debian/libmariadb3.lintian-overrides @@@ -1,0 -1,0 +1,4 @@@ ++# Most likely false positive ++hardening-no-fortify-functions [usr/lib/x86_64-linux-gnu/libmariadb3/plugin/caching_sha2_password.so] ++hardening-no-fortify-functions [usr/lib/x86_64-linux-gnu/libmariadb3/plugin/dialog.so] ++hardening-no-fortify-functions [usr/lib/x86_64-linux-gnu/libmariadb3/plugin/sha256_password.so] diff --cc debian/libmariadb3.symbols index f7dab8743,000000000..38d89271d mode 100644,000000..100644 --- a/debian/libmariadb3.symbols +++ b/debian/libmariadb3.symbols @@@ -1,342 -1,0 +1,342 @@@ +libmariadb.so.3 libmariadb3 #MINVER# +* Build-Depends-Package: libmariadb-dev + libmariadb_3@libmariadb_3 3.0.0 + libmariadb_3_3_5@libmariadb_3_3_5 3.3.5 + libmariadbclient_18@libmariadbclient_18 3.0.0 + libmysqlclient_18@libmysqlclient_18 3.0.0 + ma_pvio_register_callback@libmariadb_3 3.0.0 + mariadb_cancel@libmariadb_3 3.0.0 + mariadb_connection@libmariadb_3 3.0.0 + mariadb_convert_string@libmariadb_3 3.0.0 + mariadb_deinitialize_ssl@libmariadb_3 3.0.0 - mariadb_field_attr@libmariadb_3 3.3.1 ++ mariadb_field_attr@libmariadb_3 3.1.8 + mariadb_free_rpl_event@libmariadb_3 3.1.0 + mariadb_get_charset_by_name@libmariadb_3 3.0.0 + mariadb_get_charset_by_nr@libmariadb_3 3.0.0 + mariadb_get_info@libmariadb_3 3.0.0 + mariadb_get_infov@libmariadb_3 3.0.0 + mariadb_reconnect@libmariadb_3 3.0.0 + mariadb_rpl_close@libmariadb_3 3.1.0 - mariadb_rpl_errno@libmariadb_3_3_5 3.3.2 - mariadb_rpl_error@libmariadb_3_3_5 3.3.2 - mariadb_rpl_extract_rows@libmariadb_3_3_5 3.3.2 ++ mariadb_rpl_errno@libmariadb_3_3_5 3.3.5 ++ mariadb_rpl_error@libmariadb_3_3_5 3.3.5 ++ mariadb_rpl_extract_rows@libmariadb_3_3_5 3.3.5 + mariadb_rpl_fetch@libmariadb_3 3.1.0 + mariadb_rpl_get_optionsv@libmariadb_3 3.1.0 - mariadb_rpl_init_ex@libmariadb_3 3.3.0 ++ mariadb_rpl_init_ex@libmariadb_3 3.1.13 + mariadb_rpl_open@libmariadb_3 3.1.0 + mariadb_rpl_optionsv@libmariadb_3 3.1.0 + mariadb_stmt_execute_direct@libmariadb_3 3.0.0 + mariadb_stmt_fetch_fields@libmariadb_3 3.1.0 + mysql_affected_rows@libmariadbclient_18 3.0.0 + mysql_affected_rows@libmysqlclient_18 3.0.0 + mysql_autocommit_cont@libmariadb_3 3.0.0 + mysql_autocommit@libmariadbclient_18 3.0.0 + mysql_autocommit@libmysqlclient_18 3.0.0 + mysql_autocommit_start@libmariadb_3 3.0.0 + mysql_change_user_cont@libmariadb_3 3.0.0 + mysql_change_user@libmariadbclient_18 3.0.0 + mysql_change_user@libmysqlclient_18 3.0.0 + mysql_change_user_start@libmariadb_3 3.0.0 + mysql_character_set_name@libmariadbclient_18 3.0.0 + mysql_character_set_name@libmysqlclient_18 3.0.0 + mysql_client_find_plugin@libmariadbclient_18 3.0.0 + mysql_client_find_plugin@libmysqlclient_18 3.0.0 + mysql_client_register_plugin@libmariadbclient_18 3.0.0 + mysql_client_register_plugin@libmysqlclient_18 3.0.0 + mysql_close_cont@libmariadb_3 3.0.0 + mysql_close@libmariadbclient_18 3.0.0 + mysql_close@libmysqlclient_18 3.0.0 + mysql_close_start@libmariadb_3 3.0.0 + mysql_commit_cont@libmariadb_3 3.0.0 + mysql_commit@libmariadbclient_18 3.0.0 + mysql_commit@libmysqlclient_18 3.0.0 + mysql_commit_start@libmariadb_3 3.0.0 + mysql_data_seek@libmariadbclient_18 3.0.0 + mysql_data_seek@libmysqlclient_18 3.0.0 + mysql_debug@libmariadbclient_18 3.0.0 + mysql_debug@libmysqlclient_18 3.0.0 + mysql_dump_debug_info_cont@libmariadb_3 3.0.0 + mysql_dump_debug_info@libmariadbclient_18 3.0.0 + mysql_dump_debug_info@libmysqlclient_18 3.0.0 + mysql_dump_debug_info_start@libmariadb_3 3.0.0 + mysql_embedded@libmariadbclient_18 3.0.0 + mysql_embedded@libmysqlclient_18 3.0.0 + mysql_eof@libmariadbclient_18 3.0.0 + mysql_eof@libmysqlclient_18 3.0.0 + mysql_errno@libmariadbclient_18 3.0.0 + mysql_errno@libmysqlclient_18 3.0.0 + mysql_error@libmariadbclient_18 3.0.0 + mysql_error@libmysqlclient_18 3.0.0 + mysql_escape_string@libmariadbclient_18 3.0.0 + mysql_escape_string@libmysqlclient_18 3.0.0 + mysql_fetch_field_direct@libmariadbclient_18 3.0.0 + mysql_fetch_field_direct@libmysqlclient_18 3.0.0 + mysql_fetch_field@libmariadbclient_18 3.0.0 + mysql_fetch_field@libmysqlclient_18 3.0.0 + mysql_fetch_fields@libmariadbclient_18 3.0.0 + mysql_fetch_fields@libmysqlclient_18 3.0.0 + mysql_fetch_lengths@libmariadbclient_18 3.0.0 + mysql_fetch_lengths@libmysqlclient_18 3.0.0 + mysql_fetch_row_cont@libmariadb_3 3.0.0 + mysql_fetch_row@libmariadbclient_18 3.0.0 + mysql_fetch_row@libmysqlclient_18 3.0.0 + mysql_fetch_row_start@libmariadb_3 3.0.0 + mysql_field_count@libmariadbclient_18 3.0.0 + mysql_field_count@libmysqlclient_18 3.0.0 + mysql_field_seek@libmariadbclient_18 3.0.0 + mysql_field_seek@libmysqlclient_18 3.0.0 + mysql_field_tell@libmariadbclient_18 3.0.0 + mysql_field_tell@libmysqlclient_18 3.0.0 + mysql_free_result_cont@libmariadb_3 3.0.0 + mysql_free_result@libmariadbclient_18 3.0.0 + mysql_free_result@libmysqlclient_18 3.0.0 + mysql_free_result_start@libmariadb_3 3.0.0 + mysql_get_character_set_info@libmariadbclient_18 3.0.0 + mysql_get_character_set_info@libmysqlclient_18 3.0.0 + mysql_get_charset_by_name@libmariadbclient_18 3.0.0 + mysql_get_charset_by_name@libmysqlclient_18 3.0.0 + mysql_get_charset_by_nr@libmariadbclient_18 3.0.0 + mysql_get_charset_by_nr@libmysqlclient_18 3.0.0 + mysql_get_client_info@libmariadbclient_18 3.0.0 + mysql_get_client_info@libmysqlclient_18 3.0.0 + mysql_get_client_version@libmariadbclient_18 3.0.0 + mysql_get_client_version@libmysqlclient_18 3.0.0 + mysql_get_host_info@libmariadbclient_18 3.0.0 + mysql_get_host_info@libmysqlclient_18 3.0.0 + mysql_get_option@libmariadbclient_18 3.0.0 + mysql_get_option@libmysqlclient_18 3.0.0 + mysql_get_optionv@libmariadbclient_18 3.0.0 + mysql_get_optionv@libmysqlclient_18 3.0.0 + mysql_get_parameters@libmariadbclient_18 3.0.0 + mysql_get_parameters@libmysqlclient_18 3.0.0 + mysql_get_proto_info@libmariadbclient_18 3.0.0 + mysql_get_proto_info@libmysqlclient_18 3.0.0 + mysql_get_server_info@libmariadbclient_18 3.0.0 + mysql_get_server_info@libmysqlclient_18 3.0.0 + mysql_get_server_name@libmariadbclient_18 3.0.0 + mysql_get_server_name@libmysqlclient_18 3.0.0 + mysql_get_server_version@libmariadbclient_18 3.0.0 + mysql_get_server_version@libmysqlclient_18 3.0.0 + mysql_get_socket@libmariadbclient_18 3.0.0 + mysql_get_socket@libmysqlclient_18 3.0.0 + mysql_get_ssl_cipher@libmariadbclient_18 3.0.0 + mysql_get_ssl_cipher@libmysqlclient_18 3.0.0 + mysql_get_timeout_value@libmariadb_3 3.0.19 + mysql_get_timeout_value_ms@libmariadb_3 3.0.19 + mysql_hex_string@libmariadbclient_18 3.0.0 + mysql_hex_string@libmysqlclient_18 3.0.0 + mysql_info@libmariadbclient_18 3.0.0 + mysql_info@libmysqlclient_18 3.0.0 + mysql_init@libmariadbclient_18 3.0.0 + mysql_init@libmysqlclient_18 3.0.0 + mysql_insert_id@libmariadbclient_18 3.0.0 + mysql_insert_id@libmysqlclient_18 3.0.0 + mysql_kill_cont@libmariadb_3 3.0.0 + mysql_kill@libmariadbclient_18 3.0.0 + mysql_kill@libmysqlclient_18 3.0.0 + mysql_kill_start@libmariadb_3 3.0.0 + mysql_list_dbs@libmariadbclient_18 3.0.0 + mysql_list_dbs@libmysqlclient_18 3.0.0 + mysql_list_fields_cont@libmariadb_3 3.0.0 + mysql_list_fields@libmariadbclient_18 3.0.0 + mysql_list_fields@libmysqlclient_18 3.0.0 + mysql_list_fields_start@libmariadb_3 3.0.0 + mysql_list_processes@libmariadbclient_18 3.0.0 + mysql_list_processes@libmysqlclient_18 3.0.0 + mysql_list_tables@libmariadbclient_18 3.0.0 + mysql_list_tables@libmysqlclient_18 3.0.0 + mysql_load_plugin@libmariadbclient_18 3.0.0 + mysql_load_plugin@libmysqlclient_18 3.0.0 + mysql_load_plugin_v@libmariadbclient_18 3.0.0 + mysql_load_plugin_v@libmysqlclient_18 3.0.0 + mysql_more_results@libmariadbclient_18 3.0.0 + mysql_more_results@libmysqlclient_18 3.0.0 + mysql_net_field_length@libmariadbclient_18 3.0.0 + mysql_net_field_length@libmysqlclient_18 3.0.0 + mysql_net_read_packet@libmariadbclient_18 3.0.0 + mysql_net_read_packet@libmysqlclient_18 3.0.0 + mysql_next_result_cont@libmariadb_3 3.0.0 + mysql_next_result@libmariadbclient_18 3.0.0 + mysql_next_result@libmysqlclient_18 3.0.0 + mysql_next_result_start@libmariadb_3 3.0.0 + mysql_num_fields@libmariadbclient_18 3.0.0 + mysql_num_fields@libmysqlclient_18 3.0.0 + mysql_num_rows@libmariadbclient_18 3.0.0 + mysql_num_rows@libmysqlclient_18 3.0.0 + mysql_options4@libmariadbclient_18 3.0.0 + mysql_options4@libmysqlclient_18 3.0.0 + mysql_options@libmariadbclient_18 3.0.0 + mysql_options@libmysqlclient_18 3.0.0 + mysql_optionsv@libmariadb_3 3.0.0 + mysql_ping_cont@libmariadb_3 3.0.0 + mysql_ping@libmariadbclient_18 3.0.0 + mysql_ping@libmysqlclient_18 3.0.0 + mysql_ping_start@libmariadb_3 3.0.0 + mysql_ps_fetch_functions@libmariadb_3 3.0.0 + mysql_query_cont@libmariadb_3 3.0.0 + mysql_query@libmariadbclient_18 3.0.0 + mysql_query@libmysqlclient_18 3.0.0 + mysql_query_start@libmariadb_3 3.0.0 + mysql_read_query_result_cont@libmariadb_3 3.0.0 + mysql_read_query_result@libmariadbclient_18 3.0.0 + mysql_read_query_result@libmysqlclient_18 3.0.0 + mysql_read_query_result_start@libmariadb_3 3.0.0 + mysql_real_connect_cont@libmariadb_3 3.0.0 + mysql_real_connect@libmariadbclient_18 3.0.0 + mysql_real_connect@libmysqlclient_18 3.0.0 + mysql_real_connect_start@libmariadb_3 3.0.0 + mysql_real_escape_string@libmariadbclient_18 3.0.0 + mysql_real_escape_string@libmysqlclient_18 3.0.0 + mysql_real_query_cont@libmariadb_3 3.0.0 + mysql_real_query@libmariadbclient_18 3.0.0 + mysql_real_query@libmysqlclient_18 3.0.0 + mysql_real_query_start@libmariadb_3 3.0.0 + mysql_refresh_cont@libmariadb_3 3.0.0 + mysql_refresh@libmariadbclient_18 3.0.0 + mysql_refresh@libmysqlclient_18 3.0.0 + mysql_refresh_start@libmariadb_3 3.0.0 + mysql_reset_connection_cont@libmariadb_3 3.0.0 + mysql_reset_connection@libmariadbclient_18 3.0.0 + mysql_reset_connection@libmysqlclient_18 3.0.0 + mysql_reset_connection_start@libmariadb_3 3.0.0 + mysql_rollback_cont@libmariadb_3 3.0.0 + mysql_rollback@libmariadbclient_18 3.0.0 + mysql_rollback@libmysqlclient_18 3.0.0 + mysql_rollback_start@libmariadb_3 3.0.0 + mysql_row_seek@libmariadbclient_18 3.0.0 + mysql_row_seek@libmysqlclient_18 3.0.0 + mysql_row_tell@libmariadbclient_18 3.0.0 + mysql_row_tell@libmysqlclient_18 3.0.0 + mysql_select_db_cont@libmariadb_3 3.0.0 + mysql_select_db@libmariadbclient_18 3.0.0 + mysql_select_db@libmysqlclient_18 3.0.0 + mysql_select_db_start@libmariadb_3 3.0.0 + mysql_send_query_cont@libmariadb_3 3.0.0 + mysql_send_query@libmariadbclient_18 3.0.0 + mysql_send_query@libmysqlclient_18 3.0.0 + mysql_send_query_start@libmariadb_3 3.0.0 + mysql_server_end@libmariadbclient_18 3.0.0 + mysql_server_end@libmysqlclient_18 3.0.0 + mysql_server_init@libmariadbclient_18 3.0.0 + mysql_server_init@libmysqlclient_18 3.0.0 + mysql_session_track_get_first@libmariadbclient_18 3.0.0 + mysql_session_track_get_first@libmysqlclient_18 3.0.0 + mysql_session_track_get_next@libmariadbclient_18 3.0.0 + mysql_session_track_get_next@libmysqlclient_18 3.0.0 + mysql_set_character_set_cont@libmariadb_3 3.0.0 + mysql_set_character_set@libmariadbclient_18 3.0.0 + mysql_set_character_set@libmysqlclient_18 3.0.0 + mysql_set_character_set_start@libmariadb_3 3.0.0 + mysql_set_local_infile_default@libmariadbclient_18 3.0.0 + mysql_set_local_infile_default@libmysqlclient_18 3.0.0 + mysql_set_local_infile_handler@libmariadbclient_18 3.0.0 + mysql_set_local_infile_handler@libmysqlclient_18 3.0.0 + mysql_set_server_option_cont@libmariadb_3 3.0.0 + mysql_set_server_option@libmariadbclient_18 3.0.0 + mysql_set_server_option@libmysqlclient_18 3.0.0 + mysql_set_server_option_start@libmariadb_3 3.0.0 + mysql_shutdown_cont@libmariadb_3 3.0.0 + mysql_shutdown@libmariadbclient_18 3.0.0 + mysql_shutdown@libmysqlclient_18 3.0.0 + mysql_shutdown_start@libmariadb_3 3.0.0 + mysql_sqlstate@libmariadbclient_18 3.0.0 + mysql_sqlstate@libmysqlclient_18 3.0.0 + mysql_ssl_set@libmariadbclient_18 3.0.0 + mysql_ssl_set@libmysqlclient_18 3.0.0 + mysql_stat_cont@libmariadb_3 3.0.0 + mysql_stat@libmariadbclient_18 3.0.0 + mysql_stat@libmysqlclient_18 3.0.0 + mysql_stat_start@libmariadb_3 3.0.0 + mysql_stmt_affected_rows@libmariadbclient_18 3.0.0 + mysql_stmt_affected_rows@libmysqlclient_18 3.0.0 + mysql_stmt_attr_get@libmariadbclient_18 3.0.0 + mysql_stmt_attr_get@libmysqlclient_18 3.0.0 + mysql_stmt_attr_set@libmariadbclient_18 3.0.0 + mysql_stmt_attr_set@libmysqlclient_18 3.0.0 + mysql_stmt_bind_param@libmariadbclient_18 3.0.0 + mysql_stmt_bind_param@libmysqlclient_18 3.0.0 + mysql_stmt_bind_result@libmariadbclient_18 3.0.0 + mysql_stmt_bind_result@libmysqlclient_18 3.0.0 + mysql_stmt_close_cont@libmariadb_3 3.0.0 + mysql_stmt_close@libmariadbclient_18 3.0.0 + mysql_stmt_close@libmysqlclient_18 3.0.0 + mysql_stmt_close_start@libmariadb_3 3.0.0 + mysql_stmt_data_seek@libmariadbclient_18 3.0.0 + mysql_stmt_data_seek@libmysqlclient_18 3.0.0 + mysql_stmt_errno@libmariadbclient_18 3.0.0 + mysql_stmt_errno@libmysqlclient_18 3.0.0 + mysql_stmt_error@libmariadbclient_18 3.0.0 + mysql_stmt_error@libmysqlclient_18 3.0.0 + mysql_stmt_execute_cont@libmariadb_3 3.0.0 + mysql_stmt_execute@libmariadbclient_18 3.0.0 + mysql_stmt_execute@libmysqlclient_18 3.0.0 + mysql_stmt_execute_start@libmariadb_3 3.0.0 + mysql_stmt_fetch_column@libmariadbclient_18 3.0.0 + mysql_stmt_fetch_column@libmysqlclient_18 3.0.0 + mysql_stmt_fetch_cont@libmariadb_3 3.0.0 + mysql_stmt_fetch@libmariadbclient_18 3.0.0 + mysql_stmt_fetch@libmysqlclient_18 3.0.0 + mysql_stmt_fetch_start@libmariadb_3 3.0.0 + mysql_stmt_field_count@libmariadbclient_18 3.0.0 + mysql_stmt_field_count@libmysqlclient_18 3.0.0 + mysql_stmt_free_result_cont@libmariadb_3 3.0.0 + mysql_stmt_free_result@libmariadbclient_18 3.0.0 + mysql_stmt_free_result@libmysqlclient_18 3.0.0 + mysql_stmt_free_result_start@libmariadb_3 3.0.0 + mysql_stmt_init@libmariadbclient_18 3.0.0 + mysql_stmt_init@libmysqlclient_18 3.0.0 + mysql_stmt_insert_id@libmariadbclient_18 3.0.0 + mysql_stmt_insert_id@libmysqlclient_18 3.0.0 + mysql_stmt_more_results@libmariadbclient_18 3.0.0 + mysql_stmt_more_results@libmysqlclient_18 3.0.0 + mysql_stmt_next_result_cont@libmariadb_3 3.0.0 + mysql_stmt_next_result@libmariadbclient_18 3.0.0 + mysql_stmt_next_result@libmysqlclient_18 3.0.0 + mysql_stmt_next_result_start@libmariadb_3 3.0.0 + mysql_stmt_num_rows@libmariadbclient_18 3.0.0 + mysql_stmt_num_rows@libmysqlclient_18 3.0.0 + mysql_stmt_param_count@libmariadbclient_18 3.0.0 + mysql_stmt_param_count@libmysqlclient_18 3.0.0 + mysql_stmt_param_metadata@libmariadbclient_18 3.0.0 + mysql_stmt_param_metadata@libmysqlclient_18 3.0.0 + mysql_stmt_prepare_cont@libmariadb_3 3.0.0 + mysql_stmt_prepare@libmariadbclient_18 3.0.0 + mysql_stmt_prepare@libmysqlclient_18 3.0.0 + mysql_stmt_prepare_start@libmariadb_3 3.0.0 + mysql_stmt_reset_cont@libmariadb_3 3.0.0 + mysql_stmt_reset@libmariadbclient_18 3.0.0 + mysql_stmt_reset@libmysqlclient_18 3.0.0 + mysql_stmt_reset_start@libmariadb_3 3.0.0 + mysql_stmt_result_metadata@libmariadbclient_18 3.0.0 + mysql_stmt_result_metadata@libmysqlclient_18 3.0.0 + mysql_stmt_row_seek@libmariadbclient_18 3.0.0 + mysql_stmt_row_seek@libmysqlclient_18 3.0.0 + mysql_stmt_row_tell@libmariadbclient_18 3.0.0 + mysql_stmt_row_tell@libmysqlclient_18 3.0.0 + mysql_stmt_send_long_data_cont@libmariadb_3 3.0.0 + mysql_stmt_send_long_data@libmariadbclient_18 3.0.0 + mysql_stmt_send_long_data@libmysqlclient_18 3.0.0 + mysql_stmt_send_long_data_start@libmariadb_3 3.0.0 + mysql_stmt_sqlstate@libmariadbclient_18 3.0.0 + mysql_stmt_sqlstate@libmysqlclient_18 3.0.0 + mysql_stmt_store_result_cont@libmariadb_3 3.0.0 + mysql_stmt_store_result@libmariadbclient_18 3.0.0 + mysql_stmt_store_result@libmysqlclient_18 3.0.0 + mysql_stmt_store_result_start@libmariadb_3 3.0.0 + mysql_stmt_warning_count@libmariadb_3 3.0.0 + mysql_store_result_cont@libmariadb_3 3.0.0 + mysql_store_result@libmariadbclient_18 3.0.0 + mysql_store_result@libmysqlclient_18 3.0.0 + mysql_store_result_start@libmariadb_3 3.0.0 + mysql_thread_end@libmariadbclient_18 3.0.0 + mysql_thread_end@libmysqlclient_18 3.0.0 + mysql_thread_id@libmariadbclient_18 3.0.0 + mysql_thread_id@libmysqlclient_18 3.0.0 + mysql_thread_init@libmariadbclient_18 3.0.0 + mysql_thread_init@libmysqlclient_18 3.0.0 + mysql_thread_safe@libmariadbclient_18 3.0.0 + mysql_thread_safe@libmysqlclient_18 3.0.0 + mysql_use_result@libmariadbclient_18 3.0.0 + mysql_use_result@libmysqlclient_18 3.0.0 + mysql_warning_count@libmariadbclient_18 3.0.0 + mysql_warning_count@libmysqlclient_18 3.0.0 diff --cc debian/libmariadbd-dev.install index 5a4344721,000000000..3eebe631b mode 100644,000000..100644 --- a/debian/libmariadbd-dev.install +++ b/debian/libmariadbd-dev.install @@@ -1,6 -1,0 +1,5 @@@ +usr/include/mariadb/server +usr/lib/*/libmariadbd.a +usr/lib/*/libmariadbd.so +usr/lib/*/libmysqld.a +usr/lib/*/libmysqld.so - usr/lib/*/pkgconfig/mariadb.pc diff --cc debian/libmariadbd19t64.install index 000000000,000000000..cb6272044 new file mode 100644 --- /dev/null +++ b/debian/libmariadbd19t64.install @@@ -1,0 -1,0 +1,1 @@@ ++usr/lib/*/libmariadbd.so.* diff --cc debian/libmariadbd19t64.lintian-overrides index 000000000,000000000..fb5b9448a new file mode 100644 --- /dev/null +++ b/debian/libmariadbd19t64.lintian-overrides @@@ -1,0 -1,0 +1,13 @@@ ++# MyISAM stopwords that cannot be changed and spelling errors remain ++spelling-error-in-binary noone no one [usr/lib/*/libmariadbd.so.19] ++spelling-error-in-binary thats that's [usr/lib/*/libmariadbd.so.19] ++spelling-error-in-binary theres there's [usr/lib/*/libmariadbd.so.19] ++# This cannot be found in sources, seems like some artifact ++spelling-error-in-binary AfE Safe [usr/lib/*/libmariadbd.so.19] ++# Intentional package and soname difference ++libmariadbd19t64: package-name-doesnt-match-sonames libmariadbd19 ++# libmariadbd cannot have a symbols file as it would be massively large with all ++# the _ZNK* prefixed symbols leaking ++no-symbols-control-file usr/lib/x86_64-linux-gnu/libmariadbd.so.19 ++# Probably due to leaking ABI symbols ++exit-in-shared-library [usr/lib/x86_64-linux-gnu/libmariadbd.so.19] diff --cc debian/mariadb-backup.lintian-overrides index 000000000,000000000..1dd2eeb92 new file mode 100644 --- /dev/null +++ b/debian/mariadb-backup.lintian-overrides @@@ -1,0 -1,0 +1,6 @@@ ++# MyISAM stopwords that cannot be changed and spelling errors remain ++spelling-error-in-binary noone no one [usr/bin/*] ++spelling-error-in-binary thats that's [usr/bin/*] ++spelling-error-in-binary theres there's [usr/bin/*] ++# False positive from Lintian, these strings are nowhere in test in source code ++spelling-error-in-binary AfE Safe [usr/bin/*] diff --cc debian/mariadb-client-compat.install index 625736ea3,000000000..4682f0aca mode 100644,000000..100644 --- a/debian/mariadb-client-compat.install +++ b/debian/mariadb-client-compat.install @@@ -1,38 -1,0 +1,32 @@@ - usr/bin/mysql +usr/bin/mysql_convert_table_format +usr/bin/mysql_find_rows +usr/bin/mysql_fix_extensions +usr/bin/mysql_plugin +usr/bin/mysql_secure_installation +usr/bin/mysql_setpermission +usr/bin/mysql_tzinfo_to_sql +usr/bin/mysql_waitpid +usr/bin/mysqlaccess - usr/bin/mysqladmin +usr/bin/mysqlbinlog +usr/bin/mysqlcheck - usr/bin/mysqldump +usr/bin/mysqldumpslow +usr/bin/mysqlhotcopy +usr/bin/mysqlimport +usr/bin/mysqlshow +usr/bin/mysqlslap - usr/share/man/man1/mysql.1 +usr/share/man/man1/mysql_convert_table_format.1 +usr/share/man/man1/mysql_find_rows.1 +usr/share/man/man1/mysql_fix_extensions.1 +usr/share/man/man1/mysql_plugin.1 +usr/share/man/man1/mysql_secure_installation.1 +usr/share/man/man1/mysql_setpermission.1 +usr/share/man/man1/mysql_tzinfo_to_sql.1 +usr/share/man/man1/mysql_waitpid.1 +usr/share/man/man1/mysqlaccess.1 - usr/share/man/man1/mysqladmin.1 +usr/share/man/man1/mysqlbinlog.1 +usr/share/man/man1/mysqlcheck.1 - usr/share/man/man1/mysqldump.1 +usr/share/man/man1/mysqldumpslow.1 +usr/share/man/man1/mysqlhotcopy.1 +usr/share/man/man1/mysqlimport.1 +usr/share/man/man1/mysqlshow.1 +usr/share/man/man1/mysqlslap.1 diff --cc debian/mariadb-client-core.links index 000000000,000000000..77fc88f14 new file mode 100644 --- /dev/null +++ b/debian/mariadb-client-core.links @@@ -1,0 -1,0 +1,2 @@@ ++usr/bin/mariadb usr/bin/mysql ++usr/share/man/man1/mariadb.1 usr/share/man/man1/mysql.1 diff --cc debian/mariadb-client-core.lintian-overrides index 000000000,000000000..a20ba2637 new file mode 100644 --- /dev/null +++ b/debian/mariadb-client-core.lintian-overrides @@@ -1,0 -1,0 +1,2 @@@ ++# Man syntax needs to be fixed upstream ++groff-message troff::*: warning: macro 'an-trap' not defined [usr/share/man/*] diff --cc debian/mariadb-client.install index efc56b330,000000000..78828d44e mode 100644,000000..100644 --- a/debian/mariadb-client.install +++ b/debian/mariadb-client.install @@@ -1,51 -1,0 +1,55 @@@ +debian/additions/innotop/innotop usr/bin/ +debian/additions/mariadb-report usr/bin/ +debian/additions/mariadb.conf.d/50-client.cnf etc/mysql/mariadb.conf.d +debian/additions/mariadb.conf.d/50-mariadb-clients.cnf etc/mysql/mariadb.conf.d +debian/additions/mariadb.conf.d/60-galera.cnf etc/mysql/mariadb.conf.d +usr/bin/mariadb-access +usr/bin/mariadb-admin +usr/bin/mariadb-binlog +usr/bin/mariadb-conv +usr/bin/mariadb-convert-table-format +usr/bin/mariadb-dump +usr/bin/mariadb-dumpslow +usr/bin/mariadb-find-rows +usr/bin/mariadb-fix-extensions +usr/bin/mariadb-hotcopy +usr/bin/mariadb-import +usr/bin/mariadb-plugin +usr/bin/mariadb-secure-installation +usr/bin/mariadb-setpermission +usr/bin/mariadb-show +usr/bin/mariadb-slap +usr/bin/mariadb-tzinfo-to-sql +usr/bin/mariadb-waitpid +usr/bin/msql2mysql ++usr/bin/mysqladmin ++usr/bin/mysqldump +usr/bin/mytop +usr/bin/perror +usr/bin/replace +usr/bin/resolve_stack_dump +usr/share/man/man1/mariadb-access.1 +usr/share/man/man1/mariadb-admin.1 +usr/share/man/man1/mariadb-binlog.1 +usr/share/man/man1/mariadb-conv.1 +usr/share/man/man1/mariadb-convert-table-format.1 +usr/share/man/man1/mariadb-dump.1 +usr/share/man/man1/mariadb-dumpslow.1 +usr/share/man/man1/mariadb-find-rows.1 +usr/share/man/man1/mariadb-fix-extensions.1 +usr/share/man/man1/mariadb-hotcopy.1 +usr/share/man/man1/mariadb-import.1 +usr/share/man/man1/mariadb-plugin.1 +usr/share/man/man1/mariadb-secure-installation.1 +usr/share/man/man1/mariadb-setpermission.1 +usr/share/man/man1/mariadb-show.1 +usr/share/man/man1/mariadb-slap.1 +usr/share/man/man1/mariadb-tzinfo-to-sql.1 +usr/share/man/man1/mariadb-waitpid.1 +usr/share/man/man1/msql2mysql.1 ++usr/share/man/man1/mysqladmin.1 ++usr/share/man/man1/mysqldump.1 +usr/share/man/man1/mytop.1 +usr/share/man/man1/perror.1 +usr/share/man/man1/replace.1 +usr/share/man/man1/resolve_stack_dump.1 diff --cc debian/mariadb-client.lintian-overrides index 000000000,000000000..1e0263b05 new file mode 100644 --- /dev/null +++ b/debian/mariadb-client.lintian-overrides @@@ -1,0 -1,0 +1,4 @@@ ++# The Innotop changelog has this name for a valid reason ++wrong-name-for-upstream-changelog [usr/share/doc/mariadb-client/changelog.innotop.gz] ++# Man syntax needs to be fixed upstream ++groff-message troff::*: warning: macro 'an-trap' not defined [usr/share/man/*] diff --cc debian/mariadb-common.postinst index 0292a88c6,000000000..53d131a39 mode 100644,000000..100644 --- a/debian/mariadb-common.postinst +++ b/debian/mariadb-common.postinst @@@ -1,41 -1,0 +1,41 @@@ - #!/bin/bash ++#!/bin/sh + +set -e + +case "$1" in + configure) + # New packaging paradigm for my.cnf handling among MySQL variants + # Used in Ubuntu since Dec-2014 and in Debian since Jul-2015 + # + # If the new mysql-common package does not provide + # the update-alternatives facility, notify user about manual fall back + if [ -f /usr/share/mysql-common/configure-symlinks ] + then + /usr/share/mysql-common/configure-symlinks install mariadb "/etc/mysql/mariadb.cnf" + else + # As configure can be called many times, don't re-create the symlink + # if it is there already + if [ ! -L /etc/mysql/my.cnf ] + then + echo "Notice: configure-symlinks trigger could not be called." + echo "Please manually create symlinks by running: " + echo " mv -f /etc/mysql/my.cnf /etc/mysql/my.cnf.old" + echo " ln -sf mariadb.cnf /etc/mysql/my.cnf" + fi + fi + + # Note that MySQL in Debian runs the configure-symlinks from the + # mysql-server-x.x.postinst and postrm files, while the MySQL.com (and + # Percona.com) packaging triggers update-alternatives directly form the + # mysql-common (and percona-x-common) package using priority 200. + # + # Thus, we need to ensure here that mariadb.cnf indeed became the primary + # alternative and override with priority 500 if needed. + if ! update-alternatives --query my.cnf | grep --quiet "Value: /etc/mysql/mariadb.cnf" + then + update-alternatives --install /etc/mysql/my.cnf my.cnf "/etc/mysql/mariadb.cnf" 500 || true + fi + ;; +esac + +#DEBHELPER# diff --cc debian/mariadb-common.postrm index d807c63ae,000000000..2548733a1 mode 100644,000000..100644 --- a/debian/mariadb-common.postrm +++ b/debian/mariadb-common.postrm @@@ -1,16 -1,0 +1,16 @@@ - #!/bin/bash ++#!/bin/sh + +set -e + +case "$1" in + remove|disappear) + # New packaging paradigm for my.cnf handling among MySQL variants + # Used in Ubuntu since Dec-2014 and in Debian since Jul-2015 + if [ -f /usr/share/mysql-common/configure-symlinks ] + then + /usr/share/mysql-common/configure-symlinks remove mariadb "/etc/mysql/mariadb.cnf" + fi + ;; +esac + +#DEBHELPER# diff --cc debian/mariadb-common.preinst index 000000000,000000000..09ef4516d new file mode 100644 --- /dev/null +++ b/debian/mariadb-common.preinst @@@ -1,0 -1,0 +1,22 @@@ ++#!/bin/sh ++set -e ++ ++if [ "$1" = "install" ] || [ "$1" = "upgrade" ] ++then ++ if dpkg --compare-versions "$2" lt-nl "10.0.20-3~" ++ then ++ # revert fallback my.cnf symlink setup performed by mariadb-common ++ # from 10.0.17-1~exp2 up to 10.0.20-2 ++ if [ -L /etc/mysql/my.cnf ] && [ -f /etc/mysql/my.cnf.old ] ++ then ++ if [ "$(readlink /etc/mysql/my.cnf)" = "mariadb.cnf" ] ++ then ++ echo "Reverting my.cnf -> mariadb.cnf symlink setup by mariadb-common" ++ rm /etc/mysql/my.cnf ++ mv /etc/mysql/my.cnf.old /etc/mysql/my.cnf ++ fi ++ fi ++ fi ++fi ++ ++#DEBHELPER# diff --cc debian/mariadb-plugin-mroonga.lintian-overrides index 000000000,000000000..b1b061323 new file mode 100644 --- /dev/null +++ b/debian/mariadb-plugin-mroonga.lintian-overrides @@@ -1,0 -1,0 +1,5 @@@ ++# False positive from Lintian, these strings are nowhere in test in source code ++spelling-error-in-binary nam name [usr/lib/mysql/plugin/ha_mroonga.so] ++spelling-error-in-binary tage stage [usr/lib/mysql/plugin/ha_mroonga.so] ++# Copyright information in debian/copyright, extra file unnecessary ++extra-license-file [usr/share/mariadb/mroonga/COPYING] diff --cc debian/mariadb-plugin-mroonga.postinst index 7c6da3639,000000000..71731ed63 mode 100644,000000..100644 --- a/debian/mariadb-plugin-mroonga.postinst +++ b/debian/mariadb-plugin-mroonga.postinst @@@ -1,10 -1,0 +1,10 @@@ - #!/bin/bash ++#!/bin/sh + +set -e + +# Install Mroonga - mysql --defaults-file=/etc/mysql/debian.cnf < /usr/share/mysql/mroonga/install.sql || true ++mariadb --defaults-file=/etc/mysql/debian.cnf < /usr/share/mariadb/mroonga/install.sql || true +# Always exit with success instead of leaving dpkg in a broken state + + +#DEBHELPER# diff --cc debian/mariadb-plugin-mroonga.prerm index 0fde33765,000000000..54cba1e74 mode 100644,000000..100644 --- a/debian/mariadb-plugin-mroonga.prerm +++ b/debian/mariadb-plugin-mroonga.prerm @@@ -1,10 -1,0 +1,10 @@@ - #!/bin/bash ++#!/bin/sh + +set -e + +# Uninstall Mroonga +mariadb --defaults-file=/etc/mysql/debian.cnf < /usr/share/mariadb/mroonga/uninstall.sql || true +# Always exit with success instead of leaving dpkg in a broken state + + +#DEBHELPER# diff --cc debian/mariadb-plugin-provider-bzip2.lintian-overrides index 50e280b56,000000000..47298832b mode 100644,000000..100644 --- a/debian/mariadb-plugin-provider-bzip2.lintian-overrides +++ b/debian/mariadb-plugin-provider-bzip2.lintian-overrides @@@ -1,4 -1,0 +1,3 @@@ +# It's intentional that bzip2 compression plugin doesn't have symbols from libc +# More info https://jira.mariadb.org/browse/MDEV-28120 - library-not-linked-against-libc usr/lib/mysql/plugin/provider_bzip2.so +library-not-linked-against-libc [usr/lib/mysql/plugin/provider_bzip2.so] diff --cc debian/mariadb-plugin-provider-lz4.lintian-overrides index 4df09a0af,000000000..dbfde1331 mode 100644,000000..100644 --- a/debian/mariadb-plugin-provider-lz4.lintian-overrides +++ b/debian/mariadb-plugin-provider-lz4.lintian-overrides @@@ -1,4 -1,0 +1,3 @@@ +# It's intentional that LZ4 compression plugin doesn't have symbols from libc +# More info https://jira.mariadb.org/browse/MDEV-28120 - library-not-linked-against-libc usr/lib/mysql/plugin/provider_lz4.so +library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lz4.so] diff --cc debian/mariadb-plugin-provider-lzma.lintian-overrides index 2d9f4b8ad,000000000..79f6cb793 mode 100644,000000..100644 --- a/debian/mariadb-plugin-provider-lzma.lintian-overrides +++ b/debian/mariadb-plugin-provider-lzma.lintian-overrides @@@ -1,4 -1,0 +1,3 @@@ +# It's intentional that LZMA compression plugin doesn't have symbols from libc +# More info https://jira.mariadb.org/browse/MDEV-28120 - library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzma.so +library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lzma.so] diff --cc debian/mariadb-plugin-provider-lzo.lintian-overrides index 13015fde8,000000000..ccca4e2d3 mode 100644,000000..100644 --- a/debian/mariadb-plugin-provider-lzo.lintian-overrides +++ b/debian/mariadb-plugin-provider-lzo.lintian-overrides @@@ -1,4 -1,0 +1,3 @@@ +# It's intentional that LZO compression plugin doesn't have symbols from libc +# More info https://jira.mariadb.org/browse/MDEV-28120 - library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzo.so +library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lzo.so] diff --cc debian/mariadb-plugin-provider-snappy.lintian-overrides index 2ddf25d0d,000000000..b62907c34 mode 100644,000000..100644 --- a/debian/mariadb-plugin-provider-snappy.lintian-overrides +++ b/debian/mariadb-plugin-provider-snappy.lintian-overrides @@@ -1,4 -1,0 +1,3 @@@ +# It's intentional that Snappy compression plugin doesn't have symbols from libc +# More info https://jira.mariadb.org/browse/MDEV-28120 - library-not-linked-against-libc usr/lib/mysql/plugin/provider_snappy.so +library-not-linked-against-libc [usr/lib/mysql/plugin/provider_snappy.so] diff --cc debian/mariadb-plugin-rocksdb.lintian-overrides index 000000000,000000000..907669556 new file mode 100644 --- /dev/null +++ b/debian/mariadb-plugin-rocksdb.lintian-overrides @@@ -1,0 -1,0 +1,2 @@@ ++# Fixed upstream in https://github.com/facebook/rocksdb/pull/6481 but not yet in MariaDB ++spelling-error-in-binary COMMITED COMMITTED [usr/lib/mysql/plugin/ha_rocksdb.so] diff --cc debian/mariadb-server-compat.install index 48a8b811c,000000000..51f446ac0 mode 100644,000000..100644 --- a/debian/mariadb-server-compat.install +++ b/debian/mariadb-server-compat.install @@@ -1,12 -1,0 +1,4 @@@ - usr/bin/mysql_install_db - usr/bin/mysql_upgrade +usr/bin/mysqld_multi - usr/bin/mysqld_safe +usr/bin/mysqld_safe_helper - usr/sbin/mysqld - usr/share/man/man1/mysql_install_db.1 - usr/share/man/man1/mysql_upgrade.1 +usr/share/man/man1/mysqld_multi.1 - usr/share/man/man1/mysqld_safe.1 +usr/share/man/man1/mysqld_safe_helper.1 - usr/share/man/man8/mysqld.8 diff --cc debian/mariadb-server-core.links index 000000000,000000000..2729efd65 new file mode 100644 --- /dev/null +++ b/debian/mariadb-server-core.links @@@ -1,0 -1,0 +1,6 @@@ ++usr/bin/mariadb-install-db usr/bin/mysql_install_db ++usr/bin/mariadb-upgrade usr/bin/mysql_upgrade ++usr/sbin/mariadbd usr/sbin/mysqld ++usr/share/man/man1/mariadb-install-db.1 usr/share/man/man1/mysql_install_db.1 ++usr/share/man/man1/mariadb-upgrade.1 usr/share/man/man1/mysql_upgrade.1 ++usr/share/man/man8/mariadbd.8 usr/share/man/man8/mysqld.8 diff --cc debian/mariadb-server-core.lintian-overrides index 000000000,000000000..f8bf15f92 new file mode 100644 --- /dev/null +++ b/debian/mariadb-server-core.lintian-overrides @@@ -1,0 -1,0 +1,10 @@@ ++# MyISAM stopwords that cannot be changed and spelling errors remain ++spelling-error-in-binary noone no one [usr/sbin/mariadbd] ++spelling-error-in-binary thats that's [usr/sbin/mariadbd] ++spelling-error-in-binary theres there's [usr/sbin/mariadbd] ++# False positive from Lintian, these strings are nowhere in test in source code ++spelling-error-in-binary AfE Safe [usr/sbin/mariadbd] ++# Valid reason for extra documentation in context in directory ++package-contains-documentation-outside-usr-share-doc [usr/share/mariadb/charsets/README] ++# Man syntax needs to be fixed upstream ++groff-message troff::*: warning: macro 'an-trap' not defined [usr/share/man/*] diff --cc debian/mariadb-server.NEWS index 000000000,000000000..bdc162385 new file mode 100644 --- /dev/null +++ b/debian/mariadb-server.NEWS @@@ -1,0 -1,0 +1,227 @@@ ++mariadb (1:10.11.2-1) unstable; urgency=medium ++ ++ MariaDB 10.11.2 was released on February 16th 2023 by the MariaDB Foundation ++ (https://mariadb.org/mariadb-10-11-2-ga-now-available/). This is the first ++ release in the 10.11 series to be announced GA (general availability). The ++ 10.11 series has long-term support with commitment from the MariaDB Foundation ++ (https://mariadb.org/about/#maintenance-policy) to publish maintenance ++ versions with fixes to software defects and security vulnerabilities until ++ February 2028. ++ ++ The previous major releases (10.7, 10.8, 10.9, 10.10) were not long-terms ++ supported versions and thus not imported to Debian. To learn what is new in ++ 10.11 it is recommended to read all the release notes: ++ ++ * https://mariadb.com/kb/en/changes-improvements-in-mariadb-1011/ ++ * https://mariadb.com/kb/en/changes-improvements-in-mariadb-1010/ ++ * https://mariadb.com/kb/en/changes-improvements-in-mariadb-109/ ++ * https://mariadb.com/kb/en/changes-improvements-in-mariadb-108/ ++ * https://mariadb.com/kb/en/changes-improvements-in-mariadb-107/ ++ ++ Notable new features: ++ - New datatypes UUID and INET4 ++ - New functions SFORMAT (text formatting), NATURAL_SORT_KEY, RANDOM_BYTES and ++ several related to JSON ++ - New keyword AUTO in system versioned tables for partitioning ++ (https://mariadb.com/kb/en/system-versioned-tables/#automatically-creating-partitions) ++ - Unicode Collation Algorithm (UCA) upgrade to 14.0.0 ++ - New privileges 'READ ONLY ADMIN' and 'GRANT TO PUBLIC' ++ (https://mariadb.org/grant-to-public-in-mariadb/) ++ - password_reuse_check plugin (part of mariadb-server package) ++ - Hashicorp Key Management Plugin for implementing encryption using keys ++ stored in the Hashicorp Vault KMS (mariadb-plugin-hashicorp-key-management ++ package) ++ ++ Important packaging change: Compression libraries have been split into ++ separate packages named mariadb-provider-plugin-(bzip2/lz4/lzma/lzo/snappy). ++ If a non-zlib compression algorithm was used in InnoDB or Mroonga before ++ upgrading to 10.11, those tables will be unreadable until the appropriate ++ compression library is installed. ++ ++ Things to consider when upgrading from 10.6 to 10.11 are listed on the page ++ https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-11/. ++ ++ New server variables in 10.11 (compared to 10.6): ++ - binlog-alter-two-phase: When set, split ALTER at binary logging into 2 ++ statements: START ALTER and COMMIT/ROLLBACK ALTER. Defaults to 'FALSE'. ++ - innodb-log-file-buffering: Whether the file system cache for ib_logfile0 is ++ enabled ++ - optimizer-extra-pruning-depth: If the optimizer needs to enumerate join ++ prefix of this size or larger, then it will try aggressively prune away the ++ search space. ++ - log-slow-min-examined-row-limit: Don't write queries to slow log that ++ examine fewer rows than that ++ - log-slow-query: Log slow queries to a table or log file. Defaults logging to ++ a file 'hostname'-slow.log or a table mysql.slow_log if --log-output=TABLE ++ is used. Must be enabled to activate other slow log options. ++ - log-slow-query-file: Log slow queries to given log file. Defaults logging to ++ 'hostname'-slow.log. Must be enabled to activate other slow log options ++ - log-slow-query-time: Log all queries that have taken more than ++ log_slow_query_time seconds to execute to the slow query log file. The ++ argument will be treated as a decimal value with microsecond precision ++ - slave-max-statement-time: A query that has taken more than ++ slave_max_statement_time seconds to run on the slave will be aborted. The ++ argument will be treated as a decimal value with microsecond precision. A ++ value of 0 (default) means no timeout ++ - system-versioning-insert-history: Allows direct inserts into ROW_START and ++ ROW_END columns if secure_timestamp allows changing @@timestamp ++ - wsrep-allowlist: Allowed IP addresses split by comma delimiter ++ - wsrep-status-file: wsrep status output filename ++ ++ Changed behavior in server variables in 10.11 (compared to 10.6): ++ - explicit-defaults-for-timestamp: enabled by default ++ - optimizer-prune-level: defaults to 2 (instead of 1) ++ - old-mode: new options IGNORE_INDEX_ONLY_FOR_JOIN and COMPAT_5_1_CHECKSUM ++ - wsrep-mode: new option BF_ABORT_MARIABACKUP ++ - read-only: changing value requires 'READ ONLY ADMIN' privilege ++ ++ One of the most important performance related server variables ++ 'innodb_log_file_size' is now dynamic so it can be changed without having to ++ restart the server. ++ ++ Removed in 10.11 (compared to 10.6): ++ - innodb-log-write-ahead-size: the physical block size of the underlying ++ storage is instead detected and used ++ - wsrep-replicate-myisam: use wsrep_mode instead ++ - wsrep-strict-ddl: use wsrep_mode instead ++ ++ Deprecated server variables: ++ - innodb_change_buffering ++ - innodb-buffer-pool-chunk-size: defaults to 0 (instead of 134217728) in ++ server variables because the server automatically sizes it ++ - keep_files_on_create: orphan files are now deleted automatically, so this ++ setting should never be needed ++ ++ Note also that the MariaDB client settings have changed to now use SSL/TLS ++ by default. ++ ++ -- Otto Kekäläinen Thu, 16 Feb 2023 23:53:02 -0800 ++ ++mariadb (1:10.11.1-1) unstable; urgency=medium ++ ++ Version suffixed packages (e.g. mariadb-server-10.6) have now been deprecated ++ as it made maintenance complicated and there was no known use cases or users ++ of the naming scheme, as multiple different major version MariaDB server ++ packages could not be co-installed anyway and source or the 'mariadb-server' ++ and 'mariadb-client' packages is easiest controlled by repositories and ++ package versioning, not versions in package *names*. ++ ++ -- Otto Kekäläinen Mon, 02 Jan 2023 23:42:58 -0800 ++ ++mariadb-10.6 (1:10.6.4-1) unstable; urgency=medium ++ ++ Import new upstream release MariaDB 10.6.4 ++ - 10.6 introduces one new status variable: ++ * Innodb_buffer_pool_pages_lru_freed ++ (https://mariadb.com/kb/en/status-variables-added-in-mariadb-106/) ++ * Resultset_metadata_skipped ++ (undocumented upstream https://mariadb.com/docs/reference/mdb/status-variables/Resultset_metadata_skipped/) ++ ++ Read more at https://mariadb.com/kb/en/status-variables-added-in-mariadb-106/ ++ ++ - 10.6 introduces several new server variables: ++ * binlog_expire_logs_seconds ++ * innodb_deadlock_report ++ * innodb_read_only_compressed ++ ++ Read more at https://mariadb.com/kb/en/system-variables-added-in-mariadb-106/ ++ ++ - 10.6 removes several server variables: ++ * innodb_adaptive_max_sleep_delay ++ * innodb_background_scrub_data_* ++ * innodb_buffer_pool_instances ++ * innodb_commit_concurrency ++ * innodb_concurrency_tickets ++ * innodb_file_format ++ * innodb_large_prefix ++ * innodb_lock_schedule_algorithm ++ * innodb_log_checksums ++ * innodb_log_compressed_pages ++ * innodb_log_files_in_group ++ * innodb_log_optimize_ddl ++ * innodb_page_cleaners ++ * innodb_replication_delay (*not* related to https://mariadb.com/kb/en/delayed-replication/) ++ * innodb_scrub_* ++ * innodb_sync_array_size ++ * innodb_thread_* ++ * innodb_undo_logs ++ ++ Read more at https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/#options-that-have-been-removed-or-renamed ++ ++ - 10.6 introduces new default server variable values: ++ * character sets utf8 -> utf8mb3 ++ * innodb_flush_method fsync -> O_DIRECT ++ * innodb_use_native_aio ON -> OFF ++ * old_mode (none) -> UTF8_IS_UTF8MB3 ++ ++ - 10.6 introduces new 'sys' database and several 'sys' procedures ++ ++ Read more at https://mariadb.com/kb/en/sys-schema/ ++ ++ - Read more about above changes at ++ https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/ ++ https://mariadb.com/kb/en/changes-improvements-in-mariadb-106/ ++ ++ - Update libmariadb folder to match the one in MariaDB 10.6.4 ++ (MariaDB Connector C 10.6.4) ++ ++ -- Otto Kekäläinen Mon, 06 Sep 2021 22:55:39 -0700 ++ ++mariadb-10.5 (1:10.5.5-1) unstable; urgency=medium ++ ++ The latest version 10.5 of the MariaDB Server came out in June 2020 and is ++ guaranteed to have security releases at least until summer 2025. ++ ++ For more information on what is new in MariaDB 10.5 check out: ++ https://speakerdeck.com/ottok/debconf-2020-whats-new-in-mariadb-server-10-dot-5-and-galera-4 ++ or video from https://peertube.debian.social/videos/watch/bb80cf53-d9ba-4ed9-b472-a21238fb67f5. ++ ++ Quick summary: ++ - Service name is now 'mariadb', e.g. /etc/init.d/mariadb and systemctl mariadb ++ - The main server binary is now running as 'mariadbd' instead of old 'mysqld' ++ - Many commands are now mariadb-* instead of old mysql*, but old names ++ continue to work as symlinks ++ - Referencing the /etc/mysql/debian.cnf file is not advised anymore. It will ++ be deprecated in a future Debian release and has been obsolete anyway for ++ several years now since MariaDB in Debian introduced Unix socket ++ authentication for the root account in 2015. ++ ++ MariaDB 10.5 has been tested to be backwards compatible with all previous ++ versions of MariaDB and all previous versions of MySQL up until version 5.7. ++ Note that MySQL 8.0 introduces significant backwards incompatible changes ++ compared to MySQL 5.7, and thus in-place binary upgrades from MySQL 8.0 to ++ MariaDB 10.5 are not possible, but sysadmins need to upgrade by exporting and ++ importing SQL dumps of their databases. ++ ++ If you encounter any bugs, please make sure your bug report is of highest ++ standards so we can quickly reproduce and fix the issue. Even better if you ++ find the solution yourself, and can submit it as a Merge Request at ++ https://salsa.debian.org/mariadb-team/mariadb-10.5/ ++ ++ If you appreciate the Debian packaging work done, please star us on Salsa! ++ ++ -- Otto Kekäläinen Thu, 17 Sep 2020 14:37:47 +0300 ++ ++mariadb-10.1 (10.1.20-1) unstable; urgency=low ++ ++ MariaDB is now the default MySQL variant in Debian, at version 10.1. The ++ Stretch release introduces a new mechanism for switching the default ++ variant, using metapackages created from the 'mysql-defaults' source ++ package. For example, installing the metapackage 'default-mysql-server' will ++ install 'mariadb-server-10.1'. Users who had 'mysql-server-5.5' or ++ 'mysql-server-5.6' will have it removed and replaced by the MariaDB ++ equivalent. Similarly, installing 'default-mysql-client' will install ++ 'mariadb-client-10.1'. ++ ++ Note that the database binary data file formats are not backwards ++ compatible, so once you have upgraded to MariaDB 10.1 you will not be able ++ to switch back to any previous version of MariaDB or MySQL unless you have a ++ proper database dump. Therefore, before upgrading, please make backups of ++ all important databases with an appropriate tool such as 'mysqldump'. ++ ++ The 'virtual-mysql-*' and 'default-mysql-*' packages will continue to exist. ++ MySQL continues to be maintained in Debian, in the unstable release. See the ++ page https://wiki.debian.org/Teams/MySQL more information about the ++ mysql-related software available in Debian. ++ ++ -- Otto Kekäläinen Tue, 14 Mar 2017 16:21:58 +0200 diff --cc debian/mariadb-server.README.Debian index 7f229a149,000000000..68726f8b1 mode 100644,000000..100644 --- a/debian/mariadb-server.README.Debian +++ b/debian/mariadb-server.README.Debian @@@ -1,203 -1,0 +1,204 @@@ - * MARIADB WON'T START OR STOP? - ============================== ++* MYSQL WON'T START OR STOP? ++============================ + +The most common reasons the server does not start are: +- AppArmor is enforced and something is wrong with the confinement profile. +- Process supervisor scripts (init, systemd etc) fail to execute normally. +- The configuration in /etc/mysql/... is wrong and prevents server from running. + +First check the contents of syslog (or systemd journal) and then check the +logs at /var/log/mysql/ for any hints of what might be wrong. + +Examples: - grep mariadbd /var/log/syslog ++ grep mysql /var/log/syslog + journalctl -u mariadb + + - * NEW SERVICE NAME, PROCESS AND BINARY NAMES SINCE MARIADB 10.5 - =============================================================== ++* NEW SERVICE NAME, PROCESS AND BINARY NAMES IN MARIADB 10.5 ++============================================================ + +Starting form MariaDB 10.5, the default SysV init service name is 'mariadb', +and can be accessed at path /etc/init.d/mariadb. The alias 'mysql' is only +created on upgrades. + +On systemd services both 'mariadb' and alias 'mysql' are available all the time. + +Note that the new daemon name is 'mariadbd' instead of 'mysqld' and also most +of the binaries have been renamed to mariadb-something, yet the old mysql-something +name has been kept as a symbolic link to the new name for backwards compatibility. + + +* NATIVE SYSTEMD SERVICE INTRODUCED IN MARIADB 10.1 +=================================================== + +From MariaDB 10.1 onward the upstream mariadb.service and mariadb@.service are +used to provide the full systemd experience. Some features available in +traditional /etc/init.d/mysql have been changed. For details see +https://mariadb.com/kb/en/mariadb/systemd/ + + +* MIXING PACKAGES FROM MARIADB.ORG AND OFFICIAL DEBIAN REPOSITORIES - =================================================================== ++================================================================== + +Please note that the MariaDB packaging in official Debian repositories are of +a completely new generation compared to the legacy packaging used in MariaDB.org +repositories. You cannot mix and match MariaDB 10.1 packages from official +Debian (or Ubuntu) repositories with packages from MariaDB.org repositories. +Packages from the MariaDB.org repositories include the revision string '+maria'. + +If a MariaDB.org repository is enabled, learn to use apt pinning properly. + +Please do not file bugs in Debian regarding packages with '+maria' in the +revision string. + + +* ROOT USER AUTHENTICATION VIA UNIX SOCKET +========================================== + +On new installs no root password is set and no debian-sys-maint user is +created anymore. Instead the MariaDB root account is set to be authenticated - using the Unix socket, e.g. any mariadb invocation by root or via sudo will - let the user see the MariaDB prompt. ++using the Unix socket, e.g. any mysqld invocation by root or via sudo will ++let the user see the mysqld prompt. + - You may never ever delete the MariaDB user "root". Although it has no password ++You may never ever delete the mysql user "root". Although it has no password +is set, the unix_auth plugin ensure that it can only be run locally as the root +user. + +The credentials in /etc/mysql/debian.cnf specify the user which is used by the +init scripts to stop the server and perform log rotation. This used to be the +debian-sys-maint user which is no longer used as root can run directly. + +If you have start/stop problems make sure that the /etc/mysql/debian.cnf file +specifies the root user and no password. In the long run please stop using that +file as is has been obsoleted. + + +* MARIADB IS SECURE BY DEFAULT +============================== + +MariaDB in Debian is secure by default, because: + +- It only listens to the localhost socket and cannot be accessed remotely unless + the sysadmin changes the configuration in /etc/mysql to allow so. +- There is no debian-sys-maint with password in /etc/mysql/debian.cnf anymore. +- There is no root account with password anymore. The system admin needs to + create one themselves if they need it. With no password, all issues related + to password management and password leaking are gone. Sysadmins can access - the database without a password simply by running 'sudo mariadb' thanks to ++ the database without a password simply by running 'sudo mysql' thanks to + socket based authentication, which detects the system root user and allows - them to use the mariadb console as the MariaDB root user. For details see ++ them to use the mysqld console as the mysql root user. For details see + https://www.slideshare.net/ottokekalainen/less-passwords-more-security-unix-socket-authentication-and-other-mariadb-hardening-tips +- There is no test database nor test accounts in the out-of-the-box Debian + installation. + - Therefore there is also no need to run the 'mariadb-secure-installation'. In fact ++Therefore there is also no need to run the 'mysql_secure_installation'. In fact +that script will try to do things that are already prevented, and might fail. + + +* WHAT TO DO AFTER UPGRADES +=========================== + +The privilege tables are automatically updated so all there is left is read +the release notes on https://mariadb.com/kb/en/release-notes/ to see if any +changes affect custom apps. + - There should not be any need to run 'mariadb-upgrade' manually, as the upgrade ++There should not be any need to run 'mysql_upgrade' manually, as the upgrade +scripts do that automatically. + + +* WHAT TO DO AFTER INSTALLATION +=============================== + - The MariaDB manual describes certain steps to do at this stage in a separate ++The MySQL manual describes certain steps to do at this stage in a separate +chapter. They are not necessary as the Debian packages does them +automatically. + - There should not be any need to run 'mariadb-install-db' manually, as the install ++There should not be any need to run 'mysql_install_db' manually, as the install +scripts do that automatically. + +The only thing that is left over for the admin is + - creating new users and databases + - read the rest of this text + + +* NETWORKING +============ + +For security reasons, the Debian package has enabled networking only on the - loop-back device using "bind-address" in /etc/mysql/mariadb.cnf. Check with ++loop-back device using "bind-address" in /etc/mysql/my.cnf. Check with +"netstat -tlnp" where it is listening. If your connection is aborted +immediately check your firewall rules or network routes. + +* WHERE IS THE DOCUMENTATION? +============================= + +https://mariadb.com/kb + + +* PASSWORDS +=========== + +It is recommended you create additional admin users for your database +administration needs in addition to the default root user. + +If your local Unix account is the one you want to have local super user +access on your database with you can create the following account that will +only work for the local Unix user connecting to the database locally. + + sudo /usr/bin/mariadb -e "GRANT ALL ON *.* TO '$USER'@'localhost' IDENTIFIED VIA unix_socket WITH GRANT OPTION" + +To create a local machine account username=USERNAME with a password: + + sudo /usr/bin/mariadb -e "GRANT ALL ON *.* TO 'USERNAME'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION" + +To create a USERNAME user with password 'password' admin user that can access +the DB server over the network: + + sudo /usr/bin/mariadb -e "GRANT ALL ON *.* TO 'USERNAME'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION" + +Scripts should run as a user who have the required grants and be identified via unix_socket. + +It is wise to run scripts as the "mysql" system user. Like root, +mysql@localhost is created by default to have all privileges in MariaDB +and to use unix_socket authentication. But scripts running under "mysql" +won't have system-wide root so they won't be able to corrupt your system. + +If you are too tired to type the password in every time and unix_socket auth +doesn't suit your needs, you can store it in the file $HOME/.my.cnf. It should +be chmod 0600 (-rw------- username usergroup .my.cnf) to ensure that nobody else +can read it. Every other configuration parameter can be stored there, too. + +For more information in the MariaDB manual in/usr/share/doc/mariadb-doc or +https://mariadb.com/kb/en/configuring-mariadb-with-mycnf/. + + +* FURTHER NOTES ON REPLICATION +============================== + - If the MariaDB server is acting as a replica, you should not set --tmpdir to - point to a directory on a memory-based file system or to a directory that is - cleared when the server host restarts. A replica needs some of its temporary - files to survive a machine restart so that it can replicate temporary tables - or LOAD DATA INFILE operations. If files in the temporary file directory are - lost when the server restarts, replication fails. ++If the MySQL server is acting as a replication slave, you should not ++set --tmpdir to point to a directory on a memory-based file system or to ++a directory that is cleared when the server host restarts. A replication ++slave needs some of its temporary files to survive a machine restart so ++that it can replicate temporary tables or LOAD DATA INFILE operations. If ++files in the temporary file directory are lost when the server restarts, ++replication fails. + + +* DOWNGRADING +============= + +Unsupported. Period. + +You might get lucky downgrading a few minor versions without issued. Take a +backup first. If you break it you get to keep both pieces. Do a restore from +backup or upgrade to the previous version. + - If doing a major version downgrade, take a mariadb-dump/maria-backup consistent ++If doing a major version downgrade, take a mysqldump/maria-backup consistent +backup using the current version and reload after downgrading and purging +existing databases. + + +* BACKUPS +========= + +Backups save jobs. Don't get caught without one. diff --cc debian/mariadb-server.config index 7875b1843,000000000..9913c33f6 mode 100644,000000..100644 --- a/debian/mariadb-server.config +++ b/debian/mariadb-server.config @@@ -1,14 -1,0 +1,20 @@@ +#!/bin/bash + +set -e + ++# shellcheck source=/dev/null +. /usr/share/debconf/confmodule + - if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi - ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } ++if [ -n "$DEBIAN_SCRIPT_DEBUG" ] ++then ++ set -v -x; DEBIAN_SCRIPT_TRACE=1 ++fi ++ ++${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2} + +# Beware that there are two ypwhich one of them needs the 2>/dev/null! - if test -n "`which ypwhich 2>/dev/null`" && ypwhich >/dev/null 2>&1; then ++if test -n "$(command -v ypwhich 2>/dev/null)" && ypwhich > /dev/null 2>&1 ++then + db_input high mariadb-server/nis_warning || true + db_go +fi diff --cc debian/mariadb-server.insserv.conf index 000000000,000000000..cb29a5477 new file mode 100644 --- /dev/null +++ b/debian/mariadb-server.insserv.conf @@@ -1,0 -1,0 +1,1 @@@ ++$database mysql diff --cc debian/mariadb-server.install index c0f6dc1e3,000000000..89f3c0c5a mode 100644,000000..100755 --- a/debian/mariadb-server.install +++ b/debian/mariadb-server.install @@@ -1,84 -1,0 +1,90 @@@ ++#!/usr/bin/dh-exec +debian/additions/debian-start etc/mysql +debian/additions/debian-start.inc.sh usr/share/mariadb +debian/additions/echo_stderr usr/share/mariadb ++debian/additions/mariadb.conf.d/50-mysqld_safe.cnf etc/mysql/mariadb.conf.d +debian/additions/mariadb.conf.d/50-server.cnf etc/mysql/mariadb.conf.d +debian/additions/source_mariadb.py usr/share/apport/package-hooks +etc/apparmor.d/usr.sbin.mariadbd +etc/logrotate.d/mariadb +etc/security/user_map.conf - lib/*/security/pam_user_map.so - lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf - lib/systemd/system/mariadb-extra@.socket - lib/systemd/system/mariadb.service - lib/systemd/system/mariadb@.service - lib/systemd/system/mariadb@.socket - lib/systemd/system/mysql.service - lib/systemd/system/mysqld.service - support-files/rpm/enable_encryption.preset etc/mysql/mariadb.conf.d/99-enable-encryption.cnf.preset ++usr/lib/*/security/pam_user_map.so ++[linux-any] usr/lib/systemd/system/mariadb-extra.socket ++[linux-any] usr/lib/systemd/system/mariadb-extra@.socket ++[linux-any] usr/lib/systemd/system/mariadb.service ++[linux-any] usr/lib/systemd/system/mariadb@.service ++[linux-any] usr/lib/systemd/system/mariadb.socket ++[linux-any] usr/lib/systemd/system/mariadb@.socket ++[linux-any] usr/lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf ++[linux-any] usr/lib/systemd/system/mysql.service ++[linux-any] usr/lib/systemd/system/mysqld.service +usr/bin/aria_chk +usr/bin/aria_dump_log +usr/bin/aria_ftdump +usr/bin/aria_pack +usr/bin/aria_read_log - usr/bin/galera_new_cluster - usr/bin/galera_recovery - usr/bin/mariadb-service-convert ++[linux-any] usr/bin/galera_new_cluster ++[linux-any] usr/bin/galera_recovery ++[linux-any] usr/bin/mariadb-service-convert +usr/bin/mariadbd-multi +usr/bin/mariadbd-safe +usr/bin/mariadbd-safe-helper +usr/bin/myisam_ftdump +usr/bin/myisamchk +usr/bin/myisamlog +usr/bin/myisampack ++usr/bin/mysqld_safe ++usr/bin/wsrep_sst_backup +usr/bin/wsrep_sst_common +usr/bin/wsrep_sst_mariabackup +usr/bin/wsrep_sst_mysqldump +usr/bin/wsrep_sst_rsync +usr/bin/wsrep_sst_rsync_wan +usr/lib/mysql/plugin/auth_ed25519.so - usr/lib/mysql/plugin/auth_pam.so +usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool +usr/lib/mysql/plugin/auth_pam_v1.so - usr/lib/mysql/plugin/disks.so ++usr/lib/mysql/plugin/auth_pam.so ++[linux-any] usr/lib/mysql/plugin/disks.so +usr/lib/mysql/plugin/file_key_management.so +usr/lib/mysql/plugin/ha_archive.so +usr/lib/mysql/plugin/ha_blackhole.so +usr/lib/mysql/plugin/ha_federated.so +usr/lib/mysql/plugin/ha_federatedx.so +usr/lib/mysql/plugin/ha_sphinx.so +usr/lib/mysql/plugin/handlersocket.so +usr/lib/mysql/plugin/locales.so +usr/lib/mysql/plugin/metadata_lock_info.so +usr/lib/mysql/plugin/password_reuse_check.so +usr/lib/mysql/plugin/query_cache_info.so +usr/lib/mysql/plugin/query_response_time.so +usr/lib/mysql/plugin/server_audit.so +usr/lib/mysql/plugin/simple_password_check.so +usr/lib/mysql/plugin/sql_errlog.so +usr/lib/mysql/plugin/type_mysql_json.so +usr/lib/mysql/plugin/wsrep_info.so +usr/share/doc/mariadb-server/mariadbd.sym.gz +usr/share/man/man1/aria_chk.1 +usr/share/man/man1/aria_dump_log.1 +usr/share/man/man1/aria_ftdump.1 +usr/share/man/man1/aria_pack.1 +usr/share/man/man1/aria_read_log.1 - usr/share/man/man1/galera_new_cluster.1 - usr/share/man/man1/galera_recovery.1 - usr/share/man/man1/mariadb-service-convert.1 ++[linux-any] usr/share/man/man1/galera_new_cluster.1 ++[linux-any] usr/share/man/man1/galera_recovery.1 ++[linux-any] usr/share/man/man1/mariadb-service-convert.1 +usr/share/man/man1/mariadbd-multi.1 +usr/share/man/man1/mariadbd-safe-helper.1 +usr/share/man/man1/mariadbd-safe.1 +usr/share/man/man1/myisam_ftdump.1 +usr/share/man/man1/myisamchk.1 +usr/share/man/man1/myisamlog.1 +usr/share/man/man1/myisampack.1 ++usr/share/man/man1/mysqld_safe.1 +usr/share/man/man1/wsrep_sst_backup.1 +usr/share/man/man1/wsrep_sst_common.1 +usr/share/man/man1/wsrep_sst_mariabackup.1 +usr/share/man/man1/wsrep_sst_mysqldump.1 - usr/share/man/man1/wsrep_sst_rsync.1 +usr/share/man/man1/wsrep_sst_rsync_wan.1 ++usr/share/man/man1/wsrep_sst_rsync.1 +usr/share/mariadb/mini-benchmark - usr/share/mariadb/wsrep.cnf +usr/share/mariadb/wsrep_notify ++usr/share/mariadb/wsrep.cnf diff --cc debian/mariadb-server.lintian-overrides index 000000000,000000000..c5de18eb9 new file mode 100644 --- /dev/null +++ b/debian/mariadb-server.lintian-overrides @@@ -1,0 -1,0 +1,22 @@@ ++# False positive in Lintian, template is actually used ++unused-debconf-template mariadb-server/old_data_directory_saved [templates:2] ++# MyISAM stopwords that cannot be changed and spelling errors remain ++spelling-error-in-binary noone no one [usr/bin/*] ++spelling-error-in-binary thats that's [usr/bin/*] ++spelling-error-in-binary theres there's [usr/bin/*] ++# False positive from Lintian, these strings are nowhere in test in source code ++spelling-error-in-binary AfE Safe [usr/bin/*] ++# Man syntax needs to be fixed upstream ++groff-message troff::*: warning: macro 'an-trap' not defined [usr/share/man/*] ++# Most likely false positive ++hardening-no-fortify-functions [usr/lib/mysql/plugin/auth_pam_v1.so] ++hardening-no-fortify-functions [usr/lib/mysql/plugin/auth_pam.so] ++hardening-no-fortify-functions [usr/lib/mysql/plugin/file_key_management.so] ++hardening-no-fortify-functions [usr/lib/mysql/plugin/ha_archive.so] ++hardening-no-fortify-functions [usr/lib/mysql/plugin/ha_blackhole.so] ++hardening-no-fortify-functions [usr/lib/x86_64-linux-gnu/security/pam_user_map.so] ++# Special purpose executable to implement custom system permissions ++executable-in-usr-lib [usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool] ++# Intentional to handle upgrades from versioned package names to versionless ++# (e.g. mariadb-server-10.5 -> mariadb-server) ++uses-dpkg-database-directly [postinst] diff --cc debian/mariadb-server.logcheck.ignore.server index a64fc54e1,000000000..7db321a02 mode 100644,000000..100644 --- a/debian/mariadb-server.logcheck.ignore.server +++ b/debian/mariadb-server.logcheck.ignore.server @@@ -1,30 -1,0 +1,30 @@@ +/etc/init.d/mariadb\[[0-9]+\]: [0-9]+ processes alive and '/usr/bin/mysqladmin --defaults-(extra-)?file=/etc/mysql/debian.cnf ping' resulted in$ +/etc/init.d/mariadb\[[0-9]+\]: Check that mariadbd is running and that the socket: '/run/mysqld/mysqld.sock' exists\!$ +/etc/init.d/mariadb\[[0-9]+\]: '/usr/bin/mysqladmin --defaults-(extra-)?file=/etc/mysql/debian.cnf ping' resulted in$ +/etc/mysql/debian-start\[[0-9]+\]: Checking for crashed MySQL tables\.$ +mariadbd\[[0-9]+\]: ?$ +mariadbd\[[0-9]+\]: .*InnoDB: Shutdown completed +mariadbd\[[0-9]+\]: .*InnoDB: Started; +mariadbd\[[0-9]+\]: .*InnoDB: Starting shutdown\.\.\.$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: Normal shutdown$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: ready for connections\.$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: Shutdown complete$ +mariadbd\[[0-9]+\]: /usr/sbin/mariadbd: ready for connections\.$ +mariadbd\[[0-9]+\]: .*/usr/sbin/mariadbd: Shutdown Complete$ +mariadbd\[[0-9]+\]: Version: .* socket +mariadbd\[[0-9]+\]: Warning: Ignoring user change to 'mysql' because the user was set to 'mysql' earlier on the command line$ +mysqld_safe\[[0-9]+\]: ?$ +mysqld_safe\[[0-9]+\]: able to use the new GRANT command!$ +mysqld_safe\[[0-9]+\]: ended$ +mysqld_safe\[[0-9]+\]: NOTE: If you are upgrading from a MySQL <= 3.22.10 you should run$ +mysqld_safe\[[0-9]+\]: PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !$ - mysqld_safe\[[0-9]+\]: Please report any problems at https://mariadb.org/jira$ ++mysqld_safe\[[0-9]+\]: Please report any problems at https://jira.mariadb.org$ +mysqld_safe\[[0-9]+\]: See the manual for more instructions.$ +mysqld_safe\[[0-9]+\]: started$ +mysqld_safe\[[0-9]+\]: The latest information about MariaDB is available at$ +mysqld_safe\[[0-9]+\]: the /usr/bin/mysql_fix_privilege_tables. Otherwise you will not be$ +mysqld_safe\[[0-9]+\]: To do so, start the server, then issue the following commands:$ +mysqld_safe\[[0-9]+\]: /usr/bin/mysqladmin -u root -h app109 password 'new-password'$ +mysqld_safe\[[0-9]+\]: /usr/bin/mysqladmin -u root password 'new-password'$ +usermod\[[0-9]+\]: change user `mysql' GID from `([0-9]+)' to `\1'$ +usermod\[[0-9]+\]: change user `mysql' shell from `/bin/false' to `/bin/false'$ diff --cc debian/mariadb-server.logcheck.ignore.workstation index a64fc54e1,000000000..7db321a02 mode 100644,000000..100644 --- a/debian/mariadb-server.logcheck.ignore.workstation +++ b/debian/mariadb-server.logcheck.ignore.workstation @@@ -1,30 -1,0 +1,30 @@@ +/etc/init.d/mariadb\[[0-9]+\]: [0-9]+ processes alive and '/usr/bin/mysqladmin --defaults-(extra-)?file=/etc/mysql/debian.cnf ping' resulted in$ +/etc/init.d/mariadb\[[0-9]+\]: Check that mariadbd is running and that the socket: '/run/mysqld/mysqld.sock' exists\!$ +/etc/init.d/mariadb\[[0-9]+\]: '/usr/bin/mysqladmin --defaults-(extra-)?file=/etc/mysql/debian.cnf ping' resulted in$ +/etc/mysql/debian-start\[[0-9]+\]: Checking for crashed MySQL tables\.$ +mariadbd\[[0-9]+\]: ?$ +mariadbd\[[0-9]+\]: .*InnoDB: Shutdown completed +mariadbd\[[0-9]+\]: .*InnoDB: Started; +mariadbd\[[0-9]+\]: .*InnoDB: Starting shutdown\.\.\.$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: Normal shutdown$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: ready for connections\.$ +mariadbd\[[0-9]+\]: .*\[Note\] /usr/sbin/mariadbd: Shutdown complete$ +mariadbd\[[0-9]+\]: /usr/sbin/mariadbd: ready for connections\.$ +mariadbd\[[0-9]+\]: .*/usr/sbin/mariadbd: Shutdown Complete$ +mariadbd\[[0-9]+\]: Version: .* socket +mariadbd\[[0-9]+\]: Warning: Ignoring user change to 'mysql' because the user was set to 'mysql' earlier on the command line$ +mysqld_safe\[[0-9]+\]: ?$ +mysqld_safe\[[0-9]+\]: able to use the new GRANT command!$ +mysqld_safe\[[0-9]+\]: ended$ +mysqld_safe\[[0-9]+\]: NOTE: If you are upgrading from a MySQL <= 3.22.10 you should run$ +mysqld_safe\[[0-9]+\]: PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !$ - mysqld_safe\[[0-9]+\]: Please report any problems at https://mariadb.org/jira$ ++mysqld_safe\[[0-9]+\]: Please report any problems at https://jira.mariadb.org$ +mysqld_safe\[[0-9]+\]: See the manual for more instructions.$ +mysqld_safe\[[0-9]+\]: started$ +mysqld_safe\[[0-9]+\]: The latest information about MariaDB is available at$ +mysqld_safe\[[0-9]+\]: the /usr/bin/mysql_fix_privilege_tables. Otherwise you will not be$ +mysqld_safe\[[0-9]+\]: To do so, start the server, then issue the following commands:$ +mysqld_safe\[[0-9]+\]: /usr/bin/mysqladmin -u root -h app109 password 'new-password'$ +mysqld_safe\[[0-9]+\]: /usr/bin/mysqladmin -u root password 'new-password'$ +usermod\[[0-9]+\]: change user `mysql' GID from `([0-9]+)' to `\1'$ +usermod\[[0-9]+\]: change user `mysql' shell from `/bin/false' to `/bin/false'$ diff --cc debian/mariadb-server.mariadb.init index 26439cf44,000000000..aeffe89b8 mode 100644,000000..100644 --- a/debian/mariadb-server.mariadb.init +++ b/debian/mariadb-server.mariadb.init @@@ -1,243 -1,0 +1,298 @@@ +#!/bin/bash +# +### BEGIN INIT INFO +# Provides: mariadb +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Should-Start: $network $named $time +# Should-Stop: $network $named $time +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 - # Short-Description: Start and stop the mysql database server daemon ++# Short-Description: Start and stop the MariaDB database server daemon +# Description: Controls the main MariaDB database server daemon "mariadbd" +# and its wrapper script "mysqld_safe". +### END INIT INFO +# +set -e +set -u +${DEBIAN_SCRIPT_DEBUG:+ set -v -x} + +test -x /usr/sbin/mariadbd || exit 0 + ++# shellcheck source=/dev/null +. /lib/lsb/init-functions + - SELF=$(cd "$(dirname $0)"; pwd -P)/$(basename $0) ++SELF="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")" + +if [ -f /usr/bin/mariadb-admin ] +then + MYADMIN="/usr/bin/mariadb-admin --defaults-file=/etc/mysql/debian.cnf" +elif [ -f /usr/bin/mysqladmin ] +then + MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf" +else + log_failure_msg "Command mariadb-admin/mysqladmin not found! This SysV init script depends on it." - exit -1 ++ exit 1 +fi + +if [ ! -x /usr/bin/mariadbd-safe ] +then + log_failure_msg "/usr/bin/mariadbd-safe not found or executable! This SysV init script depends on it." - exit -1 ++ exit 1 +fi + +# priority can be overridden and "-s" adds output to stderr +ERR_LOGGER="logger -p daemon.err -t /etc/init.d/mariadb -i" + - if [ -f /etc/default/mysql ]; then ++if [ -f /etc/default/mysql ] ++then ++ # shellcheck source=/dev/null + . /etc/default/mysql +fi + +# Also source default/mariadb in case the installation was upgraded from +# packages originally installed from MariaDB.org repositories, which have +# had support for reading /etc/default/mariadb since March 2016. - if [ -f /etc/default/mariadb ]; then ++if [ -f /etc/default/mariadb ] ++then ++ # shellcheck source=/dev/null + . /etc/default/mariadb +fi + +# Safeguard (relative paths, core dumps..) +cd / +umask 077 + +# mysqladmin likes to read /root/.my.cnf. This is usually not what I want +# as many admins e.g. only store a password without a username there and +# so break my scripts. +export HOME=/etc/mysql/ + +## Fetch a particular option from mysql's invocation. +# +# Usage: void mariadbd_get_param option +mariadbd_get_param() { + /usr/sbin/mariadbd --print-defaults \ + | tr " " "\n" \ + | grep -- "--$1" \ + | tail -n 1 \ + | cut -d= -f2 +} + +## Do some sanity checks before even trying to start mariadbd. +sanity_checks() { + # check for config file - if [ ! -r /etc/mysql/my.cnf ]; then ++ if [ ! -r /etc/mysql/my.cnf ] ++ then + log_warning_msg "$0: WARNING: /etc/mysql/my.cnf cannot be read. See README.Debian.gz" + echo "WARNING: /etc/mysql/my.cnf cannot be read. See README.Debian.gz" | $ERR_LOGGER + fi + + # check for diskspace shortage - datadir=`mariadbd_get_param datadir` ++ datadir="$(mariadbd_get_param datadir)" + - # If datadir location is not changed int configuration ++ # If datadir location is not customized in configuration + # then it's not printed with /usr/sbin/mariadbd --print-defaults - # then we use 'sane' default. ++ # and this should fall backt to a sane default value + if [ -z "$datadir" ] + then + datadir="/var/lib/mysql" + fi + - # Check if there datadir location is available and - # fail if it's not - if [ ! -d "$datadir" ] ++ # Verify the datadir location exists ++ if [ ! -d "$datadir" ] && [ ! -L "$datadir" ] + then - log_failure_msg "$0: ERROR: Can't locate MariaDB installation location $datadir" - echo "ERROR: Can't locate MariaDB installation location $datadir" | $ERR_LOGGER ++ log_failure_msg "$0: ERROR: Can't locate MariaDB data location at $datadir" ++ echo "ERROR: Can't locate MariaDB data location at $datadir" | $ERR_LOGGER + exit 1 + fi + + # As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024 + # 4096 blocks is then lower than 4 MB + df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$datadir" | tail -n 1)" - if [ "$df_available_blocks" -lt "4096" ]; then ++ if [ "$df_available_blocks" -lt "4096" ] ++ then + log_failure_msg "$0: ERROR: The partition with $datadir is too full!" + echo "ERROR: The partition with $datadir is too full!" | $ERR_LOGGER + exit 1 + fi +} + +## Checks if there is a server running and if so if it is accessible. +# +# check_alive insists on a pingable server +# check_dead also fails if there is a lost mariadbd in the process list +# +# Usage: boolean mariadbd_status [check_alive|check_dead] [warn|nowarn] +mariadbd_status () { - ping_output=`$MYADMIN ping 2>&1`; ping_alive=$(( ! $? )) ++ ping_output="$($MYADMIN ping 2>&1)" ++ # The whole mariadbd_status function should be rewritten in clean shell script, ++ # so ignore minor Shellcheck nag for now as fixing it would be half of the ++ # rewrite ++ # shellcheck disable=SC2181 ++ ping_alive="$(( ! $? ))" + + ps_alive=0 - pidfile=`mariadbd_get_param pid-file` - if [ -f "$pidfile" ] && ps `cat $pidfile` >/dev/null 2>&1; then ps_alive=1; fi ++ pidfile="$(mariadbd_get_param pid-file)" ++ if [ -f "$pidfile" ] && ps "$(cat "$pidfile")" >/dev/null 2>&1 ++ then ++ ps_alive=1 ++ fi + ++ # Using '-a' is unstandard, but it works and might be needed for the grouping ++ # of the if-else, so keep it and just ignore in Shellcheck ++ # shellcheck disable=SC2166 + if [ "$1" = "check_alive" -a $ping_alive = 1 ] || - [ "$1" = "check_dead" -a $ping_alive = 0 -a $ps_alive = 0 ]; then ++ [ "$1" = "check_dead" -a $ping_alive = 0 -a $ps_alive = 0 ] ++ then + return 0 # EXIT_SUCCESS + else - if [ "$2" = "warn" ]; then ++ if [ "$2" = "warn" ] ++ then + echo -e "$ps_alive processes alive and '$MYADMIN ping' resulted in\n$ping_output\n" | $ERR_LOGGER -p daemon.debug + fi + return 1 # EXIT_FAILURE + fi +} + +# +# main() +# + +case "${1:-''}" in + + 'start') + sanity_checks; + # Start daemon + log_daemon_msg "Starting MariaDB database server" "mariadbd" - if mariadbd_status check_alive nowarn; then ++ if mariadbd_status check_alive nowarn ++ then + log_progress_msg "already running" + log_end_msg 0 + else + # Could be removed during boot + test -e /run/mysqld || install -m 755 -o mysql -g root -d /run/mysqld + + # Start MariaDB! + /usr/bin/mariadbd-safe "${@:2}" 2>&1 >/dev/null | $ERR_LOGGER & + - for i in $(seq 1 "${MYSQLD_STARTUP_TIMEOUT:-30}"); do ++ for _ in $(seq 1 "${MYSQLD_STARTUP_TIMEOUT:-30}") ++ do + sleep 1 - if mariadbd_status check_alive nowarn ; then break; fi ++ if mariadbd_status check_alive nowarn ++ then ++ break ++ fi + log_progress_msg "." + done - if mariadbd_status check_alive warn; then ++ if mariadbd_status check_alive warn ++ then + log_end_msg 0 + # Now start mysqlcheck or whatever the admin wants. + output=$(/etc/mysql/debian-start) - if [ -n "$output" ]; then ++ if [ -n "$output" ] ++ then + log_action_msg "$output" + fi + else ++ # Try one more time but save error log separately, then spit it out ++ # before logging ends and init script execution ends. ++ if pgrep -ax mariadbd > /dev/null ++ then ++ echo "ERROR: The mariadbd process is running but not responding:" ++ # shellcheck disable=SC2009 ++ # Show the mariadbd process and it's parent and next line (if there is a child process) ++ ps faxu | grep mariadbd -C 1 ++ else ++ ERROR_LOG_FILE="$(mktemp).err" ++ echo # ensure newline ++ timeout --kill-after=20 10 /usr/bin/mariadbd-safe "${@:2}" --log-error="$ERROR_LOG_FILE" ++ echo "Running '/etc/init.d/mariadb start' failed with error log:" ++ cat "$ERROR_LOG_FILE" ++ fi ++ + log_end_msg 1 + log_failure_msg "Please take a look at the syslog" + fi + fi + ;; + + 'stop') + # * As a passwordless mysqladmin (e.g. via ~/.my.cnf) must be possible + # at least for cron, we can rely on it here, too. (although we have + # to specify it explicit as e.g. sudo environments points to the normal + # users home and not /root) + log_daemon_msg "Stopping MariaDB database server" "mariadbd" - if ! mariadbd_status check_dead nowarn; then ++ if ! mariadbd_status check_dead nowarn ++ then + set +e - shutdown_out=`$MYADMIN shutdown 2>&1`; r=$? ++ shutdown_out="$($MYADMIN shutdown 2>&1)" ++ r=$? + set -e - if [ "$r" -ne 0 ]; then ++ if [ "$r" -ne 0 ] ++ then + log_end_msg 1 + [ "$VERBOSE" != "no" ] && log_failure_msg "Error: $shutdown_out" + log_daemon_msg "Killing MariaDB database server by signal" "mariadbd" - killall -15 mariadbd ++ killall -15 mariadbd || killall -15 mysqld + server_down= - for i in `seq 1 600`; do ++ for _ in {1..600} ++ do + sleep 1 - if mariadbd_status check_dead nowarn; then server_down=1; break; fi ++ if mariadbd_status check_dead nowarn ++ then ++ server_down=1 ++ break ++ fi + done - if test -z "$server_down"; then killall -9 mariadbd; fi ++ if test -z "$server_down" ++ then ++ killall -9 mariadbd || killall -15 mysqld ++ fi + fi + fi + - if ! mariadbd_status check_dead warn; then ++ if ! mariadbd_status check_dead warn ++ then + log_end_msg 1 + log_failure_msg "Please stop MariaDB manually and read /usr/share/doc/mariadb-server/README.Debian.gz!" - exit -1 ++ exit 1 + else + log_end_msg 0 + fi + ;; + + 'restart') + set +e; $SELF stop; set -e + shift + $SELF start "${@}" + ;; + + 'reload'|'force-reload') + log_daemon_msg "Reloading MariaDB database server" "mariadbd" + $MYADMIN reload + log_end_msg 0 + ;; + + 'status') - if mariadbd_status check_alive nowarn; then ++ if mariadbd_status check_alive nowarn ++ then + log_action_msg "$($MYADMIN version)" + else + log_action_msg "MariaDB is stopped." + exit 3 + fi + ;; + + 'bootstrap') - # Bootstrap the cluster, start the first node - # that initiates the cluster - log_daemon_msg "Bootstrapping the cluster" "mariadbd" - $SELF start "${@:2}" --wsrep-new-cluster - ;; ++ # Bootstrap the cluster, start the first node ++ # that initiates the cluster ++ log_daemon_msg "Bootstrapping the cluster" "mariadbd" ++ $SELF start "${@:2}" --wsrep-new-cluster ++ ;; + + *) + echo "Usage: $SELF start|stop|restart|reload|force-reload|status" + exit 1 + ;; +esac diff --cc debian/mariadb-server.postinst index 298f551fd,000000000..e472008ab mode 100644,000000..100644 --- a/debian/mariadb-server.postinst +++ b/debian/mariadb-server.postinst @@@ -1,289 -1,0 +1,304 @@@ +#!/bin/bash +set -e + +# shellcheck source=/dev/null +. /usr/share/debconf/confmodule + +if [ -n "$DEBIAN_SCRIPT_DEBUG" ] +then + set -v -x + DEBIAN_SCRIPT_TRACE=1 +fi + - ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } ++${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2} + +export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin + +# This command can be used as pipe to syslog. With "-s" it also logs to stderr. +ERR_LOGGER="logger -p daemon.err -t mariadb-server.postinst -i" +# Specify syslog tag name so it is clear the entry came from this postinst script. +# This will make an error in a logged command immediately apparent by aborting +# the install, rather than failing silently and leaving a broken install. +set -o pipefail + +case "$1" in + configure) + # This is needed because mariadb-install-db removes the pid file in /run + # and because changed configuration options should take effect immediately. + # In case the server wasn't running at all it should be ok if the stop + # script fails. I can't tell at this point because of the cleaned /run. + set +e + invoke-rc.d mariadb stop + set -e + + # An existing /etc/init.d/mysql might be on the system if there was a + # previous MySQL or MariaDB installation, since /etc/init.d files are + # considered config files and stay around even after the package is removed. + # + # The install step of this package adds a new /etc/init.d/mariadb file. As + # we also want to ensure that there are no old (and potentially outdated) + # versions of /etc/init.d/mysql we simply replace it using a copy of the + # latest 'mariadb' file. This has also the added benefit that anything that + # invokes traditional sysv init with either 'mysql' or 'mariadb' will end up + # controlling this newly installed MariaDB, and thus we maintain better + # backwards compatibility. + # + # Note that the 'Provides' line is also updated to avoid 'insserv' exiting + # on failure (when it is run by update-rc.d) because of duplicate service + # names. + if [ -f "/etc/init.d/mysql" ] && [ -f "/etc/init.d/mariadb" ] + then + # Copy init file and rename the service name and filename on the fly + sed 's/Provides: mariadb/Provides: mysql/g' /etc/init.d/mariadb > /etc/init.d/mysql + # NOTE: Number of spaces/tabs is important here! + # Confirm if the sed worked + if ! grep --quiet "Provides: mysql" /etc/init.d/mysql + then + # If not, then delete the file to avoid failures later on + rm -f /etc/init.d/mysql + echo "Warning! Failed creating a mysql named copy of mariadb init.d file" + fi + fi + + mysql_statedir=/usr/share/mariadb + mysql_datadir=/var/lib/mysql + mysql_logdir=/var/log/mysql + mysql_cfgdir=/etc/mysql + mysql_upgradedir=/var/lib/mysql-upgrade + + # If the following symlink exists, it is a preserved copy the old data dir + # created by the preinst script during a upgrade that would have otherwise + # been replaced by an empty mysql dir. This should restore it. + for dir in DATADIR LOGDIR + do + + if [ "$dir" = "DATADIR" ] + then + targetdir=$mysql_datadir + else + targetdir=$mysql_logdir + fi + + savelink="$mysql_upgradedir/$dir.link" + if [ -L "$savelink" ] + then + # If the targetdir was a symlink before we upgraded it is supposed + # to be either still be present or not existing anymore now. + if [ -L "$targetdir" ] + then + rm "$savelink" + elif [ ! -d "$targetdir" ] + then + mv "$savelink" "$targetdir" + else + # this should never even happen, but just in case... + mysql_tmp=$(mktemp -d -t mysql-symlink-restore-XXXXXX) + echo "this is very strange! see $mysql_tmp/README..." >&2 + mv "$targetdir" "$mysql_tmp" + cat << EOF > "$mysql_tmp/README" + +If you're reading this, it's most likely because you had replaced /var/lib/mysql +with a symlink, then upgraded to a new version of mysql, and then dpkg +removed your symlink (see #182747 and others). The mysql packages noticed +that this happened, and as a workaround have restored it. However, because +/var/lib/mysql seems to have been re-created in the meantime, and because +we don't want to rm -rf something we don't know as much about, we are going +to leave this unexpected directory here. If your database looks normal, +and this is not a symlink to your database, you should be able to blow +this all away. + +EOF + fi + fi + rmdir $mysql_upgradedir 2>/dev/null || true + - done ++ done # end 'for dir' loop + + # Upgrading from mysql.com needs might have the root user as auth_socket. + # auto.cnf is a sign of a mysql install, that doesn't exist in mariadb. + # We use lsof to protect against concurrent access by mysqld (mariadb has + # its own projection). We make sure we're not doing this on a MySQL-8.0 + # directory. + # This direct update is needed to enable an authentication mechanism to + # perform mariadb-upgrade, (MDEV-22678). To keep the impact minimal, we + # skip innodb and set key-buffer-size to 0 as it isn't reused. + if [ -f "$mysql_datadir/auto.cnf" ] && - [ -f "$mysql_datadir/mysql/user.MYD" ] && - ! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null && - [ ! -f "$mysql_datadir/undo_001" ] ++ [ -f "$mysql_datadir/mysql/user.MYD" ] && ++ ! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null && ++ [ ! -f "$mysql_datadir/undo_001" ] + then + echo "UPDATE mysql.user SET plugin='unix_socket' WHERE plugin='auth_socket';" | - mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null ++ mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null + fi + + # Ensure the existence and right permissions for the database and + # log files. Use mkdir option 'Z' to create with correct SELinux context. + if [ ! -d "$mysql_statedir" ] && [ ! -L "$mysql_statedir" ] + then + mkdir -Z "$mysql_statedir" + fi + if [ ! -d "$mysql_datadir" ] && [ ! -L "$mysql_datadir" ] + then + mkdir -Z "$mysql_datadir" + fi - if [ ! -d "$mysql_logdir" ] && [ ! -L "$mysql_logdir" ] - then - mkdir -Z "$mysql_logdir" - fi ++ + # When creating an ext3 jounal on an already mounted filesystem like e.g. + # /var/lib/mysql, you get a .journal file that is not modifiable by chown. + # The mysql_statedir must not be writable by the mysql user under any + # circumstances as it contains scripts that are executed by root. + set +e - chown -R 0:0 $mysql_statedir ++ find $mysql_statedir ! -uid 0 -print0 -or ! -gid 0 -print0 | xargs -0 -r sudo chown 0:0 + find $mysql_datadir ! -uid "$(id -u mysql)" -print0 | xargs -0 -r chown mysql - chown -R mysql:adm $mysql_logdir - chmod 2750 $mysql_logdir + set -e + + ## Set the correct filesystem ownership for the PAM v2 plugin + # eg. /usr/lib/x86_64-linux-gnu/mysql/plugin/auth_pam_tool_dir/ + # NOTE! This is security sensitive, don't allow for a race condition. + # + # 1. Drop privileges of directory + # -> At this point only root can see and execute auth_pam_tool + chmod 0700 /usr/lib/mysql/plugin/auth_pam_tool_dir + # + # 2. Make binary setuid + # -> At this point only root can run the setuid binary so no escalation here yet + chmod 04755 /usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool + # + # 3. Allow user 'mysql' to see and execute auth_pam_tool + # -> Now user mysql owns the directory and can see and execute the binary inside + # -> Since the binary is setuid, user mysql gets limited root powers here to + # run the PAM authetications, which need root (e.g. to validate passwords + # against /etc/shadow) + chown mysql /usr/lib/mysql/plugin/auth_pam_tool_dir + + # This is important to avoid dataloss when there is a removed + # mysql-server version from Woody lying around which used the same + # data directory and then somehow gets purged by the admin. + db_set mariadb-server/postrm_remove_database false || true + + # Clean up old flags before setting new one + rm -f $mysql_datadir/debian-*.flag + # Flag data dir to avoid downgrades ++ # @TODO: Rewrite this to use the new upstream /var/lib/mysql_upgrade_info file ++ # instead of the legacy /var/lib/debian-XX.X.flag file + touch "$mysql_datadir/debian-__MARIADB_MAJOR_VER__.flag" + + # initiate databases. Output is not allowed by debconf :-( + # This will fail if we are upgrading an existing database; in this case + # mariadb-upgrade, called from the /etc/mysql/debian-start script, will + # handle things. + # Debian: beware of the bashisms... + # Debian: can safely run on upgrades with existing databases ++ # Workaround for Debian Bug #1022994: failure to create database when ++ # working with libpam-tmpdir (by setting TMPDIR to empty value). + set +e - bash /usr/bin/mariadb-install-db --rpm --cross-bootstrap --user=mysql \ - --disable-log-bin --skip-test-db 2>&1 | \ ++ TMPDIR='' bash /usr/bin/mariadb-install-db \ ++ --rpm --cross-bootstrap \ ++ --user=mysql --disable-log-bin \ ++ --skip-test-db 2>&1 | + $ERR_LOGGER + set -e + + # On new installations root user can connect via unix_socket. + # But on upgrades, scripts rely on debian-sys-maint user and + # credentials in /etc/mysql/debian.cnf + # All tools use --defaults-file=/etc/mysql/debian.cnf + # And while it's not needed for new installations, we keep using + # --defaults-file option for tools (for the sake of upgrades) + # and thus need /etc/mysql/debian.cnf to exist, even if it's empty. + # In the long run the goal is to obsolete this file. + dc="$mysql_cfgdir/debian.cnf" + if [ ! -d "$mysql_cfgdir" ] + then + install -o 0 -g 0 -m 0755 -d $mysql_cfgdir + fi ++ + if [ ! -e "$dc" ] + then + cat /dev/null > $dc + { + echo "# THIS FILE IS OBSOLETE. STOP USING IT IF POSSIBLE."; + echo "# This file exists only for backwards compatibility for"; + echo "# tools that run '--defaults-file=/etc/mysql/debian.cnf'"; + echo "# and have root level access to the local filesystem."; + echo "# With those permissions one can run 'mariadb' directly"; + echo "# anyway thanks to unix socket authentication and hence"; + echo "# this file is useless. See package README for more info."; + echo "[client]"; + echo "host = localhost"; + echo "user = root"; + echo "[mysql_upgrade]"; + echo "host = localhost"; + echo "user = root"; + echo "# THIS FILE WILL BE REMOVED IN A FUTURE DEBIAN RELEASE."; + } >> $dc + fi + # Keep it only root-readable, as it always was + chown 0:0 $dc + chmod 0600 $dc + + # If there is a real AppArmor profile, we reload it. + # If the default empty profile is installed, then we remove any old + # profile that may be loaded. + # This allows upgrade from old versions (that have an apparmor profile + # on by default) to work both to disable a default profile, and to keep + # any profile installed and maintained by users themselves. + profile="/etc/apparmor.d/usr.sbin.mariadbd" - if [ -f "$profile" ] && aa-status --enabled 2>/dev/null ++ if [ -f "$profile" ] && aa-status --enabled 2> /dev/null + then - if grep -q /usr/sbin/mariadbd "$profile" 2>/dev/null ++ if grep -q /usr/sbin/mariadbd "$profile" 2> /dev/null + then + apparmor_parser -r "$profile" || true + else - echo "/usr/sbin/mariadbd { }" | apparmor_parser --remove 2>/dev/null || true ++ echo "/usr/sbin/mariadbd { }" | apparmor_parser --remove 2> /dev/null || true + fi + fi + + # The introduction of /etc/logrotate.d/mariadb has made the old config + # obsolete and it needs to be disabled to prevent logrotate running twice. + if [ -f /etc/logrotate.d/mysql-server ] + then + mv -vf /etc/logrotate.d/mysql-server /etc/logrotate.d/mysql-server.dpkg-bak + fi + - # @TODO: Remove once buildbot.askmonty.org has been updated not to expect this file - mkdir -p /etc/systemd/system/mariadb.service.d/ - # Note that file cannot be empty, otherwise systemd version in Ubuntu Bionic - # will think the service is masked - echo "# empty placeholder" > /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf ++ # The introduction of versionless server package is not fully backwards ++ # compatible as the purge of an old mariadb-server-x.y package would ++ # commands such as 'deb-systemd-helper purge mariadb.service' and ++ # 'update-rc.d mariadb remove'. Fix it by simly deleting any existing postrm ++ # stanzas opportunistically. ++ for old_postrm_file in /var/lib/dpkg/info/mariadb-server-10.?.postrm ++ do ++ # For loop will always run, but the globbing pattern will be expanded into ++ # something only if there are files that match the pattern, so we need to ++ # not act on it if the result is just the globbing pattern itself. ++ if [ "$old_postrm_file" != "/var/lib/dpkg/info/mariadb-server-10.?.postrm" ] ++ then ++ sed '/Automatically added by dh_installinit/,/End automatically added section/d' \ ++ -i "$old_postrm_file" || true ++ sed '/Automatically added by dh_systemd_enable/,/End automatically added section/d' \ ++ -i "$old_postrm_file" || true ++ fi ++ done + ;; + + abort-upgrade|abort-remove|abort-configure) + ;; + + triggered) + if [ -d /run/systemd/system ] + then + systemctl --system daemon-reload - else ++ elif [ -x /etc/init.d/mariadb ] ++ then + invoke-rc.d mariadb restart + fi + ;; + + *) + echo "postinst called with unknown argument '$1'" 1>&2 + exit 1 + ;; +esac + +db_stop # in case invoke fails + +#DEBHELPER# - diff --cc debian/mariadb-server.postrm index 841be00b6,000000000..fc8401bcc mode 100644,000000..100644 --- a/debian/mariadb-server.postrm +++ b/debian/mariadb-server.postrm @@@ -1,65 -1,0 +1,57 @@@ +#!/bin/bash +set -e + +# shellcheck source=/dev/null +. /usr/share/debconf/confmodule + +if [ -n "$DEBIAN_SCRIPT_DEBUG" ] +then + set -v -x + DEBIAN_SCRIPT_TRACE=1 +fi + +${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } + - #DEBHELPER# - +# +# - Purge logs and data only if they are ours (#307473) +# - Remove the mysql user only after all his owned files are purged. +# - Cleanup the initscripts only if this was the last provider of them +# +if [ "$1" = "purge" ] && [ -f "/var/lib/mysql/debian-__MARIADB_MAJOR_VER__.flag" ] +then + # we remove the mysql user only after all his owned files are purged + rm -f /var/log/mysql.{log,err}{,.0,.[1234567].gz} + rm -rf /var/log/mysql + + db_input high "mariadb-server/postrm_remove_databases" || true + db_go || true + db_get "mariadb-server/postrm_remove_databases" || true + if [ "$RET" = "true" ] + then + # never remove the debian.cnf when the databases are still existing + # else we ran into big trouble on the next install! + rm -f /etc/mysql/debian.cnf + # Remove all contents from /var/lib/mysql except if it's a + # directory with file system data. See #829491 for details and + # #608938 for potential mysql-server leftovers which erroneously + # had been renamed. + # Attempt removal only if the directory hasn't already been removed + # by dpkg to avoid failing on "No such file or directory" errors. + if [ -d /var/lib/mysql ] + then + find /var/lib/mysql -mindepth 1 \ + -not -path '*/lost+found/*' -not -name 'lost+found' \ + -not -path '*/lost@002bfound/*' -not -name 'lost@002bfound' \ + -delete + + # "|| true" still needed as rmdir still exits with non-zero if + # /var/lib/mysql is a mount point + rmdir --ignore-fail-on-non-empty /var/lib/mysql || true + fi + rm -rf /run/mysqld # this directory is created by the init script, don't leave behind + userdel mysql || true + fi + +fi + +#DEBHELPER# - - # Modified dh_systemd_start snippet that's not added automatically - if [ -d /run/systemd/system ] - then - systemctl --system daemon-reload >/dev/null || true - fi diff --cc debian/mariadb-server.preinst index 418273bbb,000000000..392fa4fbf mode 100644,000000..100644 --- a/debian/mariadb-server.preinst +++ b/debian/mariadb-server.preinst @@@ -1,262 -1,0 +1,288 @@@ - #!/bin/bash ++#!/bin/bash -e +# +# summary of how this script can be called: +# * install +# * install +# * upgrade +# * abort-upgrade +# + - set -e - +# shellcheck source=/dev/null +. /usr/share/debconf/confmodule + +# Just kill the invalid insserv.conf.d directory without fallback +if [ -d "/etc/insserv.conf.d/mariadb/" ] +then + rm -rf "/etc/insserv.conf.d/mariadb/" +fi + +if [ -n "$DEBIAN_SCRIPT_DEBUG" ] +then + set -v -x + DEBIAN_SCRIPT_TRACE=1 +fi +${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } + +export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin +mysql_datadir=/var/lib/mysql +mysql_upgradedir=/var/lib/mysql-upgrade + ++MARIADBD_USERS="root" ++ ++# Check if user 'mysql' exists before referring to it in pgrep ++# to avoid pgrep erroring on 'invalid user name' ++if id mysql >/dev/null 2>&1 ++then ++ MARIADBD_USERS="$MARIADBD_USERS,mysql" ++fi ++ +# Try to stop the server in a sane way. If it does not success let the admin +# do it himself. No database directories should be removed while the server +# is running! Another mariadbd in e.g. a different chroot is fine for us. +stop_server() { + # Return immediately if there are no mysqld processes running on a host + # (leave containerized processes with the same name in other namespaces) + # as there is no point in trying to shutdown in that case. - if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null ++ if ! pgrep -x -u "$MARIADBD_USERS" --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null + then + return + fi + + set +e + invoke-rc.d mariadb stop + invoke-rc.d mysql stop # Backwards compatibility + errno=$? + set -e + + # systemctl could emit exit code 100=no init script (fresh install) + if [ "$errno" != 0 ] && [ "$errno" != 100 ] + then + echo "Attempt to stop MariaDB/MySQL server returned exitcode $errno" 1>&2 + echo "There is a MariaDB/MySQL server running, but we failed in our attempts to stop it." 1>&2 + echo "Stop it yourself and try again!" 1>&2 + db_stop + exit 1 + fi +} + +################################ main() ########################## + +# @TODO: Rewrite this to use the new upstream /var/lib/mysql_upgrade_info file +# instead of the legacy /var/lib/debian-XX.X.flag file +this_version=__MARIADB_MAJOR_VER__ +max_upgradeable_version=5.7 + +# Check if a flag file is found that indicates a previous MariaDB or MySQL +# version was installed. If multiple flags are found, check which one was +# the biggest version number. +for flag in "$mysql_datadir"/debian-*.flag +do + + # The for loop leaves $flag as the query string if there are no results, + # so the check below is needed to stop further processing when there are + # no real results. + if [ "$flag" = "$mysql_datadir/debian-*.flag" ] + then + break + fi + ++ # The whole flag_version thing should be rewritten, so ignore minor Shellcheck ++ # nag for now ++ # shellcheck disable=SC2001 + flag_version=$(echo "$flag" | sed 's/.*debian-\([0-9\.]\+\).flag/\1/') + + # Initialize value if empty + if [ -z "$found_version" ] + then + found_version=$flag_version + fi + + # Update value if now bigger then before + if dpkg --compare-versions "$flag_version" '>>' "$found_version" + then + found_version=$flag_version + fi + +done + + +# If an upgrade is detected, proceed with it automatically without +# requiring any user interaction. +# +# However, if the user attempts to downgrade, warn about the incompatibility. +# Downgrade is detected if the flag version is bigger than $this_version +# (e.g. 10.1 > 10.0) or the flag version is smaller than 10.0 but bigger +# than $max_upgradeable_version. +if [ -n "$found_version" ] +then + + # MySQL 8.0 in Ubuntu has a bug in packaging and the file is name wrongly + # 'debian-5.7.flag', so in case '5.7' was encountered an extra check needs to + # be done to see is there is a file called undo_001, which is a sign of 8.0. + if [ "$found_version" == "5.7" ] && [ -f "$mysql_datadir/undo_001" ] + then + # Seems to be a 8.0, flag has wrongly 5.7 (know bug) + found_version=8.0 + fi + + echo "$mysql_datadir: found previous version $found_version" + + if dpkg --compare-versions "$found_version" '>>' "$this_version" + then + downgrade_detected=true + fi + + if dpkg --compare-versions "$found_version" '>>' "$max_upgradeable_version" \ + && dpkg --compare-versions "$found_version" '<<' "10.0" + then + downgrade_detected=true + fi + +fi + +# If there is no debian-*.flag, and no version was detected, but a file that +# indicated MySQL 8.0 is found (undo_001 is created by default in MySQL 8.0+ +# installs), then that file is enough of additional indication to trigger the +# move of the data directory. +if [ -z "$found_version" ] && + [ -z "$(find $mysql_datadir/debian-*.flag 2> /dev/null)" ] && + [ -f "$mysql_datadir/undo_001" ] +then - echo "$mysql_datadir: no server version flag found, assuming MySQL 8.0 data encountered" ++ echo "$mysql_datadir: no server version flag found, assuming MySQL 8.0 data encountered" 1>&2 + downgrade_detected=true + found_version="previous" # Just use dummy name as we don't know real version +fi + +# Don't abort dpkg if downgrade is detected (as was done previously). +# Instead simply move the old datadir and create a new for this_version. +if [ -n "$downgrade_detected" ] +then + db_input critical "mariadb-server/old_data_directory_saved" || true + db_go - echo "The file $mysql_datadir/debian-$found_version.flag indicates a" 1>&2 ++ echo "The contents of $mysql_datadir/ indicates a" 1>&2 + echo "version that cannot automatically be upgraded. Therefore the" 1>&2 + echo "previous data directory will be renamed to $mysql_datadir-$found_version and" 1>&2 + echo "a new data directory will be initialized at $mysql_datadir." 1>&2 + echo "Please manually export/import your data (e.g. with mysqldump) if needed." 1>&2 + mv -f "$mysql_datadir" "$mysql_datadir-$found_version" + # Also move away the old debian.cnf file that included credentials that are + # no longer valid. If none existed, ignore error and let dpkg continue. + mv -f /etc/mysql/debian.cnf "/etc/mysql/debian.cnf-$found_version" || true +fi + +# to be sure +stop_server + +# If we use NIS then errors should be tolerated. It's up to the +# user to ensure that the mysql user is correctly setup. +# Beware that there are two ypwhich one of them needs the 2>/dev/null! - if test -n "$(which ypwhich 2>/dev/null)" && ypwhich >/dev/null 2>&1 ++if test -n "$(command -v ypwhich 2>/dev/null)" && ypwhich > /dev/null 2>&1 +then + set +e +fi + +# +# Now we have to ensure the following state: - # /etc/passwd: mysql:x:100:101:MySQL Server:/nonexistent:/bin/false ++# /etc/passwd: mysql:x:100:101:MariaDB Server:/nonexistent:/bin/false +# /etc/group: mysql:x:101: +# +# Sadly there could any state be present on the system so we have to +# modify everything carefully i.e. not doing a chown before creating +# the user etc... +# + +# creating mysql group if he isn't already there +if ! getent group mysql >/dev/null +then + # Adding system group: mysql. + addgroup --system mysql >/dev/null +fi + +# creating mysql user if he isn't already there +if ! getent passwd mysql >/dev/null +then + # Adding system user: mysql. + adduser \ + --system \ + --disabled-login \ + --ingroup mysql \ + --no-create-home \ + --home /nonexistent \ - --gecos "MySQL Server" \ ++ --gecos "MariaDB Server" \ + --shell /bin/false \ - mysql >/dev/null ++ mysql >/dev/null 2>&1 +fi + +# end of NIS tolerance zone +set -e + +# if there's a symlink, let's store where it's pointing, because otherwise +# it's going to be lost in some situations +for dir in DATADIR LOGDIR +do + checkdir=$(eval echo "$"$dir) - if [ -L "$checkdir" ]; then ++ if [ -L "$checkdir" ] ++ then + # Use mkdir option 'Z' to create with correct SELinux context. + mkdir -pZ "$mysql_upgradedir" + cp -dT "$checkdir" "$mysql_upgradedir/$dir.link" + fi +done + +# creating mysql home directory +if [ ! -d $mysql_datadir ] && [ ! -L $mysql_datadir ] +then + # Use mkdir option 'Z' to create with correct SELinux context. + mkdir -Z $mysql_datadir +fi + - # Check if MariaDB datadir is available if not fails. - # There should be symlink or directory available or something will fail. - if [ -d "$mysql_datadir" ] || [ -L "$mysql_datadir" ] ++# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024 ++# 4096 blocks is then lower than 4 MB ++df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$mysql_datadir" | tail -n 1)" ++if [ "$df_available_blocks" -lt "4096" ] +then - # As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024 - # 4096 blocks is then lower than 4 MB - df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$mysql_datadir" | tail -n 1)" - if [ "$df_available_blocks" -lt "4096" ] - then - echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2 - db_stop - exit 1 - fi - else - echo "ERROR: There's no directory or symlink available: $mysql_datadir/" 1>&2 - db_stop - exit 1 ++ echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2 ++ db_stop ++ exit 1 +fi + +# Since the home directory was created before putting the user into +# the mysql group and moreover we cannot guarantee that the +# permissions were correctly *before* calling this script, we fix them now. +# In case we use NIS and no mysql user is present then this script should +# better fail now than later.. +# The "set +e" is necessary as e.g. a ".journal" of a ext3 partition is +# not chgrp'able (#318435). +set +e +find $mysql_datadir ! -uid "$(id -u mysql)" -print0 | xargs -0 -r chown mysql +find $mysql_datadir -follow -not -group mysql -print0 2>/dev/null \ + | xargs -0 --no-run-if-empty chgrp mysql +set -e + +db_stop + +#DEBHELPER# ++ ++# dh_installinit/13.11.3 adds this check but only with 'install', so we need to ++# have and extra one to check 'upgrade'. This ensures that upgrades from ++# mariadb-server-x.y to mariadb-server (without version suffix) ends up with ++# the executable bit set on /etc/init.d/mariadb, which otherwise would end up ++# disabled due to the mariadb-server-x.y.postrm being triggered. ++# $1 = upgrade ++# $2 = 1:10.6.11-2 ++if [ "$1" = "upgrade" ] && [ -n "$2" ] && [ -e "/etc/init.d/mariadb" ] ++then ++ chmod +x "/etc/init.d/mariadb" >/dev/null || true ++fi ++ ++# dh_installinit/13.11.3 adds this check but with extra condition that there ++# must be a version passed as '$2', but that will always be empty when install ++# runs after the unpack that is retriggered for package 'mariadb-server' when ++# the old 'mariadb-server-10.6' is purged, so we need to repeat the same check ++# here without any expectation for '$2'. This ensures that upgrades from ++# mariadb-server-x.y to mariadb-server (without version suffix) ends up with the ++# executable bit set on /etc/init.d/mariadb. ++if [ "$1" = "install" ] && [ -e "/etc/init.d/mariadb" ] ++then ++ chmod +x "/etc/init.d/mariadb" >/dev/null || true ++fi diff --cc debian/mariadb-test-data.install index fd40bf77d,000000000..a0cc352e1 mode 100644,000000..100644 --- a/debian/mariadb-test-data.install +++ b/debian/mariadb-test-data.install @@@ -1,6 -1,0 +1,7 @@@ ++debian/unstable-tests.* usr/share/mariadb/mariadb-test/ +usr/share/mariadb/mariadb-test/collections +usr/share/mariadb/mariadb-test/include +usr/share/mariadb/mariadb-test/main +usr/share/mariadb/mariadb-test/plugin +usr/share/mariadb/mariadb-test/std_data +usr/share/mariadb/mariadb-test/suite diff --cc debian/mariadb-test-data.lintian-overrides index cb05b7480,000000000..7175e1482 mode 100644,000000..100644 --- a/debian/mariadb-test-data.lintian-overrides +++ b/debian/mariadb-test-data.lintian-overrides @@@ -1,32 -1,0 +1,24 @@@ - # These should be moved, see https://jira.mariadb.org/browse/MDEV-21654 - arch-dependent-file-in-usr-share [usr/share/mariadb/mariadb-test/suite/plugins/pam/pam_mariadb_mtr.so] - arch-independent-package-contains-binary-or-object [usr/share/mariadb/mariadb-test/suite/plugins/pam/pam_mariadb_mtr.so] - # Mainly for support for *BSD family. Not right way to do but this is test package and not for production - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/std_data/checkDBI_DBD-MariaDB.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/engines/rr_trx/run_stress_tx_rr.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_1/lib/DataGen_local.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_1/lib/DataGen_modify.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_2/lib/gen_charset_utf8.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/rpl/extension/checksum.pl] +# Intentional for test files - national-encoding usr/share/mariadb/mariadb-test/* ++national-encoding [usr/share/mariadb/mariadb-test/*] +# Extra test documentation files that really need to be kept in context in test directory - package-contains-documentation-outside-usr-share-doc usr/share/mariadb/mariadb-test/* ++package-contains-documentation-outside-usr-share-doc [usr/share/mariadb/mariadb-test/*] +# Intentional directory structure - repeated-path-segment auth_gssapi usr/share/mariadb/mariadb-test/plugin/auth_gssapi/auth_gssapi/ - repeated-path-segment connect usr/share/mariadb/mariadb-test/plugin/connect/connect/ - repeated-path-segment disks usr/share/mariadb/mariadb-test/plugin/disks/disks/ - repeated-path-segment func_test usr/share/mariadb/mariadb-test/plugin/func_test/func_test/ - repeated-path-segment metadata_lock_info usr/share/mariadb/mariadb-test/plugin/metadata_lock_info/metadata_lock_info/ - repeated-path-segment mroonga usr/share/mariadb/mariadb-test/plugin/mroonga/mroonga/ - repeated-path-segment mroonga usr/share/mariadb/mariadb-test/plugin/mroonga/mroonga/include/mroonga/ - repeated-path-segment oqgraph usr/share/mariadb/mariadb-test/plugin/oqgraph/oqgraph/ - repeated-path-segment query_response_time usr/share/mariadb/mariadb-test/plugin/query_response_time/query_response_time/ - repeated-path-segment rocksdb usr/share/mariadb/mariadb-test/plugin/rocksdb/rocksdb/ - repeated-path-segment sequence usr/share/mariadb/mariadb-test/plugin/sequence/sequence/ - repeated-path-segment sphinx usr/share/mariadb/mariadb-test/plugin/sphinx/sphinx/ - repeated-path-segment spider usr/share/mariadb/mariadb-test/plugin/spider/spider/ - repeated-path-segment type_inet usr/share/mariadb/mariadb-test/plugin/type_inet/type_inet/ - repeated-path-segment type_test usr/share/mariadb/mariadb-test/plugin/type_test/type_test/ - repeated-path-segment user_variables usr/share/mariadb/mariadb-test/plugin/user_variables/user_variables/ - repeated-path-segment wsrep_info usr/share/mariadb/mariadb-test/plugin/wsrep_info/wsrep_info/ ++repeated-path-segment auth_gssapi [usr/share/mariadb/mariadb-test/plugin/auth_gssapi/auth_gssapi/] ++repeated-path-segment connect [usr/share/mariadb/mariadb-test/plugin/connect/connect/] ++repeated-path-segment disks [usr/share/mariadb/mariadb-test/plugin/disks/disks/] ++repeated-path-segment func_test [usr/share/mariadb/mariadb-test/plugin/func_test/func_test/] ++repeated-path-segment metadata_lock_info [usr/share/mariadb/mariadb-test/plugin/metadata_lock_info/metadata_lock_info/] ++repeated-path-segment mroonga [usr/share/mariadb/mariadb-test/plugin/mroonga/mroonga/] ++repeated-path-segment mroonga [usr/share/mariadb/mariadb-test/plugin/mroonga/mroonga/include/mroonga/] ++repeated-path-segment oqgraph [usr/share/mariadb/mariadb-test/plugin/oqgraph/oqgraph/] ++repeated-path-segment query_response_time [usr/share/mariadb/mariadb-test/plugin/query_response_time/query_response_time/] ++repeated-path-segment rocksdb [usr/share/mariadb/mariadb-test/plugin/rocksdb/rocksdb/] ++repeated-path-segment sequence [usr/share/mariadb/mariadb-test/plugin/sequence/sequence/] ++repeated-path-segment sphinx [usr/share/mariadb/mariadb-test/plugin/sphinx/sphinx/] ++repeated-path-segment spider [usr/share/mariadb/mariadb-test/plugin/spider/spider/] ++repeated-path-segment type_inet [usr/share/mariadb/mariadb-test/plugin/type_inet/type_inet/] ++repeated-path-segment type_mysql_timestamp [usr/share/mariadb/mariadb-test/plugin/type_mysql_timestamp/type_mysql_timestamp/] ++repeated-path-segment type_test [usr/share/mariadb/mariadb-test/plugin/type_test/type_test/] ++repeated-path-segment type_uuid [usr/share/mariadb/mariadb-test/plugin/type_uuid/type_uuid/] ++repeated-path-segment user_variables [usr/share/mariadb/mariadb-test/plugin/user_variables/user_variables/] ++repeated-path-segment wsrep_info [usr/share/mariadb/mariadb-test/plugin/wsrep_info/wsrep_info/] diff --cc debian/mariadb-test.lintian-overrides index 6e7bdf05e,000000000..6e97c9d99 mode 100644,000000..100644 --- a/debian/mariadb-test.lintian-overrides +++ b/debian/mariadb-test.lintian-overrides @@@ -1,8 -1,0 +1,20 @@@ +# These should be moved, see https://jira.mariadb.org/browse/MDEV-21653 +arch-dependent-file-in-usr-share [usr/share/mariadb/mariadb-test/lib/My/SafeProcess/my_safe_process] +arch-dependent-file-in-usr-share [usr/share/mariadb/mariadb-test/lib/My/SafeProcess/wsrep_check_version] - # Mainly for support for *BSD family. Not right way to do but this is test package and not for production - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/lib/process-purecov-annotations.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/lib/v1/mysql-test-run.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/mariadb-stress-test.pl] - incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/mariadb-test-run.pl] ++# MyISAM stopwords that cannot be changed and spelling errors remain ++spelling-error-in-binary noone no one [usr/bin/*] ++spelling-error-in-binary thats that's [usr/bin/*] ++spelling-error-in-binary theres there's [usr/bin/*] ++# False positive from Lintian, these strings are nowhere in test in source code ++spelling-error-in-binary AfE Safe [usr/bin/*] ++# Valid reason for documentation in context in directory ++package-contains-documentation-outside-usr-share-doc [usr/share/mariadb/mariadb-test/README*] ++# Test plugins intentionally not fully featured ++shared-library-lacks-prerequisites [usr/lib/mysql/plugin/auth_0x0100.so] ++shared-library-lacks-prerequisites [usr/lib/mysql/plugin/debug_key_management.so] ++shared-library-lacks-prerequisites [usr/lib/mysql/plugin/test_sql_service.so] ++# The file mysql-test-run.pl is a symlink for mariadb-test-run.pl, which does ++# not have a man page, so the man page is indeed used and not a spare one ++spare-manual-page [usr/share/man/man1/mysql-test-run.pl.1.gz] ++# Text script, should be moved to another path ++no-manual-page [usr/bin/test-connect-t] diff --cc debian/not-installed index 705d8c906,000000000..b35658b51 mode 100644,000000..100644 --- a/debian/not-installed +++ b/debian/not-installed @@@ -1,65 -1,0 +1,60 @@@ +etc/columnstore/storagemanager.cnf.example # Copy of etc/columnstore/storagemanager.cnf that is installed ++etc/logrotate.d/mysql # Debian packaging uses mariadb-server.mysql-server.logrotate +etc/my.cnf # Debian packaging has /etc/mysql/my.cnf, which is a symlink to mariadb.cnf +etc/mysql/mariadb.conf.d/client.cnf # Debian packaging uses files from debian/additions/mariadb.cnf.d/ +etc/mysql/mariadb.conf.d/enable_encryption.preset # Debian packaging uses files from debian/additions/mariadb.cnf.d/ +etc/mysql/mariadb.conf.d/mysql-clients.cnf # Debian packaging uses files from debian/additions/mariadb.cnf.d/ +etc/mysql/mariadb.conf.d/server.cnf # Debian packaging uses files from debian/additions/mariadb.cnf.d/ - lib/systemd/system/mariadb-extra.socket # Installed by rules file - lib/systemd/system/mariadb.socket # Installed by rules file +usr/bin/mariadb-embedded # Shipping the embedded server in distro packaging does not make sense +usr/bin/mysql_config # Debian packaging has mysql_config as symlink to mariadb_config +usr/bin/mysql_embedded # Symlink to mariadb-embedded which is intentionally not included +usr/bin/sst_dump # Use the one from rocksdb-tools package - usr/bin/uca-dump - usr/bin/wsrep_sst_backup - usr/lib/aarch64-linux-gnu/libdbbc.a # ColumnStore header file - usr/lib/aarch64-linux-gnu/libidbboot.a # ColumnStore header file - usr/lib/aarch64-linux-gnu/libprocessor.a # ColumnStore header file - usr/lib/aarch64-linux-gnu/libwe_xml.a # ColumnStore header file ++usr/lib/*/libdbbc.a # ColumnStore header file ++usr/lib/*/libidbboot.a # ColumnStore header file ++usr/lib/*/libprocessor.a # ColumnStore header file ++usr/lib/*/libwe_xml.a # ColumnStore header file +usr/lib/sysusers.d/mariadb.conf # Not used (yet) in Debian systemd +usr/lib/tmpfiles.d/mariadb.conf # Not used (yet) in Debian systemd - usr/lib/x86_64-linux-gnu/libdbbc.a # ColumnStore header file - usr/lib/x86_64-linux-gnu/libidbboot.a # ColumnStore header file - usr/lib/x86_64-linux-gnu/libprocessor.a # ColumnStore header file - usr/lib/x86_64-linux-gnu/libwe_xml.a # ColumnStore header file +usr/sbin/rcmysql +usr/share/doc/mariadb-server/COPYING (related file: "debian/tmp/usr/share/mariadb/mroonga/COPYING") +usr/share/doc/mariadb-server/CREDITS +usr/share/doc/mariadb-server/INSTALL-BINARY - usr/share/doc/mariadb-server/README.md +usr/share/doc/mariadb-server/README-wsrep ++usr/share/doc/mariadb-server/README.md +usr/share/doc/mariadb-server/THIRDPARTY - usr/share/groonga/COPYING +usr/share/groonga-normalizer-mysql/lgpl-2.0.txt +usr/share/groonga-normalizer-mysql/README.md ++usr/share/groonga/COPYING +usr/share/groonga/README.md +usr/share/man/man1/mariadb-embedded.1 # Shipping the embedded server in distro packaging does not make sense +usr/share/man/man1/my_safe_process.1 +usr/share/man/man1/mysql_embedded.1 # Symlink to mariadb-embedded.1 which is intentionally not included - usr/share/man/man1/mysql.server.1 +usr/share/man/man1/mysql-stress-test.pl.1 ++usr/share/man/man1/mysql-test-run.pl.1 # Spare manual page, should be deleted upstream ++usr/share/man/man1/mysql.server.1 +usr/share/mariadb/binary-configure ++usr/share/mariadb/JavaWrappers.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless ++usr/share/mariadb/JdbcInterface.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless +usr/share/mariadb/magic +usr/share/mariadb/maria_add_gis_sp.sql # mariadb-server-core.install has *_bootstrap.sql - usr/share/mariadb/mariadb.logrotate +usr/share/mariadb/mariadb-test/asan.supp +usr/share/mariadb/mariadb-test/lsan.supp - usr/share/mariadb/mariadb-test/unstable-tests ++usr/share/mariadb/mariadb.logrotate +usr/share/mariadb/Mongo2.jar +usr/share/mariadb/Mongo3.jar - usr/share/mariadb/mysqld_multi.server +usr/share/mariadb/mysql.server # Debian packaging uses mariadb-server.mariadb.init ++usr/share/mariadb/mysqld_multi.server +usr/share/mariadb/policy/apparmor/README # In MariaDB we don't want to use AppArmor at the moment +usr/share/mariadb/policy/apparmor/usr.sbin.mysqld # In MariaDB we don't want to use AppArmor at the moment +usr/share/mariadb/policy/apparmor/usr.sbin.mysqld.local # In MariaDB we don't want to use AppArmor at the moment +usr/share/mariadb/policy/selinux/mariadb-server.fc # In MariaDB we don't want to use SELinux at the moment +usr/share/mariadb/policy/selinux/mariadb-server.te # In MariaDB we don't want to use SELinux at the moment +usr/share/mariadb/policy/selinux/mariadb.te # In MariaDB we don't want to use SELinux at the moment +usr/share/mariadb/policy/selinux/README # In MariaDB we don't want to use SELinux at the moment +usr/share/mariadb/systemd/mariadb-extra@.socket # Installed by rules file +usr/share/mariadb/systemd/mariadb.service # Installed by rules file +usr/share/mariadb/systemd/mariadb@.service # Installed by rules file +usr/share/mariadb/systemd/mariadb@.socket # Installed by rules file - usr/share/mariadb/systemd/mysqld.service # Installed by rules file +usr/share/mariadb/systemd/mysql.service # Installed by rules file ++usr/share/mariadb/systemd/mysqld.service # Installed by rules file +usr/share/mariadb/systemd/use_galera_new_cluster.conf diff --cc debian/patches/0025-Change-the-default-optimization-from-O3-to-O2-in-mys.patch index 000000000,000000000..538dc6b53 new file mode 100644 --- /dev/null +++ b/debian/patches/0025-Change-the-default-optimization-from-O3-to-O2-in-mys.patch @@@ -1,0 -1,0 +1,55 @@@ ++From: Ondrej Sury ++Date: Wed, 22 Nov 2017 20:32:51 +0000 ++Subject: Change the default optimization from -O3 to -O2 in ++ mysql_release.cmake BUILD_CONFIG profile ++Forwarded: no ++Bug: https://jira.mariadb.org/browse/MDEV-19734?focusedCommentId=156606&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-156606 ++ ++--- ++ cmake/build_configurations/mysql_release.cmake | 12 ++++++------ ++ .../PerconaFT/cmake_modules/TokuSetupCompiler.cmake | 16 ++++++++-------- ++ 2 files changed, 14 insertions(+), 14 deletions(-) ++ ++--- a/cmake/build_configurations/mysql_release.cmake +++++ b/cmake/build_configurations/mysql_release.cmake ++@@ -174,12 +174,12 @@ IF(UNIX) ++ IF(CMAKE_COMPILER_IS_GNUCC) ++ SET(COMMON_C_FLAGS "-g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing -Wno-uninitialized") ++ SET(CMAKE_C_FLAGS_DEBUG "-O ${COMMON_C_FLAGS}") ++- SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}") +++ SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 ${COMMON_C_FLAGS}") ++ ENDIF() ++ IF(CMAKE_COMPILER_IS_GNUCXX) ++ SET(COMMON_CXX_FLAGS "-g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing -Wno-uninitialized") ++ SET(CMAKE_CXX_FLAGS_DEBUG "-O ${COMMON_CXX_FLAGS}") ++- SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_CXX_FLAGS}") +++ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 ${COMMON_CXX_FLAGS}") ++ ENDIF() ++ ++ # IBM Z flags ++@@ -228,8 +228,8 @@ IF(UNIX) ++ ENDIF() ++ SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}") ++ SET(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CXX_FLAGS}") ++- SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -unroll2 -ip ${COMMON_C_FLAGS}") ++- SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -unroll2 -ip ${COMMON_CXX_FLAGS}") +++ SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -unroll2 -ip ${COMMON_C_FLAGS}") +++ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -unroll2 -ip ${COMMON_CXX_FLAGS}") ++ SET(WITH_SSL no) ++ ENDIF() ++ ENDIF() ++@@ -238,12 +238,12 @@ IF(UNIX) ++ IF(CMAKE_C_COMPILER_ID MATCHES "Clang") ++ SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-parentheses-equality -Wno-string-plus-int") ++ SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}") ++- SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}") +++ SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 ${COMMON_C_FLAGS}") ++ ENDIF() ++ IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") ++ SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-parentheses-equality -Wno-string-plus-int") ++ SET(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CXX_FLAGS}") ++- SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_CXX_FLAGS}") +++ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 ${COMMON_CXX_FLAGS}") ++ ENDIF() ++ ++ # Solaris flags diff --cc debian/patches/1006531-hurd-no-auth-socket.patch index 000000000,000000000..d6ae82fe6 new file mode 100644 --- /dev/null +++ b/debian/patches/1006531-hurd-no-auth-socket.patch @@@ -1,0 -1,0 +1,28 @@@ ++Forwarded: no ++Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1006531 ++From: Daniel Black ++Subject: mariadb: FTBFS on hurd-i386: undefined reference to misc functions and files ++ ++requires https://github.com/MariaDB/server/pull/2893 as debian ++explicit architectures aren't needed since dh_auto_configure handles ++this. ++ ++If it works, upstream welcome. ++ ++Hurd string from uname -m, "SYSTEM processor: i686-AT386" in mariadb ++output. And wiki reference https://en.wikipedia.org/wiki/Uname ++ ++--- a/cmake/build_configurations/mysql_release.cmake +++++ b/cmake/build_configurations/mysql_release.cmake ++@@ -118,7 +118,10 @@ ELSEIF(DEB) ++ SET(WITH_ZLIB system CACHE STRING "") ++ SET(WITH_LIBWRAP ON) ++ SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON) ++- SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "") +++ # No hurd implementation +++ IF(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "i686-AT386") +++ SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "") +++ ENDIF() ++ SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "") ++ SET(WITH_PCRE system CACHE STRING "") ++ SET(CLIENT_PLUGIN_ZSTD OFF) diff --cc debian/patches/1063738-x32-compile-time-assert.patch index 000000000,000000000..b125b87ac new file mode 100644 --- /dev/null +++ b/debian/patches/1063738-x32-compile-time-assert.patch @@@ -1,0 -1,0 +1,26 @@@ ++Forwarded: no ++Author: Otto Kekäläinen ++Date: Thu Jul 4 00:03:58 2024 -0700 ++Subject: [PATCH] Make compile_time_assert compatible with x32 (Closes: #1063738) ++ ++ The x32 build was failing on: ++ ++ compile_time_assert(sizeof(MYSQL) == 77*sizeof(void*)+656); ++ ++ Reported upstream at https://jira.mariadb.org/browse/MDEV-34195. ++ This is a regression from upstream commits c432c9ef and 06a884a57071. ++ ++ Fix is based on advice from https://lists.debian.org/debian-amd64/2024/07/msg00003.html ++ which is also aligned with https://wiki.debian.org/X32Port. ++ ++--- a/tests/mysql_client_fw.c +++++ b/tests/mysql_client_fw.c ++@@ -1442,7 +1442,7 @@ int main(int argc, char **argv) ++ this limited check is enough, if sizeof(MYSQL) changes, it changes ++ everywhere ++ */ ++-#if defined __x86_64__ +++#if defined(__x86_64__) && !defined(__ILP32__) ++ compile_time_assert(sizeof(MYSQL) == 1272); ++ #elif defined __i386__ ++ compile_time_assert(sizeof(MYSQL) == 964); diff --cc debian/patches/2541-fix-stack-overflow-in-pinbox-allocator.patch index 000000000,000000000..07beca66e new file mode 100644 --- /dev/null +++ b/debian/patches/2541-fix-stack-overflow-in-pinbox-allocator.patch @@@ -1,0 -1,0 +1,283 @@@ ++Forwarded: https://github.com/MariaDB/server/pull/2541 ++Origin: https://patch-diff.githubusercontent.com/raw/MariaDB/server/pull/2541.patch ++From: Hugo Wen ++Date: Sat, 11 Mar 2023 00:27:42 +0000 ++Subject: [PATCH] Fix a stack overflow in pinbox allocator ++ ++MariaDB supports a "wait-free concurrent allocator based on pinning addresses". ++In `lf_pinbox_real_free()` it tries to sort the pinned addresses for better ++performance to use binary search during "real free". `alloca()` was used to ++allocate stack memory and copy addresses. ++ ++To prevent a stack overflow when allocating the stack memory the function checks ++if there's enough stack space. However, the available stack size was calculated ++inaccurately which eventually caused database crash due to stack overflow. ++ ++The crash was seen on MariaDB 10.6.11 but the same code defect exists on all ++MariaDB versions. ++ ++A similar issue happened previously and the fix in fc2c1e43 was to add a ++`ALLOCA_SAFETY_MARGIN` which is 8192 bytes. However, that safety margin is not ++enough during high connection workloads. ++ ++MySQL also had a similar issue and the fix ++https://github.com/mysql/mysql-server/commit/b086fda was to remove the use of ++`alloca` and replace qsort approach by a linear scan through all pointers (pins) ++owned by each thread. ++ ++This commit is mostly the same as it is the only way to solve this issue as: ++1. Frame sizes in different architecture can be different. ++2. Number of active (non-null) pinned addresses varies, so the frame ++ size for the recursive sorting function `msort_with_tmp` is also hard ++ to predict. ++3. Allocating big memory blocks in stack doesn't seem to be a very good ++ practice. ++ ++For further details see the mentioned commit in MySQL and the inline comments. ++ ++All new code of the whole pull request, including one or several files ++that are either new files or modified ones, are contributed under the ++BSD-new license. I am contributing on behalf of my employer Amazon Web ++Services, Inc. ++--- ++ mysys/lf_alloc-pin.c | 180 ++++++++++++++----------------------------- ++ 1 file changed, 59 insertions(+), 121 deletions(-) ++ ++--- a/mysys/lf_alloc-pin.c +++++ b/mysys/lf_alloc-pin.c ++@@ -103,12 +103,6 @@ ++ #include ++ #include "my_cpu.h" ++ ++-/* ++- when using alloca() leave at least that many bytes of the stack - ++- for functions we might be calling from within this stack frame ++-*/ ++-#define ALLOCA_SAFETY_MARGIN 8192 ++- ++ #define LF_PINBOX_MAX_PINS 65536 ++ ++ static void lf_pinbox_real_free(LF_PINS *pins); ++@@ -239,24 +233,21 @@ void lf_pinbox_put_pins(LF_PINS *pins) ++ } while (!my_atomic_cas32((int32 volatile*) &pinbox->pinstack_top_ver, ++ (int32*) &top_ver, ++ top_ver-pins->link+nr+LF_PINBOX_MAX_PINS)); ++- return; ++ } ++ ++-static int ptr_cmp(void **a, void **b) +++/* +++ Get the next pointer in the purgatory list. +++ Note that next_node is not used to avoid the extra volatile. +++*/ +++#define pnext_node(P, X) (*((void **)(((char *)(X)) + (P)->free_ptr_offset))) +++ +++static inline void add_to_purgatory(LF_PINS *pins, void *addr) ++ { ++- return *a < *b ? -1 : *a == *b ? 0 : 1; +++ pnext_node(pins->pinbox, addr)= pins->purgatory; +++ pins->purgatory= addr; +++ pins->purgatory_count++; ++ } ++ ++-#define add_to_purgatory(PINS, ADDR) \ ++- do \ ++- { \ ++- my_atomic_storeptr_explicit( \ ++- (void **)((char *)(ADDR)+(PINS)->pinbox->free_ptr_offset), \ ++- (PINS)->purgatory, MY_MEMORY_ORDER_RELEASE); \ ++- (PINS)->purgatory= (ADDR); \ ++- (PINS)->purgatory_count++; \ ++- } while (0) ++- ++ /* ++ Free an object allocated via pinbox allocator ++ ++@@ -274,138 +265,85 @@ void lf_pinbox_free(LF_PINS *pins, void ++ lf_pinbox_real_free(pins);); ++ } ++ ++-struct st_harvester { ++- void **granary; ++- int npins; +++struct st_match_and_save_arg { +++ LF_PINS *pins; +++ LF_PINBOX *pinbox; +++ void *old_purgatory; ++ }; ++ ++ /* ++- callback forlf_dynarray_iterate: ++- scan all pins of all threads and accumulate all pins +++ Callback for lf_dynarray_iterate: +++ Scan all pins of all threads, for each active (non-null) pin, +++ scan the current thread's purgatory. If present there, move it +++ to a new purgatory. At the end, the old purgatory will contain +++ pointers not pinned by any thread. ++ */ ++-static int harvest_pins(LF_PINS *el, struct st_harvester *hv) +++static int match_and_save(LF_PINS *el, struct st_match_and_save_arg *arg) ++ { ++ int i; ++- LF_PINS *el_end= el+MY_MIN(hv->npins, LF_DYNARRAY_LEVEL_LENGTH); +++ LF_PINS *el_end= el + LF_DYNARRAY_LEVEL_LENGTH; ++ for (; el < el_end; el++) ++ { ++ for (i= 0; i < LF_PINBOX_PINS; i++) ++ { ++ void *p= my_atomic_loadptr((void **)&el->pin[i]); ++ if (p) ++- *hv->granary++= p; +++ { +++ void *cur= arg->old_purgatory; +++ void **list_prev= &arg->old_purgatory; +++ while (cur) +++ { +++ void *next= pnext_node(arg->pinbox, cur); +++ +++ if (p == cur) +++ { +++ /* pinned - keeping */ +++ add_to_purgatory(arg->pins, cur); +++ /* unlink from old purgatory */ +++ *list_prev= next; +++ } +++ else +++ list_prev= (void **)((char *)cur+arg->pinbox->free_ptr_offset); +++ cur= next; +++ } +++ if (!arg->old_purgatory) +++ return 1; +++ } ++ } ++ } ++- /* ++- hv->npins may become negative below, but it means that ++- we're on the last dynarray page and harvest_pins() won't be ++- called again. We don't bother to make hv->npins() correct ++- (that is 0) in this case. ++- */ ++- hv->npins-= LF_DYNARRAY_LEVEL_LENGTH; ++ return 0; ++ } ++ ++ /* ++- callback forlf_dynarray_iterate: ++- scan all pins of all threads and see if addr is present there ++-*/ ++-static int match_pins(LF_PINS *el, void *addr) ++-{ ++- int i; ++- LF_PINS *el_end= el+LF_DYNARRAY_LEVEL_LENGTH; ++- for (; el < el_end; el++) ++- for (i= 0; i < LF_PINBOX_PINS; i++) ++- if (my_atomic_loadptr((void **)&el->pin[i]) == addr) ++- return 1; ++- return 0; ++-} ++- ++-#define next_node(P, X) (*((uchar * volatile *)(((uchar *)(X)) + (P)->free_ptr_offset))) ++-#define anext_node(X) next_node(&allocator->pinbox, (X)) ++- ++-/* ++ Scan the purgatory and free everything that can be freed ++ */ ++ static void lf_pinbox_real_free(LF_PINS *pins) ++ { ++- int npins; ++- void *list; ++- void **addr= NULL; ++- void *first= NULL, *last= NULL; ++- struct st_my_thread_var *var= my_thread_var; ++- void *stack_ends_here= var ? var->stack_ends_here : NULL; ++ LF_PINBOX *pinbox= pins->pinbox; ++ ++- npins= pinbox->pins_in_array+1; +++ /* Store info about current purgatory. */ +++ struct st_match_and_save_arg arg = {pins, pinbox, pins->purgatory}; +++ /* Reset purgatory. */ +++ pins->purgatory= NULL; +++ pins->purgatory_count= 0; ++ ++-#ifdef HAVE_ALLOCA ++- if (stack_ends_here != NULL) ++- { ++- int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; ++- /* create a sorted list of pinned addresses, to speed up searches */ ++- if (available_stack_size(&pinbox, stack_ends_here) > ++- alloca_size + ALLOCA_SAFETY_MARGIN) ++- { ++- struct st_harvester hv; ++- addr= (void **) alloca(alloca_size); ++- hv.granary= addr; ++- hv.npins= npins; ++- /* scan the dynarray and accumulate all pinned addresses */ ++- lf_dynarray_iterate(&pinbox->pinarray, ++- (lf_dynarray_func)harvest_pins, &hv); ++- ++- npins= (int)(hv.granary-addr); ++- /* and sort them */ ++- if (npins) ++- qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); ++- } ++- } ++-#endif ++ ++- list= pins->purgatory; ++- pins->purgatory= 0; ++- pins->purgatory_count= 0; ++- while (list) +++ lf_dynarray_iterate(&pinbox->pinarray, +++ (lf_dynarray_func)match_and_save, &arg); +++ +++ if (arg.old_purgatory) ++ { ++- void *cur= list; ++- list= *(void **)((char *)cur+pinbox->free_ptr_offset); ++- if (npins) ++- { ++- if (addr) /* use binary search */ ++- { ++- void **a, **b, **c; ++- for (a= addr, b= addr+npins-1, c= a+(b-a)/2; (b-a) > 1; c= a+(b-a)/2) ++- if (cur == *c) ++- a= b= c; ++- else if (cur > *c) ++- a= c; ++- else ++- b= c; ++- if (cur == *a || cur == *b) ++- goto found; ++- } ++- else /* no alloca - no cookie. linear search here */ ++- { ++- if (lf_dynarray_iterate(&pinbox->pinarray, ++- (lf_dynarray_func)match_pins, cur)) ++- goto found; ++- } ++- } ++- /* not pinned - freeing */ ++- if (last) ++- last= next_node(pinbox, last)= (uchar *)cur; ++- else ++- first= last= (uchar *)cur; ++- continue; ++-found: ++- /* pinned - keeping */ ++- add_to_purgatory(pins, cur); +++ /* Some objects in the old purgatory were not pinned, free them. */ +++ void *last= arg.old_purgatory; +++ while (pnext_node(pinbox, last)) +++ last= pnext_node(pinbox, last); +++ pinbox->free_func(arg.old_purgatory, last, pinbox->free_func_arg); ++ } ++- if (last) ++- pinbox->free_func(first, last, pinbox->free_func_arg); ++ } ++ +++#define next_node(P, X) (*((uchar * volatile *)(((uchar *)(X)) + (P)->free_ptr_offset))) +++#define anext_node(X) next_node(&allocator->pinbox, (X)) +++ ++ /* lock-free memory allocator for fixed-size objects */ ++ ++ /* diff --cc debian/patches/env-perl-usr-bin-perl.patch index 000000000,000000000..96376243e new file mode 100644 --- /dev/null +++ b/debian/patches/env-perl-usr-bin-perl.patch @@@ -1,0 -1,0 +1,99 @@@ ++Forwarded: https://github.com/MariaDB/server/pull/1718 (rejected, will never be merged) ++Origin: https://patch-diff.githubusercontent.com/raw/MariaDB/server/pull/1718.patch ++From: Otto Kekäläinen ++Date: Sun, 20 Dec 2020 20:58:42 +0200 ++Subject: Fix perl path in scripts ++ Fix Lintian issue ++ https://lintian.debian.org/tags/incorrect-path-for-interpreter.html ++ . ++ Upstream will never accept this patch, see ++ https://github.com/MariaDB/server/pull/1718 ++ ++--- a/mysql-test/lib/process-purecov-annotations.pl +++++ b/mysql-test/lib/process-purecov-annotations.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ # -*- cperl -*- ++ ++ # This script processes a .gcov coverage report to honor purecov ++--- a/mysql-test/lib/v1/mysql-test-run.pl +++++ b/mysql-test/lib/v1/mysql-test-run.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ # -*- cperl -*- ++ ++ # Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. ++--- a/mysql-test/mariadb-stress-test.pl +++++ b/mysql-test/mariadb-stress-test.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. ++ # ++--- a/mysql-test/mariadb-test-run.pl +++++ b/mysql-test/mariadb-test-run.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ # -*- cperl -*- ++ ++ # Copyright (c) 2004, 2014, Oracle and/or its affiliates. ++--- a/mysql-test/std_data/checkDBI_DBD-MariaDB.pl +++++ b/mysql-test/std_data/checkDBI_DBD-MariaDB.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ # Copyright (c) 2011, Oracle and/or its affiliates ++ # ++--- a/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl +++++ b/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ################################################################################ ++ # ++ # This script runs the transactional stress test "stress_tx_rr" against the ++--- a/mysql-test/suite/funcs_1/lib/DataGen_local.pl +++++ b/mysql-test/suite/funcs_1/lib/DataGen_local.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ ++ if ( (scalar(@ARGV) != 1 ) || ($ARGV[0] =~ /[^0-9]/i ) ) ++--- a/mysql-test/suite/funcs_1/lib/DataGen_modify.pl +++++ b/mysql-test/suite/funcs_1/lib/DataGen_modify.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ ++ if ( (scalar(@ARGV) != 2 ) || ($ARGV[0] =~ /[^0-9]/i ) ) ++--- a/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl +++++ b/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ ################################################################################# ++ # Author: Serge Kozlov # ++--- a/mysql-test/suite/rpl/extension/checksum.pl +++++ b/mysql-test/suite/rpl/extension/checksum.pl ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ ++ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. ++ # ++--- a/scripts/mytop.sh +++++ b/scripts/mytop.sh ++@@ -1,4 +1,4 @@ ++-#!/usr/bin/env perl +++#!/usr/bin/perl ++ # ++ # $Id: mytop,v 1.99-maria6 2019/10/22 14:53:51 jweisbuch Exp $ ++ diff --cc debian/patches/fix-reproducible-builds-rocksdb.patch index 000000000,000000000..1bc012529 new file mode 100644 --- /dev/null +++ b/debian/patches/fix-reproducible-builds-rocksdb.patch @@@ -1,0 -1,0 +1,26 @@@ ++Origin: https://github.com/facebook/rocksdb/commit/0a9a05ae12943b1529ef1eabbca5ce5a71c986bf ++# Merged in RocksDB 6.19.3, but not updated into MariaDB yet ++Bug: https://github.com/facebook/rocksdb/issues/7035 ++Author: Otto Kekäläinen ++Subject: Make RocksDB build reproducible ++ ++The RocksDB binary included a string with the build timestamp: ++> rocksdb_build_git_date:@2021-05-23·16:04:38@ ++ ++As this changes from build to build, it makes the builds unreproducible. ++Simply removing it solves the issue. ++ ++This temporary fix can be removed when a proper fix already done in upstream ++lands in MariaDB when the RocksDB submodule is updated to a newer release. ++ ++--- a/storage/rocksdb/rocksdb/util/build_version.cc.in +++++ b/storage/rocksdb/rocksdb/util/build_version.cc.in ++@@ -1,5 +1,5 @@ ++ // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. ++ #include "build_version.h" ++-const char* rocksdb_build_git_sha = "rocksdb_build_git_sha:@@GIT_SHA@@"; ++-const char* rocksdb_build_git_date = "rocksdb_build_git_date:@@GIT_DATE_TIME@@"; ++-const char* rocksdb_build_compile_date = __DATE__; +++const char* rocksdb_build_git_sha = "rocksdb_build_git_sha:REDACTED"; +++const char* rocksdb_build_git_date = "rocksdb_build_git_date:REDACTED"; +++const char* rocksdb_build_compile_date = "REDACTED"; diff --cc debian/patches/fix-spelling-libmariadb.patch index 000000000,000000000..57cdaec15 new file mode 100644 --- /dev/null +++ b/debian/patches/fix-spelling-libmariadb.patch @@@ -1,0 -1,0 +1,155 @@@ ++Forwarded: https://github.com/mariadb-corporation/mariadb-connector-c/pull/220 ++Origin: https://patch-diff.githubusercontent.com/raw/mariadb-corporation/mariadb-connector-c/pull/220.patch ++Author: Otto Kekäläinen ++Date: Sat, 11 Mar 2023 11:22:24 -0800 ++Subject: [PATCH] Fix trivial spelling errors ++ ++- handshak -> handshake ++- occured -> occurred ++- releated -> related ++- reponse -> response ++- seperated -> separated ++- sucess -> success ++- use use -> use ++ ++All new code of the whole pull request, including one or several files ++that are either new files or modified ones, are contributed under the ++BSD-new license. I am contributing on behalf of my employer Amazon Web ++Services, Inc. ++--- ++ man/mariadb_get_infov.3 | 4 ++-- ++ man/mariadb_reconnect.3 | 2 +- ++ man/mysql_ping.3 | 2 +- ++ man/mysql_real_connect.3 | 4 ++-- ++ man/mysql_send_query.3 | 2 +- ++ man/mysql_set_character_set.3 | 2 +- ++ man/mysql_stmt_error.3 | 2 +- ++ man/mysql_stmt_reset.3 | 2 +- ++ man/mysql_store_result.3 | 2 +- ++ unittest/libmariadb/result.c | 2 +- ++ 10 files changed, 12 insertions(+), 12 deletions(-) ++ ++--- a/libmariadb/man/mariadb_get_infov.3 +++++ b/libmariadb/man/mariadb_get_infov.3 ++@@ -5,7 +5,7 @@ ++ .hy ++ .SS Name ++ .PP ++-mariadb_get_infov \- retrieves generic or connection releated +++mariadb_get_infov \- retrieves generic or connection related ++ information ++ .SS Synopsis ++ .IP ++@@ -170,7 +170,7 @@ Retrieves character set information for ++ .PD 0 ++ .P ++ .PD ++-Returns the handshak capability flags] of the client. +++Returns the handshake capability flags] of the client. ++ .IP \[bu] 2 ++ \f[C]MARIADB_CONNECTION_ERROR\f[R] ++ .PD 0 ++--- a/libmariadb/man/mariadb_reconnect.3 +++++ b/libmariadb/man/mariadb_reconnect.3 ++@@ -22,7 +22,7 @@ It uses the same credentials which were ++ \f[B]mysql_real_connect(3)\f[R]. ++ .SS Return value ++ .PP ++-The function will return 0 on sucess, a non zero value on error +++The function will return 0 on success, a non zero value on error ++ .PP ++ \f[B]Note\f[R]: The function will return an error, if the option ++ \f[C]MYSQL_OPT_RECONNECT\f[R] wasn\[cq]t set before. ++--- a/libmariadb/man/mysql_ping.3 +++++ b/libmariadb/man/mysql_ping.3 ++@@ -36,7 +36,7 @@ Also resources bundled to the connection ++ temporary tables, \&...) will be released. ++ .SS Return value ++ .PP ++-Returns zero on success, nonzero if an error occured. +++Returns zero on success, nonzero if an error occurred. ++ .SS See also ++ .IP \[bu] 2 ++ \f[B]mysql_optionsv(3)\f[R] ++--- a/libmariadb/man/mysql_real_connect.3 +++++ b/libmariadb/man/mysql_real_connect.3 ++@@ -141,11 +141,11 @@ since version 3.3.0). ++ The following syntax is required: ++ .RS 2 ++ .IP \[bu] 2 ++-hostname and port must be seperated by a colon (:) +++hostname and port must be separated by a colon (:) ++ .IP \[bu] 2 ++ IPv6 addresses must be enclosed within square brackets ++ .IP \[bu] 2 ++-hostname:port pairs must be be seperated by a comma (,) +++hostname:port pairs must be be separated by a comma (,) ++ .IP \[bu] 2 ++ if only one host:port was specified, the host string needs to end with a ++ comma. ++--- a/libmariadb/man/mysql_send_query.3 +++++ b/libmariadb/man/mysql_send_query.3 ++@@ -5,7 +5,7 @@ ++ .SS Name ++ .PP ++ mysql_send_query \- sends a SQL statement without waiting for server ++-reponse +++response ++ .SS Synopsis ++ .IP ++ .nf ++--- a/libmariadb/man/mysql_set_character_set.3 +++++ b/libmariadb/man/mysql_set_character_set.3 ++@@ -34,7 +34,7 @@ of \f[C]SET NAMES ...\f[R] since \f[B]my ++ might fail or deliver unexpected results. ++ .SS Return value ++ .PP ++-Zero on success, non zero if an error occured +++Zero on success, non zero if an error occurred ++ .SS Supported character sets ++ .PP ++ The client library supports the following character sets: ++--- a/libmariadb/man/mysql_stmt_error.3 +++++ b/libmariadb/man/mysql_stmt_error.3 ++@@ -27,7 +27,7 @@ The string will be empty if no error occ ++ .SS Return value ++ .IP \[bu] 2 ++ A string describing the last error or an empty string if no error ++-occured. +++occurred. ++ .SS Notes ++ .IP \[bu] 2 ++ Client error messages are listed in the \f[C]errmsg.h\f[R] header file, ++--- a/libmariadb/man/mysql_stmt_reset.3 +++++ b/libmariadb/man/mysql_stmt_reset.3 ++@@ -24,7 +24,7 @@ Resets a prepared statement on client an ++ Returns zero on success, nonzero if an error occurred. ++ .SS Return value ++ .PP ++-Returns zero on succes, 1 if an error occured. +++Returns zero on succes, 1 if an error occurred. ++ .SS Notes ++ .IP \[bu] 2 ++ \f[C]mysql_stmt_reset()\f[R] resets the statement on the server, ++--- a/libmariadb/man/mysql_store_result.3 +++++ b/libmariadb/man/mysql_store_result.3 ++@@ -31,7 +31,7 @@ allocated by \f[B]mysql_init(3)\f[R] and ++ \f[B]mysql_real_connect(3)\f[R]. ++ .SS Return value ++ .PP ++-Returns a buffered result set or NULL in case an error occured or if the +++Returns a buffered result set or NULL in case an error occurred or if the ++ query didn\[cq]t return data (e.g.\ when executing an INSERT, UPDATE, ++ DELETE or REPLACE statement). ++ ## See also * \f[B]mysql_free_result(3)\f[R] * ++--- a/libmariadb/unittest/libmariadb/result.c +++++ b/libmariadb/unittest/libmariadb/result.c ++@@ -65,7 +65,7 @@ static int client_use_result(MYSQL *mysq ++ result= mysql_use_result(mysql); ++ FAIL_IF(!result, "Invalid result set"); ++ ++- /* since we use use result, we shouldn't be able execute other api calls */ +++ /* since we use result, we shouldn't be able execute other api calls */ ++ rc= mysql_ping(mysql); ++ FAIL_IF(!rc, "Error expected"); ++ diff --cc debian/patches/fix-spelling-mariadb.patch index 000000000,000000000..b5695be52 new file mode 100644 --- /dev/null +++ b/debian/patches/fix-spelling-mariadb.patch @@@ -1,0 -1,0 +1,121 @@@ ++Forwarded: no ++Author: Otto Kekäläinen ++Date: Sun, 10 Mar 2024 16:56:13 +0000 ++Subject: [PATCH] Fix misc spelling in MariaDB Server repository ++ ++--- a/storage/connect/odbconn.cpp +++++ b/storage/connect/odbconn.cpp ++@@ -281,7 +281,7 @@ static CATPARM *AllocCatInfo(PGLOBAL g, ++ cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD)); ++ ++ } catch (int n) { ++- htrc("Exeption %d: %s\n", n, g->Message); +++ htrc("Exception %d: %s\n", n, g->Message); ++ cap = NULL; ++ } catch (const char *msg) { ++ htrc(g->Message, msg); ++--- a/extra/mariabackup/innobackupex.cc +++++ b/extra/mariabackup/innobackupex.cc ++@@ -188,7 +188,7 @@ enum innobackupex_options ++ OPT_DATABASES, ++ OPT_DECOMPRESS, ++ ++- /* options wich are passed directly to xtrabackup */ +++ /* options which are passed directly to xtrabackup */ ++ OPT_CLOSE_FILES, ++ OPT_COMPACT, ++ OPT_COMPRESS, ++@@ -447,7 +447,7 @@ static struct my_option ibx_long_options ++ {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, ++ "This option specifies time in seconds that mariadb-backup should wait for " ++ "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " ++- "currently running queries using explicite LOCK TABLES has ended. " +++ "currently running queries using explicit LOCK TABLES has ended. " ++ "If there are still such queries when the timeout expires, mariadb-backup " ++ "terminates with an error. Default is 0, in which case mariadb-backup waits " ++ "indefinitely for BACKUP STAGE START to finish", ++--- a/extra/mariabackup/xtrabackup.cc +++++ b/extra/mariabackup/xtrabackup.cc ++@@ -217,7 +217,7 @@ uint xtrabackup_compress = FALSE; ++ uint xtrabackup_compress_threads; ++ ulonglong xtrabackup_compress_chunk_size = 0; ++ ++-/* sleep interval beetween log copy iterations in log copying thread +++/* sleep interval between log copy iterations in log copying thread ++ in milliseconds (default is 1 second) */ ++ ulint xtrabackup_log_copy_interval = 1000; ++ static ulong max_buf_pool_modified_pct; ++@@ -1600,11 +1600,11 @@ struct my_option xb_client_options[]= { ++ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, ++ ++ {"rsync", OPT_RSYNC, ++- "Obsolete depricated option", +++ "Obsolete deprecated option", ++ &ignored_option, &ignored_option, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, ++ ++ {"no-backup-locks", OPT_NO_BACKUP_LOCKS, ++- "Obsolete depricated option", +++ "Obsolete deprecated option", ++ &ignored_option, &ignored_option, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, ++ ++ {"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS, ++@@ -1732,7 +1732,7 @@ struct my_option xb_client_options[]= { ++ {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, ++ "This option specifies time in seconds that mariadb-backup should wait for " ++ "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " ++- "currently running queries using explicite LOCK TABLES has ended. " +++ "currently running queries using explicit LOCK TABLES has ended. " ++ "If there are still such queries when the timeout expires, mariadb-backup " ++ "terminates with an error. Default is 0, in which case mariadb-backup waits " ++ "indefinitely for BACKUP STAGE START to finish", ++@@ -5642,7 +5642,7 @@ void CorruptedPages::backup_fix_ddl(ds_c ++ } ++ ++ /* Mariabackup doesn't detect any FILE_OP for the deferred ++- tablespace. There is a possiblity that page0 could've +++ tablespace. There is a possibility that page0 could've ++ been corrupted persistently in the disk */ ++ for (auto space_name: defer_space_names) { ++ if (!check_if_skip_table(space_name.c_str())) { ++--- a/support-files/mysql.server.sh +++++ b/support-files/mysql.server.sh ++@@ -194,7 +194,7 @@ su_kill() { ++ ++ # ++ # Read defaults file from 'basedir'. If there is no defaults file there ++-# check if it's in the old (depricated) place (datadir) and read it from there +++# check if it's in the old (deprecated) place (datadir) and read it from there ++ # ++ ++ extra_args="" ++--- a/sql/opt_subselect.cc +++++ b/sql/opt_subselect.cc ++@@ -6886,7 +6886,7 @@ bool JOIN::choose_subquery_plan(table_ma ++ add("rows", inner_record_count_1). ++ add("materialization_cost", materialize_strategy_cost). ++ add("in_exist_cost", in_exists_strategy_cost). ++- add("choosen", strategy); +++ add("chosen", strategy); ++ } ++ ++ DBUG_PRINT("info", ++@@ -6924,7 +6924,7 @@ bool JOIN::choose_subquery_plan(table_ma ++ { ++ Json_writer_object trace_wrapper(thd); ++ Json_writer_object trace_subquery(thd, "subquery_plan_revert"); ++- trace_subquery.add("choosen", "in_to_exists"); +++ trace_subquery.add("chosen", "in_to_exists"); ++ } ++ } ++ ++--- a/sql/sql_select.cc +++++ b/sql/sql_select.cc ++@@ -14670,7 +14670,7 @@ void JOIN::drop_unused_derived_keys() ++ } ++ /* ++ We dropped all keys except the chosen one and unique keys. ++- The choosen one is stored as the first key (number 0). +++ The chosen one is stored as the first key (number 0). ++ */ ++ tab->ref.key= 0; ++ } diff --cc debian/patches/fix-spelling-rocksdb.patch index 000000000,000000000..6e6810976 new file mode 100644 --- /dev/null +++ b/debian/patches/fix-spelling-rocksdb.patch @@@ -1,0 -1,0 +1,39 @@@ ++Forwarded: https://github.com/facebook/rocksdb/pull/9653 ++Origin: https://patch-diff.githubusercontent.com/raw/facebook/rocksdb/pull/9653.patch ++# Merged in RocksDB 7.3.1, but not updated into MariaDB yet ++From: Otto Kekäläinen ++Date: Wed, 2 Mar 2022 18:13:18 -0800 ++Subject: Fix various spelling errors still found in code ++ Two upstream PRs remain that have been merged, but not imported on MariaDB yet. ++ ++--- a/storage/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +++++ b/storage/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc ++@@ -46,7 +46,7 @@ Status ExternalSstFileIngestionJob::Prep ++ TablePropertiesCollectorFactory::Context::kUnknownColumnFamily && ++ f.cf_id != cfd_->GetID()) { ++ return Status::InvalidArgument( ++- "External file column family id dont match"); +++ "External file column family id don't match"); ++ } ++ } ++ ++@@ -646,7 +646,7 @@ Status ExternalSstFileIngestionJob::Assi ++ return Status::InvalidArgument("Global seqno is required, but disabled"); ++ } else if (file_to_ingest->global_seqno_offset == 0) { ++ return Status::InvalidArgument( ++- "Trying to set global seqno for a file that dont have a global seqno " +++ "Trying to set global seqno for a file that don't have a global seqno " ++ "field"); ++ } ++ ++--- a/storage/rocksdb/rocksdb/include/rocksdb/cache.h +++++ b/storage/rocksdb/rocksdb/include/rocksdb/cache.h ++@@ -60,7 +60,7 @@ struct LRUCacheOptions { ++ // If greater than zero, the LRU list will be split into a high-pri ++ // list and a low-pri list. High-pri entries will be insert to the ++ // tail of high-pri list, while low-pri entries will be first inserted to ++- // the low-pri list (the midpoint). This is refered to as +++ // the low-pri list (the midpoint). This is referred to as ++ // midpoint insertion strategy to make entries never get hit in cache ++ // age out faster. ++ // diff --cc debian/patches/hide-mysql-command-deprecation-warnings.patch index 000000000,000000000..fe0308d90 new file mode 100644 --- /dev/null +++ b/debian/patches/hide-mysql-command-deprecation-warnings.patch @@@ -1,0 -1,0 +1,28 @@@ ++ ++Forwarded: no ++Author: Otto Kekäläinen ++Date: Sun, Jun 30 2024 15:18:06 +0000 ++Subject: [PATCH] Disable the 'mysql*' command deprecation warning ++ ++Many command-line tools expect the commands they run to return without ++any output in stderr or having error codes. The fact that now in MariaDB ++11.4 all 'mysql*' commands emit a deprecation warning causes a lot of ++scripts to fail, such as the /etc/init.d/mariadb itself and many dependant ++programs as witnessed via Debian autopkgtests. See examples below. ++ ++https://ci.debian.net/packages/m/mariadb-connector-odbc/testing/amd64/48373500/ ++https://ci.debian.net/packages/p/pam-mysql/testing/amd64/48373511/ ++https://ci.debian.net/packages/r/roundcube/testing/amd64/48373518/ ++ ++--- a/mysys/my_init.c +++++ b/mysys/my_init.c ++@@ -200,7 +200,8 @@ my_bool my_init(void) ++ #endif ++ if ((res == 0 || my_readlink(link_name, my_progname, MYF(0)) == 0) && ++ strncmp(link_name + dirname_length(link_name), "mariadb", 7) == 0) ++- my_error(EE_NAME_DEPRECATED, MYF(MY_WME), link_name); +++ /* Intentionally don't emit any errors for now */ +++ DBUG_PRINT("deprecation warning", "skipped"); ++ } ++ } ++ diff --cc debian/patches/hurd-i386-plugin_disks_information_schema_disks.cc.patch index 000000000,000000000..ca5b669af new file mode 100644 --- /dev/null +++ b/debian/patches/hurd-i386-plugin_disks_information_schema_disks.cc.patch @@@ -1,0 -1,0 +1,19 @@@ ++Forwarded: no ++Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1069094 ++Author: Svante Signell ++Subject: Bug#1069094: mariadb: FTBFS on hurd-i386 ++ ++Define PATH_MAX if not defined. ++ ++--- a/plugin/disks/information_schema_disks.cc +++++ b/plugin/disks/information_schema_disks.cc ++@@ -32,6 +32,9 @@ ++ #include ++ #endif ++ #endif +++#ifndef PATH_MAX +++#define PATH_MAX 4096 +++#endif ++ #include ++ #include ++ #include /* check_global_access() */ diff --cc debian/patches/hurd-i386-storage_connect_ioapi.h.patch index 000000000,000000000..75cd7dfa5 new file mode 100644 --- /dev/null +++ b/debian/patches/hurd-i386-storage_connect_ioapi.h.patch @@@ -1,0 -1,0 +1,22 @@@ ++Forwarded: no ++Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1069094 ++Author: Svante Signell ++Subject: Bug#1069094: mariadb: FTBFS on hurd-i386 ++ ++Add Hurd to define __USE_FILE_OFFSET64 et al. ++ ++--- a/storage/connect/ioapi.h +++++ b/storage/connect/ioapi.h ++@@ -21,9 +21,10 @@ ++ #ifndef _ZLIBIOAPI64_H ++ #define _ZLIBIOAPI64_H ++ ++-#if defined(__linux__) +++#if defined(__linux__) || defined (__GNU__) ++ ++- // Linux needs this to support file operation on files larger then 4+GB +++ // Linux and Hurd needs this to support file operation on files larger +++ // than 4+GB. ++ // But might need better if/def to select just the platforms that needs them. ++ ++ #ifndef __USE_FILE_OFFSET64 diff --cc debian/patches/install-files-into-usr.patch index 000000000,000000000..378847788 new file mode 100644 --- /dev/null +++ b/debian/patches/install-files-into-usr.patch @@@ -1,0 -1,0 +1,27 @@@ ++Forwarded: no ++Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1061348 ++From: Michael Biebl ++Date: Mon, 22 Jan 2024 22:52:25 +0100 ++Subject: [PATCH] Install PAM modules and systemd units into /usr ++ ++Since Debian trixie all files need to be installed into their canonical ++location under /usr. ++--- ++ cmake/install_layout.cmake | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/cmake/install_layout.cmake +++++ b/cmake/install_layout.cmake ++@@ -194,10 +194,10 @@ SET(INSTALL_SUPPORTFILESDIR_DEB ++ SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql") ++ ++ SET(INSTALL_UNIX_ADDRDIR_DEB "/run/mysqld/mysqld.sock") ++-SET(INSTALL_SYSTEMD_UNITDIR_DEB "/lib/systemd/system") +++SET(INSTALL_SYSTEMD_UNITDIR_DEB "/usr/lib/systemd/system") ++ SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d") ++ SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d") ++-SET(INSTALL_PAMDIR_DEB "/lib/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/security") +++SET(INSTALL_PAMDIR_DEB "/usr/lib/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/security") ++ SET(INSTALL_PAMDATADIR_DEB "/etc/security") ++ ++ # diff --cc debian/patches/mroonga-mrn-lib-dirs-path-reproducible-build.patch index 000000000,000000000..eeb91cc7f new file mode 100644 --- /dev/null +++ b/debian/patches/mroonga-mrn-lib-dirs-path-reproducible-build.patch @@@ -1,0 -1,0 +1,39 @@@ ++Forwarded: not-needed ++Origin: https://github.com/mroonga/mroonga/issues/298#issuecomment-1030815927 ++Bug: https://github.com/mroonga/mroonga/issues/298 ++From: Sutou Kouhei ++Date: Sat, 5 Feb 2022 11:05:39 +0900 ++Subject: [PATCH] cmake: add support for reproducible buildS ++ . ++ We should use relative path not absolute path. ++ We can use target without breaking reproducibility. ++--- a/storage/mroonga/CMakeLists.txt +++++ b/storage/mroonga/CMakeLists.txt ++@@ -214,7 +214,7 @@ set(MYSQL_INCLUDE_DIRS ++ ++ if(MRN_BUNDLED) ++ set(MYSQL_PLUGIN_DIR "${INSTALL_PLUGINDIR}") ++- set(MYSQL_SERVICES_LIB_DIR "${MYSQL_BUILD_DIR}/libservices") +++ set(MYSQL_SERVICES_LIB_DIR) ++ set(MYSQL_CFLAGS "${CMAKE_C_FLAGS}") ++ set(MYSQL_VERSION "${MYSQL_BASE_VERSION}") ++ else() ++@@ -253,15 +253,11 @@ endif() ++ ++ if(MRN_GROONGA_BUNDLED) ++ set(GROONGA_INCLUDE_DIRS "${MRN_BUNDLED_GROONGA_DIR}/include") ++- set(GROONGA_LIBRARY_DIRS "${MRN_BUNDLED_GROONGA_DIR}/lib") ++- set(GROONGA_LIBRARIES "libgroonga") +++ set(GROONGA_LIBRARY "libgroonga") ++ ++- set(MRN_LIBRARY_DIRS ${GROONGA_LIBRARY_DIRS}) ++- set(MRN_LIBRARIES ${GROONGA_LIBRARIES}) +++ set(MRN_LIBRARY_DIRS) +++ set(MRN_LIBRARIES ${GROONGA_LIBRARY}) ++ if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED) ++- set(MRN_LIBRARY_DIRS ++- ${MRN_LIBRARY_DIRS} ++- "${MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR}/normalizers") ++ set(MRN_LIBRARIES ${MRN_LIBRARIES} mysql_normalizer) ++ endif() ++ else() diff --cc debian/patches/rocksdb-kfreebsd.patch index 000000000,000000000..2b7f2d922 new file mode 100644 --- /dev/null +++ b/debian/patches/rocksdb-kfreebsd.patch @@@ -1,0 -1,0 +1,151 @@@ ++Forwarded: https://github.com/facebook/rocksdb/pull/6992 ++# Merged in RocksDB 6.12.6 but not updated into MariaDB yet ++From: Andrew Kryczka ++Date: Tue, 16 Jun 2020 19:34:21 -0700 ++# Merged in RocksDB 6.13.fb, but not updated into MariaDB yet ++Bug: https://jira.mariadb.org/browse/MDEV-19251 ++Description: ++ Upstream has merged this but we still need to wait for it to be included ++ in a RocksDB release and imported into MariaDB and then into Debian. ++--- a/storage/rocksdb/build_rocksdb.cmake +++++ b/storage/rocksdb/build_rocksdb.cmake ++@@ -90,6 +90,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux" ++ add_definitions(-DOS_LINUX) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS") ++ add_definitions(-DOS_SOLARIS) +++elseif(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD") +++ add_definitions(-DOS_GNU_KFREEBSD) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") ++ add_definitions(-DOS_FREEBSD) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD") ++--- a/storage/rocksdb/rocksdb/CMakeLists.txt +++++ b/storage/rocksdb/rocksdb/CMakeLists.txt ++@@ -91,7 +91,7 @@ if(MSVC) ++ option(WITH_XPRESS "build with windows built in compression" OFF) ++ include(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty.inc) ++ else() ++- if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") +++ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND NOT CMAKE_SYSTEM_NAME MATCHES "kFreeBSD") ++ # FreeBSD has jemalloc as default malloc ++ # but it does not have all the jemalloc files in include/... ++ set(WITH_JEMALLOC ON) ++@@ -413,6 +413,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux" ++ add_definitions(-DOS_LINUX) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS") ++ add_definitions(-DOS_SOLARIS) +++elseif(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD") +++ add_definitions(-DOS_GNU_KFREEBSD) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") ++ add_definitions(-DOS_FREEBSD) ++ elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD") ++--- a/storage/rocksdb/rocksdb/build_tools/build_detect_platform +++++ b/storage/rocksdb/rocksdb/build_tools/build_detect_platform ++@@ -190,6 +190,17 @@ EOF ++ PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread" ++ # PORT_FILES=port/freebsd/freebsd_specific.cc ++ ;; +++ GNU/kFreeBSD) +++ PLATFORM=OS_GNU_KFREEBSD +++ COMMON_FLAGS="$COMMON_FLAGS -DOS_GNU_KFREEBSD" +++ if [ -z "$USE_CLANG" ]; then +++ COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp" +++ else +++ PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -latomic" +++ fi +++ PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread -lrt" +++ # PORT_FILES=port/gnu_kfreebsd/gnu_kfreebsd_specific.cc +++ ;; ++ NetBSD) ++ PLATFORM=OS_NETBSD ++ COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp -D_REENTRANT -DOS_NETBSD" ++--- a/storage/rocksdb/rocksdb/env/env_posix.cc +++++ b/storage/rocksdb/rocksdb/env/env_posix.cc ++@@ -41,7 +41,7 @@ ++ #include ++ #include ++ // Get nano time includes ++-#if defined(OS_LINUX) || defined(OS_FREEBSD) +++#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_GNU_KFREEBSD) ++ #elif defined(__MACH__) ++ #include ++ #include ++@@ -287,7 +287,8 @@ class PosixEnv : public CompositeEnvWrap ++ } ++ ++ uint64_t NowNanos() override { ++-#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_AIX) +++#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_GNU_KFREEBSD) || \ +++ defined(OS_AIX) ++ struct timespec ts; ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ return static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; ++@@ -307,8 +308,8 @@ class PosixEnv : public CompositeEnvWrap ++ } ++ ++ uint64_t NowCPUNanos() override { ++-#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_AIX) || \ ++- (defined(__MACH__) && defined(__MAC_10_12)) +++#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_GNU_KFREEBSD) || \ +++ defined(OS_AIX) || (defined(__MACH__) && defined(__MAC_10_12)) ++ struct timespec ts; ++ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); ++ return static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; ++--- a/storage/rocksdb/rocksdb/port/stack_trace.cc +++++ b/storage/rocksdb/rocksdb/port/stack_trace.cc ++@@ -32,7 +32,7 @@ namespace port { ++ ++ namespace { ++ ++-#if defined(OS_LINUX) || defined(OS_FREEBSD) +++#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_GNU_KFREEBSD) ++ const char* GetExecutableName() { ++ static char name[1024]; ++ ++--- a/storage/rocksdb/rdb_io_watchdog.h +++++ b/storage/rocksdb/rdb_io_watchdog.h ++@@ -56,19 +56,19 @@ class Rdb_io_watchdog { ++ int stop_timers() { ++ int ret = 0; ++ ++- if (m_io_check_watchdog_timer) { +++ if (m_io_check_watchdog_timer != reinterpret_cast(-1)) { ++ ret = timer_delete(m_io_check_watchdog_timer); ++ ++ if (!ret) { ++- m_io_check_watchdog_timer = nullptr; +++ m_io_check_watchdog_timer = reinterpret_cast(-1); ++ } ++ } ++ ++- if (m_io_check_timer && !ret) { +++ if (m_io_check_timer != reinterpret_cast(-1) && !ret) { ++ ret = timer_delete(m_io_check_timer); ++ ++ if (!ret) { ++- m_io_check_timer = nullptr; +++ m_io_check_timer = reinterpret_cast(-1); ++ } ++ } ++ ++@@ -93,8 +93,8 @@ class Rdb_io_watchdog { ++ ++ public: ++ explicit Rdb_io_watchdog(std::vector &&directories) ++- : m_io_check_timer(nullptr), ++- m_io_check_watchdog_timer(nullptr), +++ : m_io_check_timer(reinterpret_cast(-1)), +++ m_io_check_watchdog_timer(reinterpret_cast(-1)), ++ m_io_in_progress(false), ++ m_dirs_to_check(std::move(directories)), ++ m_buf(nullptr) { ++--- a/storage/rocksdb/rdb_io_watchdog.cc +++++ b/storage/rocksdb/rdb_io_watchdog.cc ++@@ -111,7 +111,7 @@ void Rdb_io_watchdog::io_check_callback( ++ sql_print_warning("Deleting the watchdog I/O timer failed with %d.", errno); ++ } ++ ++- m_io_check_watchdog_timer = nullptr; +++ m_io_check_watchdog_timer = reinterpret_cast(-1); ++ ++ RDB_MUTEX_UNLOCK_CHECK(m_reset_mutex); ++ } diff --cc debian/patches/series index 000000000,000000000..142d3ab6f new file mode 100644 --- /dev/null +++ b/debian/patches/series @@@ -1,0 -1,0 +1,17 @@@ ++0025-Change-the-default-optimization-from-O3-to-O2-in-mys.patch ++rocksdb-kfreebsd.patch ++env-perl-usr-bin-perl.patch ++fix-spelling-rocksdb.patch ++fix-reproducible-builds-rocksdb.patch ++mroonga-mrn-lib-dirs-path-reproducible-build.patch ++2541-fix-stack-overflow-in-pinbox-allocator.patch ++fix-spelling-libmariadb.patch ++install-files-into-usr.patch ++1006531-hurd-no-auth-socket.patch ++startup-message.patch ++fix-spelling-mariadb.patch ++hurd-i386-plugin_disks_information_schema_disks.cc.patch ++hurd-i386-storage_connect_ioapi.h.patch ++hide-mysql-command-deprecation-warnings.patch ++1063738-x32-compile-time-assert.patch ++ diff --cc debian/patches/startup-message.patch index 000000000,000000000..5c4994a4a new file mode 100644 --- /dev/null +++ b/debian/patches/startup-message.patch @@@ -1,0 -1,0 +1,68 @@@ ++Forwarded: no ++Author: Otto Kekäläinen ++Date: Sun, 10 Mar 2024 16:56:13 +0000 ++Subject: [PATCH] Show banner in server and client startup to drive community engagement ++ ++Suggest to users that they can support MariaDB development by simply giving a ++star on GitHub. This patch experiments with how well such a banner works, and ++may later change the contents to drive some other kind of engagement. ++ ++Client output: ++ Welcome to the MariaDB monitor. Commands end with ; or \g. ++ Your MariaDB connection id is 34 ++ Server version: 10.11.7-MariaDB-3 Debian n/a ++ ++ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. ++ Support MariaDB developers by giving a star at https://github.com/MariaDB/server ++ ++ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ++ ++ MariaDB [(none)]> ++ ++Server output: ++ [Note] Support MariaDB developers by giving a star at https://github.com/MariaDB/server ++ ++Server output if build in git directory: ++ [Note] Starting MariaDB 10.11.7-MariaDB-3 source revision 219efb0a6ab0ee8ce2ec831c715783586c4db2ef as process 5426 ++ ++--- a/client/mysql.cc +++++ b/client/mysql.cc ++@@ -1333,6 +1333,9 @@ int main(int argc,char *argv[]) ++ mysql_thread_id(&mysql), server_version_string(&mysql)); ++ put_info((char*) glob_buffer.ptr(),INFO_INFO); ++ put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"), INFO_INFO); +++ put_info("Support MariaDB developers by giving a star at " +++ "https://github.com/MariaDB/server", +++ INFO_INFO); ++ } ++ ++ #ifdef HAVE_READLINE ++--- a/sql/mysqld.cc +++++ b/sql/mysqld.cc ++@@ -4932,12 +4932,21 @@ static int init_server_components() ++ my_sleep_for_space= mariadb_sleep_for_space; ++ ++ /* ++- Print source revision hash, as one of the first lines, if not the ++- first in error log, for troubleshooting and debugging purposes +++ Print source revision hash, if set, for troubleshooting and debugging +++ purposes. If not, suggest database adming to help project by giving a +++ star on GitHub. ++ */ ++- if (!opt_help) ++- sql_print_information("Starting MariaDB %s source revision %s as process %lu", ++- server_version, SOURCE_REVISION, (ulong) getpid()); +++ if (!opt_help) { +++ if (SOURCE_REVISION) { +++ sql_print_information("Starting MariaDB %s source revision %s as process %lu", +++ server_version, SOURCE_REVISION, (ulong) getpid()); +++ } else { +++ sql_print_information("Starting MariaDB %s as process %lu", +++ server_version, (ulong) getpid()); +++ sql_print_information("Support MariaDB developers by giving a star at " +++ "https://github.com/MariaDB/server"); +++ } +++ } ++ ++ #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE ++ /* diff --cc debian/po/ar.po index 171200593,000000000..3737c7595 mode 100644,000000..100644 --- a/debian/po/ar.po +++ b/debian/po/ar.po @@@ -1,107 -1,0 +1,107 @@@ +# translation of templates.po to Arabic +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Ossama M. Khayat , 2007. +msgid "" +msgstr "" - "Project-Id-Version: templates\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2007-05-01 13:04+0300\n" +"Last-Translator: Ossama M. Khayat \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=6; plural=n==1 ? 0 : n==0 ? 1 : n==2 ? 2: n%100>=3 && " +"n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +": n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "ملاحظة هامة لمستخدمي NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +#, fuzzy +#| msgid "" +#| "You should also check the permissions and the owner of the /var/lib/mysql " +#| "directory:" +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "عليك أيضاً أن تقوم بالتأكد من صلاحيات مالك الملف /var/lib/mysql: " + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "إزالة جميع قواعد بيانات MariaDB؟" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "الدليل /var/lib/mysql الذي يحتوي قواعد بيانات MariaDB ستتم إزالته." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"إن كنت تقوم بإزالة حزمة MariaDB كي تقوم لاحقاً بتثبيت نسخة أحدث أو إن كانت " +"حزمة mariadb-server مختلفة تستخدمها، فيجب إبقاء البيانات." diff --cc debian/po/ca.po index 5eb310971,000000000..cf41099aa mode 100644,000000..100644 --- a/debian/po/ca.po +++ b/debian/po/ca.po @@@ -1,109 -1,0 +1,109 @@@ +# mariadb (debconf) translation to Catalan. +# his file is distributed under the same license as the mariadb package. +# Aleix Badia i Bosch 2004 +# Innocent De Marchi 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-03-20 17:55+0100\n" +"Last-Translator: Innocent De Marchi \n" +"Language-Team: Debian l10n Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.11\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "El directori de dades antigues es desarà a una nova localització" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Ja hi ha un fitxer amb el nom «/var/lib/mysql/debian-*.flag» en aquests " +"sistema. El número indica la versió de format binari de la base de dades que " +"no és possible actualitzar (o tornar a una versió anterior) automàticament." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"En conseqüència, el directori de dades anterior serà renomenat a «/var/lib/" +"mysql-*» i s'iniciarà un nou directori de dades a «/var/lib/mysql»." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Si us plau, importau o exportau manualment les vostres dades (p. ex. amb " +"«mysqldump») si és necessari." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Nota important pels usuaris de «NIS/YP»" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Fer servir MariaDB sota «NIS/YP» requereix afegir un compte d'usuari MySQL " +"al sistema local fent servir:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"També heu de comprovar els permisos i els propietaris del directori «/var/" +"lib/mysql»" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Eliminar totes les bases de dades MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"El directori «/var/lib/mysql» que conté totes les bases de dades MariaDB " +"està a punt d'ésser eliminat." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Si estau des-instal·lant el paquet MariaDB amb la intenció d'instal·lar a " +"continuació una versió més recent o hi ha una versió diferent del paquet " +"«mariadb-server» que l'està fent servir, cal mantenir les dades." diff --cc debian/po/cs.po index 67619ca1c,000000000..d55024a43 mode 100644,000000..100644 --- a/debian/po/cs.po +++ b/debian/po/cs.po @@@ -1,115 -1,0 +1,115 @@@ +# +# Translators, if you are not familiar with the PO format, gettext +# documentation is worth reading, especially sections dedicated to +# this format, e.g. by running: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Some information specific to po-debconf are available at +# /usr/share/doc/po-debconf/README-trans +# or http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Developers do not need to manually edit POT or PO files. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2020-10-18 17:13+0200\n" +"Last-Translator: Miroslav Kure \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Starý adresář s daty bude uložen na novém místě." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" - "V systému existuje soubor /var/lib/mysql/debian-*.flag. Číslo znamená " - "verzi binárního formátu databáze, kterou nelze automaticky aktualizovat " - "(ani degradovat)." ++"V systému existuje soubor /var/lib/mysql/debian-*.flag. Číslo znamená verzi " ++"binárního formátu databáze, kterou nelze automaticky aktualizovat (ani " ++"degradovat)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" - "Z tohoto důvodu bude původní adresář přejmenován na /var/lib/mysql-* " - "a ve /var/lib/mysql se inicializuje nové datové úložiÅ¡tě." ++"Z tohoto důvodu bude původní adresář přejmenován na /var/lib/mysql-* a ve /" ++"var/lib/mysql se inicializuje nové datové úložiÅ¡tě." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Pokud je to potřeba, vyexportujte/naimportujte data ručně (např. pomocí " +"mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Důležitá poznámka pro uživatele NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Používání MariaDB pod NIS/YP vyžaduje, aby byl účet mysql uživatele přidán " +"na lokálním systému příkazem:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Také byste měli zkontrolovat vlastníka a oprávnění adresáře /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Odstranit vÅ¡echny MariaDB databáze?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Adresář /var/lib/mysql, ve kterém se nachází MariaDB databáze, bude " +"odstraněn." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Jestliže odstraňujete balík MariaDB za účelem instalace novější verze " +"MariaDB, nebo pokud tato data souběžně využívá jiný balík mariadb-server, " +"měli byste data ponechat." diff --cc debian/po/da.po index c639f03a9,000000000..4a82051f5 mode 100644,000000..100644 --- a/debian/po/da.po +++ b/debian/po/da.po @@@ -1,109 -1,0 +1,109 @@@ +# Danish translation mariadb. +# Copyright (C) 2014 mariadb og nedenstÃ¥ende oversættere. +# This file is distributed under the same license as the mariadb package. +# Claus Hindsgaul , 2005, 2006, 2007. +# Joe Hansen , 2014, 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2016-07-09 22:41+0200\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Den gamle datamappe vil blive gemt pÃ¥ en ny placering" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"En fil navngivet /var/lib/msyql/debian-*.flag findes pÃ¥ dette system. " +"Nummeret antyder en databaseversion i binært format, som ikke automatisk kan " +"opgraderes (eller nedgraderes)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Derfor vil den tidligere datamappe blive omdøbt til /var/lib/mysql-* og en " +"ny datamappe vil blive initialiseret i /var/lib/msyql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Eksporter/importer venligst manuelt dine data (f.eks. med mysqldump) hvis " +"krævet." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Vigtig oplysning til NIS/YP-brugere" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Brug af MariaDB under NIS/YP kræver, at en mysql-brugerkonto tilføjes pÃ¥ det " +"lokale system med:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Du bør ogsÃ¥ kontrollere filrettighederne og ejerskabet af mappen /var/lib/" +"mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Fjern alle MariaDB-databaser?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Mappen /var/lib/mysql, der indeholder MariaDB-databaserne, er ved at blive " +"fjernet." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Hvis du fjerner MariaDB-pakken for senere at installere en nyere version, " +"eller hvis en anden mariadb-server-pakke allerede benytter den, bør dataene " +"bevares." diff --cc debian/po/de.po index 9d3056013,000000000..2292e3be3 mode 100644,000000..100644 --- a/debian/po/de.po +++ b/debian/po/de.po @@@ -1,109 -1,0 +1,109 @@@ - # German translation of mariadb 10.0.13-1 ++# German translation of mariadb +# Alwin Meschede , 2006, 2007. +# Thomas Mueller , 2009. +# Chris Leick , 2014-2016. +# +msgid "" +msgstr "" - "Project-Id-Version: mariadb 10.0.25-1\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2016-05-12 22:39+0100\n" +"Last-Translator: Chris Leick \n" +"Language-Team: German \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Das alte Datenverzeichnis wird an einer neuen Stelle gespeichert" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Auf diesem System gibt es bereits eine Datei namens /var/lib/mysql/debian-*." +"flag. Die Zahl gibt eine Binärformatversion der Datenbank an, von der nicht " +"automatisch ein Upgrade (oder Downgrade) durchgeführt werden kann." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Daher wird das vorherige Datenverzeichnis in /var/lib/mysql-* umbenannt und " +"unter /var/lib/mysql wird ein neues Datenverzeichnis initialisiert." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Bitte exportieren/importieren Sie im Bedarfsfall Ihre Daten (z.B. mit " +"Mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Wichtige Anmerkung für NIS/YP-Benutzer!" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Falls MariaDB mit NIS/YP genutzt wird, muss ein »mysql«-Benutzerkonto auf " +"dem lokalen System hinzugefügt werden mit:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Sie sollten außerdem Besitzer und Zugriffsrechte des Verzeichnisses /var/lib/" +"mysql überprüfen:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Alle MariaDB-Datenbanken entfernen?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Das Verzeichnis /var/lib/mysql mit den MariaDB-Datenbanken soll entfernt " +"werden." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Falls geplant ist, das MariaDB-Paket zu entfernen, um lediglich eine höhere " +"Version zu installieren oder ein anderes mariadb-server-Paket die Daten " +"benutzt, sollten diese beibehalten werden." diff --cc debian/po/es.po index 1dd087782,000000000..4a383b175 mode 100644,000000..100644 --- a/debian/po/es.po +++ b/debian/po/es.po @@@ -1,144 -1,0 +1,144 @@@ +# MariaDB translation to Spanish +# Copyright (C) 2005-2016 Software in the Public Interest, SPI Inc. +# This file is distributed under the same license as the mariadb package. +# +# Changes: +# - Initial translation +# Jesus Aneiros, 2006 +# - Updated +# Javier Fernandez-Sanguino, 2006-2007, 2012, 2016 +# - Revision +# Nacho Barrientos Arias +# Fernando Cerezal +# David Martínez Moreno +# Ricardo Mones +# Carlos Galisteo +# Javier Fernandez-Sanguino +# +# +# Traductores, si no conoce el formato PO, merece la pena leer la +# documentación de gettext, especialmente las secciones dedicadas a este +# formato, por ejemplo ejecutando: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Equipo de traducción al español, por favor lean antes de traducir +# los siguientes documentos: +# +# - El proyecto de traducción de Debian al español +# http://www.debian.org/intl/spanish/ +# especialmente las notas y normas de traducción en +# http://www.debian.org/intl/spanish/notas +# +# - La guía de traducción de po's de debconf: +# /usr/share/doc/po-debconf/README-trans +# o http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Si tiene dudas o consultas sobre esta traducción consulte con el último +# traductor (campo Last-Translator) y ponga en copia a la lista de +# traducción de Debian al español () +msgid "" +msgstr "" - "Project-Id-Version: mysql-dfsg-5.1_5.0.24-3\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2016-04-30 21:26+0200\n" +"Last-Translator: Javier Fernández-Sanguino \n" +"Language-Team: Debian l10 Spanish \n" +"Language: Spanish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-POFile-SpellExtra: YP mariadb lib ej server flag mysqldump mysql var NIS\n" +"X-POFile-SpellExtra: MariaDB\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Se guardará el directorio antiguo de datos a la nueva ubicación" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Se ha encontrado un archivo «/var/lib/mysql/debian-*.flag» en el sistema. " +"Este número indica una versión de base de datos en formato binario que no " +"puede ser subirse (o bajarse) de versión automáticamente." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Por tanto, el archivo de datos anterior se renombrará a «/var/lib/mysql-*» y " +"se inicializará un nuevo directorio de datos en «/var/lib/mysql»." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Si lo necesita, tendrá que exportar e importar sus datos manualmente (p.ej. " +"con mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Nota importante para los usuarios de NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Para utilizar MariaDB bajo NIS/YP es necesario añadir una cuenta de usuario " +"mysql en el sistema local con:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"También debería comprobar los permisos y el propietario del directorio /var/" +"lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "¿Desea eliminar todas las bases de datos MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"El directorio /var/lib/mysql contiene bases de datos MariaDB que van a " +"eliminarse." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Debería mantener los datos si tiene planificado instalar una versión de " +"MariaDB más reciente o si hay un paquete «mariadb-server» distinto que los " +"está utilizando." diff --cc debian/po/eu.po index ee7191356,000000000..cf9826f77 mode 100644,000000..100644 --- a/debian/po/eu.po +++ b/debian/po/eu.po @@@ -1,104 -1,0 +1,104 @@@ +# translation of eu.po to Euskara +# Piarres BEobide , 2006. +# Piarres Beobide , 2009. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +msgid "" +msgstr "" - "Project-Id-Version: eu\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2009-07-29 11:59+0200\n" +"Last-Translator: Piarres Beobide \n" +"Language-Team: Euskara \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.11.4\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "NIS/YP erabiltzaileentzat ohar garrantzitsua" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +#, fuzzy +#| msgid "" +#| "You should also check the permissions and the owner of the /var/lib/mysql " +#| "directory:" +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Honetaz gain /var/lib/mysql direktorioaren jabea eta baimenak egiaztatu " +"beharko zenituzke:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Ezabatu MariaDB datubase guztiak?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"MariaDB datubaseak dituen /var/lib/mysql direktorioa ezabatua izango da." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"MariaDB paketea beranduago bertsio berriago bat instalatzeko kentzen ari " +"bazara, edo beste mariadb-server pakete bat berau erabiltzen ari bada, " +"datuak mantendu egin beharko lirateke." diff --cc debian/po/fi.po index d5a1b6d7b,000000000..a58a51630 mode 100644,000000..100644 --- a/debian/po/fi.po +++ b/debian/po/fi.po @@@ -1,105 -1,0 +1,105 @@@ +# Finnish translations for mariadb package +# This file is distributed under the same license as the mariadb package. +# Antti Järvinen , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-03-15 22:36+0200\n" +"Last-Translator: antti.jarvinen@katiska.org\n" +"Language-Team: \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.11\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Vanha datahakemisto tullaan tallentamaan uuteen paikkaan" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Järjestelmässä on tiedosto /var/lib/mysql/debian-*.flag. Numero osoittaa " +"tietokantatiedoston binääriformaatin version, josta/johon päivittäminen ei " +"automaattisesti onnistu. " + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Siksipä vanha datahakemisto tullaan siirtämään nimelle /var/lib/mysql-* ja " +"uudet tiedostot luodaan hakemistoon /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Tarpeittesi mukaan tuo tai vie tietokannan sisältö käsipelillä, esim. " +"käyttäen mysqldump-ohjelmaa." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Merkittävä huomio NIS/YP -käyttäjille" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"MariaDB:n käyttäminen NIS/YP:n kanssa edellyttää, että järjestelmään luodaan " +"käyttäjätunnus mysql:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "Tarkista myös hakemiston /var/lib/mysql omistaja ja oikeudet:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Poistetaanko kaikki MariaDB-tietokannat?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"MariaDB-tietokannat sisältävä hakemisto /var/lib/mysql ollaan poistamassa." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Jos poistat MariaDB-paketin asentaaksesi uudemman version tai jos joku muu " +"mariadb-server -paketti jo käyttää tietoja, tiedot tulisi säästää. " diff --cc debian/po/fr.po index 14b4c84a1,000000000..d18cc719b mode 100644,000000..100644 --- a/debian/po/fr.po +++ b/debian/po/fr.po @@@ -1,113 -1,0 +1,112 @@@ - # Translation of mariadb debconf templates to French +# Copyright (C) 2004-2016 Debian French l10n team - # This file is distributed under the same license as the mariadb packages. - # ++# French translation of mariadb ++# This file is distributed under the same license as the mariadb package. +# Translators: - # Christian Perrier , 2004, 2006, 2007, 2009, 2013. +# Baptiste Jammet , 2016. ++# Christian Perrier , 2004-2013 ++# bubu , 2023. ++# +msgid "" +msgstr "" - "Project-Id-Version: fr\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" - "PO-Revision-Date: 2016-12-31 18:35+0100\n" - "Last-Translator: Baptiste Jammet \n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" ++"PO-Revision-Date: 2023-01-30 18:38+0100\n" ++"Last-Translator: bubu \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" - "debian.org>\n" - "X-Generator: Lokalize 1.5\n" - "Plural-Forms: Plural-Forms: nplurals=2; plural=n>1;\n" ++"X-Generator: Poedit 2.4.2\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "L'ancien répertoire de données sera sauvegardé à un nouvel emplacement" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" - "Un fichier nommé /var/lib/mysql/debian-*.flag existe déjà sur ce système. Le " ++"Un fichier nommé /var/lib/mysql/debian-*.flag existe sur ce système. Le " +"numéro indique une version de base de données au format binaire qui ne peut " - "pas être mise à niveau (ou rétrogradée) automatiquement." ++"être mise à niveau automatiquement (ni rétrogradée)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" - "L'ancien répertoire sera renommé en /var/lib/mysql-* et un nouveau " - "répertoire de données sera initialisé à l'emplacement /var/lib/mysql." ++"Par conséquent, le répertoire de données précédent sera renommé /var/lib/" ++"mysql.* et un nouveau répertoire sera initialisé à /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" - "Veuillez exporter puis importer vos données manuellement si besoin (par " - "exemple avec mysqldump)." ++"Veuillez importer et exporter vos données manuellement (par exemple avec " ++"mysqldump) si nécessaire." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" - msgstr "Note importante pour les utilisateurs NIS/YP" ++msgstr "Remarque importante pour les utilisateurs de NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" - "L'utilisation de MariaDB avec NIS/YP impose l'ajout d'un compte local " - "« mysql » avec la commande :" ++"L'utilisation de MariaDB sous NIS/YP nécessite qu'un compte utilisateur " ++"« mysql » soit ajouté au système local avec :" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" - "Vous devez également vérifier le propriétaire et les permissions du " - "répertoire /var/lib/mysql :" ++"Vous devriez aussi vérifier les permissions et propriétaire du répertoire /" ++"var/lib/mysql :" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Faut-il supprimer toutes les bases de données MariaDB ?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" - "Le répertoire /var/lib/mysql qui contient les bases de données de MariaDB va " - "être supprimé." ++"Le répertoire /var/lib/mysql qui contient les bases de données MariaDB est " ++"sur le point d'être supprimé." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" - "Si vous retirez le paquet MariaDB en vue d'en installer une version plus " - "récente ou si un autre paquet mariadb-server les utilise déjà, vous devriez " - "les conserver." ++"Si vous supprimez le paquet MariaDB pour installer ultérieurement une " ++"version plus récente ou si un autre paquet mariadb-server l'utilise déjà, " ++"les données devraient être conservées." diff --cc debian/po/gl.po index 5567c6098,000000000..cda277c95 mode 100644,000000..100644 --- a/debian/po/gl.po +++ b/debian/po/gl.po @@@ -1,102 -1,0 +1,106 @@@ - # Galician translation of mysql-dfsg-5.1's debconf templates - # This file is distributed under the same license as the mysql-dfsg-5.1 package. ++# Galician translation of mariadb debconf templates ++# This file is distributed under the same license as the mariadb package. +# Jacobo Tarrio , 2007. +# +msgid "" +msgstr "" - "Project-Id-Version: mysql-dfsg-5.1\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" - "PO-Revision-Date: 2007-04-20 09:44+0200\n" - "Last-Translator: Jacobo Tarrio \n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" ++"PO-Revision-Date: 2023-01-30 10:35+0100\n" ++"Last-Translator: Pablo \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" ++"Plural-Forms: nplurals=2; plural=(n != 1);\n" ++"X-Generator: Poedit 3.2.2\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" - msgstr "" ++msgstr "O antigo directorio con datos gardarase noutro sitio." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" ++"Xa existe un ficheiro chamado /var/lib/mysql/debian-*.flag. O número indica " ++"unha versión do formato binario da base de datos que non se pode actualizar " ++"(ou desactualizar) de forma automática." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" ++"Por mor disto, o directorio de datos antigo moverase a /var/lib/mysql-* e " ++"crearase un novo directorio de datos en /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" ++"Se o precisa, exporte e importe os datos de forma manual (v.g. con " ++"mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" - msgstr "Nota importante para os usuarios de NIS/YP" ++msgstr "Aviso importante se usa NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" ++"Para usar MariaDB con NIS/YP precisa engadir a conta de usuario mysql ao " ++"sistema local facendo:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 - #, fuzzy - #| msgid "" - #| "You should also check the permissions and the owner of the /var/lib/mysql " - #| "directory:" +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" - msgstr "" - "Tamén debería comprobar os permisos e o propietario do directorio /var/lib/" - "mysql:" ++msgstr "Tamén comprobe os permisos e propietario do directorio /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" - msgstr "¿Eliminar tódalas bases de datos de MariaDB?" ++msgstr "Eliminar todas as bases de datos MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" - "Hase eliminar o directorio /var/lib/mysql, que contén as bases de datos de " - "MariaDB." ++"Vaise eliminar o directorio /var/lib/mysql con todas as base de datos MariaDB" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" - "Se está a eliminar o paquete MariaDB para instalar despois unha versión máis " - "recente ou se xa hai un paquete mariadb-server diferente a empregalo, " - "debería conservar os datos." ++"Recomendamos que non elimine os datos se vai eliminar o paquete MariaDB para " ++"instalar unha versión máis nova, ou se inda os usa algún paquete mariadb-" ++"server." diff --cc debian/po/it.po index 56f134fd5,000000000..6afcd3581 mode 100644,000000..100644 --- a/debian/po/it.po +++ b/debian/po/it.po @@@ -1,107 -1,0 +1,107 @@@ +# Italian (it) translation of debconf templates for mariadb +# This file is distributed under the same license as the mariadb package. +# Luca Monducci , 2006-2017. +# +msgid "" +msgstr "" - "Project-Id-Version: mariadb 10.0.13 Italian debconf templates\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-083-20 20:29+0100\n" +"Last-Translator: Luca Monducci \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "La vecchia directory data verrà salvata in una nuova posizione" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Su questo sistema esiste già un file con nome /var/lib/mysql/debian-*.flag. " +"Il numero indica una versione del database in formato binario che non è " +"possibile promuovere (o retrocedere) a una nuova versione automaticamente." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Di conseguenza la precedene directory data verrà rinominata in /var/lib/" +"mysql-* e verrà preparata una nuova directory data in /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Se necessario eseguire manualmente l'export/import (per esempio con " +"mysqldump) dei propri dati." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Nota importante per gli utenti NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Per usare MariaDB con NIS/YP è necessario aggiungere al sistema un account " +"utente locale con nome mysql con:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Inoltre è opportuno verificare i permessi e la proprietà della directory /" +"var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Eliminare tutti i database MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"La directory /var/lib/mysql che contiene i database di MariaDB sta per " +"essere eliminata." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Se si rimuove il pacchetto MariaDB per poi installare una versione più " +"recente oppure se sono già in uso da un altro pacchetto mariadb-server, i " +"dati non devono essere eliminati." diff --cc debian/po/ja.po index a8b2a0a96,000000000..556a3ea0d mode 100644,000000..100644 --- a/debian/po/ja.po +++ b/debian/po/ja.po @@@ -1,118 -1,0 +1,118 @@@ +# +# Translators, if you are not familiar with the PO format, gettext +# documentation is worth reading, especially sections dedicated to +# this format, e.g. by running: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Some information specific to po-debconf are available at +# /usr/share/doc/po-debconf/README-trans +# or http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Developers do not need to manually edit POT or PO files. +# Hideki Yamane (Debian-JP) , 2013. +# Takuma Yamada , 2016-2017. +# +msgid "" +msgstr "" - "Project-Id-Version: mariadb 10.0.32-1\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2016-05-01 11:27+0900\n" +"Last-Translator: Takuma Yamada \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.6\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "古いデータディレクトリは、新しい場所に保存されます" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"/var/lib/mysql/debian-*.flag という名前のファイルがこのシステム上に存在しま" +"す。番号は、自動的にアップグレード (またはダウングレード) することができない" +"データベースバイナリフォーマットのバージョンを示します。" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"そのため、以前のデータディレクトリは /var/lib/mysql-* にリネームされ、新しい" +"データディレクトリは /var/lib/mysql に初期化されます。" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"必要に応じて、(例えば mysqldump で) データを手動でエクスポート/インポートして" +"ください。" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "NIS/YP ユーザへの重要な注意" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"NIS/YP 配下で MariaDB を使うにはローカルのシステムに mysql のユーザアカウント" +"を追加するのが必要です。" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "/var/lib/mysql の所有者権限をチェックする必要もあります。" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "すべての MariaDB データベースを削除しますか?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"MariaDB データベースを含んでいるディレクトリ /var/lib/mysql を削除しようとし" +"ています。" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"後でより新しいバージョンのものをインストールしようとするために MariaDB パッ" +"ケージを削除しようとしている、あるいは別の mariadb-server パッケージを既に" +"使っている場合、データは保持する必要があります。" diff --cc debian/po/nb.po index e4255bdea,000000000..c0efb3235 mode 100644,000000..100644 --- a/debian/po/nb.po +++ b/debian/po/nb.po @@@ -1,103 -1,0 +1,103 @@@ +# translation of mysql_nb.po to Norwegian BokmÃ¥l +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Bjørn Steensrud , 2007. +msgid "" +msgstr "" - "Project-Id-Version: mysql_nb\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2007-02-18 12:13+0100\n" +"Last-Translator: Bjørn Steensrud \n" +"Language-Team: Norwegian BokmÃ¥l \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.2\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +#, fuzzy +#| msgid "Important note for NIS/YP users!" +msgid "Important note for NIS/YP users" +msgstr "Viktig merknad for NIS/YP-brukere!" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +#, fuzzy +#| msgid "" +#| "The script is about to remove the data directory /var/lib/mysql. If it is " +#| "planned to just install a higher MySQL version or if a different mysql-" +#| "server package is already using it, the data should be kept." +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Dette skriptet skal til Ã¥ fjerne data-mappa /var/lib/mysql. Denne mappa bør " +"beholdes hvis det bare skal installeres en høyere MariaDB-versjon, eller " +"hvis en annen mariadb-server-pakke allerede bruker den." diff --cc debian/po/nl.po index 2cf0a2b1f,000000000..58f0a61e7 mode 100644,000000..100644 --- a/debian/po/nl.po +++ b/debian/po/nl.po @@@ -1,111 -1,0 +1,111 @@@ - # Dutch mariadb-10 po-debconf translation, ++# Dutch mariadb po-debconf translation, +# Copyright (C) 2006 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the mariadb package. +# Vincent Zweije , 2006. +# Frans Spiesschaert , 2014, 2016, 2018. +# +msgid "" +msgstr "" - "Project-Id-Version: mariadb-10.2.7-1\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2018-03-29 21:25+0200\n" +"Last-Translator: Frans Spiesschaert \n" +"Language-Team: Debian Dutch l10n Team \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.7\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "De oude data-map zal op een nieuwe locatie bewaard worden" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Er bestaat op dit systeem een bestand met als naam /var/lib/mysql/debian-*." +"flag. Het nummer duidt op een versie van het binair database-bestandsformaat " +"dat niet automatisch opgewaardeerd (of gedegradeerd) kan worden." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Daarom zal de vroegere data-map hernoemd worden naar /var/lib/mysql-* en zal " +"er een nieuwe data-map geïnitialiseerd worden op /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Gelieve uw data zo nodig handmatig te exporteren/importeren (bijv. met " +"mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Belangrijke opmerking voor gebruikers van NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Het gebruik van MariaDB onder NIS/YP vereist dat een mysql gebruikersaccount " +"wordt toegevoegd aan het lokale systeem met:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"U moet ook controleren wie eigenaar is en wat de gebruikersrechten zijn van " +"de map /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Wilt u alle MariaDB-databases verwijderen?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"De map /var/lib/mysql die de MariaDB-databases bevat staat op het punt om " +"verwijderd te worden." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Als u het MariaDB-pakket verwijdert om later een meer recente versie te " +"installeren of als een ander mariadb-serverpakket het al gebruikt, zou de " +"data behouden moeten worden." diff --cc debian/po/pt.po index fae123972,000000000..2f3149df6 mode 100644,000000..100644 --- a/debian/po/pt.po +++ b/debian/po/pt.po @@@ -1,109 -1,0 +1,109 @@@ - # Portuguese translation for mysql-dfsg-5.1's debconf messages ++# Portuguese translation for mariadb debconf messages +# Copyright (C) 2006 Miguel Figueiredo +# This file is distributed under the same license as the mariadb package. +# Miguel Figueiredo , 2014 +# Rui Branco , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-08-06 10:00+0100\n" +"Last-Translator: Rui Branco \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "O antigo directório de data será guardado num novo local" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Já existe um ficheiro /var/lib/mysql/debian-*.flag no sistema. O número " +"indica uma base de dados de formato binário que não pode ser actualizada " +"automaticamente (ou baixar de versão)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Assim o directório de dados anterior será renomeado para /var/lib/mysql-* e " +"um novo directório de dados será inicializado em /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Por favor, se necessário, exporte/importe manualmente os seus dados (p.ex. " +"com mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Nota importante para os utilizadores de NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Utilizar MariaDB com NIS/YP necessita de uma conta de utilizador de mysql " +"para ser acrescentada ao sistema local com:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Deve também verificar as permissões e o dono do directório /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Remover todas as bases de dados MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"O directório /var/lib/mysql que contém as bases de dados MariaDB está " +"prestes a ser removido." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Se está a remover o pacote MariaDB de forma a posteriormente instalar uma " +"versão mais recente ou se um pacote mariadb-server já o está a utilizar, " +"então os dados devem ser mantidos." diff --cc debian/po/pt_BR.po index 0249342c5,000000000..faba8c966 mode 100644,000000..100644 --- a/debian/po/pt_BR.po +++ b/debian/po/pt_BR.po @@@ -1,109 -1,0 +1,109 @@@ +# Debconf translations for mariadb. +# This file is distributed under the same license as the mariadb package. +# André Luís Lopes, , 2005-2007. - # Adriano Rafael Gomes , 2015-2016. ++# Adriano Rafael Gomes , 2015-2023. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" - "PO-Revision-Date: 2016-04-30 16:16-0300\n" - "Last-Translator: Adriano Rafael Gomes \n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" ++"PO-Revision-Date: 2023-02-04 15:43-0300\n" ++"Last-Translator: Adriano Rafael Gomes \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "O diretório de dados antigo será salvo em novo local" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Um arquivo chamado /var/lib/mysql/debian-*.flag já existe nesse sistema. O " - "número indicou uma versão de formato binário de banco de dados que não pode " ++"número indica uma versão de formato binário de banco de dados que não pode " +"ser atualizada (ou rebaixada) automaticamente." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Portanto, o diretório de dados anterior será renomeado para /var/lib/mysql-* " +"e um novo diretório de dados será inicializado em /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Por favor, exporte/importe manualmente seus dados (por exemplo, com " +"mysqldump) se necessário." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Aviso importante para usuários NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Usar o MariaDB sob NIS/YP requer que uma conta de usuário mysql seja " +"adicionada ao sistema local com:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Você deverá também verificar as permissões e o dono do diretório /var/lib/" +"mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Remover todas as bases de dados do MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"O diretório /var/lib/mysql, o qual contém as bases de dados do MariaDB, está " +"prestes a ser removido." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Caso você esteja removendo o pacote MariaDB para posteriormente instalar uma " +"versão mais recente ou, caso uma versão diferente do pacote mariadb-server " +"esteja sendo utilizada, os dados deverão ser mantidos." diff --cc debian/po/ro.po index 66ea63ef7,000000000..c2851f002 mode 100644,000000..100644 --- a/debian/po/ro.po +++ b/debian/po/ro.po @@@ -1,103 -1,0 +1,110 @@@ - # Romanian translation of mysql-dfsg. - # Copyright (C) 2006 THE mysql-dfsg'S COPYRIGHT HOLDER - # This file is distributed under the same license as the mysql-dfsg package. ++# Romanian translation of mariadb. ++# Copyright © 2006, 2023 THE mariadb COPYRIGHT HOLDER ++# This file is distributed under the same license as the mariadb package. +# +# Stan Ioan-Eugen , 2006. ++# Remus-Gabriel Chelu , 2023. ++# +msgid "" +msgstr "" - "Project-Id-Version: po-debconf://mysql-dfsg\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" - "PO-Revision-Date: 2006-12-20 21:27+0200\n" - "Last-Translator: stan ioan-eugen \n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" ++"PO-Revision-Date: 2023-01-29 23:56+0100\n" ++"Last-Translator: Remus-Gabriel Chelu \n" +"Language-Team: romanian \n" - "Language: \n" ++"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" - "X-Generator: KBabel 1.11.4\n" ++"X-Generator: Poedit 3.2.2\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" - msgstr "" ++msgstr "Vechiul director de date va fi salvat în noua locație" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" ++"Un fișier numit „/var/lib/mysql/debian-*.flag” există în acest sistem. Numărul " ++"indică o versiune în format binar al bazei de date care nu poate fi actualizată " ++"(sau retrogradată) automat." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" - "Therefore the previous data directory will be renamed to /var/lib/mysql-* " - "and a new data directory will be initialized at /var/lib/mysql." ++"Therefore the previous data directory will be renamed to /var/lib/mysql-* and a " ++"new data directory will be initialized at /var/lib/mysql." +msgstr "" ++"Prin urmare, directorul de date anterior va fi redenumit în „/var/lib/mysql-*” " ++"și un nou director de date va fi inițializat la „/var/lib/mysql”." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 - msgid "" - "Please manually export/import your data (e.g. with mysqldump) if needed." ++msgid "Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" ++"Exportați/importați manual datele dumneavoastră (de exemplu, cu «mysqldump»), " ++"dacă este necesar." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 - #, fuzzy - #| msgid "Important note for NIS/YP users!" +msgid "Important note for NIS/YP users" - msgstr "Notă importantă pentru utilizatorii NIS/YP!" ++msgstr "Notă importantă pentru utilizatorii NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" ++"Dacă MariaDB se utilizează sub NIS/YP, se necesită adăugarea unui cont de " ++"utilizator „mysql” în sistemul local cu:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" ++"Ar trebui să verificați, de asemenea, permisiunile și dreptul de proprietate " ++"asupra directorului „/var/lib/mysql”:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" - msgstr "" ++msgstr "Eliminați toate bazele de date MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" - "The /var/lib/mysql directory which contains the MariaDB databases is about " - "to be removed." ++"The /var/lib/mysql directory which contains the MariaDB databases is about to " ++"be removed." +msgstr "" ++"Directorul „/var/lib/mysql” care conține bazele de date MariaDB este pe cale să " ++"fie eliminat." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 - #, fuzzy - #| msgid "" - #| "The script is about to remove the data directory /var/lib/mysql. If it is " - #| "planned to just install a higher MySQL version or if a different mysql-" - #| "server package is already using it, the data should be kept." +msgid "" - "If you're removing the MariaDB package in order to later install a more " - "recent version or if a different mariadb-server package is already using it, " - "the data should be kept." ++"If you're removing the MariaDB package in order to later install a more recent " ++"version or if a different mariadb-server package is already using it, the data " ++"should be kept." +msgstr "" - "Scriptul urmează să şteargă directorul de date /var/lib/mysql. Dacă plănuiÅ£i " - "doar să instalaÅ£i o versiune nouă MariaDB sau datele sunt folosite de către " - "un alt pachet mariadb-server, atunci ar trebui păstraÅ£i datele." ++"Dacă eliminați pachetul MariaDB pentru a instala ulterior o versiune mai " ++"recentă sau dacă un alt pachet mariadb-server îl folosește deja, datele ar " ++"trebui păstrate." diff --cc debian/po/ru.po index 9b36c68fd,000000000..5271c568d mode 100644,000000..100644 --- a/debian/po/ru.po +++ b/debian/po/ru.po @@@ -1,110 -1,0 +1,110 @@@ +# translation of ru.po to Russian +# +# Ilgiz Kalmetev , 2003. +# Yuriy Talakan' , 2005, 2006. +# Yuriy Talakan' , 2007. +# Yuri Kozlov , 2009, 2014, 2016. +msgid "" +msgstr "" - "Project-Id-Version: mariadb 10.0.25-1\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2016-05-04 18:56+0300\n" +"Last-Translator: Yuri Kozlov \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Каталог со старыми данными будет сохранён в новом месте" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"В системе найден файл /var/lib/mysql/debian-*.flag. Число представляет " +"версию двоичного формата базы данных, которую невозможно обновить " +"автоматически (или откатить к старой версии)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"В следствии этого, предыдущий каталог с данными будет переименован в /var/" +"lib/mysql-*, а в /var/lib/mysql будет инициализирован каталог для новых " +"данных." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Если нужно, выполните экспорт/импорт данных вручную (например, с помощью " +"mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Важное замечание для пользователей NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Использование MariaDB в NIS/YP требует добавления учётной записи mysql в " +"локальную систему с:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "Также проверьте права доступа и владельца каталога /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Удалить все базы данных MariaDB?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Запрос на удаление каталога /var/lib/mysql, содержащий базы данных MariaDB." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Если вы удаляете пакет MariaDB для установки более новой версии MariaDB, или " +"есть другие пакеты mariadb-server, использующие этот каталог, то данные " +"лучше сохранить." diff --cc debian/po/sv.po index 4cd09734e,000000000..806ebba3c mode 100644,000000..100644 --- a/debian/po/sv.po +++ b/debian/po/sv.po @@@ -1,110 -1,0 +1,110 @@@ +# Translation of mariadb debconf template to Swedish +# Copyright (C) 2017 Martin Bagge +# This file is distributed under the same license as the mariadb package. +# +# Andreas Henriksson , 2007 +# Martin Bagge , 2009, 2015, 2017 +msgid "" +msgstr "" - "Project-Id-Version: mysql-dfsg-5.1 5.0.21-3\n" ++"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-03-23 09:20+0100\n" +"Last-Translator: Martin Bagge / brother \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.11\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Den gamla data-katalogen kommer att sparas till en ny plats" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"En fil med namn pÃ¥ formatet /var/lib/mysql/debian-*.flag hittades i " +"systemet. Siffran indikerar ett binärformat pÃ¥ databasen som inte kan " +"uppgraderas (eller nedgraderas)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Därför kommer den gamla data-katalogen att byta namn till /var/lib/mysql-* " +"och en ny katalog kommer att initieras pÃ¥ /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Exportera/importera din data manuellt (exempelvis med mysqldump) om detta är " +"nödvändigt." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Viktig information för NIS/YP-användare" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"För att kunna använda MariaDB under NIS/YP mÃ¥ste ett användarkonto för mysql " +"läggas till i systemet." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Du bör ocksÃ¥ kontrollera rättigheterna och ägaren av katalogen /var/lib/" +"mysql." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Ta bort alla MariaDB-databaser?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Katalogen /var/lib/mysql som innehÃ¥ller MariaDB-databaser kommer att tas " +"bort." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Om avinstallationen av MariaDB-paketet görs för att senare kunna installera " +"en nyare version eller om en annan mariadb-server redan använder filerna ska " +"de inte raderas." diff --cc debian/po/templates.pot index 102b6214c,000000000..49daaa3ed mode 100644,000000..100644 --- a/debian/po/templates.pot +++ b/debian/po/templates.pot @@@ -1,93 -1,0 +1,93 @@@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the mariadb package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" diff --cc debian/po/tr.po index 74320c147,000000000..b8ec2a7f6 mode 100644,000000..100644 --- a/debian/po/tr.po +++ b/debian/po/tr.po @@@ -1,107 -1,0 +1,107 @@@ +# Turkish translation of mariadb-server. +# This file is distributed under the same license as the mariadb-server package. +# Gürkan Aslan , 2004 +# Atila KOÇ , 2015, 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-03-16 13:16+0300\n" +"Last-Translator: Atila KOÇ \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7.1\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Eski veritabanı dizini yeni konumuna kaydedilecektir" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Bu sistemde /var/lib/mysql/debian-*.flag adlı bir dosya bulunmaktadır. " +"Belirtilen numara kendiliğinden yükseltilemeyecek ya da alçaltılamayacak bir " +"ikilik veritabanı biçimini işaret etmektedir." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Önceki veri dizini /var/lib/mysql-* olarak yeniden adlandırılacak ve yeni " +"veri dizini /var/lib/mysql konumunda hazırlanacaktır." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "Gerektiğinde verinizi elle (ör. mysqldump ile) içe/dışa aktarın." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "NIS/YP kullanıcıları için önemli not" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"MariaDB'nin NIS/YP ile kullanılması için yerel sisteme aşağıdaki komut " +"çalıştırılarak mysql kullanıcı hesabının eklenmesi gereklidir:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"/var/lib/mysql dizininin sahiplik ve izin ayarlarını da gözden " +"geçirmelisiniz:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Tüm MariaDB veritabanları kaldırılsın mı?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"MariaDB veritabanlarını barındıran /var/lib/mysql dizini kaldırılmak üzere" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Eğer MariaDB paketini daha sonra güncel bir sürümünü kurmak üzere " +"kaldırıyorsanız ya da veritabanlarınıza başka bir mariadb-server paketi ile " +"erişiyorsanız, veritabanlarınızı kaldırmamalısınız." diff --cc debian/po/vi.po index bd048b56b,000000000..3600ec3af mode 100644,000000..100644 --- a/debian/po/vi.po +++ b/debian/po/vi.po @@@ -1,109 -1,0 +1,109 @@@ +# Vietnamese translations for mariadb package +# Bản dịch Tiếng Việt dành cho gói mariadb. +# This file is distributed under the same license as the mariadb package. +# Trần Ngọc Quân , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: mariadb\n" +"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" - "POT-Creation-Date: 2019-07-23 19:16-0300\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" +"PO-Revision-Date: 2017-03-18 13:32+0700\n" +"Last-Translator: Trần Ngọc Quân \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.7\n" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "The old data directory will be saved at new location" +msgstr "Thư mục dữ liệu cÅ© sẽ được lưu tại vị trí mới" + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " +"indicates a database binary format version that cannot automatically be " +"upgraded (or downgraded)." +msgstr "" +"Một tập tin có tên /var/lib/mysql/debian-*.flag đã sẵn có trên hệ thống này. " +"Con số chỉ ra rằng một phiên bản định dạng cÆ¡ sở dữ liệu không thể tá»± động " +"nâng cấp (hoặc hạ cấp)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Therefore the previous data directory will be renamed to /var/lib/mysql-* " +"and a new data directory will be initialized at /var/lib/mysql." +msgstr "" +"Do đó thư mục dữ liệu trước đây sẽ được đổi tên thành /var/lib/mysql-* và " +"thư mục dữ liệu mới sẽ được khởi tạo tại /var/lib/mysql." + +#. Type: note +#. Description +#: ../mariadb-server.templates:2001 +msgid "" +"Please manually export/import your data (e.g. with mysqldump) if needed." +msgstr "" +"Vui lòng xuất/nhập dữ liệu cá»§a bạn bằng tay nếu thấy cần (ví dụ bằng " +"mysqldump)." + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "Important note for NIS/YP users" +msgstr "Chú ý quan trọng cho người dùng NIS/YP" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"Using MariaDB under NIS/YP requires a mysql user account to be added on the " +"local system with:" +msgstr "" +"Dùng MariaDB dưới NIS/YP cần một tài khoản người dùng được thêm vào một hệ " +"thống nội bộ với:" + +#. Type: note +#. Description +#: ../mariadb-server.templates:3001 +msgid "" +"You should also check the permissions and ownership of the /var/lib/mysql " +"directory:" +msgstr "" +"Bạn cÅ©ng nên kiểm tra phân quyền và chá»§ sở hữu cá»§a thư mục /var/lib/mysql:" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "Remove all MariaDB databases?" +msgstr "Xóa bỏ mọi cÆ¡ sở dữ liệu MariaDB chứ?" + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"The /var/lib/mysql directory which contains the MariaDB databases is about " +"to be removed." +msgstr "" +"Thư mục /var/lib/mysql nÆ¡i mà chứa các cÆ¡ sở dữ liệu MariaDB chuẩn bị bị xóa " +"bỏ." + +#. Type: boolean +#. Description +#: ../mariadb-server.templates:4001 +msgid "" +"If you're removing the MariaDB package in order to later install a more " +"recent version or if a different mariadb-server package is already using it, " +"the data should be kept." +msgstr "" +"Nếu bạn gỡ bỏ gói cốt để mà sau này cài đặt gói máy phục vụ phiên bản gần " +"đây hoặc là một gói mariadb-server khác đang được dùng, dữ liệu nên được giữ " +"lại." diff --cc debian/po/zh_CN.po index 000000000,000000000..7a621796a new file mode 100644 --- /dev/null +++ b/debian/po/zh_CN.po @@@ -1,0 -1,0 +1,99 @@@ ++# Simplified Chinese translation of mariadb-server ++# This file is distributed under the same license as the mariadb package. ++# Tianyu Chen , 2023. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: mariadb\n" ++"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n" ++"POT-Creation-Date: 2022-12-31 18:55-0800\n" ++"PO-Revision-Date: 2023-02-02 03:08+0800\n" ++"Last-Translator: Tianyu Chen \n" ++"Language-Team: \n" ++"Language: zh_CN\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"Plural-Forms: nplurals=1; plural=0;\n" ++"X-Generator: Poedit 3.2.2\n" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:2001 ++msgid "The old data directory will be saved at new location" ++msgstr "旧的数据目录将被保存在新位置" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:2001 ++msgid "" ++"A file named /var/lib/mysql/debian-*.flag exists on this system. The number " ++"indicates a database binary format version that cannot automatically be " ++"upgraded (or downgraded)." ++msgstr "" ++"系统中存在名为 /var/lib/mysql/debian-*.flag 的文件。这个数字说明系统中存在一" ++"个对应版本的数据库无法自动升级(或降级)。" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:2001 ++msgid "" ++"Therefore the previous data directory will be renamed to /var/lib/mysql-* " ++"and a new data directory will be initialized at /var/lib/mysql." ++msgstr "" ++"因此之前的数据目录将被重命名至 /var/lib/mysql-*,新的数据目录将被初始化为 /" ++"var/lib/mysql。" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:2001 ++msgid "" ++"Please manually export/import your data (e.g. with mysqldump) if needed." ++msgstr "如必要,请手动导出/导入你的数据。(如,使用 mysqldump)" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:3001 ++msgid "Important note for NIS/YP users" ++msgstr "对 NIS/YP 用户的重要提示" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:3001 ++msgid "" ++"Using MariaDB under NIS/YP requires a mysql user account to be added on the " ++"local system with:" ++msgstr "在 NIS/YP 下使用 MariaDB 需要使用以下命令在系统中添加一个 mysql 用户:" ++ ++#. Type: note ++#. Description ++#: ../mariadb-server.templates:3001 ++msgid "" ++"You should also check the permissions and ownership of the /var/lib/mysql " ++"directory:" ++msgstr "你还需要检查 /var/lib/mysql 目录的权限和所有权:" ++ ++#. Type: boolean ++#. Description ++#: ../mariadb-server.templates:4001 ++msgid "Remove all MariaDB databases?" ++msgstr "移除全部 MariaDB 数据库?" ++ ++#. Type: boolean ++#. Description ++#: ../mariadb-server.templates:4001 ++msgid "" ++"The /var/lib/mysql directory which contains the MariaDB databases is about " ++"to be removed." ++msgstr "包含 MariaDB 数据库的目录 /var/lib/mysql 将被删除。" ++ ++#. Type: boolean ++#. Description ++#: ../mariadb-server.templates:4001 ++msgid "" ++"If you're removing the MariaDB package in order to later install a more " ++"recent version or if a different mariadb-server package is already using it, " ++"the data should be kept." ++msgstr "" ++"如果您是为了安装新版本而卸载 MariaDB 包,或正在使用另一个 mariadb-server 包," ++"您应该保留数据。" diff --cc debian/rules index d010a880f,000000000..9950b38b7 mode 100755,000000..100755 --- a/debian/rules +++ b/debian/rules @@@ -1,196 -1,0 +1,234 @@@ +#!/usr/bin/make -f + +# Enable Debian Hardening +# https://wiki.debian.org/Hardening +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# Disable LTO on Ubuntu, see LP: #1970634 and https://jira.mariadb.org/browse/MDEV-25633 +ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes), yes) + export DEB_BUILD_MAINT_OPTIONS += optimize=-lto +endif + +DPKG_EXPORT_BUILDFLAGS = 1 +# Include all defaults, including buildflags.mk +include /usr/share/dpkg/default.mk +# CPPFLAGS are nor read by CMake, so copy them to CXXFLAGS +# See why at https://cmake.org/Bug/view.php?id=12928 +# This is needed for e.g. all automatic Debian hardening flags to apply on all cmake builds. +CFLAGS+=$(CPPFLAGS) +CXXFLAGS+=$(CPPFLAGS) + +# Only do a strict symbol checking on Linux ++# https://manpages.debian.org/testing/dpkg-dev/dpkg-gensymbols.1.en.html ++# Level 4: Fails if some libraries have been introduced. +ifneq (,$(filter linux,$(DEB_HOST_ARCH_OS))) - DPKG_GENSYMBOLS_CHECK_LEVEL := 4 ++ export DPKG_GENSYMBOLS_CHECK_LEVEL = 4 +endif + +BUILDDIR := builddir - DEB_VERSION_REVISION := $(shell echo $(DEB_VERSION) | sed -e 's/.*[~-]\(.*\)/\1/') ++DEB_VERSION_REVISION := $(shell echo $(DEB_VERSION) | sed -e 's/^.*-//') +DEB_VERSION_VERSION := $(shell echo $(DEB_VERSION) | sed -e 's/^.*:\(.*\)\(-\|+\).*/\1/') +DEB_VERSION_MAJOR := $(shell echo $(DEB_VERSION_VERSION) | sed -e 's/^\(.*\)\..*$$/\1/') +RELEASE := $(shell lsb_release -r -s) # Use changelog based DEB_DISTRIBUTION instead? - TMP:=$(CURDIR)/debian/tmp ++TMP := $(CURDIR)/debian/tmp ++MTR_SKIP_TEST_LIST := $(shell mktemp) + +# According to Debian Policy version 4.2.0 builds should be as verbose as +# possible unless 'terse' is specifically passed. +ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS))) + export DH_VERBOSE=1 +endif + +# Parallel build support as advised +# at https://www.debian.org/doc/debian-policy/ch-source.html#s-debianrules-options +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + MAKEFLAGS += -j$(NUMJOBS) +else + # NUMJOBS cannot be empty as it is used as a parameter to mtr, default to 'auto'. + NUMJOBS = auto +endif + +# RocksDB cannot build on 32-bit platforms +ifeq (32,$(DEB_HOST_ARCH_BITS)) + CMAKEFLAGS += -DPLUGIN_ROCKSDB=NO +endif + ++# Only attempt to build with PMEM on archs that have package libpmem-dev available ++# See https://packages.debian.org/search?searchon=names&keywords=libpmem-dev ++ifneq (,$(filter $(DEB_HOST_ARCH),amd64 arm64 ppc64el riscv64)) ++ CMAKEFLAGS += -DWITH_PMEM=ON ++endif ++ ++# Fix compilation errors like "relocation truncated to fit: GPREL16 against symbol `wsrep_debug'" ++ifeq ($(DEB_HOST_ARCH),alpha) ++ export DEB_LDFLAGS_MAINT_APPEND += -Wl,--no-relax ++endif ++ +# Add support for verbose builds +MAKEFLAGS += VERBOSE=1 + +override_dh_auto_clean: + @echo "RULES.$@" + dh_testdir - dh_testroot - rm -rf $(BUILDDIR) builddir-native mysql-test/unstable-tests - debconf-updatepo # Update po-files when clean runs before each build ++ # Delete obsolete/unstable components and embedded source code copies ++ # to ensure they are not used in Debian and in general to keep MariaDB binaries ++ # secure and using only system libraries that can be updated quickly and easily ++ # in case security vulnerabilities are found in any of the libraries ++ rm -rf $(BUILDDIR) builddir-native extra/readline extra/wolfssl zlib libmariadb/external/zlib ++ # Remove columnstore as the source code is dirty and software not mature enough for Debian anyway ++ rm -rf storage/columnstore ++ # Delete precompiled binaries in upstream sources to ensure they are not used in Debian ++ rm -rf storage/connect/JavaWrappers.jar storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2 ++ ++ # Update po-files when clean runs before each build ++ debconf-updatepo ++ ++ # Clean up files created by custom sections in build that 'dh clean' does not see automatically ++ rm -rf debian/mariadb-server.*.socket debian/substvars + +override_dh_auto_configure: + @echo "RULES.$@" + dh_testdir + +ifneq ($(DEB_BUILD_ARCH),$(DEB_HOST_ARCH)) - dpkg-architecture -a$(DEB_BUILD_ARCH) -f -c dh_auto_configure --builddirectory=builddir-native ++ dpkg-architecture -a$(DEB_BUILD_ARCH) -f -c dh_auto_configure --builddirectory=builddir-native --reload-all-buildenv-variables + dh_auto_build --builddirectory=builddir-native -- import_executables +endif + + echo "server:Version=$(DEB_VERSION)" >> debian/substvars + - # As packages does not have major version any more on package name there is no way as it not set by dpkg - # to use this on postinst script. Use sed to determine major version ++ # As packages does not have major version any more in package name there is no ++ # way as it not set by dpkg to use this on postinst script. Use sed to ++ # determine major version instead. ++ # @TODO: Rewrite this to use the new upstream /var/lib/mysql_upgrade_info file ++ # instead of the legacy /var/lib/debian-XX.X.flag file + sed -i 's/__MARIADB_MAJOR_VER__/$(DEB_VERSION_MAJOR)/g' debian/mariadb-server.post* debian/mariadb-server.preinst + - # Don't build ColumnStore as part of the native build as it does not meet the - # quality standards in Debian. Also building it requires an extra 4 GB of disk - # space which makes native Debian builds fail as the total disk space needed - # for MariaDB becomes over 10 GB. Only build CS via autobake-deb.sh. - # - # Note: Don't use '-DWITH_URING=ON' as some Buildbot builders are missing it - # and would fail permanently. ++ # Don't build ColumnStore, not mature enough for Debian yet. + PATH=$${MYSQL_BUILD_PATH:-"/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin"} \ - NO_UPDATE_BUILD_VERSION=1 \ + dh_auto_configure --builddirectory=$(BUILDDIR) -- \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + $(CMAKEFLAGS) \ + $(if $(filter $(DEB_BUILD_ARCH),$(DEB_HOST_ARCH)),,-DIMPORT_EXECUTABLES=$(CURDIR)/builddir-native/import_executables.cmake) \ - -DCOMPILATION_COMMENT="mariadb.org binary distribution" \ ++ -DCOMPILATION_COMMENT="$(DEB_VENDOR) $(RELEASE)" \ + -DMYSQL_SERVER_SUFFIX="-$(DEB_VERSION_REVISION)" \ + -DSYSTEM_TYPE="debian-$(DEB_HOST_GNU_SYSTEM)" \ + -DBUILD_CONFIG=mysql_release \ + -DCONC_DEFAULT_CHARSET=utf8mb4 \ + -DPLUGIN_AWS_KEY_MANAGEMENT=NO \ + -DPLUGIN_COLUMNSTORE=NO \ ++ -DWITH_NUMA=AUTO \ + -DIGNORE_AIO_CHECK=ON \ ++ -DWITH_URING=ON \ ++ -DWITH_INNODB_SNAPPY=ON \ ++ -DHAVE_SYSTEM_LIBFMT_EXITCODE=0 \ + -DDEB=$(DEB_VENDOR) + +# This is needed, otherwise 'make test' will run before binaries have been built +override_dh_auto_build: + @echo "RULES.$@" + # Print build env info to help debug builds on different platforms + dpkg-architecture - cd $(BUILDDIR) && $(MAKE) --output-sync=target ++ cd $(BUILDDIR) && $(MAKE) + +override_dh_auto_test: + @echo "RULES.$@" + dh_testdir - # Ensure at least an empty file exists - touch mysql-test/unstable-tests ++ # Skip running test suite after build if DEB_BUILD_OPTIONS contains 'nocheck' ++ @echo "DEB_BUILD_OPTIONS: $(DEB_BUILD_OPTIONS)" ++ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + # Skip unstable tests if such are defined for arch - [ ! -f debian/unstable-tests.$(DEB_HOST_ARCH) ] || cat debian/unstable-tests.$(DEB_HOST_ARCH) >> mysql-test/unstable-tests ++ [ ! -f debian/unstable-tests.$(DEB_HOST_ARCH) ] || cat debian/unstable-tests.$(DEB_HOST_ARCH) >> $(MTR_SKIP_TEST_LIST) ++ # Show contents of skip list on this architecture ++ @echo "On architecture $(DEB_HOST_ARCH) skip tests:" ++ cat $(MTR_SKIP_TEST_LIST) + # Run testsuite - ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + cd $(BUILDDIR)/mysql-test && \ - ./mtr --force --mem \ ++ export MTR_PRINT_CORE=detailed && \ ++ ./mtr --force --testcase-timeout=120 --suite-timeout=540 --retry=3 \ ++ --verbose-restart --max-save-core=1 --max-save-datadir=1 \ + --parallel=$(NUMJOBS) --skip-rpl --suite=main \ - --skip-test-list=unstable-tests ++ --skip-test-list=$(MTR_SKIP_TEST_LIST) \ ++ $(MTR_ARGUMENTS_APPEND) ++ # Don't use --mem here as official Debian builders and most Docker systems don't have a large mem device available and ++ # would fail with errors on lack of disk space. +endif + +override_dh_auto_install: + @echo "RULES.$@" + dh_testdir + dh_testroot + + # Run 'make install' without output since it is uninteresting and + # silencing it helps to make overall build log shorter and more readable + @echo "Running $(MAKE) install DESTDIR=$(TMP) ..." + cd $(BUILDDIR) && $(MAKE) install DESTDIR=$(TMP) > /dev/null + + # If mariadb-test package is removed, also remove most of it's files + grep --quiet "Package: mariadb-test" debian/control || rm -rf $(TMP)/usr/share/mariadb/mariadb-test + ++ # Delete lone compiled binary that that does not belong in the ++ # mariadb-test-data package and which seems hard to move ++ # https://jira.mariadb.org/browse/MDEV-21654 ++ rm -rf $(TMP)/usr/share/mariadb/mariadb-test/suite/plugins/pam/pam_mariadb_mtr.so ++ + # Delete private files from libraries so they don't get shipped in the -dev packages + rm -r $(TMP)/usr/include/mariadb/server/private + + # Don't ship sql-bench at all, just delete it completely even though it builds + rm -r $(TMP)/usr/sql-bench + + # nm numeric soft is not enough, therefore extra sort in command + # to satisfy Debian reproducible build requirements + mkdir -p $(TMP)/usr/share/doc/mariadb-server + nm --defined-only $(BUILDDIR)/sql/mariadbd | LC_ALL=C sort | gzip -n -9 > $(TMP)/usr/share/doc/mariadb-server/mariadbd.sym.gz + + # Rename and install AppArmor profile + install -D -m 644 debian/apparmor-profile $(TMP)/etc/apparmor.d/usr.sbin.mariadbd + ++ # Install mariadb.pc as a symlink for the client library, ++ # use -f to override the existing server mariadb.pc file ++ ln -sf libmariadb.pc $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/mariadb.pc ++ + # Install libmariadbclient18 compatibility links + ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so - ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so.18 - - # Install libmysqlclientclientXX compatibility links - ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.18 - ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.19 - ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.20 + + # Install libmariadbclient.a compatibility link + ln -s libmariadb.a $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.a + + # Symlink plugins that are used by both server and client and thus need to + # load from the libmariadb path as well + ln -s ../../../mysql/plugin/auth_test_plugin.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/auth_test_plugin.so + ln -s ../../../mysql/plugin/qa_auth_interface.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/qa_auth_interface.so + ln -s ../../../mysql/plugin/test_sql_service.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/test_sql_service.so + # Move test plugins that are only needed by the client to the libmariadb path + mv -v $(TMP)/usr/lib/mysql/plugin/qa_auth_client.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/ + ++# Define name used for service, and install mariadb.service on Linux only +override_dh_installsystemd: - dh_systemd_enable --name=mariadb mariadb.service - dh_systemd_enable --no-enable --name=mariadb mariadb.socket - dh_systemd_enable --no-enable --name=mariadb-extra mariadb-extra.socket - dh_systemd_enable --no-enable --name=mariadb@ mariadb.socket - dh_systemd_enable --no-enable --name=mariadb-extra@ mariadb-extra.socket - dh_systemd_enable --no-enable --name=mariadb@ mariadb@.service - - # Start MariaDB at sequence number 19 before 20 where apache, proftpd etc gets - # started which might depend on a running database server. ++ifneq (,$(filter linux,$(DEB_HOST_ARCH_OS))) ++ dh_installsystemd -pmariadb-server mariadb.service ++endif ++ ++# Change dh_missing from fail to list on non-Linux ++override_dh_missing: ++ifneq (,$(filter linux,$(DEB_HOST_ARCH_OS))) ++ dh_missing --list-missing ++endif ++ +override_dh_installinit-arch: - dh_installinit --name=mariadb -- defaults 19 21 - dh_systemd_start --restart-after-upgrade ++ dh_installinit --name=mariadb + +# Use custom server version string variable +override_dh_gencontrol: + dh_gencontrol -- -Tdebian/substvars + +# If a file is not supposed to be included anywhere, add it to the not-installed +# file and document the reason. Note that dh_install supports the above mentioned +# white list file only starting from Debian Stretch and Ubuntu Xenial. +# To find more, grep build logs for 'but is not installed to anywhere'. +%: - dh $@ --parallel --with systemd --fail-missing ++ dh $@ + +# vim: ts=8 diff --cc debian/salsa-ci.yml index f5ffab990,000000000..7ce6b68d8 mode 100644,000000..100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@@ -1,894 -1,0 +1,1093 @@@ +--- +# Include Salsa-CI as a base +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml + +# Override Salsa-CI with MariaDB specific variations +variables: ++ BUILT_PACKAGES: "libmariadb-dev libmariadb-dev-compat libmariadb3 ++ libmariadbd19t64 libmariadbd-dev mariadb-common mariadb-client-core ++ mariadb-client mariadb-server-core mariadb-server mariadb-backup ++ mariadb-plugin-connect mariadb-plugin-s3 mariadb-plugin-rocksdb ++ mariadb-plugin-oqgraph mariadb-plugin-mroonga mariadb-plugin-spider ++ mariadb-plugin-gssapi-server mariadb-plugin-gssapi-client ++ mariadb-plugin-cracklib-password-check mariadb-plugin-hashicorp-key-management ++ mariadb-plugin-provider-bzip2 mariadb-plugin-provider-lz4 ++ mariadb-plugin-provider-lzma mariadb-plugin-provider-lzo ++ mariadb-plugin-provider-snappy mariadb-test mariadb-test-data" + DEB_BUILD_OPTIONS: "nocheck noautodbgsym" - RELEASE: bullseye ++ RELEASE: sid ++ # Reprotest works, but takes very long time and often fails due to timeouts. ++ # Thus is best kept disabled and only occasionally manually enabled to ++ # test that reproducibility works, along with atomic reprotest to directly ++ # pinpoint what aspect of the build is broken if not reproducible. + SALSA_CI_DISABLE_REPROTEST: 1 ++ SALSA_CI_ENABLE_ATOMIC_REPROTEST: 0 + SALSA_CI_DISABLE_MISSING_BREAKS: 0 - SALSA_CI_DISABLE_RC_BUGS: 1 - SALSA_CI_DISABLE_BUILD_PACKAGE_ALL: 1 - SALSA_CI_DISABLE_BUILD_PACKAGE_ANY: 1 - GIT_SUBMODULE_STRATEGY: recursive - SALSA_CI_GBP_BUILDPACKAGE_ARGS: "--git-submodules" # did not apply to extract-sources ++ SALSA_CI_DISABLE_RC_BUGS: 0 + +# Extend Salsa-CI build jobs to have longer timeout as the default GitLab +# timeout (1h) is often not enough +.build-package: + timeout: 3h + +stages: + - provisioning + - build + - test - - upgrade in Bullseye - - upgrade from Buster - - upgrade extras ++ - upgrade MariaDB ++ - upgrade MariaDB and distro ++ - upgrade MariaDB variant + - test extras + - publish # Stage referenced by Salsa-CI template aptly stanza, so must exist even though not used + - build: - extends: .build-package - script: &autobake-deb-steps - # Run Salsa-CI .build-before-script equivalent - - mkdir -p ${WORKING_DIR} ${CCACHE_WORK_DIR} - - mv ${CCACHE_WORK_DIR} ${CCACHE_TMP_DIR} - # Run Salsa-CI .build-script equivalent, with extra devscripts so autobake-deb.sh can run 'dch' - - export CCACHE_DIR=${CCACHE_TMP_DIR} - - apt-get update && eatmydata apt-get install --no-install-recommends -y ccache fakeroot build-essential devscripts lsb-release - - cd ${WORKING_DIR}/${SOURCE_DIR} - - eatmydata apt-get build-dep --no-install-recommends -y . - - update-ccache-symlinks; ccache -z # Zero out ccache counters - - while true; do sleep 600; echo "10 minutes passed" >&2; done & # Progress keeper since build is long and silent - - debian/autobake-deb.sh |& tail -n 10000 # Keep Gitlab-CI output under 4 MB - - cd ${WORKING_DIR} - - rm -rf ${WORKING_DIR}/${SOURCE_DIR} - - du -shc ${WORKING_DIR}/* # Show total file size of artifacts. Must stay are under 100 MB. - - ccache -s # Show ccache stats to validate it worked - - mv ${CCACHE_TMP_DIR} ${CCACHE_WORK_DIR} - - build i386: - extends: .build-package-i386 - script: - - *autobake-deb-steps - - build bullseye-backports: - extends: .build-package - variables: - RELEASE: bullseye-backports ++gnitpick: ++ stage: provisioning ++ image: debian:sid-slim ++ script: | ++ # Bare minimal (<4MB) for apt-key and gnitpick to work ++ apt-get update -qq && apt-get -qq install --no-install-recommends --yes ca-certificates curl python3-minimal git ++ curl -sS https://raw.githubusercontent.com/Seravo/gnitpick/master/gnitpick.py -o /usr/bin/gnitpick; chmod +x /usr/bin/gnitpick ++ # Actual Gnitpick part ++ gnitpick --target-repository https://salsa.debian.org/mariadb-team/mariadb-server.git --target-branch debian/latest ++ except: ++ variables: ++ - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ ++ allow_failure: true # Gnitpick does not fully support this branch naming scheme so ignore it for now ++ ++packaging-fix-checks: ++ stage: provisioning ++ image: debian:sid-slim ++ script: ++ - apt-get update -qq && apt-get -qq install --no-install-recommends --yes git devscripts python3-debian shellcheck make lsb-release dh-debputy python3-pygls ++ # Check debian/* for typical errors. Don't check spelling as there are too ++ # many false positives and anyway spelling issues are level 'pedantic' in ++ # Debputy and do not emit an exit code, so wouldn't show up as failure in CI ++ # anyway. ++ - debputy lint ++ - | ++ if [ "$(find debian/patches/ -type f -not -name series | wc -l)" -eq "$(cat debian/patches/series | wc -l)" ] ++ then ++ echo "The directory debian/patches/ contents and debian/patches/series file match by count." ++ else ++ find debian/patches -type f -not -name series -printf "%P\n" | sort > /tmp/patches-directory-sorted ++ sort debian/patches/series > /tmp/patches-series-sorted ++ diff -y /tmp/patches-series-sorted /tmp/patches-directory-sorted ++ echo ++ echo "The directory debian/patches/ file count does not match that in debian/series. Check that there are no unaccounted patches!" ++ exit 1 ++ fi ++ - | ++ wrap-and-sort -ast ++ git checkout debian/tests/control # Revert touching this file, wrap-and-sort shouldn't do it ++ if [ "$(git diff --name-only | wc -l)" -eq 0 ] ++ then ++ echo "No uncommitted changes after 'wrap-and-sort -ast', maintainer has done good job keeping files in order." ++ else ++ git diff ++ echo ++ echo "Debian packaging files are unordered! Please run 'wrap-and-sort -vast'." ++ exit 1 ++ fi ++ # Print syntax errors if found, otherwise continue silently ++ - make --dry-run --makefile=debian/rules > /dev/null ++ - | ++ shellcheck -x --shell=sh $(grep -Irnw debian/ -e '^#!.*/sh' | sort -u |cut -d ':' -f 1 | xargs) ++ shellcheck -x --shell=bash $(grep -Irnw debian/ -e '^#!.*/bash' | sort -u |cut -d ':' -f 1 | xargs) ++ except: ++ variables: ++ - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ ++ allow_failure: true # 'debputy lint' is in active development and failures can be false + +# Buster only has libfmt 6.1 but 7.0 is required, so backport build for Buster +# is not possible unless somebody packages libfmt7-dev for Buster. + - build sid: - extends: .build-package - script: - - *autobake-deb-steps - variables: - RELEASE: sid ++test-crossbuild-arm64: ++ stage: build ++ # Cross-builds allowed to fail by default in Salsa-CI + - # Build native deb without using autobake-deb.sh. This way we will detect - # if the debian/control file and other packaging is correct as-is for Debian Sid. - build native deb amd64: - extends: .build-package ++test-crossbuild-armhf: ++ stage: build ++ extends: .test-crossbuild-package-arm64 ++ variables: ++ HOST_ARCH: armhf ++ allow_failure: true # Cross-builds seem to fail frequently due to unclear reasons + - build native deb i386: - extends: .build-package-i386 ++test-crossbuild-armel: ++ stage: build ++ extends: .test-crossbuild-package-arm64 ++ variables: ++ HOST_ARCH: armel ++ allow_failure: true # Cross-builds seem to fail frequently due to unclear reasons + +autopkgtest: + extends: .test-autopkgtest + artifacts: + reports: + junit: ${WORKING_DIR}/debci/artifacts/mysql-test-run-junit.xml + +piuparts: - extends: .test-piuparts + stage: test extras + +blhc: - extends: .test-blhc + stage: test extras - # Build log checker needs a .build file and thus only works on native build - needs: - - job: build native deb amd64 + +# In addition to Salsa-CI, also run these fully MariaDB specific build jobs + +# Define snippets used to construct jobs + +.test-prepare-container: &test-prepare-container | + cd ${WORKING_DIR} # Don't repeat this step, it's just cd ./debian/output + # Enable automatic restarts from maint scripts + sed -i "s/101/0/g" -i /usr/sbin/policy-rc.d + # Fake /sbin/runlevel to avoid warnings of "invoke-rc.d: could not determine current runlevel" + echo -e '#!/bin/sh\necho "N 5"' > /sbin/runlevel; chmod +x /sbin/runlevel + # Avoid the warnings of "debconf: unable to initialize frontend: Dialog" + echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections ++ # Emit non-zero exit code also on warnings ++ echo 'APT::Update::Error-Mode "any";' > /etc/apt/apt.conf.d/non-zero-exit-on-warnings + # Prime the apt cache so later apt commands can run + apt-get update -qq + ++# Readline was removed from Debian Sid (and Bullseye) in Feb 2021. To be able to install older ++# versions of MariaDB that depend on it, fetch and install it from Buster. ++.test-install-readline-in-sid-for-backwards-compat: &test-install-readline-in-sid-for-backwards-compat | ++ curl -sS -O https://snapshot.debian.org/archive/debian/20190316T031117Z/pool/main/r/readline5/libreadline5_5.2%2Bdfsg-3%2Bb13_amd64.deb ++ apt-get -qq install --no-install-recommends --yes ./libreadline5_5.2%2Bdfsg-3%2Bb13_amd64.deb ++ ++# OpenSSL 1.1 was Debian Sid in Dec 2022 (as Bookworm will ship with OpenSSL 3.0 ++# only). To be able to install versions of MariaDB that depend on OpenSSL 1.1, ++# fetch and install it manually. ++.test-install-openssl1-in-sid-for-backwards-compat: &test-install-openssl1-in-sid-for-backwards-compat | ++ curl -sS -O https://snapshot.debian.org/archive/debian/20220507T034236Z/pool/main/o/openssl/libssl1.1_1.1.1o-1_amd64.deb ++ apt-get -qq install --no-install-recommends --yes ./libssl1.1_1.1.1o-1_amd64.deb ++ ++# Package libaio1 was replaced by libaio1t64 in Debian Sid in April 2024. To ++# continue installing old MariaDB versions that depend on libaio1, use libaio1 ++# from snapshots. ++.test-install-libaio-in-sid-for-backwards-compat: &test-install-libaio-in-sid-for-backwards-compat | ++ curl -sS -O https://snapshot.debian.org/archive/debian/20240331T210805Z/pool/main/liba/libaio/libaio1_0.3.113-5_amd64.deb ++ apt-get -qq install --no-install-recommends --yes ./libaio1_0.3.113-5_amd64.deb ++ +.test-verify-initial: &test-verify-initial | + dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - service mysql status || service mariadb status # Early MariaDB 10.5 only had 'mariadb' ++ # MariaDB until 10.5 only had 'mysql', and since only 'mariadb', so try both ++ service mysql status || service mariadb status + mysql --skip-column-names -e "select @@version, @@version_comment" # Show version + mysql --table -e "SHOW DATABASES;" # List databases before upgrade + mysql --table -e "SELECT host,user,plugin,authentication_string FROM user;" mysql + mysql --table -e "SELECT * FROM plugin;" mysql + mysql --table -e "SHOW PLUGINS;" mysql + - # Readline was removed from Debian Sid (and Bullseye) in Feb 2021. To be able to install older - # versions of MariaDB that depend on it, fetch and install it from Buster. - .test-install-readline-in-sid-for-backwards-compat: &test-install-readline-in-sid-for-backwards-compat | - curl -sS -O http://ftp.de.debian.org/debian/pool/main/r/readline5/libreadline5_5.2+dfsg-3+b13_amd64.deb - apt-get -qq install --no-install-recommends --yes ./libreadline5_5.2+dfsg-3+b13_amd64.deb - - .test-enable-bullseye-repos: &test-enable-bullseye-repos - # Replace any old repos with just Sid - - echo 'deb http://deb.debian.org/debian bullseye main' > /etc/apt/sources.list - # Upgrade minimal stack first - - apt-get update -qq - - apt-get install -y apt - - .test-enable-buster-backports-repos: &test-enable-buster-backports-repos | - # Enable buster-backports (assumes environment already Debian Buster) - echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/buster-backports.list - # Increase default backports priority policy from '100' to '500' so it can actually be used - cat << EOF > /etc/apt/preferences.d/enable-backports-to-satisfy-dependencies - Package: * - Pin: release n=buster-* - Pin-Priority: 500 - EOF - apt-get update -qq - - .test-enable-bullseye-backports-repos: &test-enable-bullseye-backports-repos | - # Enable bullseye-backports (assumes environment already Debian Bullseye) - echo 'deb http://deb.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/bullseye-backports.list - # Increase default backports priority policy from '100' to '500' so it can actually be used - cat << EOF > /etc/apt/preferences.d/enable-backports-to-satisfy-dependencies - Package: * - Pin: release n=bullseye-* - Pin-Priority: 500 - EOF - apt-get update -qq - +.test-enable-sid-repos: &test-enable-sid-repos - # Apply usrmerge workaround for Stretch/Buster/Bullseye to Bookworm/Sid upgrades - - echo 'this system will not be supported in the future' > /etc/unsupported-skip-usrmerge-conversion ++ - apt-get install -qq --yes --no-install-recommends ca-certificates curl ++ - curl -sS -O https://snapshot.debian.org/archive/debian/20240531T083821Z/pool/main/g/glibc/libc6_2.38-11_amd64.deb + # Replace any old repos with just Sid + - echo 'deb http://deb.debian.org/debian sid main' > /etc/apt/sources.list + # Upgrade minimal stack first + - apt-get update -qq - # Next step will fail on https://bugs.debian.org/993755 ++ - apt-get -qq install --no-install-recommends --yes ./libc6_2.38-11_amd64.deb || export APT_STATUS="failed" ++ # Ensure upgrades past 2.38-11 are blocked so ++ - apt-mark hold libc6 ++ # Complete upgrade of minimal stack ++ - apt-get install -qq --yes apt || export APT_STATUS="failed" ++ # Due to https://bugs.debian.org/993755 and #975077 upgrades from Buster or ++ # older to Bookworm or newer fails on: + # /usr/bin/perl: error while loading shared libraries: libcrypt.so.1: cannot + # open shared object file: No such file or directory + # dpkg: error processing package libc6:amd64 (--configure): - - apt-get install -y apt || true - # Apply workaround - - cd $(mktemp -d) # Use temp dir where apt can download and unpack files - - apt-get -y download libcrypt1 - - dpkg-deb -x libcrypt1_*.deb . - - cp -ra lib/* /lib/ - - cd - # Back to /builds/$USER/mariadb-server/debian/output - - find /lib/*/libcrypt.* -ls # Show that new libcrypt is there - - apt-get -y --fix-broken install - # Complete upgrade of minimal stack - - apt-get install -y apt ++ # Therefore, run this extra workaround if first run of apt-get install failed: ++ - | ++ if [ "$APT_STATUS" = "failed" ] ++ then ++ cd $(mktemp -d) # Use temp dir where apt can download and unpack files ++ apt-get -y download libcrypt1 ++ dpkg-deb -x libcrypt1_*.deb . ++ cp -ra usr/lib/* /lib/ || true # libcrypt 1:4.4.36-3+ ++ cd - # Back to /builds/$USER/mariadb-server/debian/output ++ find /lib/*/libcrypt.* -ls # Show that new libcrypt is there ++ apt-get -qq --yes --fix-broken install ++ apt-get install -qq --yes apt ++ fi ++ ++.test-enable-artifacts-repo: &test-enable-artifacts-repo | ++ apt-get install -qq --yes apt-utils ++ apt-ftparchive packages . > Packages ++ echo "deb [trusted=yes] file:$(pwd) ./" > /etc/apt/sources.list.d/mariadb-local.list ++ apt-get update -qq + - .test-install: &test-install - # Install MariaDB built in this commit - - apt-get install -y ./*.deb ++.test-install-all: &test-install-all ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate ${BUILT_PACKAGES} ++ - apt-get install -qq --yes ${BUILT_PACKAGES} + # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - mariadb --version ++ - dpkg -l | grep -iE 'maria|mysql|galera' ++ - find /etc -name '*mariadb*' -ls -or -name '*mysql*' -ls | sort -k 11 ++ # Purge old versions if they exist ++ - apt-get purge --yes mariadb*10.? ++ - find /etc -name '*mariadb*' -ls -or -name '*mysql*' -ls | sort -k 11 ++ ++.test-full-upgrade: &test-full-upgrade ++ - *test-enable-artifacts-repo ++ - apt-get full-upgrade -qq --simulate ++ - apt-get full-upgrade -qq --yes ++ # Verify installation of MariaDB built in this commit ++ - mariadb --version ++ - dpkg -l | grep -iE 'maria|mysql|galera' ++ - find /etc -name '*mariadb*' -ls -or -name '*mysql*' -ls | sort -k 11 ++ # Purge old versions if they exist ++ - apt-get purge --yes mariadb*10.? ++ - find /etc -name '*mariadb*' -ls -or -name '*mysql*' -ls | sort -k 11 ++ # Purging the old server might stop the running server, so restart it just in case ++ - service mariadb restart ++ ++.test-install-all-libs: &test-install-all-libs ++ - *test-enable-artifacts-repo ++ - apt-get install -yq --no-install-recommends libmariadb-dev-compat libmariadbd-dev ++ # Installs 31 packages, including: ++ # libmariadb3 libmariadb-dev libmariadb-dev-compat libmariadbd19t64 libmariadbd-dev ++ ++.test-full-upgrade-libs: &test-full-upgrade-libs ++ - *test-enable-artifacts-repo ++ - apt-get full-upgrade -y ++ - dpkg -l | grep -iE 'maria|mysql|galera' ++ # library tests don't have the mariadb client nor server, so don't check them + +.test-verify-final: &test-verify-final | ++ dpkg -l | grep -e "mariadb-server.*11\.4" + mkdir -p debug # Ensure dir exists before using it + find /var/lib/mysql -ls > debug/var-lib-mysql.list || true # Ignore errors about "no such file or directory" + cp -ra /etc/mysql debug/etc-mysql - cp -ra /var/log/mysql debug/var-log-mysql + mariadb --skip-column-names -e "select @@version, @@version_comment" # Show version + mariadb --table -e "SHOW DATABASES;" # List databases + mariadb --table -e "SELECT host,user,plugin,authentication_string FROM user;" mysql + mariadb --table -e "SELECT * FROM plugin;" mysql + mariadb --table -e "SHOW PLUGINS;" mysql + # Test that InnoDB works and that command 'mysql' is also still usable + mysql -e "CREATE DATABASE test; USE test; CREATE TABLE t(a INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t VALUEs (1); SELECT * FROM t; DROP TABLE t; DROP DATABASE test;" + +.test-verify-libs: &test-verify-libs + # Don't use a collapsed command as Gitlab-CI would hide each command from the output + - ldconfig -p | grep -e mariadb -e mysql + - pkg-config --list-all + - pkg-config --cflags --libs mysqlclient + - pkg-config --cflags --libs libmariadb + - pkg-config --cflags --libs mariadb - - apt-get install -y --no-install-recommends g++ ++ - apt-get install -qq --yes --no-install-recommends g++ + - | + # Build a test binary that depends on libmysqlclient + cat > b933063.cpp < + #include + #include + int main() + { + MYSQL h; + if (!mysql_init(&h) + || mysql_options(&h, MYSQL_READ_DEFAULT_GROUP, "") + // || mysql_options(&h, MYSQL_SET_CHARSET_NAME, "utf8mb4") + || !mysql_real_connect(&h, "", "", NULL, "", 0, NULL, 0)) + throw std::runtime_error(mysql_error(&h)); + std::string q = "show variables like '%char%'"; + if (mysql_real_query(&h, q.data(), q.size())) + throw std::runtime_error(mysql_error(&h)); + MYSQL_RES* result = mysql_store_result(&h); + if (!result && mysql_errno(&h)) + throw std::runtime_error(mysql_error(&h)); + while (MYSQL_ROW row = mysql_fetch_row(result)) + { + std::cout << row[0] << ": " << row[1] << "\n"; + } + return 0; + } + EOF - apt-get install -y ./*.deb # Server must be installed for client to connect ++ apt-get install -q --yes ./*.deb # Server must be installed for client to connect + echo "Testing -l mysqlclient" + g++ b933063.cpp -l mysqlclient && ./a.out | tee result + if grep --quiet latin result; then echo "ERROR: Charset latin found!"; exit 1; fi + echo "Testing -l mariadbclient" + g++ b933063.cpp -l mariadbclient && ./a.out | tee result + if grep --quiet latin result; then echo "ERROR: Charset latin found!"; exit 1; fi ++ - | ++ # Build a test binary to verify API version strings ++ cat > b1031863.cpp < ++ #include ++ #include ++ using namespace std; + - .test-install-all-libs: &test-install-all-libs - - apt-get install -y ./libmariadb3_*.deb ./libmariadb-dev_*.deb ./libmariadb-dev-compat_*.deb ./libmariadbd19_*.deb ./libmariadbd-dev_*.deb ./mariadb-common_*.deb ++ void test_if_starts_with(const string expected, const string tested, const string name) { ++ int r = strncmp(tested.c_str(), expected.c_str(), expected.size()); ++ if (r == 0) { ++ cout << name << ": " << tested << "\n"; ++ } else { ++ cout << "ERROR: " << name << " started with " << tested << " instead of the expected " << expected << "!\n"; ++ exit(1); ++ } ++ } + - fresh install: ++ int main() ++ { ++ MYSQL h; ++ // Constants refer to server version ++ test_if_starts_with("1104", to_string(MARIADB_VERSION_ID), "MARIADB_VERSION_ID"); ++ test_if_starts_with("1104", to_string(MYSQL_VERSION_ID), "MYSQL_VERSION_ID"); ++ // Client ABI returns connector version ++ test_if_starts_with("304", to_string(mysql_get_client_version()), "mysql_get_client_version()"); ++ test_if_starts_with("3.4", mysql_get_client_info(), "mysql_get_client_info()"); ++ return 0; ++ } ++ EOF ++ g++ b1031863.cpp -l mysqlclient && ./a.out ++ ++.salsa-ci-template-for-mariadb: + stage: test + needs: + - job: build + image: debian:${RELEASE} + artifacts: + when: always + name: "$CI_BUILD_NAME" + paths: + - ${WORKING_DIR}/debug + script: - - *test-prepare-container - - *test-install - - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ - - *test-verify-final ++ - echo "This script section must be overridden in each test" && exit 1 + variables: + GIT_STRATEGY: none + except: + variables: + - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb-10.5 Bullseye upgrade: - stage: upgrade in Bullseye ++.salsa-ci-template-for-mariadb-upgrade: ++ stage: test + needs: + - job: build + image: debian:${RELEASE} + artifacts: + when: always + name: "$CI_BUILD_NAME" + paths: + - ${WORKING_DIR}/debug - script: ++ before_script: + - *test-prepare-container - # Install everything MariaDB 10.5 currently in Debian Bullseye - - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadb*' - - *test-verify-initial - - *test-install - - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ - - *test-verify-final ++ - apt-get install -qq --yes --no-install-recommends ca-certificates curl ++ - | ++ [[ -d /etc/apt/keyrings ]] || mkdir /etc/apt/keyrings ++ curl -sS https://mariadb.org/mariadb_release_signing_key.pgp -o /etc/apt/keyrings/mariadb-keyring.pgp ++ cat >/etc/apt/sources.list.d/mariadb.sources < /etc/apt/sources.list.d/bookworm.list ++ rm /etc/apt/sources.list.d/debian.sources ++ apt-get update -qq ++ # In February 2023 Bookworm snapshot this will install MariaDB 10.6 ++ - apt-get install -qq --yes mariadb-server ++ # Verify installation of MariaDB from (February 2023) Bookworm ++ - dpkg -l | grep -e "mariadb-server.*10\.6" ++ - *test-verify-initial ++ - *test-enable-sid-repos ++ # Ensure mariadbd will not crash on next shutdown for any reason ++ - service mariadb restart ++ - *test-full-upgrade ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - apt-get purge --yes mariadb*10.? ++ - *test-verify-final ++ ++mariadb-10.6 and Jammy upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: ubuntu:jammy ++ script: ++ - *test-prepare-container ++ # Install everything MariaDB currently in Ubuntu Jammy ++ - apt-get install -qq --yes 'mariadb-*' 'libmariadb*' ++ # Verify installation of MariaDB from Jammy ++ - dpkg -l | grep -e "mariadb-server.*10\.6" ++ - *test-verify-initial ++ # Install Debian Sid signing keys as Ubuntu does not have them by default ++ - apt-get install -qq --yes --no-install-recommends curl ++ - curl -sSLO http://deb.debian.org/debian/pool/main/d/debian-archive-keyring/debian-archive-keyring_2023.4_all.deb ++ - apt-get install -qq --yes ./debian-archive-keyring_* ++ - *test-enable-sid-repos ++ # Ensure mariadbd will not crash on next shutdown for any reason ++ - service mariadb restart ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server ++ # Due to usrmerge, full-upgrade from Jammy to Trixie or newer cannot work ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - apt-get purge --yes mariadb*10.? ++ - *test-verify-final ++ ++mariadb-10.5 and Bullseye upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: debian:bullseye ++ script: ++ - *test-prepare-container ++ # Install everything MariaDB currently in Debian Bullseye ++ - apt-get install -qq --yes 'default-mysql*' 'mariadb-*' 'libmariadb*' ++ # Verify installation of MariaDB from Bullseye ++ - dpkg -l | grep -e "mariadb-server.*10\.5" ++ - *test-verify-initial ++ - *test-enable-sid-repos ++ # Ensure mariadbd will not crash on next shutdown for any reason ++ - service mariadb restart ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server ++ # Due to usrmerge, full-upgrade from Bullseye to Trixie or newer cannot work ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - apt-get purge --yes mariadb*10.? ++ - *test-verify-final ++ ++mariadb-10.3 and Buster upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro + image: debian:buster - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug + script: + - *test-prepare-container - # Install everything MariaDB 10.3 currently in Debian Buster - - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadb*' ++ # Install everything MariaDB currently in Debian Buster ++ - apt-get install -qq --yes 'default-mysql*' 'mariadb-*' 'libmariadb*' + # Verify installation of MariaDB from Buster ++ - dpkg -l | grep -e "mariadb-server.*10\.3" + - *test-verify-initial - - *test-enable-bullseye-repos - - *test-install - # mariadb-10.3 in Buster ships a /etc/init.d/mysql so it should continue to work ++ - *test-enable-sid-repos ++ # Ensure mariadbd will not crash on next shutdown for any reason ++ - service mysql restart # in 10.3 service name is still 'mysql' ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server ++ # Due to usrmerge, full-upgrade from Bullseye to Trixie or newer cannot work + - service mysql status ++ # mariadb-10.3 in Buster ships a /etc/init.d/mysql and it continues to exist ++ # after upgrade, and is removed only on purge ++ - apt-get purge --yes mariadb*10.? + - service mariadb status ++ # Give the mariadb-upgrade plenty of time to complete, otherwise next commands ++ # fail on non-existing mariadb.sys user ++ - sleep 15 ++ - *test-verify-final ++ ++mariadb-10.3 and Focal upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: ubuntu:focal ++ script: ++ - *test-prepare-container ++ # Install everything MariaDB currently in Ubuntu Focal ++ - apt-get install -qq --yes 'mariadb-*' 'libmariadb*' ++ # Verify installation of MariaDB from Focal ++ - dpkg -l | grep -e "mariadb-server.*10\.3" ++ - *test-verify-initial ++ # Install Debian Sid signing keys as Ubuntu does not have them by default ++ - apt-get install -qq --yes --no-install-recommends curl ++ - curl -sSLO http://deb.debian.org/debian/pool/main/d/debian-archive-keyring/debian-archive-keyring_2023.4_all.deb ++ - apt-get install -qq --yes ./debian-archive-keyring_* ++ - *test-enable-sid-repos ++ # Ensure mariadbd will not crash on next shutdown for any reason ++ - service mysql restart # in 10.3 service name is still 'mysql' ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server ++ # Due to usrmerge, full-upgrade from Focal to Trixie or newer cannot work ++ - service mysql status ++ # mariadb-10.3 in Focal ships a /etc/init.d/mysql and it continues to exist ++ # after upgrade, and is removed only on purge ++ - apt-get purge --yes mariadb*10.? ++ # Give the mariadb-upgrade plenty of time to complete, otherwise next commands ++ # fail on non-existing mariadb.sys user ++ - sleep 15 ++ - *test-verify-final ++ ++# Similar to the Cacti install test, check that MariaDB consumer Zoph upgrades ++default-mysql-server and Bookworm upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: debian:bookworm ++ script: ++ - *test-prepare-container ++ # Install everything MariaDB currently in Debian Bookworm ++ - apt-get install -qq --yes default-mysql-server zoph ++ # Verify installation of MariaDB from Bookworm ++ - dpkg -l | grep -e "mariadb-server.*10\.11" ++ - *test-verify-initial ++ - *test-enable-sid-repos ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate default-mysql-server ++ - apt-get install -qq --yes default-mysql-server ++ - *test-full-upgrade ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - *test-verify-final ++ ++# Similar to the Cacti install test, check that MariaDB consumer Zoph upgrades ++default-mysql-server and Bullseye upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: debian:bullseye ++ script: ++ - *test-prepare-container ++ # Install everything MariaDB currently in Debian Bullseye ++ - apt-get install -qq --yes default-mysql-server zoph ++ # Verify installation of MariaDB from Bullseye ++ - dpkg -l | grep -e "mariadb-server.*10\.5" ++ - *test-verify-initial ++ - *test-enable-sid-repos ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate default-mysql-server ++ - apt-get install -qq --yes default-mysql-server ++ # Due to usrmerge, full-upgrade from Bullseye to Trixie or newer cannot work ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + +test basic features: - stage: test - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++ extends: .salsa-ci-template-for-mariadb + script: + - *test-prepare-container - - *test-install ++ - *test-install-all + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final + - | + # Print info about server + mariadb --skip-column-names -e "select @@version, @@version_comment" + mariadb --skip-column-names -e "select engine, support, transactions, savepoints from information_schema.engines order by engine" | sort + mariadb --skip-column-names -e "select plugin_name, plugin_status, plugin_type, plugin_library, plugin_license from information_schema.all_plugins order by plugin_name, plugin_library" + # Test various features + mariadb -e "CREATE DATABASE db" + mariadb -e "CREATE TABLE db.t_innodb(a1 SERIAL, c1 CHAR(8)) ENGINE=InnoDB; INSERT INTO db.t_innodb VALUES (1,'"'"'foo'"'"'),(2,'"'"'bar'"'"')" + mariadb -e "CREATE TABLE db.t_myisam(a2 SERIAL, c2 CHAR(8)) ENGINE=MyISAM; INSERT INTO db.t_myisam VALUES (1,'"'"'foo'"'"'),(2,'"'"'bar'"'"')" + mariadb -e "CREATE TABLE db.t_aria(a3 SERIAL, c3 CHAR(8)) ENGINE=Aria; INSERT INTO db.t_aria VALUES (1,'"'"'foo'"'"'),(2,'"'"'bar'"'"')" + mariadb -e "CREATE TABLE db.t_memory(a4 SERIAL, c4 CHAR(8)) ENGINE=MEMORY; INSERT INTO db.t_memory VALUES (1,'"'"'foo'"'"'),(2,'"'"'bar'"'"')" + mariadb -e "CREATE ALGORITHM=MERGE VIEW db.v_merge AS SELECT * FROM db.t_innodb, db.t_myisam, db.t_aria" + mariadb -e "CREATE ALGORITHM=TEMPTABLE VIEW db.v_temptable AS SELECT * FROM db.t_innodb, db.t_myisam, db.t_aria" + mariadb -e "CREATE PROCEDURE db.p() SELECT * FROM db.v_merge" + mariadb -e "CREATE FUNCTION db.f() RETURNS INT DETERMINISTIC RETURN 1" + # Test that the features still work (this step can be done e.g. after an upgrade) + mariadb -e "SHOW TABLES IN db" + mariadb -e "SELECT * FROM db.t_innodb; INSERT INTO db.t_innodb VALUES (3,'"'"'foo'"'"'),(4,'"'"'bar'"'"')" + mariadb -e "SELECT * FROM db.t_myisam; INSERT INTO db.t_myisam VALUES (3,'"'"'foo'"'"'),(4,'"'"'bar'"'"')" + mariadb -e "SELECT * FROM db.t_aria; INSERT INTO db.t_aria VALUES (3,'"'"'foo'"'"'),(4,'"'"'bar'"'"')" + mariadb -e "SELECT * FROM db.t_memory; INSERT INTO db.t_memory VALUES (3,'"'"'foo'"'"'),(4,'"'"'bar'"'"')" + mariadb -e "SELECT COUNT(*) FROM db.v_merge" + mariadb -e "SELECT COUNT(*) FROM db.v_temptable" + mariadb -e "CALL db.p()" + mariadb -e "SELECT db.f()" + - | + # Test TLS connections + dpkg -l | grep -i -e tls -e ssl + # Create user for TCP connection, must have password + mariadb -e "SET PASSWORD FOR 'mysql'@'localhost' = PASSWORD('asdf234');" + cat < /root/.my.cnf + [client] + user=mysql + password=asdf234 + protocol=tcp + EOF + export CERT_PATH=/usr/share/mariadb/mariadb-test/std_data + openssl verify -CAfile $CERT_PATH/cacert.pem $CERT_PATH/server-cert.pem + openssl x509 -subject -issuer -noout -in $CERT_PATH/cacert.pem + openssl x509 -subject -issuer -noout -in $CERT_PATH/server-cert.pem + cat < /etc/mysql/mariadb.conf.d/tls.cnf + [client-server] + ssl = on + ssl-ca = $CERT_PATH/cacert.pem + ssl-cert = $CERT_PATH/server-cert.pem + ssl-key = $CERT_PATH/server-key.pem + [server] + require-secure-transport = on + [client] + ssl-verify-server-cert = on + EOF + service mariadb restart + mariadb -Bse 'STATUS' | tee result + # Ensure important values present, otherwise fail job + grep --quiet "localhost via TCP/IP" result + mariadb -Bse 'SHOW VARIABLES' | grep -e tls -e ssl | tee result + grep --quiet "have_ssl YES" result + grep --quiet TLSv1.3 result + mariadb -Bse 'SHOW SESSION STATUS' | grep -i -e tls -e ssl | tee result + grep --quiet TLSv1.3 result - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ ++ ++# Install Cacti, which in uses dbconfig-common to configure the MariaDB user and ++# connection automatically in order to validate that at least one downstream ++# server consumer continues to work. ++test consumer cacti: ++ extends: .salsa-ci-template-for-mariadb ++ script: ++ - *test-prepare-container ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --yes cacti ++ - mariadb -E -e "SHOW CREATE TABLE version;" cacti + +# Build a piece of software that was designed for libmysqlclient-dev but using the +# libmariadb-dev-compat layer. Should always end up using libmariadb.so.3 run-time. +build mariadbclient consumer Python-MySQLdb: - stage: test - needs: - - job: build - image: debian:${RELEASE} ++ extends: .salsa-ci-template-for-mariadb + script: + - *test-prepare-container - # Run each step separately to avoid an 800+ line chunk that lacks the - # commands themselves printed and Gitlab-CI cutting off the output - - apt-get install -y pkg-config ./libmariadb-dev*.deb ./libmariadb3_*.deb ./mariadb-common*.deb - - pkg-config --cflags --libs mysqlclient # See what MySQLdb builds with - - apt-get install -y python3-pip - - pip3 install mysqlclient # Compiles module against libmysqlclient - - apt-get purge -y libmariadb-dev # Not needed for run-time ++ - *test-install-all-libs ++ - apt-get install -qq --yes pkg-config python3-pip ++ # See what MySQLdb will build with ++ - pkg-config --cflags --libs mysqlclient ++ # MySQLdb is also available in Debian as package python3-mysqldb, but ++ # install it from pip to force that the client is compiled with ++ # libmariadb-dev-compat on-the-fly. ++ # Python 3.11 needs `--break-system-packages` to proceed with this. ++ - pip3 install --break-system-packages mysqlclient # Compiles module against libmysqlclient ++ - apt-get purge --yes libmariadb-dev # Not needed for run-time + - python3 -c "import MySQLdb; print(MySQLdb.get_client_info())" - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - default-libmysqlclient-dev Bullseye upgrade: - stage: upgrade in Bullseye - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++libmysql* to libmariadb* upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB + script: + - *test-prepare-container - - apt-get install -y pkg-config default-libmysqlclient-dev default-libmysqld-dev ++ # Install all libmysql* available in Debian unstable ++ - apt-get install -qq --yes pkg-config libmysqlclient-dev + - pkg-config --list-all - - *test-install-all-libs ++ - pkg-config --cflags mysqlclient # mysqlclient.pc from original package ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --yes libmariadb3 ++ - pkg-config --list-all ++ - apt-get install -qq --yes libmariadb-dev ++ - pkg-config --list-all ++ - apt-get install -qq --yes libmariadb-dev-compat ++ - pkg-config --cflags mysqlclient # mysqlclient.pc from compat package ++ - pkg-config --list-all ++ - apt-get install -qq --yes libmariadbd19t64 ++ - pkg-config --list-all ++ - apt-get install -qq --yes libmariadbd-dev ++ - pkg-config --list-all ++ - apt-get install -qq --yes default-libmysqlclient-dev default-libmysqld-dev + - *test-verify-libs - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - default-libmysqlclient-dev Buster upgrade: - stage: upgrade from Buster - needs: - - job: build - image: debian:buster - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++default-libmysqlclient-dev upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB ++ script: ++ - *test-prepare-container ++ - apt-get install -qq --yes pkg-config default-libmysqlclient-dev default-libmysqld-dev ++ - pkg-config --list-all ++ - *test-full-upgrade-libs ++ - *test-verify-libs ++ ++default-libmysqlclient-dev and Bookworm upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: debian:bookworm ++ script: ++ - *test-prepare-container ++ - apt-get install -qq --yes pkg-config default-libmysqlclient-dev ++ - pkg-config --list-all ++ - *test-enable-sid-repos ++ # Must be reinstalled as libc6 upgrade removes them: ++ - apt-get install -qq --yes pkg-config default-libmysqlclient-dev ++ - *test-full-upgrade-libs ++ - *test-verify-libs ++ ++default-libmysqlclient-dev and Bullseye upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB and distro ++ image: debian:bullseye + script: + - *test-prepare-container - - apt-get install -y pkg-config default-libmysqlclient-dev ++ - apt-get install -qq --yes pkg-config default-libmysqlclient-dev + - pkg-config --list-all - - *test-enable-bullseye-repos ++ - *test-enable-sid-repos ++ # Don't use latest libc6-dev as trying to install it errors on: ++ # The current installation does not have a merged-/usr layout. ++ # This is unsupported and unpacking libc6 would break the system. ++ - curl -sS -O https://snapshot.debian.org/archive/debian/20240531T083821Z/pool/main/g/glibc/libc6-dev_2.38-11_amd64.deb ++ - curl -sS -O https://snapshot.debian.org/archive/debian/20240531T083821Z/pool/main/g/glibc/libc-dev-bin_2.38-11_amd64.deb ++ - apt-get -qq install --no-install-recommends --yes --allow-downgrades ./libc6-dev_2.38-11_amd64.deb ./libc-dev-bin_2.38-11_amd64.deb ++ # Must be reinstalled as libc6 upgrade removes them: ++ - apt-get install -qq --yes pkg-config default-libmysqlclient-dev ++ # Due to usrmerge, full-upgrade from Bullseye to Trixie or newer cannot work + - *test-install-all-libs + - *test-verify-libs - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ ++ ++# No longer possible since as it pulls as dependencies packages that trigger ++# usrmerge, which cannot run in a container ++#default-libmysqlclient-dev and Buster upgrade: + +# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. +# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. - # - # Testing on Focal binaries on Buster works. Using Jammy binaries on Bullseye - # does not work as libc in Jammy is too new. - mysql-8.0 from Ubuntu 22.04 upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mysql-8.0 in Sid upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB variant ++ image: debian:sid + script: + - *test-prepare-container - # Add Ubuntu Focal archive keys and repository - - apt-get install --no-install-recommends --yes gpg gpg-agent dirmngr ca-certificates # Bare minimal (<4MB) for apt-key to work - - apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 871920D1991BC93C 3B4FE6ACC0B21F32 - - echo "deb http://archive.ubuntu.com/ubuntu/ focal main restricted" > /etc/apt/sources.list.d/ubuntu.list - - apt-get update -qq - # First install often fail due to bug in mysql-8.0 - - apt-get install -y mysql-server 'libmysqlc*' || true - - sleep 10 && apt-get install -f ++ # The postinst fails often if 'ps' is missing from system, so install procps ++ - apt-get install -qq --yes 'mysql*' libmysqlcppconn7t64 ++ # Ensure MySQL 8.0 package actually got installed ++ - dpkg -l | grep -e "mysql-server.*8\.0" + - *test-verify-initial - - *test-install - - service mysql status ++ - *test-install-all ++ # Due to some (currently unknown) changes in MySQL 8.0 packaging or apt ++ # behaviour changes, a system with a previous installation of MySQL 8.0 will ++ # on upgrades to MariaDB first fully remove MySQL, including the ++ # /etc/init.d/mysql file, so previous techniques in ++ # mariadb-server-10.6.postinst to maintain backwards compatibility with ++ # 'service mysql status' after installing MariaDB on top MySQL no longer ++ # works. Thus the step to test it now intentionally has a fallback to use ++ # the service name 'mariadb' instead, and the fallback is always used. + - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server ++ - service mysql status || service mariadb status + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + +# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. +# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. - mysql-community-cluster-8.0 from MySQL.com upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mysql-8.0 in Ubuntu 23.10 upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB variant ++ image: ubuntu:mantic + script: + - *test-prepare-container - - apt-get install --no-install-recommends --yes ca-certificates curl systemctl - - curl -sS "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x859be8d7c586f538430b19c2467b942d3a79bd29" -o /etc/apt/trusted.gpg.d/mysql.asc - - echo "deb https://repo.mysql.com/apt/debian/ bullseye mysql-cluster-8.0" > /etc/apt/sources.list.d/mysql.list - - apt-get update -qq - - apt-get install -y mysql-cluster-community-server ++ - apt-get install -qq --yes procps mysql-server 'libmysqlc*' ++ # Ensure MySQL 8.0 package actually got installed ++ - dpkg -l | grep mysql ++ - service mysql status ++ - *test-verify-initial ++ # Install Debian Sid signing keys as Ubuntu does not have them by default ++ - apt-get install -qq --yes --no-install-recommends curl ++ - curl -sSLO http://deb.debian.org/debian/pool/main/d/debian-archive-keyring/debian-archive-keyring_2023.4_all.deb ++ - apt-get install -qq --yes ./debian-archive-keyring_* ++ - *test-enable-sid-repos ++ # Ensure mysqld will not crash on next shutdown for any reason ++ - service mysql restart ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server ++ # Due to usrmerge, full-upgrade from Mantic to Trixie or newer may not work ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ # Remove everything MySQL except mysql-common which also MariaDB depends on ++ - apt-get purge --yes mysql-s* mysql-cl* libmysql* ++ - *test-verify-final ++ ++# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. ++# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. ++mysql-community-cluster-8.0 from MySQL.com with Bookworm upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB variant ++ image: debian:bookworm ++ script: ++ - *test-prepare-container ++ - | ++ apt-get install -qq --yes --no-install-recommends ca-certificates curl systemctl ++ curl -sS "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xbca43417c3b485dd128ec6d4b7b3b788a8d3785c" -o /etc/apt/trusted.gpg.d/mysql.asc ++ echo "deb https://repo.mysql.com/apt/debian/ bookworm mysql-cluster-8.0" > /etc/apt/sources.list.d/mysql.list ++ apt-get update -qq ++ - apt-get install -qq --yes mysql-cluster-community-server + - sed 's/ExecStartPre=+/ExecStartPre=/' -i /lib/systemd/system/mysql.service # Hack to make file compatible with systemctl shim + - systemctl start mysql + - dpkg -l | grep -iE 'maria|mysql|galera' + - systemctl status mysql; mysql -e 'SELECT VERSION()' + - systemctl stop mysql # Stop manually as maintainer scripts don't handle this with systemctl shim - - *test-install ++ - *test-enable-sid-repos ++ - *test-enable-artifacts-repo ++ - apt-get install -qq --simulate mariadb-server ++ - apt-get install -qq --yes mariadb-server + # Ignore systemctl shim result as MariaDB systemd file is incompatible with it and yields: + # ERROR:systemctl:the ExecStartPre control process exited with error code + - systemctl status mysql || true + - mysql -e 'SELECT VERSION()' || true + - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org 10.11 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-11.4 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "11.4" + script: - - *test-prepare-container - - apt install -y curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.11/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update - - apt-get install -y mariadb-server ++ - apt-get install -qq --yes mariadb-server + - *test-verify-initial + # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb ++ # Force downgrades so our version installs on top of upstream revision, e.g. 1:11.4.2-1 vs 1:11.4.2+mariadb~debsid ++ - apt-get install -q --yes --allow-downgrades ./*.deb + # Verify installation of MariaDB built in this commit + - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed + - mariadb --version # Client version + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org 10.10 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.11 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.11" + script: - - *test-prepare-container - - apt install -y curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.10/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update - - apt-get install -y mariadb-server ++ # this should not use Sid to begin with ++ - apt-get install -qq --yes mariadb-server=1:10.11.8+maria~debsid mariadb-client=1:10.11.8+maria~debsid + - *test-verify-initial - # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb - # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - *test-full-upgrade + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org 10.9 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.10 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.10" + script: - - *test-prepare-container - - apt install -y curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.9/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update - - apt-get install -y mariadb-server-10.9 mariadb-client-10.9 ++ # this should not use Sid to begin with ++ - apt-get install -qq --yes mariadb-server=1:10.10.2+maria~debunstable mariadb-client=1:10.10.2+maria~debunstable + - *test-verify-initial - # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb - # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - *test-full-upgrade + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org-10.8 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.9 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.9" + script: - - *test-prepare-container - - apt install -y curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.8/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update - - apt-get install -y mariadb-server-10.8 ++ # this should not use Sid to begin with ++ - apt-get install -qq --yes mariadb-server=1:10.9.4+maria~debunstable mariadb-client=1:10.9.4+maria~debunstable + - *test-verify-initial - # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb - # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - *test-full-upgrade + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org-10.7 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.8 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.8" + script: - - *test-prepare-container - - apt install -y curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.7/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update - - apt-get install -y mariadb-server-10.7 ++ - apt-get install -qq --yes mariadb-server-10.8 + - *test-verify-initial - # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb - # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - *test-install-all + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org-10.6 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.7 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.7" + script: - - *test-prepare-container - - apt-get -qq install --no-install-recommends --yes ca-certificates curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.6/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update -qq - - apt-get install -y mariadb-server-10.6 ++ - apt-get install -qq --yes mariadb-server-10.7 + - *test-verify-initial - # Install MariaDB built in this commit - # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid - - apt-get install -y --allow-downgrades ./*.deb - # Verify installation of MariaDB built in this commit - - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed - - mariadb --version # Client version ++ - *test-install-all + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org-10.5 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++mariadb.org-10.6 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.6" + script: - - *test-prepare-container - - apt-get -qq install --no-install-recommends --yes ca-certificates curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://archive.mariadb.org/mariadb-10.5/repo/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update -qq - - apt-get install -y mariadb-server-10.5 ++ # Package libmariadbclient-dev from mariadb.org conflicts with libmariadb-dev in Sid, so cannot use wildcard that would include it ++ # Enable this line when there is a way to install them only from the mariadb.org repo ++ # - apt-get install -qq --yes 'mariadb*' libmariadb3 'libmariadb-*' 'libmariadbd*' ++ - apt-get install -qq --yes mariadb-server-10.6 + - *test-verify-initial - - *test-install ++ - *test-install-all + - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ + - *test-verify-final ++ ++# archive.mariadb.org for Debian Sid latest is 10.5.13 ++mariadb.org-10.5 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant + variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ ++ MARIADB_VERSION: "10.5" ++ script: ++ - *test-install-openssl1-in-sid-for-backwards-compat ++ - apt-get install -qq --yes mariadb-server-10.5 ++ - *test-verify-initial ++ - *test-install-all ++ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - *test-verify-final + - mariadb.org-10.4 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++# archive.mariadb.org for Debian Sid latest is 10.4.17 ++mariadb.org-10.4 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.4" + script: - - *test-prepare-container - - apt-get -qq install --no-install-recommends --yes ca-certificates curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://archive.mariadb.org/mariadb-10.4/repo/debian buster main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update -qq + - *test-install-readline-in-sid-for-backwards-compat - - apt-get install -y mariadb-server-10.4 ++ - *test-install-openssl1-in-sid-for-backwards-compat ++ - *test-install-libaio-in-sid-for-backwards-compat ++ - apt-get install -qq --yes mariadb-server-10.4 + # MariaDB.org version of 10.4 and early 10.5 do not install an init file, so + # it must be installed here manually + - cp /usr/share/mysql/mysql.init /etc/init.d/mysql; chmod +x /etc/init.d/mysql; service mysql start; sleep 5 + - *test-verify-initial - # Buster backports is needed for liburing1 (>= 0.7) and galera-4 (>= 26.4) - - *test-enable-buster-backports-repos - - *test-install ++ - *test-install-all + - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server + - service mysql status + - service mariadb status + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - mariadb.org-10.3 to mariadb upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++# archive.mariadb.org for Debian Sid latest is 10.3.27 ++mariadb.org-10.3 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.3" + script: - - *test-prepare-container - - apt-get -qq install --no-install-recommends --yes ca-certificates curl - - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://archive.mariadb.org/mariadb-10.3/repo/debian buster main" > /etc/apt/sources.list.d/mariadb.list - - apt-get update -qq + - *test-install-readline-in-sid-for-backwards-compat - - apt-get install -y mariadb-server-10.3 ++ - *test-install-openssl1-in-sid-for-backwards-compat ++ - *test-install-libaio-in-sid-for-backwards-compat ++ - apt-get install -qq --yes mariadb-server-10.3 + - *test-verify-initial - # Buster backports is needed for liburing1 (>= 0.7) and galera-4 (>= 26.4) - - *test-enable-buster-backports-repos - - *test-install - - service mysql status ++ - *test-install-all ++ # mariadb-10.3 in Buster ships a /etc/init.d/mysql and it continues to exist ++ # after upgrade, and is removed only on purge ++ - service mysql status || service mariadb status + # Give the mariadb-upgrade plenty of time to complete, otherwise next commands + # fail on non-existing mariadb.sys user + - sleep 15 + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - # archive.mariadb.org has for 10.2 only Stretch, so we can't test upgrades to - # 10.6 with only Buster and Bullseye builds ++# archive.mariadb.org for Debian Sid latest is 10.2.21 ++mariadb.org-10.2 upgrade: ++ extends: .salsa-ci-template-for-mariadb-upgrade ++ stage: upgrade MariaDB variant ++ variables: ++ MARIADB_VERSION: "10.2" ++ script: ++ - *test-install-readline-in-sid-for-backwards-compat ++ - *test-install-openssl1-in-sid-for-backwards-compat ++ - *test-install-libaio-in-sid-for-backwards-compat ++ - apt-get install -qq --yes mariadb-server-10.2 ++ # Verify initial state before upgrade ++ - dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed ++ - service mysql status ++ # prepending with --defaults-file=/etc/mysql/debian.cnf is needed in upstream 5.5–10.3 ++ - | ++ mysql --defaults-file=/etc/mysql/debian.cnf --skip-column-names -e "SELECT @@version, @@version_comment" ++ mysql --defaults-file=/etc/mysql/debian.cnf --table -e "SHOW DATABASES;" ++ mysql --defaults-file=/etc/mysql/debian.cnf --table -e "SELECT * FROM mysql.user; SHOW CREATE USER root@localhost;" ++ mysql --defaults-file=/etc/mysql/debian.cnf --table -e "SELECT * FROM mysql.plugin; SHOW PLUGINS;" ++ - *test-install-all ++ # mariadb-10.2 in ships a /etc/init.d/mysql and it continues to exist ++ # after upgrade, and is removed only on purge ++ - service mysql status || service mariadb status ++ # Give the mariadb-upgrade plenty of time to complete, otherwise next commands ++ # fail on non-existing mariadb.sys user ++ - sleep 15 ++ - *test-verify-final + - mysql.com-5.7 upgrade: - stage: upgrade extras ++# Buster is the last Debian release Oracle MySQL 5.7 offers binaries for ++mysql.com-5.7 with Buster upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB variant + needs: + - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++ image: debian:buster + script: + - *test-prepare-container + - | - apt-get install --no-install-recommends --yes gpg gpg-agent dirmngr ca-certificates # Bare minimal (<4MB) for apt-key to work - apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 467B942D3A79BD29 - echo "deb https://repo.mysql.com/apt/debian/ bullseye mysql-5.7" > /etc/apt/sources.list.d/mysql.list ++ apt-get install -qq --yes --no-install-recommends gpg gpg-agent dirmngr ca-certificates # Bare minimal (<4MB) for apt-key to work ++ apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 B7B3B788A8D3785C ++ echo "deb https://repo.mysql.com/apt/debian/ buster mysql-5.7" > /etc/apt/sources.list.d/mysql.list + apt-get update -qq - apt-get install -y 'mysql*' 'libmysqlc*' ++ - apt-get install -qq --yes mysql-server 'libmysqlc*' ++ # Ensure MySQL 5.7 package actually got installed ++ - dpkg -l | grep -e "mysql-server.*5.7" + - *test-verify-initial - - *test-install ++ - *test-enable-sid-repos ++ - *test-install-all + # Due to some (currently unknown) changes in MySQL 5.7 packaging or apt + # behaviour changes, a system with a previous installation of MySQL will + # on upgrades to MariaDB first fully remove MySQL, including the + # /etc/init.d/mysql file, so previous techniques in + # mariadb-server-10.6.postinst to maintain backwards compatibility with + # 'service mysql status' after installing MariaDB on top MySQL no longer + # works. Thus the step to test it now intentionally has a fallback to use + # the service name 'mariadb' instead, and the fallback is always used. + - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server - - service mariadb status # There is no init.d/mysql in MariaDB 10.5+ ++ - service mysql status || service mariadb status + - sleep 15 # Give the mysql_upgrade a bit of extra time to complete with MySQL 5.7 before querying the server + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + - percona-xtradb-5.7 upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug ++# Note: pmm2-client does not exist in the Bookworm repository anymore ++percona-xtradb-5.7 with Bookworm upgrade: ++ extends: .salsa-ci-template-for-mariadb ++ stage: upgrade MariaDB variant ++ image: debian:bookworm + script: + - *test-prepare-container + - | - apt-get install --no-install-recommends --yes gpg gpg-agent dirmngr ca-certificates # Bare minimal (<4MB) for apt-key to work - apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 9334A25F8507EFA5 - echo "deb https://repo.percona.com/apt/ ${RELEASE} main" > /etc/apt/sources.list.d/mysql.list ++ apt-get install -qq --yes --no-install-recommends ca-certificates curl systemctl ++ curl -sS "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x9334A25F8507EFA5" -o /etc/apt/trusted.gpg.d/percona.asc ++ echo "deb https://repo.percona.com/apt/ bookworm main" > /etc/apt/sources.list.d/percona.list + apt-get update -qq - apt-get install -y percona-xtradb-cluster-full-57 percona-xtrabackup-24 percona-toolkit pmm2-client ++ - apt-get install -qq --yes percona-xtradb-cluster-full-57 percona-xtrabackup-24 percona-toolkit ++ # Ensure Percona 5.7 package actually got installed ++ - dpkg -l | grep -e "percona.*5\.7" + - service mysql status + - *test-verify-initial - - *test-install - - service mysql status ++ - *test-enable-sid-repos ++ - *test-install-all ++ # Percona package owned /etc/init.d/mysql, so on removal and upgrade to MariaDB old service name can't be referenced anymore ++ - service mariadb status + - sleep 15 # Give the mysql_upgrade a bit of extra time to complete with MySQL 5.7 before querying the server + - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ diff --cc debian/source/format index 89ae9db8f,000000000..163aaf8d8 mode 100644,000000..100644 --- a/debian/source/format +++ b/debian/source/format @@@ -1,1 -1,0 +1,1 @@@ - 3.0 (native) ++3.0 (quilt) diff --cc debian/source/lintian-overrides index e0366164b,000000000..0bdf3905c mode 100644,000000..100644 --- a/debian/source/lintian-overrides +++ b/debian/source/lintian-overrides @@@ -1,98 -1,0 +1,95 @@@ - # MariaDB use high enough debhelper so this is should - # be considered as bug in lintia - missing-build-dependency-for-dh-addon systemd * - # Necessary for drop-in-place-replacement upgrades on mysql-server/-client - # since package breaks/replaces these but at the same time also provides them - version-substvar-for-external-package mariadb-client-core -> mysql-client-5.5 - version-substvar-for-external-package mariadb-server -> mysql-server - version-substvar-for-external-package libmariadb-dev -> libmysqlclient-dev - version-substvar-for-external-package libmariadb-dev -> libmysqld-dev - version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev -> libmysqlclient-dev [debian/control:74] - version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev -> libmysqld-dev [debian/control:74] - version-substvar-for-external-package libmariadbd-dev -> libmariadbclient-dev - # ColumnStore not used in Debian, safe to ignore. Reported upstream in https://jira.mariadb.org/browse/MDEV-24124 - source-is-missing storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2 - source-is-missing [storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2] - # Must be fixed upstream - source-is-missing storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-*.custom.js - # New Lintian syntax (from version 2.115) ++# Intentional control relationships ++version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev -> libmysqld-dev * ++# Do not alert for documentation in html +source-is-missing [sql/share/charsets/languages.html] +source-is-missing [storage/rocksdb/rocksdb/docs/_includes/footer.html] - # Intentional control relationships - version-substvar-for-external-package Replaces * libmariadbd-dev -> libmariadbclient-dev - version-substvar-for-external-package Replaces * libmariadb-dev -> libmysqlclient-dev - version-substvar-for-external-package Replaces * libmariadb-dev -> libmysqld-dev - # New Lintian syntax (from version 2.115) - version-substvar-for-external-package Replaces * libmariadb-dev -> libmysqlclient-dev [debian/control:*] - version-substvar-for-external-package Replaces * libmariadb-dev -> libmysqld-dev [debian/control:*] - version-substvar-for-external-package Replaces * libmariadbd-dev -> libmariadbclient-dev [debian/control:*] +# Data or test files where long lines are justified - very-long-line-length-in-source-file *.test * - very-long-line-length-in-source-file *.result * - very-long-line-length-in-source-file BUILD/compile-* - very-long-line-length-in-source-file *COPYING.rtf * ++very-long-line-length-in-source-file * [*.dfm:*] ++very-long-line-length-in-source-file * [*.expected:*] ++very-long-line-length-in-source-file * [*.frm:*] ++very-long-line-length-in-source-file * [*.MYD:*] ++very-long-line-length-in-source-file * [*.MYI:*] ++very-long-line-length-in-source-file * [*.p7b:*] ++very-long-line-length-in-source-file * [*.pcap:*] ++very-long-line-length-in-source-file * [*.result:*] ++very-long-line-length-in-source-file * [*.test:*] ++very-long-line-length-in-source-file * [*COPYING.rtf:*] ++very-long-line-length-in-source-file * [BUILD/compile-*] +# These are mainly found under extra/wolfssl - very-long-line-length-in-source-file *.cproject * - very-long-line-length-in-source-file *.md * - very-long-line-length-in-source-file *.scfg * - very-long-line-length-in-source-file *.launch * - very-long-line-length-in-source-file extra/wolfssl/wolfssl/IDE/Espressif/ESP-IDF/test/test_wolfssl.c * - very-long-line-length-in-source-file extra/wolfssl/wolfssl/configure.ac * - very-long-line-length-in-source-file extra/wolfssl/wolfssl/doc/formats/html/html_changes/tabs.css * ++very-long-line-length-in-source-file * [*.cproject:*] ++very-long-line-length-in-source-file * [*.launch:*] ++very-long-line-length-in-source-file * [*.md:*] ++very-long-line-length-in-source-file * [*.scfg:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/doc/dox_comments/header_files-ja/ssl.h:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/doc/dox_comments/header_files-ja/types.h:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/doc/dox_comments/header_files-ja/wolfio.h:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/doc/formats/html/html_changes/tabs.css:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/IDE/Espressif/ESP-IDF/test/test_wolfssl.c:*] ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/IDE/IAR-MSP430/main.c:*] +# Preprocessed C files which have long lines - very-long-line-length-in-source-file extra/wolfssl/wolfssl/wolfcrypt/src/*.i * ++very-long-line-length-in-source-file * [extra/wolfssl/wolfssl/wolfcrypt/src/*.i:*] +# These are all results for test cases and similar so they can be +# especially formatted to be too long - very-long-line-length-in-source-file mysql-test/*.dump * - very-long-line-length-in-source-file mysql-test/*.inc * - very-long-line-length-in-source-file mysql-test/*.rdiff * - very-long-line-length-in-source-file mysql-test/*.txt * - very-long-line-length-in-source-file mysql-test/*.weekly * - # Test file - very-long-line-length-in-source-file plugin/handler_socket/regtest/test_01_lib/test19.expected * ++very-long-line-length-in-source-file * [mysql-test/*.000*:*] ++very-long-line-length-in-source-file * [mysql-test/*.ARZ:*] ++very-long-line-length-in-source-file * [mysql-test/*.dump:*] ++very-long-line-length-in-source-file * [mysql-test/*.ibd:*] ++very-long-line-length-in-source-file * [mysql-test/*.inc:*] ++very-long-line-length-in-source-file * [mysql-test/*.MAD:*] ++very-long-line-length-in-source-file * [mysql-test/*.MAI:*] ++very-long-line-length-in-source-file * [mysql-test/*.rdiff:*] ++very-long-line-length-in-source-file * [mysql-test/*.txt:*] ++very-long-line-length-in-source-file * [mysql-test/*.weekly:*] ++very-long-line-length-in-source-file * [mysql-test/*001:*] ++very-long-line-length-in-source-file * [mysql-test/*ibdata*:*] ++very-long-line-length-in-source-file * [mysql-test/std_data/Moscow_leap:*] ++very-long-line-length-in-source-file * [mysql-test/suite/parts/r/*.out:*] +# SQL source file that has very long inserts/selects - very-long-line-length-in-source-file mysql-test/std_data/init_file_longline_3816.sql * - very-long-line-length-in-source-file scripts/fill_help_tables.sql * - very-long-line-length-in-source-file scripts/mariadb_system_tables.sql * - very-long-line-length-in-source-file scripts/mariadb_test_data_timezone.sql * ++very-long-line-length-in-source-file * [scripts/fill_help_tables.sql:*] ++very-long-line-length-in-source-file * [scripts/mariadb_system_tables.sql:*] +# Machine formatted HTML - very-long-line-length-in-source-file sql/share/charsets/languages.html * ++very-long-line-length-in-source-file * [sql/share/charsets/languages.html:*] ++very-long-line-length-in-source-file * [sql/share/errmsg-utf8.txt:*] +# Very long test string - very-long-line-length-in-source-file storage/archive/archive_test.c line 30 is 1051 characters long (>512) - # autogenerated thrift file - very-long-line-length-in-source-file storage/cassandra/gen-cpp/cassandra_types.h * ++very-long-line-length-in-source-file * [storage/archive/archive_test.c:*] +# ColumnStore ignores +# In Directory mysql-test are some long test includes - very-long-line-length-in-source-file storage/columnstore/columnstore/.drone.jsonnet * - very-long-line-length-in-source-file storage/columnstore/columnstore/CMakeLists.txt * - very-long-line-length-in-source-file storage/columnstore/columnstore/mysql-test/columnstore/csinternal/include/autopilot_create_datatypetestm_tables.inc * - very-long-line-length-in-source-file storage/columnstore/columnstore/mysql-test/columnstore/csinternal/include/autopilot_create_datatypeupdate_table.inc * - very-long-line-length-in-source-file storage/columnstore/columnstore/*.xmi * - very-long-line-length-in-source-file storage/columnstore/columnstore/dbcon/doc/q19_plan.txt * - very-long-line-length-in-source-file storage/columnstore/columnstore/utils/udfsdk/docs/source/reference/mcsv1Context.rst * - very-long-line-length-in-source-file storage/columnstore/columnstore/utils/winport/win_setup_mysql_part1.sql * ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/.drone.jsonnet:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/*.xmi:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/CMakeLists.txt:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/dbcon/doc/q19_plan.txt:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/mysql-test/columnstore/include/autopilot_create_datatypeupdate_table.inc:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/mysql-test/columnstore/include/autopilot_create_datatypetestm_tables.inc:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/primitives/linux-port/dictblock.cdf:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/storage-manager/test_data/*:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/utils/json/json.hpp:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/utils/udfsdk/docs/source/reference/mcsv1Context.rst:*] +# Minified CSS files. These appear in several places - very-long-line-length-in-source-file *badge_only.css * - very-long-line-length-in-source-file *theme.css line * ++very-long-line-length-in-source-file * [*badge_only.css:*] ++very-long-line-length-in-source-file * [*theme.css:*] ++# Font files ++very-long-line-length-in-source-file * [*.eot:*] +# General storage ignores - very-long-line-length-in-source-file storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/jquery-ui-1.8.12.custom.css * - very-long-line-length-in-source-file storage/rocksdb/mysql-test/rocksdb/t/bypass_select_basic_bloom-master.opt * - very-long-line-length-in-source-file storage/rocksdb/mysql-test/rocksdb/t/type_enum.inc * - very-long-line-length-in-source-file storage/rocksdb/mysql-test/rocksdb/t/type_set.inc * - very-long-line-length-in-source-file storage/rocksdb/rocksdb/docs/_includes/footer.html * - very-long-line-length-in-source-file storage/rocksdb/rocksdb/docs/_posts/*.markdown line * - very-long-line-length-in-source-file storage/spider/mysql-test/spider/bugfix/include/sql_mode_init.inc * - very-long-line-length-in-source-file storage/tokudb/PerconaFT/cmake_modules/TokuBuildTagDatabases.cmake * - very-long-line-length-in-source-file storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/po.m4 * ++very-long-line-length-in-source-file * [storage/rocksdb/mysql-test/rocksdb/t/bypass_select_basic_bloom-master.opt:*] ++very-long-line-length-in-source-file * [storage/rocksdb/mysql-test/rocksdb/t/type_enum.inc:*] ++very-long-line-length-in-source-file * [storage/rocksdb/mysql-test/rocksdb/t/type_set.inc:*] ++very-long-line-length-in-source-file * [storage/rocksdb/rocksdb/docs/_includes/footer.html:*] ++very-long-line-length-in-source-file * [storage/rocksdb/rocksdb/docs/_posts/*.markdown:*] ++very-long-line-length-in-source-file * [storage/spider/mysql-test/spider/bugfix/include/sql_mode_init.inc:*] +# These are generated files which should not make any harm - source-contains-autogenerated-visual-c++-file storage/columnstore/columnstore/*.rc - source-contains-autogenerated-visual-c++-file storage/columnstore/columnstore/*.h - source-contains-autogenerated-visual-c++-file win/upgrade_wizard/resource.h - source-contains-autogenerated-visual-c++-file win/upgrade_wizard/upgrade.rc - - # New in 10.11 - version-substvar-for-external-package Conflicts ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev [debian/control:95] - version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev [debian/control:109] - missing-build-dependency-for-dh-addon systemd (does not satisfy debhelper:any (>= 9.20160709~) | debhelper-compat:any | dh-sequence-systemd:any | dh-systemd:any) [debian/rules] - source-is-missing [sql/share/charsets/languages.html] - source-is-missing [storage/rocksdb/rocksdb/docs/_includes/footer.html] ++source-contains-autogenerated-visual-c++-file [extra/wolfssl/wolfssl/IDE/WIN10/resource.h] ++source-contains-autogenerated-visual-c++-file [extra/wolfssl/wolfssl/IDE/WIN10/wolfssl-fips.rc] ++source-contains-autogenerated-visual-c++-file [extra/wolfssl/wolfssl/resource.h] ++source-contains-autogenerated-visual-c++-file [storage/columnstore/columnstore/*.h] ++source-contains-autogenerated-visual-c++-file [win/upgrade_wizard/resource.h] ++source-contains-autogenerated-visual-c++-file [win/upgrade_wizard/upgrade.rc] ++# Known cases, pending to be fixed upstream ++very-long-line-length-in-source-file * [libmariadb/benchmark/main-benchmark.cc:*] ++very-long-line-length-in-source-file * [man/mariadb.1:*] ++very-long-line-length-in-source-file * [scripts/msql2mysql.sh:*] ++very-long-line-length-in-source-file * [scripts/wsrep_sst_mysqldump.sh:*] ++very-long-line-length-in-source-file * [sql-bench/bench-init.pl.sh:*] ++very-long-line-length-in-source-file * [sql-bench/test-ATIS.sh:*] ++very-long-line-length-in-source-file * [sql-bench/test-wisconsin.sh:*] ++very-long-line-length-in-source-file * [storage/columnstore/columnstore/utils/windowfunction/windowfunctiontype.cpp:*] ++very-long-line-length-in-source-file * [strings/ctype-czech.c:*] diff --cc debian/tests/configuration-tracing index 000000000,000000000..5d6861903 new file mode 100755 --- /dev/null +++ b/debian/tests/configuration-tracing @@@ -1,0 -1,0 +1,126 @@@ ++#!/bin/sh ++# dep8 smoke test for mariadbd ++# Author: Otto Kekäläinen ++# ++# This test should be declared in debian/tests/control with a dependency ++# on the package that provides a configured MariaDB server (eg. ++# mariadb-server). ++# ++# This test should be declared in debian/tests/control with the ++# following restrictions: ++# - needs-root (binaries in /usr/sbin need root to run) ++# - allow-stderr (set -x always outputs to stderr, also if mariadbd was not ++# launched as a service it will complain that mysql.plugin table is empty) ++# ++# This test prints out various configuration information from mariadbd and ++# compares the result to expected values in original binary/build. ++# ++ ++normalize_value() { ++ VARIABLE="$1" ++ VALUE="$2" ++ # In sed the '\s.*' will match whitespace followed by any other chars until end of line ++ sed "s/^$VARIABLE\(\s\s*\).*$/$VARIABLE\1$VALUE/" -i "$TEMPFILE" ++} ++ ++trace() { ++ TRACE_NAME="$(echo "$*" | sed -E 's|/usr/(s?)bin/||' | sed 's/ //g' | sed 's/--/-/g')" ++ ++ # Show in test what was run ++ echo ++ echo "Tracing: $*" ++ ++ # shellcheck disable=SC2068 ++ $@ > "$TRACE_NAME.actual" ++ ++ # Normalize contents for know special case ++ if echo "$*" | grep -q verbose ++ then ++ TEMPFILE="$(mktemp)" ++ # Use 'tail' to skip first line that has version and architecture strings which ++ # we intentionally do not want to include in the trace file. ++ tail -n +2 "$TRACE_NAME.actual" > "$TEMPFILE" ++ ++ # Hostname varies one very machine ++ sed "s/$(hostname)/HOSTNAME/g" -i "$TEMPFILE" ++ ++ # Version/revision increases on every release ++ VERSION=$(mariadbd --help --verbose | grep -e "^version " | rev | cut -d ' ' -f 1 | rev) ++ sed "s/$VERSION/VERSION/g" -i "$TEMPFILE" ++ ++ # SSL library version inherited form dependency, not relevant for tracing ++ # the correctness of the MariaDB build itself ++ sed 's/OpenSSL 3.*/SSL-VERSION/' -i "$TEMPFILE" ++ ++ # Normalize values that depend on build environment ++ normalize_value system-time-zone UTC # depends on OS environment ++ normalize_value open-files-limit 32000 # depends on OS environment ++ normalize_value thread-pool-size 2 # depends on CPU cores available ++ normalize_value version-compile-machine ARCH # x86_64, aarch64, armv7l .. ++ ++ # armhf/armel might have: debian-linux-gnueabi, debian-linux-gnueabihf ++ normalize_value version-compile-os debian-linux-gnu ++ ++ # In Sid 'Debian n/a', in Bookworm 'Debian 12' ++ normalize_value version-comment "Debian RELEASE" ++ ++ # Inherits git commit id from latest upstream release and thus not constant ++ normalize_value version-source-revision - ++ ++ # 32-bit systems (i386, armel, armhf) have lower values ++ normalize_value innodb-io-capacity-max 18446744073709551615 # 32-bit: 4294967295 ++ normalize_value max-binlog-cache-size 18446744073709547520 # 32-bit: 4294963200 ++ normalize_value max-binlog-stmt-cache-size 18446744073709547520 # 32-bit: 4294963200 ++ normalize_value myisam-max-sort-file-size 18446744073709551615 # 32-bit: 2146435072 ++ normalize_value myisam-mmap-size 9223372036853727232 # 32-bit: 4294967295 ++ normalize_value tmp-disk-table-size 18446744073709551615 # 32-bit: 4294967295 ++ ++ # ppc64el has larger default value: 393216 ++ normalize_value log-tc-size 24576 ++ ++ mv "$TEMPFILE" "$TRACE_NAME.actual" ++ fi ++ ++ echo "diff --ignore-space-change -u $TRACE_NAME.expected $TRACE_NAME.actual" ++ # Validate that trace file in source code matches tested ++ if ! diff --ignore-space-change -u "$TRACE_NAME.expected" "$TRACE_NAME.actual" ++ then ++ echo "Error: Output from '$*' did NOT match what was expected" ++ echo ++ echo "If the change is intentional, update the debian/tests/traces to match" ++ echo "the new values and document change to users in mariadb-server.NEWS" ++ ++ if [ -n "$ERRORS" ] ++ then ++ ERRORS="$ERRORS, $TRACE_NAME" ++ else ++ ERRORS="$TRACE_NAME" ++ fi ++ fi ++} ++ ++echo "Running test 'configuration-tracing'" ++cd debian/tests/traces || exit 1 ++ ++set -e ++ ++ERRORS="" ++ ++# Dump out what parameters mariadb would be called with by default ++trace /usr/bin/mariadb --print-defaults ++ ++# Dump out all help texts, client variables and their default values ++trace /usr/bin/mariadb --verbose --help ++ ++# Dump out what parameters mariadbd would be called with by default on system ++trace /usr/sbin/mariadbd --print-defaults ++ ++# Dump out all help texts, server variables and their default values ++trace /usr/sbin/mariadbd --verbose --help ++ ++# Emit non-zero exit code if there was errors ++if [ -n "$ERRORS" ] ++then ++ echo "Error: mismatch in $ERRORS" ++ exit 1 ++fi diff --cc debian/tests/control index 01bb91957,000000000..2a8c23a50 mode 100644,000000..100644 --- a/debian/tests/control +++ b/debian/tests/control @@@ -1,17 -1,0 +1,21 @@@ ++Tests: configuration-tracing ++Depends: ++ diffutils, ++ mariadb-server, ++Restrictions: allow-stderr needs-root ++ +Tests: smoke - # RocksDB is not built for all archs. Rather than duplicating the condition - # for its existence (see the list in debian/control), install it if available - # and check in the test if it's functional when it should be. - # The plugin package also already depends on the other one. - Depends: mariadb-plugin-provider-bzip2, - mariadb-plugin-provider-lz4, - mariadb-plugin-provider-lzma, - mariadb-plugin-provider-lzo, - mariadb-plugin-provider-snappy, - mariadb-plugin-rocksdb | mariadb-server ++Depends: ++ mariadb-plugin-provider-bzip2, ++ mariadb-plugin-provider-lz4, ++ mariadb-plugin-provider-lzma, ++ mariadb-plugin-provider-lzo, ++ mariadb-plugin-provider-snappy, ++ mariadb-plugin-rocksdb [amd64 arm64 mips64el ppc64el riscv64], +Restrictions: allow-stderr needs-root isolation-container + +Tests: upstream - Depends: eatmydata, - mariadb-test ++Depends: ++ eatmydata, ++ mariadb-test, +Restrictions: allow-stderr breaks-testbed diff --cc debian/tests/smoke index b3e09acc8,000000000..06227bdf5 mode 100644,000000..100644 --- a/debian/tests/smoke +++ b/debian/tests/smoke @@@ -1,114 -1,0 +1,123 @@@ +#!/bin/sh +# dep8 smoke test for mysql-server +# Author: Robie Basak +# +# This test should be declared in debian/tests/control with a dependency +# on the package that provides a configured MariaDB server (eg. +# mariadb-server). +# +# This test should be declared in debian/tests/control with the +# following restrictions: - # - # needs-root (to be able to log into the database) - # allow-stderr ++# - allow-stderr (set -x always outputs to stderr) ++# - needs-root (to be able to log into the database) ++# - isolation-container (to be able to start service) +# +# This test: +# +# 1) Creates a test database and test user as the root user. +# +# 2) Creates a test table and checks it appears to operate normally +# using the test user and test database. +# +# 3) Checks compression support for InnoDB & RocksDB engine. + +echo "Running test 'smoke'" +set -ex + +# Start the daemon if it was not running. For example in Docker testing +# environments there might not be any systemd et al and the service needs to +# be started manually. - if ! which systemctl ++if ! command -v systemctl +then + if ! /etc/init.d/mariadb status + then + echo "Did not find systemctl and daemon was not running, starting it.." + /etc/init.d/mariadb start + fi +else + # If systemd (and systemctl) is available, but the service did not start, then + # this smoke test is supposed to fail if next commands don't work. + echo "Found systemctl, continuing smoke test.." + # Compression plugins are separated from main server package + # to own packages (for example LZ4 package mariadb-plugin-provider-lz4) + # and they are installed after mariadb-server. + # which means that they don't exist if MariaDB is not restarted + systemctl restart mariadb +fi + +mariadb <&2 - exit 1 ++result=$(echo 'SELECT bar+1 FROM foo;' | mariadb --batch --skip-column-names --user=testuser --password=testpassword testdatabase) ++if [ "$result" != "42" ] ++then ++ echo "Unexpected result" >&2 ++ exit 1 +fi + +mariadb --user=testuser --password=testpassword testdatabase <&2 + exit 1 + fi + done +else - ! dpkg-query -W $plugin ++ if dpkg-query -W $plugin ++ then ++ echo "Error: Plugin $plugin was found even though it should not exist on a 32-bit and little-endian system" ++ exit 1 ++ fi +fi diff --cc debian/tests/traces/mariadb-print-defaults.expected index 000000000,000000000..acb579539 new file mode 100644 --- /dev/null +++ b/debian/tests/traces/mariadb-print-defaults.expected @@@ -1,0 -1,0 +1,2 @@@ ++/usr/bin/mariadb would have been started with the following arguments: ++--socket=/run/mysqld/mysqld.sock diff --cc debian/tests/traces/mariadb-verbose-help.expected index 000000000,000000000..abf004ae6 new file mode 100644 --- /dev/null +++ b/debian/tests/traces/mariadb-verbose-help.expected @@@ -1,0 -1,0 +1,236 @@@ ++Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. ++ ++Usage: /usr/bin/mariadb [OPTIONS] [database] ++ ++Default options are read from the following files in the given order: ++/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf ++The following groups are read: mysql mariadb-client client client-server client-mariadb ++The following options may be given as the first argument: ++--print-defaults Print the program argument list and exit. ++--no-defaults Don't read default options from any option file. ++The following specify which files/extra groups are read (specified before remaining options): ++--defaults-file=# Only read default options from the given file #. ++--defaults-extra-file=# Read this file after the global files are read. ++--defaults-group-suffix=# Additionally read default groups with # appended as a suffix. ++ ++ -?, --help Display this help and exit. ++ -I, --help Synonym for -? ++ --abort-source-on-error ++ Abort 'source filename' operations in case of errors ++ --auto-rehash Enable automatic rehashing. One doesn't need to use ++ 'rehash' to get table and field completion, but startup ++ and reconnecting may take a longer time. ++ (Defaults to on; use --skip-auto-rehash to disable.) ++ -A, --no-auto-rehash ++ No automatic rehashing. One has to use 'rehash' to get ++ table and field completion. This gives a quicker start of ++ mysql and disables rehashing on reconnect. ++ --auto-vertical-output ++ Automatically switch to vertical output mode if the ++ result is wider than the terminal width. ++ -B, --batch Don't use history file. Disable interactive behavior. ++ (Enables --silent.) ++ --binary-as-hex Print binary data as hex ++ --binary-mode Binary mode allows certain character sequences to be ++ processed as data that would otherwise be treated with a ++ special meaning by the parser. Specifically, this switch ++ turns off parsing of all client commands except \C and ++ DELIMITER in non-interactive mode (i.e., when binary mode ++ is combined with either 1) piped input, 2) the --batch ++ mysql option, or 3) the 'source' command). Also, in ++ binary mode, occurrences of '\r\n' and ASCII '\0' are ++ preserved within strings, whereas by default, '\r\n' is ++ translated to '\n' and '\0' is disallowed in user input. ++ --character-sets-dir=name ++ Directory for character set files. ++ --column-names Write column names in results. ++ (Defaults to on; use --skip-column-names to disable.) ++ -N, --skip-column-names ++ Don't write column names in results. ++ --column-type-info Display column type information. ++ -c, --comments Preserve comments. Send comments to the server. The ++ default is --skip-comments (discard comments), enable ++ with --comments. ++ -C, --compress Use compression in server/client protocol. ++ --connect-expired-password ++ Notify the server that this client is prepared to handle ++ expired password sandbox mode even if --batch was ++ specified. ++ --connect-timeout=# Number of seconds before connection timeout. ++ -D, --database=name Database to use. ++ -#, --debug[=#] This is a non-debug version. Catch this and exit. ++ --debug-check Check memory and open file usage at exit. ++ -T, --debug-info Print some debug info at exit. ++ --default-auth=name Default authentication client-side plugin to use. ++ --default-character-set=name ++ Set the default character set. ++ --delimiter=name Delimiter to be used. ++ --enable-cleartext-plugin ++ Obsolete option. Exists only for MySQL compatibility. ++ -e, --execute=name Execute command and quit. (Disables --force and history ++ file.) ++ -f, --force Continue even if we get an SQL error. Sets ++ abort-source-on-error to 0 ++ -h, --host=name Connect to host. ++ -H, --html Produce HTML output. ++ -i, --ignore-spaces Ignore space after function names. ++ --init-command=name SQL Command to execute when connecting to MariaDB server. ++ Will automatically be re-executed when reconnecting. ++ --line-numbers Write line numbers for errors. ++ (Defaults to on; use --skip-line-numbers to disable.) ++ -L, --skip-line-numbers ++ Don't write line number for errors. ++ --local-infile Enable LOAD DATA LOCAL INFILE. ++ --max-allowed-packet=# ++ The maximum packet length to send to or receive from ++ server. ++ --max-join-size=# Automatic limit for rows in a join when using ++ --safe-updates. ++ -G, --named-commands ++ Enable named commands. Named commands mean this program's ++ internal commands; see mysql> help . When enabled, the ++ named commands can be used from any line of the query, ++ otherwise only from the first line, before an enter. ++ Disable with --disable-named-commands. This option is ++ disabled by default. ++ --net-buffer-length=# ++ The buffer size for TCP/IP and socket communication. ++ -b, --no-beep Turn off beep on error. ++ -o, --one-database Ignore statements except those that occur while the ++ default database is the one named at the command line. ++ --pager[=name] Pager to use to display results. If you don't supply an ++ option, the default pager is taken from your ENV variable ++ PAGER. Valid pagers are less, more, cat [> filename], ++ etc. See interactive help (\h) also. This option does not ++ work in batch mode. Disable with --disable-pager. This ++ option is disabled by default. ++ -p, --password[=name] ++ Password to use when connecting to server. If password is ++ not given it's asked from the tty. ++ --plugin-dir=name Directory for client-side plugins. ++ -P, --port=# Port number to use for connection or 0 for default to, in ++ order of preference, my.cnf, $MYSQL_TCP_PORT, ++ /etc/services, built-in default (3306). ++ --progress-reports Get progress reports for long running commands (like ++ ALTER TABLE) ++ (Defaults to on; use --skip-progress-reports to disable.) ++ --prompt=name Set the command line prompt to this value. ++ --protocol=name The protocol to use for connection (tcp, socket, pipe). ++ -q, --quick Don't cache result, print it row by row. This may slow ++ down the server if the output is suspended. Doesn't use ++ history file. ++ -r, --raw Write fields without conversion. Used with --batch. ++ --reconnect Reconnect if the connection is lost. ++ (Defaults to on; use --skip-reconnect to disable.) ++ -U, --safe-updates Only allow UPDATE and DELETE that uses keys. ++ -U, --i-am-a-dummy Synonym for option --safe-updates, -U. ++ --sandbox Disallow commands that access the file system (except \P ++ without an argument and \e). ++ --secure-auth Refuse client connecting to server if it uses old ++ (pre-4.1.1) protocol. ++ --select-limit=# Automatic limit for SELECT when using --safe-updates. ++ --server-arg=name Send embedded server this as a parameter. ++ --show-query-costs Show query cost after every statement. ++ --show-warnings Show warnings after every statement. ++ --sigint-ignore Ignore SIGINT (CTRL-C). ++ -s, --silent Be more silent. Print results with a tab as separator, ++ each row on new line. ++ -S, --socket=name The socket file to use for connection. ++ --ssl Enable SSL for connection (automatically enabled with ++ other flags). ++ (Defaults to on; use --skip-ssl to disable.) ++ --ssl-ca=name CA file in PEM format (check OpenSSL docs, implies ++ --ssl). ++ --ssl-capath=name CA directory (check OpenSSL docs, implies --ssl). ++ --ssl-cert=name X509 cert in PEM format (implies --ssl). ++ --ssl-cipher=name SSL cipher to use (implies --ssl). ++ --ssl-key=name X509 key in PEM format (implies --ssl). ++ --ssl-crl=name Certificate revocation list (implies --ssl). ++ --ssl-crlpath=name Certificate revocation list path (implies --ssl). ++ --tls-version=name TLS protocol version for secure connection. ++ --ssl-fp=name Server certificate fingerprint (implies --ssl). ++ --ssl-fplist=name File with accepted server certificate fingerprints, one ++ per line (implies --ssl). ++ --ssl-verify-server-cert ++ Verify server's certificate to prevent man-in-the-middle ++ attacks ++ (Defaults to on; use --skip-ssl-verify-server-cert to disable.) ++ -t, --table Output in table format. ++ --tee=name Append everything into outfile. See interactive help (\h) ++ also. Does not work in batch mode. Disable with ++ --disable-tee. This option is disabled by default. ++ -n, --unbuffered Flush buffer after each query. ++ -u, --user=name User for login if not current user. ++ -v, --verbose Write more. (-v -v -v gives the table output format). ++ -V, --version Output version information and exit. ++ -E, --vertical Print the output of a query (rows) vertically. ++ -w, --wait Wait and retry if connection is down. ++ -X, --xml Produce XML output. ++ ++Variables (--variable-name=value) ++and boolean options {FALSE|TRUE} Value (after reading options) ++--------------------------------- ---------------------------------------- ++abort-source-on-error FALSE ++auto-rehash TRUE ++auto-vertical-output FALSE ++binary-as-hex FALSE ++binary-mode FALSE ++character-sets-dir (No default value) ++column-names TRUE ++column-type-info FALSE ++comments FALSE ++compress FALSE ++connect-expired-password FALSE ++connect-timeout 0 ++database (No default value) ++debug-check FALSE ++debug-info FALSE ++default-auth (No default value) ++default-character-set auto ++delimiter ; ++force FALSE ++host (No default value) ++html FALSE ++ignore-spaces FALSE ++init-command (No default value) ++line-numbers TRUE ++local-infile FALSE ++max-allowed-packet 16777216 ++max-join-size 1000000 ++named-commands FALSE ++net-buffer-length 16384 ++no-beep FALSE ++plugin-dir (No default value) ++port 0 ++progress-reports TRUE ++prompt \N [\d]> ++protocol ++quick FALSE ++raw FALSE ++reconnect TRUE ++safe-updates FALSE ++i-am-a-dummy FALSE ++sandbox FALSE ++secure-auth FALSE ++select-limit 1000 ++show-query-costs FALSE ++show-warnings FALSE ++sigint-ignore FALSE ++socket /run/mysqld/mysqld.sock ++ssl TRUE ++ssl-ca (No default value) ++ssl-capath (No default value) ++ssl-cert (No default value) ++ssl-cipher (No default value) ++ssl-key (No default value) ++ssl-crl (No default value) ++ssl-crlpath (No default value) ++tls-version (No default value) ++ssl-fp (No default value) ++ssl-fplist (No default value) ++ssl-verify-server-cert TRUE ++table FALSE ++unbuffered FALSE ++user (No default value) ++vertical FALSE ++xml FALSE diff --cc debian/tests/traces/mariadbd-print-defaults.expected index 000000000,000000000..829414a50 new file mode 100644 --- /dev/null +++ b/debian/tests/traces/mariadbd-print-defaults.expected @@@ -1,0 -1,0 +1,2 @@@ ++/usr/sbin/mariadbd would have been started with the following arguments: ++--socket=/run/mysqld/mysqld.sock --pid-file=/run/mysqld/mysqld.pid --basedir=/usr --bind-address=127.0.0.1 --expire_logs_days=10 --character-set-server=utf8mb4 --character-set-collations=utf8mb4=uca1400_ai_ci diff --cc debian/tests/traces/mariadbd-verbose-help.expected index 000000000,000000000..712881d76 new file mode 100644 --- /dev/null +++ b/debian/tests/traces/mariadbd-verbose-help.expected @@@ -1,0 -1,0 +1,3170 @@@ ++Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. ++ ++Starts the MariaDB database server. ++ ++Usage: /usr/sbin/mariadbd [OPTIONS] ++ ++Default options are read from the following files in the given order: ++/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf ++The following groups are read: mysqld server mysqld-11.4 mariadb mariadb-11.4 mariadbd mariadbd-11.4 client-server galera ++The following options may be given as the first argument: ++--print-defaults Print the program argument list and exit. ++--no-defaults Don't read default options from any option file. ++The following specify which files/extra groups are read (specified before remaining options): ++--defaults-file=# Only read default options from the given file #. ++--defaults-extra-file=# Read this file after the global files are read. ++--defaults-group-suffix=# Additionally read default groups with # appended as a suffix. ++ ++ --allow-suspicious-udfs ++ Allows use of user-defined functions (UDFs) consisting of ++ only one symbol xxx() without corresponding xxx_init() or ++ xxx_deinit(). That also means that one can load any ++ function from any library, for example exit() from ++ libc.so ++ --alter-algorithm[=name] ++ Specify the alter table algorithm. One of: DEFAULT, COPY, ++ INPLACE, NOCOPY, INSTANT ++ --analyze-sample-percentage=# ++ Percentage of rows from the table ANALYZE TABLE will ++ sample to collect table statistics. Set to 0 to let ++ MariaDB decide what percentage of rows to sample. ++ -a, --ansi Use ANSI SQL syntax instead of MySQL syntax. This mode ++ will also set transaction isolation level 'serializable'. ++ --aria-block-size=# Block size to be used for Aria index pages. ++ --aria-checkpoint-interval=# ++ Interval between tries to do an automatic checkpoints. In ++ seconds; 0 means 'no automatic checkpoints' which makes ++ sense only for testing. ++ --aria-checkpoint-log-activity=# ++ Number of bytes that the transaction log has to grow ++ between checkpoints before a new checkpoint is written to ++ the log. ++ --aria-encrypt-tables ++ Encrypt tables (only for tables with ROW_FORMAT=PAGE ++ (default) and not FIXED/DYNAMIC) ++ --aria-force-start-after-recovery-failures=# ++ Number of consecutive log recovery failures after which ++ logs will be automatically deleted to cure the problem; 0 ++ (the default) disables the feature. ++ --aria-group-commit=name ++ Specifies Aria group commit mode. Possible values are ++ "none" (no group commit), "hard" (with waiting to actual ++ commit), "soft" (no wait for commit (DANGEROUS!!!)) ++ --aria-group-commit-interval=# ++ Interval between commits in microseconds (1/1000000 sec). ++ 0 stands for no waiting for other threads to come and do ++ a commit in "hard" mode and no sync()/commit at all in ++ "soft" mode. Option has only an effect if ++ aria_group_commit is used ++ --aria-log-dir-path=name ++ Path to the directory where to store transactional log ++ --aria-log-file-size=# ++ Limit for transaction log size ++ --aria-log-purge-type=name ++ Specifies how Aria transactional log will be purged. One ++ of: immediate, external, at_flush ++ --aria-max-sort-file-size=# ++ Don't use the fast sort index method to created index if ++ the temporary file would get bigger than this. ++ --aria-page-checksum ++ Maintain page checksums (can be overridden per table with ++ PAGE_CHECKSUM clause in CREATE TABLE) ++ (Defaults to on; use --skip-aria-page-checksum to disable.) ++ --aria-pagecache-age-threshold=# ++ This characterizes the number of hits a hot block has to ++ be untouched until it is considered aged enough to be ++ downgraded to a warm block. This specifies the percentage ++ ratio of that number of hits to the total number of ++ blocks in the page cache. ++ --aria-pagecache-buffer-size=# ++ The size of the buffer used for index blocks for Aria ++ tables. Increase this to get better index handling (for ++ all reads and multiple writes) to as much as you can ++ afford. ++ --aria-pagecache-division-limit=# ++ The minimum percentage of warm blocks in key cache ++ --aria-pagecache-file-hash-size=# ++ Number of hash buckets for open and changed files. If ++ you have a lot of Aria files open you should increase ++ this for faster flush of changes. A good value is ++ probably 1/10 of number of possible open Aria files. ++ --aria-recover-options[=name] ++ Specifies how corrupted tables should be automatically ++ repaired. Any combination of: NORMAL, BACKUP, FORCE, ++ QUICK, OFF ++ Use 'ALL' to set all combinations. ++ --aria-repair-threads=# ++ Number of threads to use when repairing Aria tables. The ++ value of 1 disables parallel repair. ++ --aria-sort-buffer-size=# ++ The buffer that is allocated when sorting the index when ++ doing a REPAIR or when creating indexes with CREATE INDEX ++ or ALTER TABLE. ++ --aria-stats-method=name ++ Specifies how Aria index statistics collection code ++ should treat NULLs. One of: nulls_unequal, nulls_equal, ++ nulls_ignored ++ --aria-sync-log-dir=name ++ Controls syncing directory after log file growth and new ++ file creation. One of: NEVER, NEWFILE, ALWAYS ++ --auto-increment-increment[=#] ++ Auto-increment columns are incremented by this ++ --auto-increment-offset[=#] ++ Offset added to Auto-increment columns. Used when ++ auto-increment-increment != 1 ++ --autocommit Set default value for autocommit (0 or 1) ++ (Defaults to on; use --skip-autocommit to disable.) ++ --automatic-sp-privileges ++ Creating and dropping stored procedures alters ACLs ++ (Defaults to on; use --skip-automatic-sp-privileges to disable.) ++ --back-log=# The number of outstanding connection requests MariaDB can ++ have. This comes into play when the main MariaDB thread ++ gets very many connection requests in a very short time ++ (Automatically configured unless set explicitly) ++ -b, --basedir=name Path to installation directory. All paths are usually ++ resolved relative to this ++ --big-tables Old variable, which if set to 1, allows large result sets ++ by saving all temporary sets to disk, avoiding 'table ++ full' errors. No longer needed, as the server now handles ++ this automatically. ++ --bind-address=name IP address to bind to. Several addresses may be ++ specified, separated by a comma (,). ++ --binlog-alter-two-phase ++ When set, split ALTER at binary logging into 2 ++ statements: START ALTER and COMMIT/ROLLBACK ALTER ++ --binlog-annotate-row-events ++ Tells the master to annotate RBR events with the ++ statement that caused these events ++ (Defaults to on; use --skip-binlog-annotate-row-events to disable.) ++ --binlog-cache-size=# ++ The size of the transactional cache for updates to ++ transactional engines for the binary log. If you often ++ use transactions containing many statements, you can ++ increase this to get more performance ++ --binlog-checksum=name ++ Type of BINLOG_CHECKSUM_ALG. Include checksum for log ++ events in the binary log. One of: NONE, CRC32 ++ --binlog-commit-wait-count=# ++ If non-zero, binlog write will wait at most ++ binlog_commit_wait_usec microseconds for at least this ++ many commits to queue up for group commit to the binlog. ++ This can reduce I/O on the binlog and provide increased ++ opportunity for parallel apply on the slave, but too high ++ a value will decrease commit throughput. ++ --binlog-commit-wait-usec=# ++ Maximum time, in microseconds, to wait for more commits ++ to queue up for binlog group commit. Only takes effect if ++ the value of binlog_commit_wait_count is non-zero. ++ --binlog-direct-non-transactional-updates ++ Causes updates to non-transactional engines using ++ statement format to be written directly to binary log. ++ Before using this option make sure that there are no ++ dependencies between transactional and non-transactional ++ tables such as in the statement INSERT INTO t_myisam ++ SELECT * FROM t_innodb; otherwise, slaves may diverge ++ from the master. ++ --binlog-do-db=name Tells the master it should log updates for the specified ++ database, and exclude all others not explicitly ++ mentioned. ++ --binlog-expire-logs-seconds=# ++ If non-zero, binary logs will be purged after ++ binlog_expire_logs_seconds seconds; It and ++ expire_logs_days are linked, such that changes in one are ++ converted into the other. Possible purges happen at ++ startup and at binary log rotation. ++ --binlog-file-cache-size=# ++ The size of file cache for the binary log ++ --binlog-format=name ++ What form of binary logging the master will use: either ++ ROW for row-based binary logging, STATEMENT for ++ statement-based binary logging, or MIXED. MIXED is ++ statement-based binary logging except for those ++ statements where only row-based is correct: those which ++ involve user-defined functions (i.e. UDFs) or the UUID() ++ function; for those, row-based binary logging is ++ automatically used. ++ --binlog-gtid-index Enable the creation of a GTID index for every binlog ++ file, and the use of such index for speeding up GTID ++ lookup in the binlog. ++ (Defaults to on; use --skip-binlog-gtid-index to disable.) ++ --binlog-gtid-index-page-size=# ++ Page size to use for the binlog GTID index. ++ --binlog-gtid-index-span-min=# ++ Control sparseness of the binlog GTID index. If set to N, ++ at most one index record will be added for every N bytes ++ of binlog file written, to reduce the size of the index. ++ Normally does not need tuning. ++ --binlog-ignore-db=name ++ Tells the master that updates to the given database ++ should not be logged to the binary log. ++ --binlog-legacy-event-pos ++ Fill in the end_log_pos field of _all_ events in the ++ binlog, even when doing so costs performance. Can be used ++ in case some old application needs it for backwards ++ compatibility. Setting this option can hurt binlog ++ scalability. ++ --binlog-optimize-thread-scheduling ++ Run fast part of group commit in a single thread, to ++ optimize kernel thread scheduling. On by default. Disable ++ to run each transaction in group commit in its own ++ thread, which can be slower at very high concurrency. ++ This option is mostly for testing one algorithm versus ++ the other, and it should not normally be necessary to ++ change it. ++ (Defaults to on; use --skip-binlog-optimize-thread-scheduling to disable.) ++ --binlog-row-event-max-size=# ++ The maximum size of a row-based binary log event in ++ bytes. Rows will be grouped into events smaller than this ++ size if possible. The value has to be a multiple of 256. ++ --binlog-row-image=name ++ Controls whether rows should be logged in 'FULL', ++ 'FULL_NODUP', 'NOBLOB' or 'MINIMAL' formats. 'FULL', ++ means that all columns in the before and after image are ++ logged. 'FULL_NODUP', means that all columns are logged ++ in before image, but only changed columns or all columns ++ of inserted record are logged in after image, 'NOBLOB', ++ means that mysqld avoids logging blob columns whenever ++ possible (eg, blob column was not changed or is not part ++ of primary key). 'MINIMAL', means that a PK equivalent ++ (PK columns or full row if there is no PK in the table) ++ is logged in the before image, and only changed columns ++ are logged in the after image. (Default: FULL). ++ --binlog-row-metadata=name ++ Controls whether metadata is logged using FULL , MINIMAL ++ format and NO_LOG.FULL causes all metadata to be logged; ++ MINIMAL means that only metadata actually required by ++ slave is logged; NO_LOG NO metadata will be ++ logged.Default: NO_LOG. ++ --binlog-space-limit=# ++ Alias for max_binlog_total_size. Compatibility with ++ Percona server. ++ --binlog-stmt-cache-size=# ++ The size of the statement cache for updates to ++ non-transactional engines for the binary log. If you ++ often use statements updating a great number of rows, you ++ can increase this to get more performance. ++ --block-encryption-mode=name ++ Default block encryption mode for AES_ENCRYPT() and ++ AES_DECRYPT() functions. One of: aes-128-ecb, aes-192-ecb, ++ aes-256-ecb, aes-128-cbc, aes-192-cbc, aes-256-cbc, ++ aes-128-ctr, aes-192-ctr, aes-256-ctr ++ --bootstrap Used by mysql installation scripts. ++ --bulk-insert-buffer-size=# ++ Size of tree cache used in bulk insert optimisation. Note ++ that this is a limit per thread! ++ --character-set-client-handshake ++ Don't ignore client side character set value sent during ++ handshake. ++ (Defaults to on; use --skip-character-set-client-handshake to disable.) ++ --character-set-collations=name ++ Overrides for character set default collations. ++ --character-set-filesystem=name ++ Set the filesystem character set. ++ -C, --character-set-server=name ++ Set the default character set. ++ --character-sets-dir=name ++ Directory where character sets are ++ -r, --chroot=name Chroot mysqld daemon during startup. ++ --collation-server=name ++ Set the default collation. ++ --column-compression-threshold=# ++ Minimum column data length eligible for compression ++ --column-compression-zlib-level=# ++ zlib compression level (1 gives best speed, 9 gives best ++ compression) ++ --column-compression-zlib-strategy=name ++ The strategy parameter is used to tune the compression ++ algorithm. Use the value DEFAULT_STRATEGY for normal ++ data, FILTERED for data produced by a filter (or ++ predictor), HUFFMAN_ONLY to force Huffman encoding only ++ (no string match), or RLE to limit match distances to one ++ (run-length encoding). Filtered data consists mostly of ++ small values with a somewhat random distribution. In this ++ case, the compression algorithm is tuned to compress them ++ better. The effect of FILTERED is to force more Huffman ++ coding and less string matching; it is somewhat ++ intermediate between DEFAULT_STRATEGY and HUFFMAN_ONLY. ++ RLE is designed to be almost as fast as HUFFMAN_ONLY, but ++ give better compression for PNG image data. The strategy ++ parameter only affects the compression ratio but not the ++ correctness of the compressed output even if it is not ++ set appropriately. FIXED prevents the use of dynamic ++ Huffman codes, allowing for a simpler decoder for special ++ applications. ++ --column-compression-zlib-wrap ++ Generate zlib header and trailer and compute adler32 ++ check value. It can be used with storage engines that ++ don't provide data integrity verification to detect data ++ corruption. ++ --completion-type=name ++ The transaction completion type. One of: NO_CHAIN, CHAIN, ++ RELEASE ++ --concurrent-insert[=name] ++ Use concurrent insert with MyISAM. One of: NEVER, AUTO, ++ ALWAYS ++ --connect-timeout=# The number of seconds the mysqld server is waiting for a ++ connect packet before responding with 'Bad handshake' ++ --console Write error output on screen; don't remove the console ++ window on windows. ++ --core-file Write core on crashes ++ -h, --datadir=name Path to the database root directory ++ --deadlock-search-depth-long=# ++ Long search depth for the two-step deadlock detection ++ --deadlock-search-depth-short=# ++ Short search depth for the two-step deadlock detection ++ --deadlock-timeout-long=# ++ Long timeout for the two-step deadlock detection (in ++ microseconds) ++ --deadlock-timeout-short=# ++ Short timeout for the two-step deadlock detection (in ++ microseconds) ++ -#, --debug[=name] Built in DBUG debugger. Disabled in this build. ++ --debug-abort-slave-event-count=# ++ Option used by mysql-test for debugging and testing of ++ replication. ++ --debug-disconnect-slave-event-count=# ++ Option used by mysql-test for debugging and testing of ++ replication. ++ -T, --debug-exit-info[=#] ++ Used for debugging. Use at your own risk. ++ --debug-gdb Set up signals usable for debugging. ++ --debug-max-binlog-dump-events=# ++ Option used by mysql-test for debugging and testing of ++ replication. ++ --debug-no-sync Disables system sync calls. Only for running tests or ++ debugging! ++ --debug-sporadic-binlog-dump-fail ++ Option used by mysql-test for debugging and testing of ++ replication. ++ --default-password-lifetime=# ++ This defines the global password expiration policy. 0 ++ means automatic password expiration is disabled. If the ++ value is a positive integer N, the passwords must be ++ changed every N days. This behavior can be overridden ++ using the password expiration options in ALTER USER. ++ --default-regex-flags=name ++ Default flags for the regex library. Any combination of: ++ DOTALL, DUPNAMES, EXTENDED, EXTENDED_MORE, EXTRA, ++ MULTILINE, UNGREEDY ++ Use 'ALL' to set all combinations. ++ --default-storage-engine=name ++ The default storage engine for new tables ++ --default-time-zone=name ++ Set the default time zone. ++ --default-tmp-storage-engine=name ++ The default storage engine for user-created temporary ++ tables ++ --default-week-format=# ++ The default week format used by WEEK() functions ++ --delay-key-write[=name] ++ Specifies how MyISAM tables handles CREATE TABLE ++ DELAY_KEY_WRITE. If set to ON, the default, any DELAY KEY ++ WRITEs are honored. The key buffer is then flushed only ++ when the table closes, speeding up writes. MyISAM tables ++ should be automatically checked upon startup in this ++ case, and --external locking should not be used, as it ++ can lead to index corruption. If set to OFF, DELAY KEY ++ WRITEs are ignored, while if set to ALL, all new opened ++ tables are treated as if created with DELAY KEY WRITEs ++ enabled. ++ --delayed-insert-limit=# ++ After inserting delayed_insert_limit rows, the INSERT ++ DELAYED handler will check if there are any SELECT ++ statements pending. If so, it allows these to execute ++ before continuing. ++ --delayed-insert-timeout=# ++ How long a INSERT DELAYED thread should wait for INSERT ++ statements before terminating ++ --delayed-queue-size=# ++ What size queue (in rows) should be allocated for ++ handling INSERT DELAYED. If the queue becomes full, any ++ client that does INSERT DELAYED will wait until there is ++ room in the queue again ++ --des-key-file=name Load keys for des_encrypt() and des_encrypt from given ++ file. ++ --disconnect-on-expired-password ++ This variable controls how the server handles clients ++ that are not aware of the sandbox mode. If enabled, the ++ server disconnects the client, otherwise the server puts ++ the client in a sandbox mode. ++ --div-precision-increment=# ++ Precision of the result of '/' operator will be increased ++ on that value ++ --encrypt-binlog Encrypt binary logs (including relay logs) ++ --encrypt-tmp-disk-tables ++ Encrypt temporary on-disk tables (created as part of ++ query execution) ++ --encrypt-tmp-files Encrypt temporary files (created for filesort, binary log ++ cache, etc) ++ --enforce-storage-engine=name ++ Force the use of a storage engine for new tables ++ --eq-range-index-dive-limit=# ++ The optimizer will use existing index statistics instead ++ of doing index dives for equality ranges if the number of ++ equality ranges for the index is larger than or equal to ++ this number. If set to 0, index dives are always used. ++ --event-scheduler[=name] ++ Enable the event scheduler. Possible values are ON, OFF, ++ and DISABLED (keep the event scheduler completely ++ deactivated, it cannot be activated run-time) ++ --expensive-subquery-limit=# ++ The maximum number of rows a subquery may examine in ++ order to be executed during optimization and used for ++ constant optimization ++ --expire-logs-days=# ++ If non-zero, binary logs will be purged after ++ expire_logs_days days; It and binlog_expire_logs_seconds ++ are linked, such that changes in one are converted into ++ the other, presentable as a decimal value with 1/1000000 ++ of the day precision; possible purges happen at startup ++ and at binary log rotation ++ --explicit-defaults-for-timestamp ++ This option causes CREATE TABLE to create all TIMESTAMP ++ columns as NULL with DEFAULT NULL attribute, Without this ++ option, TIMESTAMP columns are NOT NULL and have implicit ++ DEFAULT clauses. ++ (Defaults to on; use --skip-explicit-defaults-for-timestamp to disable.) ++ --external-locking Use system (external) locking (disabled by default). ++ With this option enabled you can run myisamchk to test ++ (not repair) tables while the MySQL server is running. ++ Disable with --skip-external-locking. ++ --extra-max-connections=# ++ The number of connections on extra-port ++ --extra-port=# Extra port number to use for tcp connections in a ++ one-thread-per-connection manner. 0 means don't use ++ another port ++ --feedback[=name] Enable or disable FEEDBACK plugin. One of: ON, OFF, FORCE ++ (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --feedback-http-proxy=name ++ Proxy server host:port. ++ --feedback-send-retry-wait=# ++ Wait this many seconds before retrying a failed send. ++ --feedback-send-timeout=# ++ Timeout (in seconds) for the sending the report. ++ --feedback-url=name Space separated URLs to send the feedback report to. ++ --feedback-user-info=name ++ User specified string that will be included in the ++ feedback report. ++ --flashback Setup the server to use flashback. This enables binary ++ log in row mode and will enable extra logging for DDL's ++ needed by flashback feature ++ --flush Flush MyISAM tables to disk between SQL commands ++ --flush-time=# A dedicated thread is created to flush all tables at the ++ given interval ++ --ft-boolean-syntax=name ++ List of operators for MATCH ... AGAINST ( ... IN BOOLEAN ++ MODE) ++ --ft-max-word-len=# The maximum length of the word to be included in a ++ FULLTEXT index. Note: FULLTEXT indexes must be rebuilt ++ after changing this variable ++ --ft-min-word-len=# The minimum length of the word to be included in a ++ FULLTEXT index. Note: FULLTEXT indexes must be rebuilt ++ after changing this variable ++ --ft-query-expansion-limit=# ++ Number of best matches to use for query expansion ++ --ft-stopword-file=name ++ Use stopwords from this file instead of built-in list ++ --gdb Set up signals usable for debugging. Deprecated, use ++ --debug-gdb instead. ++ --general-log Log connections and queries to a table or log file. ++ Defaults logging to a file 'hostname'.log or a table ++ mysql.general_logif --log-output=TABLE is used. ++ --general-log-file=name ++ Log connections and queries to given file ++ --getopt-prefix-matching ++ Recognize command-line options by their unambiguos ++ prefixes. ++ (Defaults to on; use --skip-getopt-prefix-matching to disable.) ++ --group-concat-max-len=# ++ The maximum length of the result of function ++ GROUP_CONCAT() ++ --gtid-cleanup-batch-size=# ++ Normally does not need tuning. How many old rows must ++ accumulate in the mysql.gtid_slave_pos table before a ++ background job will be run to delete them. Can be ++ increased to reduce number of commits if using many ++ different engines with --gtid_pos_auto_engines, or to ++ reduce CPU overhead if using a huge number of different ++ gtid_domain_ids. Can be decreased to reduce number of old ++ rows in the table. ++ --gtid-domain-id=# Used with global transaction ID to identify logically ++ independent replication streams. When events can ++ propagate through multiple parallel paths (for example ++ multiple masters), each independent source server must ++ use a distinct domain_id. For simple tree-shaped ++ replication topologies, it can be left at its default, 0. ++ --gtid-ignore-duplicates ++ When set, different master connections in multi-source ++ replication are allowed to receive and process event ++ groups with the same GTID (when using GTID mode). Only ++ one will be applied, any others will be ignored. Within a ++ given replication domain, just the sequence number will ++ be used to decide whether a given GTID has been already ++ applied; this means it is the responsibility of the user ++ to ensure that GTID sequence numbers are strictly ++ increasing. ++ --gtid-pos-auto-engines=name ++ List of engines for which to automatically create a ++ mysql.gtid_slave_pos_ENGINE table, if a transaction using ++ that engine is replicated. This can be used to avoid ++ introducing cross-engine transactions, if engines are ++ used different from that used by table ++ mysql.gtid_slave_pos ++ --gtid-strict-mode Enforce strict seq_no ordering of events in the binary ++ log. Slave stops with an error if it encounters an event ++ that would cause it to generate an out-of-order binlog if ++ executed. When ON the same server-id semisync-replicated ++ transactions that duplicate existing ones in binlog are ++ ignored without error and slave interruption. ++ -?, --help Display this help and exit. ++ --histogram-size=# Number of bytes used for a histogram. If set to 0, no ++ histograms are created by ANALYZE. ++ --histogram-type=name ++ Specifies type of the histograms created by ANALYZE. ++ Possible values are: SINGLE_PREC_HB - single precision ++ height-balanced, DOUBLE_PREC_HB - double precision ++ height-balanced, JSON_HB - height-balanced, stored as ++ JSON. ++ --host-cache-size=# How many host names should be cached to avoid resolving. ++ (Automatically configured unless set explicitly) ++ --idle-readonly-transaction-timeout=# ++ The number of seconds the server waits for read-only idle ++ transaction ++ --idle-transaction-timeout=# ++ The number of seconds the server waits for idle ++ transaction ++ --idle-write-transaction-timeout=# ++ The number of seconds the server waits for write idle ++ transaction ++ --ignore-builtin-innodb ++ Disable initialization of builtin InnoDB plugin ++ --ignore-db-dirs=name ++ Specifies a directory to add to the ignore list when ++ collecting database names from the datadir. Put a blank ++ argument to reset the list accumulated so far. ++ --in-predicate-conversion-threshold=# ++ The minimum number of scalar elements in the value list ++ of IN predicate that triggers its conversion to IN ++ subquery. Set to 0 to disable the conversion. ++ --init-connect=name Command(s) that are executed for each new connection ++ (unless the user has SUPER privilege) ++ --init-file=name Read SQL commands from this file at startup ++ --init-rpl-role=name ++ Set the replication role. One of: MASTER, SLAVE ++ --init-slave=name Command(s) that are executed by a slave server each time ++ the SQL thread starts ++ --innodb[=name] Enable or disable InnoDB plugin. One of: ON, OFF, FORCE ++ (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-adaptive-flushing ++ Attempt flushing dirty pages to avoid IO bursts at ++ checkpoints. ++ (Defaults to on; use --skip-innodb-adaptive-flushing to disable.) ++ --innodb-adaptive-flushing-lwm=# ++ Percentage of log capacity below which no adaptive ++ flushing happens. ++ --innodb-adaptive-hash-index ++ Enable InnoDB adaptive hash index (disabled by default). ++ --innodb-adaptive-hash-index-parts[=#] ++ Number of InnoDB Adaptive Hash Index Partitions (default ++ 8) ++ --innodb-autoextend-increment=# ++ Data file autoextend increment in megabytes ++ --innodb-autoinc-lock-mode=# ++ The AUTOINC lock modes supported by InnoDB: 0 => Old ++ style AUTOINC locking (for backward compatibility); 1 => ++ New style AUTOINC locking; 2 => No AUTOINC locking ++ (unsafe for SBR) ++ --innodb-buf-dump-status-frequency=# ++ A number between [0, 100] that tells how oftern buffer ++ pool dump status in percentages should be printed. E.g. ++ 10 means that buffer pool dump status is printed when ++ every 10% of number of buffer pool pages are dumped. ++ Default is 0 (only start and end status is printed). ++ --innodb-buffer-page[=name] ++ Enable or disable INNODB_BUFFER_PAGE plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-buffer-page-lru[=name] ++ Enable or disable INNODB_BUFFER_PAGE_LRU plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-buffer-pool-chunk-size=# ++ Size of a single memory chunk for resizing buffer pool. ++ Online buffer pool resizing happens at this granularity. ++ 0 means autosize this variable based on buffer pool size. ++ --innodb-buffer-pool-dump-at-shutdown ++ Dump the buffer pool into a file named ++ @@innodb_buffer_pool_filename ++ (Defaults to on; use --skip-innodb-buffer-pool-dump-at-shutdown to disable.) ++ --innodb-buffer-pool-dump-now ++ Trigger an immediate dump of the buffer pool into a file ++ named @@innodb_buffer_pool_filename ++ --innodb-buffer-pool-dump-pct=# ++ Dump only the hottest N% of each buffer pool, defaults to ++ 25 ++ --innodb-buffer-pool-filename=name ++ Filename to/from which to dump/load the InnoDB buffer ++ pool ++ --innodb-buffer-pool-load-abort ++ Abort a currently running load of the buffer pool ++ --innodb-buffer-pool-load-at-startup ++ Load the buffer pool from a file named ++ @@innodb_buffer_pool_filename ++ (Defaults to on; use --skip-innodb-buffer-pool-load-at-startup to disable.) ++ --innodb-buffer-pool-load-now ++ Trigger an immediate load of the buffer pool from a file ++ named @@innodb_buffer_pool_filename ++ --innodb-buffer-pool-size=# ++ The size of the memory buffer InnoDB uses to cache data ++ and indexes of its tables. ++ --innodb-buffer-pool-stats[=name] ++ Enable or disable INNODB_BUFFER_POOL_STATS plugin. One ++ of: ON, OFF, FORCE (don't start if the plugin fails to ++ load), FORCE_PLUS_PERMANENT (like FORCE, but the plugin ++ can not be uninstalled). ++ --innodb-checksum-algorithm=name ++ The algorithm InnoDB uses for page checksumming. Possible ++ values are FULL_CRC32 for new files, always use CRC-32C; ++ for old, see CRC32 below; STRICT_FULL_CRC32 for new ++ files, always use CRC-32C; for old, see STRICT_CRC32 ++ below; CRC32 write crc32, allow previously used ++ algorithms to match when reading; STRICT_CRC32 write ++ crc32, do not allow other algorithms to match when ++ reading; New files created with full_crc32 are readable ++ by MariaDB 10.4.3+ ++ --innodb-cmp[=name] Enable or disable INNODB_CMP plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-cmp-per-index[=name] ++ Enable or disable INNODB_CMP_PER_INDEX plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-cmp-per-index-enabled ++ Enable INFORMATION_SCHEMA.innodb_cmp_per_index, may have ++ negative impact on performance (off by default) ++ --innodb-cmp-per-index-reset[=name] ++ Enable or disable INNODB_CMP_PER_INDEX_RESET plugin. One ++ of: ON, OFF, FORCE (don't start if the plugin fails to ++ load), FORCE_PLUS_PERMANENT (like FORCE, but the plugin ++ can not be uninstalled). ++ --innodb-cmp-reset[=name] ++ Enable or disable INNODB_CMP_RESET plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-cmpmem[=name] ++ Enable or disable INNODB_CMPMEM plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-cmpmem-reset[=name] ++ Enable or disable INNODB_CMPMEM_RESET plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-compression-algorithm[=name] ++ Compression algorithm used on page compression. One of: ++ none, zlib, lz4, lzo, lzma, bzip2, or snappy ++ --innodb-compression-default ++ Is compression the default for new tables ++ --innodb-compression-failure-threshold-pct[=#] ++ If the compression failure rate of a table is greater ++ than this number more padding is added to the pages to ++ reduce the failures. A value of zero implies no padding ++ --innodb-compression-level=# ++ Compression level used for zlib compression. 0 is no ++ compression, 1 is fastest, 9 is best compression and ++ default is 6. ++ --innodb-compression-pad-pct-max[=#] ++ Percentage of empty space on a data page that can be ++ reserved to make the page compressible. ++ --innodb-data-file-buffering ++ Whether the file system cache for data files is enabled ++ --innodb-data-file-path=name ++ Path to individual files and their sizes. ++ --innodb-data-file-write-through ++ Whether each write to data files writes through ++ --innodb-data-home-dir=name ++ The common part for InnoDB table spaces. ++ --innodb-deadlock-detect ++ Enable/disable InnoDB deadlock detector (default ON). if ++ set to OFF, deadlock detection is skipped, and we rely on ++ innodb_lock_wait_timeout in case of deadlock. ++ (Defaults to on; use --skip-innodb-deadlock-detect to disable.) ++ --innodb-deadlock-report=name ++ How to report deadlocks (if innodb_deadlock_detect=ON).. ++ One of: off, basic, full ++ --innodb-default-encryption-key-id=# ++ Default encryption key id used for table encryption. ++ --innodb-default-row-format=name ++ The default ROW FORMAT for all innodb tables created ++ without explicit ROW_FORMAT. Possible values are ++ REDUNDANT, COMPACT, and DYNAMIC. The ROW_FORMAT value ++ COMPRESSED is not allowed. One of: redundant, compact, ++ dynamic ++ --innodb-disable-sort-file-cache ++ Whether to disable OS system file cache for sort I/O ++ --innodb-doublewrite[=name] ++ Whether and how to use the doublewrite buffer. OFF=Assume ++ that writes of innodb_page_size are atomic; ON=Prevent ++ torn writes (the default); fast=Like ON, but do not ++ synchronize writes to data files ++ --innodb-encrypt-log ++ Enable redo log encryption ++ --innodb-encrypt-tables[=name] ++ Enable encryption for tables. Don't forget to enable ++ --innodb-encrypt-log too. One of: OFF, ON, FORCE ++ --innodb-encrypt-temporary-tables ++ Enrypt the temporary table data. ++ --innodb-encryption-rotate-key-age=# ++ Key rotation - re-encrypt in background all pages that ++ were encrypted with a key that many (or more) versions ++ behind. Value 0 indicates that key rotation is disabled. ++ --innodb-encryption-rotation-iops=# ++ Use this many iops for background key rotation ++ --innodb-encryption-threads=# ++ Number of threads performing background key rotation ++ --innodb-fast-shutdown[=#] ++ Speeds up the shutdown process of the InnoDB storage ++ engine. Possible values are 0, 1 (faster), 2 ++ (crash-like), 3 (fastest clean). ++ --innodb-fatal-semaphore-wait-threshold=# ++ Maximum number of seconds that semaphore times out in ++ InnoDB. ++ --innodb-file-per-table ++ Stores each InnoDB table to an .ibd file in the database ++ dir. ++ (Defaults to on; use --skip-innodb-file-per-table to disable.) ++ --innodb-fill-factor=# ++ Percentage of B-tree page filled during bulk insert ++ --innodb-flush-log-at-timeout[=#] ++ Write and flush logs every (n) second. ++ --innodb-flush-log-at-trx-commit[=#] ++ Controls the durability/speed trade-off for commits. Set ++ to 0 (write and flush redo log to disk only once per ++ second), 1 (flush to disk at each commit), 2 (write to ++ log at commit but flush to disk only once per second) or ++ 3 (flush to disk at prepare and at commit, slower and ++ usually redundant). 1 and 3 guarantees that after a ++ crash, committed transactions will not be lost and will ++ be consistent with the binlog and other transactional ++ engines. 2 can get inconsistent and lose transactions if ++ there is a power failure or kernel crash but not if ++ mysqld crashes. 0 has no guarantees in case of crash. 0 ++ and 2 can be faster than 1 or 3. ++ --innodb-flush-method=name ++ With which method to flush data.. One of: fsync, O_DSYNC, ++ littlesync, nosync, O_DIRECT, O_DIRECT_NO_FSYNC ++ --innodb-flush-neighbors[=#] ++ Set to 0 (don't flush neighbors from buffer pool), 1 ++ (flush contiguous neighbors from buffer pool) or 2 (flush ++ neighbors from buffer pool), when flushing a block ++ --innodb-flush-sync Allow IO bursts at the checkpoints ignoring io_capacity ++ setting. ++ (Defaults to on; use --skip-innodb-flush-sync to disable.) ++ --innodb-flushing-avg-loops=# ++ Number of iterations over which the background flushing ++ is averaged. ++ --innodb-force-primary-key ++ Do not allow creating a table without primary key (off by ++ default) ++ --innodb-force-recovery=# ++ Helps to save your data in case the disk image of the ++ database becomes corrupt. Value 5 can return bogus data, ++ and 6 can permanently corrupt data. ++ --innodb-ft-aux-table=name ++ FTS internal auxiliary table to be checked ++ --innodb-ft-being-deleted[=name] ++ Enable or disable INNODB_FT_BEING_DELETED plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-ft-cache-size=# ++ InnoDB Fulltext search cache size in bytes ++ --innodb-ft-config[=name] ++ Enable or disable INNODB_FT_CONFIG plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-ft-default-stopword[=name] ++ Enable or disable INNODB_FT_DEFAULT_STOPWORD plugin. One ++ of: ON, OFF, FORCE (don't start if the plugin fails to ++ load), FORCE_PLUS_PERMANENT (like FORCE, but the plugin ++ can not be uninstalled). ++ --innodb-ft-deleted[=name] ++ Enable or disable INNODB_FT_DELETED plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-ft-enable-diag-print ++ Whether to enable additional FTS diagnostic printout ++ --innodb-ft-enable-stopword ++ Create FTS index with stopword. ++ (Defaults to on; use --skip-innodb-ft-enable-stopword to disable.) ++ --innodb-ft-index-cache[=name] ++ Enable or disable INNODB_FT_INDEX_CACHE plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-ft-index-table[=name] ++ Enable or disable INNODB_FT_INDEX_TABLE plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-ft-max-token-size=# ++ InnoDB Fulltext search maximum token size in characters ++ --innodb-ft-min-token-size=# ++ InnoDB Fulltext search minimum token size in characters ++ --innodb-ft-num-word-optimize[=#] ++ InnoDB Fulltext search number of words to optimize for ++ each optimize table call ++ --innodb-ft-result-cache-limit=# ++ InnoDB Fulltext search query result cache limit in bytes ++ --innodb-ft-server-stopword-table[=name] ++ The user supplied stopword table name. ++ --innodb-ft-sort-pll-degree=# ++ InnoDB Fulltext search parallel sort degree, will round ++ up to nearest power of 2 number ++ --innodb-ft-total-cache-size=# ++ Total memory allocated for InnoDB Fulltext Search cache ++ --innodb-ft-user-stopword-table[=name] ++ User supplied stopword table name, effective in the ++ session level. ++ --innodb-immediate-scrub-data-uncompressed ++ Enable scrubbing of data ++ --innodb-instant-alter-column-allowed=name ++ File format constraint for ALTER TABLE. One of: never, ++ add_last, add_drop_reorder ++ --innodb-io-capacity=# ++ Number of IOPs the server can do. Tunes the background IO ++ rate ++ --innodb-io-capacity-max=# ++ Limit to which innodb_io_capacity can be inflated. ++ --innodb-lock-wait-timeout=# ++ Timeout in seconds an InnoDB transaction may wait for a ++ lock before being rolled back. The value 100000000 is ++ infinite timeout. ++ --innodb-lock-waits[=name] ++ Enable or disable INNODB_LOCK_WAITS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-locks[=name] ++ Enable or disable INNODB_LOCKS plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-log-buffer-size=# ++ Redo log buffer size in bytes. ++ --innodb-log-file-buffering ++ Whether the file system cache for ib_logfile0 is enabled ++ --innodb-log-file-size=# ++ Redo log size in bytes. ++ --innodb-log-file-write-through ++ Whether each write to ib_logfile0 is write through ++ --innodb-log-group-home-dir=name ++ Path to ib_logfile0 ++ --innodb-log-spin-wait-delay[=#] ++ Delay between log buffer spin lock polls (0 to use a ++ blocking latch) ++ --innodb-lru-flush-size=# ++ How many pages to flush on LRU eviction ++ --innodb-lru-scan-depth=# ++ How deep to scan LRU to keep it clean ++ --innodb-max-dirty-pages-pct=# ++ Percentage of dirty pages allowed in bufferpool. ++ --innodb-max-dirty-pages-pct-lwm=# ++ Percentage of dirty pages at which flushing kicks in. The ++ value 0 (default) means 'refer to ++ innodb_max_dirty_pages_pct'. ++ --innodb-max-purge-lag=# ++ Desired maximum length of the purge queue (0 = no limit) ++ --innodb-max-purge-lag-delay=# ++ Maximum delay of user threads in micro-seconds ++ --innodb-max-purge-lag-wait=# ++ Wait until History list length is below the specified ++ limit ++ --innodb-max-undo-log-size[=#] ++ Desired maximum UNDO tablespace size in bytes ++ --innodb-metrics[=name] ++ Enable or disable INNODB_METRICS plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-monitor-disable=name ++ Turn off a monitor counter ++ --innodb-monitor-enable=name ++ Turn on a monitor counter ++ --innodb-monitor-reset=name ++ Reset a monitor counter ++ --innodb-monitor-reset-all=name ++ Reset all values for a monitor counter ++ --innodb-numa-interleave ++ Use NUMA interleave memory policy to allocate InnoDB ++ buffer pool. ++ --innodb-old-blocks-pct=# ++ Percentage of the buffer pool to reserve for 'old' ++ blocks. ++ --innodb-old-blocks-time=# ++ Move blocks to the 'new' end of the buffer pool if the ++ first access was at least this many milliseconds ago. The ++ timeout is disabled if 0. ++ --innodb-online-alter-log-max-size=# ++ Maximum modification log file size for online index ++ creation ++ --innodb-open-files=# ++ How many files at the maximum InnoDB keeps open at the ++ same time. ++ --innodb-optimize-fulltext-only ++ Only optimize the Fulltext index of the table ++ --innodb-page-size[=#] ++ Page size to use for all InnoDB tablespaces. ++ --innodb-prefix-index-cluster-optimization ++ Deprecated parameter with no effect ++ (Defaults to on; use --skip-innodb-prefix-index-cluster-optimization to disable.) ++ --innodb-print-all-deadlocks ++ Print all deadlocks to MariaDB error log (off by default) ++ --innodb-purge-batch-size[=#] ++ Number of UNDO log pages to purge in one batch from the ++ history list. ++ --innodb-purge-rseg-truncate-frequency[=#] ++ Deprecated parameter with no effect ++ --innodb-purge-threads[=#] ++ Number of tasks for purging transaction history ++ --innodb-random-read-ahead ++ Whether to use read ahead for random access within an ++ extent. ++ --innodb-read-ahead-threshold=# ++ Number of pages that must be accessed sequentially for ++ InnoDB to trigger a readahead. ++ --innodb-read-io-threads=# ++ Number of background read I/O threads in InnoDB. ++ --innodb-read-only Start InnoDB in read only mode (off by default) ++ --innodb-read-only-compressed ++ Make ROW_FORMAT=COMPRESSED tables read-only ++ --innodb-rollback-on-timeout ++ Roll back the complete transaction on lock wait timeout, ++ for 4.x compatibility (disabled by default) ++ --innodb-snapshot-isolation ++ Use snapshot isolation (write-write conflict detection). ++ --innodb-sort-buffer-size=# ++ Memory buffer size for index creation ++ --innodb-spin-wait-delay[=#] ++ Maximum delay between polling for a spin lock (4 by ++ default) ++ --innodb-stats-auto-recalc ++ InnoDB automatic recalculation of persistent statistics ++ enabled for all tables unless overridden at table level ++ (automatic recalculation is only done when InnoDB decides ++ that the table has changed too much and needs a new ++ statistics) ++ (Defaults to on; use --skip-innodb-stats-auto-recalc to disable.) ++ --innodb-stats-include-delete-marked ++ Include delete marked records when calculating persistent ++ statistics ++ --innodb-stats-method=name ++ Specifies how InnoDB index statistics collection code ++ should treat NULLs. Possible values are NULLS_EQUAL ++ (default), NULLS_UNEQUAL and NULLS_IGNORED. One of: ++ nulls_equal, nulls_unequal, nulls_ignored ++ --innodb-stats-modified-counter=# ++ The number of rows modified before we calculate new ++ statistics (default 0 = current limits) ++ --innodb-stats-on-metadata ++ Enable statistics gathering for metadata commands such as ++ SHOW TABLE STATUS for tables that use transient ++ statistics (off by default) ++ --innodb-stats-persistent ++ InnoDB persistent statistics enabled for all tables ++ unless overridden at table level ++ (Defaults to on; use --skip-innodb-stats-persistent to disable.) ++ --innodb-stats-persistent-sample-pages=# ++ The number of leaf index pages to sample when calculating ++ persistent statistics (by ANALYZE, default 20) ++ --innodb-stats-traditional ++ Enable traditional statistic calculation based on number ++ of configured pages (default true) ++ (Defaults to on; use --skip-innodb-stats-traditional to disable.) ++ --innodb-stats-transient-sample-pages=# ++ The number of leaf index pages to sample when calculating ++ transient statistics (if persistent statistics are not ++ used, default 8) ++ --innodb-status-file ++ Enable SHOW ENGINE INNODB STATUS output in the ++ innodb_status. file ++ --innodb-status-output ++ Enable InnoDB monitor output to the error log. ++ --innodb-status-output-locks ++ Enable InnoDB lock monitor output to the error log. ++ Requires innodb_status_output=ON. ++ --innodb-strict-mode ++ Use strict mode when evaluating create options. ++ (Defaults to on; use --skip-innodb-strict-mode to disable.) ++ --innodb-sync-spin-loops=# ++ Count of spin-loop rounds in InnoDB mutexes (30 by ++ default) ++ --innodb-sys-columns[=name] ++ Enable or disable INNODB_SYS_COLUMNS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-fields[=name] ++ Enable or disable INNODB_SYS_FIELDS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-foreign[=name] ++ Enable or disable INNODB_SYS_FOREIGN plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-foreign-cols[=name] ++ Enable or disable INNODB_SYS_FOREIGN_COLS plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-indexes[=name] ++ Enable or disable INNODB_SYS_INDEXES plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-tables[=name] ++ Enable or disable INNODB_SYS_TABLES plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-tablespaces[=name] ++ Enable or disable INNODB_SYS_TABLESPACES plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-tablestats[=name] ++ Enable or disable INNODB_SYS_TABLESTATS plugin. One of: ++ ON, OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-sys-virtual[=name] ++ Enable or disable INNODB_SYS_VIRTUAL plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-table-locks ++ Enable InnoDB locking in LOCK TABLES ++ (Defaults to on; use --skip-innodb-table-locks to disable.) ++ --innodb-tablespaces-encryption[=name] ++ Enable or disable INNODB_TABLESPACES_ENCRYPTION plugin. ++ One of: ON, OFF, FORCE (don't start if the plugin fails ++ to load), FORCE_PLUS_PERMANENT (like FORCE, but the ++ plugin can not be uninstalled). ++ --innodb-temp-data-file-path=name ++ Path to files and their sizes making temp-tablespace. ++ --innodb-tmpdir[=name] ++ Directory for temporary non-tablespace files. ++ --innodb-truncate-temporary-tablespace-now ++ Shrink the temporary tablespace ++ --innodb-trx[=name] Enable or disable INNODB_TRX plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --innodb-undo-directory=name ++ Directory where undo tablespace files live, this path can ++ be absolute. ++ --innodb-undo-log-truncate ++ Enable or Disable Truncate of UNDO tablespace. ++ --innodb-undo-tablespaces=# ++ Number of undo tablespaces to use. ++ --innodb-use-atomic-writes ++ Enable atomic writes, instead of using the doublewrite ++ buffer, for files on devices that supports atomic writes. ++ (Defaults to on; use --skip-innodb-use-atomic-writes to disable.) ++ --innodb-use-native-aio ++ Use native AIO if supported on this platform. ++ (Defaults to on; use --skip-innodb-use-native-aio to disable.) ++ --innodb-write-io-threads=# ++ Number of background write I/O threads in InnoDB. ++ --interactive-timeout=# ++ The number of seconds the server waits for activity on an ++ interactive connection before closing it ++ --join-buffer-size=# ++ The size of the buffer that is used for joins ++ --join-buffer-space-limit=# ++ The limit of the space for all join buffers used by a ++ query ++ --join-cache-level=# ++ Controls what join operations can be executed with join ++ buffers. Odd numbers are used for plain join buffers ++ while even numbers are used for linked buffers ++ --keep-files-on-create ++ Don't overwrite stale .MYD and .MYI even if no directory ++ is specified ++ --key-buffer-size=# The size of the buffer used for index blocks for MyISAM ++ tables. Increase this to get better index handling (for ++ all reads and multiple writes) to as much as you can ++ afford ++ --key-cache-age-threshold=# ++ This characterizes the number of hits a hot block has to ++ be untouched until it is considered aged enough to be ++ downgraded to a warm block. This specifies the percentage ++ ratio of that number of hits to the total number of ++ blocks in key cache ++ --key-cache-block-size=# ++ The default size of key cache blocks ++ --key-cache-division-limit=# ++ The minimum percentage of warm blocks in key cache ++ --key-cache-file-hash-size=# ++ Number of hash buckets for open and changed files. If ++ you have a lot of MyISAM files open you should increase ++ this for faster flush of changes. A good value is ++ probably 1/10 of number of possible open MyISAM files. ++ --key-cache-segments=# ++ The number of segments in a key cache ++ -L, --language=name Client error messages in given language. May be given as ++ a full path. Deprecated. Use --lc-messages-dir instead. ++ --large-pages Enable support for large pages ++ --lc-messages=name Set the language used for the error messages. ++ -L, --lc-messages-dir=name ++ Directory where error messages are ++ --lc-time-names=name ++ Set the language used for the month names and the days of ++ the week. ++ --local-infile Enable LOAD DATA LOCAL INFILE ++ (Defaults to on; use --skip-local-infile to disable.) ++ --lock-wait-timeout=# ++ Timeout in seconds to wait for a lock before returning an ++ error. ++ --log-basename=name Basename for all log files and the .pid file. This sets ++ all log file names at once (in 'datadir') and is normally ++ the only option you need for specifying log files. Sets ++ names for --log-bin, --log-bin-index, --relay-log, ++ --relay-log-index, --general-log-file, ++ --log-slow-query-file, --log-error-file, and --pid-file ++ --log-bin[=name] Log update queries in binary format. Optional argument ++ should be name for binary log. If not given ++ 'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will ++ be used (the later if --log-basename is not specified). ++ We strongly recommend to use either --log-basename or ++ specify a filename to ensure that replication doesn't ++ stop if the real hostname of the computer changes. ++ --log-bin-compress Whether the binary log can be compressed ++ --log-bin-compress-min-len[=#] ++ Minimum length of sql statement(in statement mode) or ++ record(in row mode)that can be compressed. ++ --log-bin-index=name ++ File that holds the names for last binary log files. ++ --log-bin-trust-function-creators ++ If set to FALSE (the default), then when --log-bin is ++ used, creation of a stored function (or trigger) is ++ allowed only to users having the SUPER privilege and only ++ if this stored function (trigger) may not break binary ++ logging. Note that if ALL connections to this server ++ ALWAYS use row-based binary logging, the security issues ++ do not exist and the binary logging cannot break, so you ++ can safely set this to TRUE ++ --log-ddl-recovery=name ++ Path to file used for recovery of DDL statements after a ++ crash ++ --log-disabled-statements=name ++ Don't log certain types of statements to general log. Any ++ combination of: slave, sp ++ Use 'ALL' to set all combinations. ++ --log-error[=name] Log errors to file (instead of stdout). If file name is ++ not specified then 'datadir'/'log-basename'.err or the ++ 'pid-file' path with extension .err is used ++ --log-isam[=name] Log all MyISAM changes to file. ++ --log-output=name How logs should be written. Any combination of: NONE, ++ FILE, TABLE ++ Use 'ALL' to set all combinations. ++ --log-queries-not-using-indexes ++ Log queries that are executed without benefit of any ++ index to the slow log if it is open. Same as ++ log_slow_filter='not_using_index' ++ --log-short-format Don't log extra information to update and slow-query ++ logs. ++ --log-slave-updates Tells the slave to log the updates from the slave thread ++ to the binary log. You will need to turn it on if you ++ plan to daisy-chain the slaves. ++ --log-slow-admin-statements ++ Log slow OPTIMIZE, ANALYZE, ALTER and other ++ administrative statements to the slow log if it is open. ++ Resets or sets the option 'admin' in log_slow_filter. ++ Deprecated, use log_slow_filter without 'admin'. ++ (Defaults to on; use --skip-log-slow-admin-statements to disable.) ++ --log-slow-disabled-statements=name ++ Don't log certain types of statements to slow log. Any ++ combination of: admin, call, slave, sp ++ Use 'ALL' to set all combinations. ++ --log-slow-filter=name ++ Log only certain types of queries to the slow log. If ++ variable empty all kind of queries are logged. All types ++ are bound by slow_query_time, except 'not_using_index' ++ which is always logged if enabled. Any combination of: ++ admin, filesort, filesort_on_disk, ++ filesort_priority_queue, full_join, full_scan, ++ not_using_index, query_cache, query_cache_miss, tmp_table, ++ tmp_table_on_disk ++ Use 'ALL' to set all combinations. ++ --log-slow-max-warnings=# ++ Max numbers of warnings printed to slow query log per ++ statement ++ --log-slow-min-examined-row-limit=# ++ Don't write queries to slow log that examine fewer rows ++ than that ++ --log-slow-query Log slow queries to a table or log file. Defaults logging ++ to a file 'hostname'-slow.log or a table mysql.slow_log ++ if --log-output=TABLE is used. Must be enabled to ++ activate other slow log options. ++ --log-slow-query-file=name ++ Log slow queries to given log file. Defaults logging to ++ 'hostname'-slow.log. Must be enabled to activate other ++ slow log options ++ --log-slow-query-time=# ++ Log all queries that have taken more than ++ log_slow_query_time seconds to execute to the slow query ++ log file. The argument will be treated as a decimal value ++ with microsecond precision ++ --log-slow-rate-limit=# ++ Write to slow log every #th slow query. Set to 1 to log ++ everything. Increase it to reduce the size of the slow or ++ the performance impact of slow logging ++ --log-slow-slave-statements ++ Log slow statements executed by slave thread to the slow ++ log if it is open. Resets or sets the option 'slave' in ++ log_slow_disabled_statements ++ (Defaults to on; use --skip-log-slow-slave-statements to disable.) ++ --log-slow-verbosity=name ++ Verbosity level for the slow log. Any combination of: ++ innodb, query_plan, explain, engine, warnings, full ++ Use 'ALL' to set all combinations. ++ --log-tc=name Path to transaction coordinator log (used for ++ transactions that affect more than one storage engine, ++ when binary log is disabled). ++ --log-tc-size=# Size of transaction coordinator log. ++ -W, --log-warnings[=#] ++ Log some non critical warnings to the error log.Value can ++ be between 0 and 11. Higher values mean more verbosity ++ --long-query-time=# Alias for log_slow_query_time. Log all queries that have ++ taken more than long_query_time seconds to execute to the ++ slow query log file. The argument will be treated as a ++ decimal value with microsecond precision ++ --low-priority-updates ++ INSERT/DELETE/UPDATE has lower priority than selects ++ --lower-case-table-names[=#] ++ If set to 1 table names are stored in lowercase on disk ++ and table names will be case-insensitive. Should be set ++ to 2 if you are using a case insensitive file system ++ --master-info-file=name ++ The location and name of the file that remembers the ++ master and where the I/O replication thread is in the ++ master's binlogs. Defaults to master.info ++ --master-retry-count=# ++ The number of tries the slave will make to connect to the ++ master before giving up. ++ --master-verify-checksum ++ Force checksum verification of logged events in the ++ binary log before sending them to slaves or printing them ++ in the output of SHOW BINLOG EVENTS ++ --max-allowed-packet=# ++ Max packet length to send to or receive from the server ++ --max-binlog-cache-size=# ++ Sets the total size of the transactional cache ++ --max-binlog-size=# Binary log will be rotated automatically when the size ++ exceeds this value. ++ --max-binlog-stmt-cache-size=# ++ Sets the total size of the statement cache ++ --max-binlog-total-size=# ++ Maximum space to use for all binary logs. Extra logs are ++ deleted on server start, log rotation, FLUSH LOGS or when ++ writing to binlog. Default is 0, which means no size ++ restrictions. See also slave_connections_needed_for_purge ++ --max-connect-errors=# ++ If there is more than this number of interrupted ++ connections from a host this host will be blocked from ++ further connections ++ --max-connections=# The number of simultaneous clients allowed ++ --max-delayed-threads=# ++ Don't start more than this number of threads to handle ++ INSERT DELAYED statements. If set to zero INSERT DELAYED ++ will be not used ++ --max-digest-length=# ++ Maximum length considered for digest text. ++ --max-error-count=# Max number of errors/warnings to store for a statement ++ --max-heap-table-size=# ++ Don't allow creation of heap tables bigger than this ++ --max-join-size=# Joins that are probably going to read more than ++ max_join_size records return an error ++ --max-length-for-sort-data=# ++ Max number of bytes in sorted records ++ --max-password-errors=# ++ If there is more than this number of failed connect ++ attempts due to invalid password, user will be blocked ++ from further connections until FLUSH_PRIVILEGES. ++ --max-prepared-stmt-count=# ++ Maximum number of prepared statements in the server ++ --max-recursive-iterations[=#] ++ Maximum number of iterations when executing recursive ++ queries ++ --max-relay-log-size=# ++ relay log will be rotated automatically when the size ++ exceeds this value. If 0 at startup, it's set to ++ max_binlog_size ++ --max-rowid-filter-size=# ++ The maximum size of the container of a rowid filter ++ --max-seeks-for-key=# ++ Limit assumed max number of seeks when looking up rows ++ based on a key ++ --max-session-mem-used=# ++ Amount of memory a single user session is allowed to ++ allocate. This limits the value of the session variable ++ MEM_USED ++ --max-sort-length=# The number of bytes to use when sorting BLOB or TEXT ++ values (only the first max_sort_length bytes of each ++ value are used; the rest are ignored) ++ --max-sp-recursion-depth[=#] ++ Maximum stored procedure recursion depth ++ --max-statement-time=# ++ A query that has taken more than max_statement_time ++ seconds will be aborted. The argument will be treated as ++ a decimal value with microsecond precision. A value of 0 ++ (default) means no timeout ++ --max-user-connections=# ++ The maximum number of active connections for a single ++ user (0 = no limit) ++ --max-write-lock-count=# ++ After this many write locks, allow some read locks to run ++ in between ++ --memlock Lock mysqld in memory. ++ --metadata-locks-cache-size=# ++ Unused ++ --metadata-locks-hash-instances=# ++ Unused ++ --min-examined-row-limit=# ++ Alias for log_slow_min_examined_row_limit. Don't write ++ queries to slow log that examine fewer rows than that ++ --mrr-buffer-size=# Size of buffer to use when using MRR with range access ++ --myisam-block-size=# ++ Block size to be used for MyISAM index pages ++ --myisam-data-pointer-size=# ++ Default pointer size to be used for MyISAM tables ++ --myisam-max-sort-file-size=# ++ Don't use the fast sort index method to created index if ++ the temporary file would get bigger than this ++ --myisam-mmap-size=# ++ Restricts the total memory used for memory mapping of ++ MySQL tables ++ --myisam-recover-options[=name] ++ Specifies how corrupted tables should be automatically ++ repaired. Any combination of: DEFAULT, BACKUP, FORCE, ++ QUICK, BACKUP_ALL, OFF ++ Use 'ALL' to set all combinations. ++ --myisam-repair-threads=# ++ If larger than 1, when repairing a MyISAM table all ++ indexes will be created in parallel, with one thread per ++ index. The value of 1 disables parallel repair ++ --myisam-sort-buffer-size=# ++ The buffer that is allocated when sorting the index when ++ doing a REPAIR or when creating indexes with CREATE INDEX ++ or ALTER TABLE ++ --myisam-stats-method=name ++ Specifies how MyISAM index statistics collection code ++ should treat NULLs. Possible values of name are ++ NULLS_UNEQUAL (default behavior for 4.1 and later), ++ NULLS_EQUAL (emulate 4.0 behavior), and NULLS_IGNORED ++ --myisam-use-mmap Use memory mapping for reading and writing MyISAM tables ++ --mysql56-temporal-format ++ Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, ++ DATETIME, TIMESTAMP columns. ++ (Defaults to on; use --skip-mysql56-temporal-format to disable.) ++ --net-buffer-length=# ++ Buffer length for TCP/IP and socket communication ++ --net-read-timeout=# ++ Number of seconds to wait for more data from a connection ++ before aborting the read ++ --net-retry-count=# If a read on a communication port is interrupted, retry ++ this many times before giving up ++ --net-write-timeout=# ++ Number of seconds to wait for a block to be written to a ++ connection before aborting the write ++ --note-verbosity=name ++ Verbosity level for note-warnings given to the user. See ++ also @@sql_notes.. Any combination of: basic, ++ unusable_keys, explain ++ Use 'ALL' to set all combinations. ++ --old Use compatible behavior from previous MariaDB version. ++ See also --old-mode ++ --old-mode=name Used to emulate old behavior from earlier MariaDB or ++ MySQL versions. Any combination of: ++ NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO, ++ ZERO_DATE_TIME_CAST, UTF8_IS_UTF8MB3, ++ IGNORE_INDEX_ONLY_FOR_JOIN, COMPAT_5_1_CHECKSUM, ++ NO_NULL_COLLATION_IDS, LOCK_ALTER_TABLE_COPY ++ Use 'ALL' to set all combinations. ++ --old-passwords Use old password encryption method (needed for 4.0 and ++ older clients) ++ --old-style-user-limits ++ Enable old-style user limits (before 5.0.3, user ++ resources were counted per each user+host vs. per ++ account). ++ --open-files-limit=# ++ If this is not 0, then mysqld will use this value to ++ reserve file descriptors to use with setrlimit(). If this ++ value is 0 or autoset then mysqld will reserve ++ max_connections*5 or max_connections + table_cache*2 ++ (whichever is larger) number of file descriptors ++ (Automatically configured unless set explicitly) ++ --optimizer-adjust-secondary-key-costs=# ++ Unused, will be removed. ++ --optimizer-disk-read-cost=# ++ Cost of reading a block of IO_SIZE (4096) from a disk (in ++ usec). ++ --optimizer-disk-read-ratio=# ++ Chance that we have to do a disk read to find a row or ++ index entry from the engine cache ++ (cache_misses/total_cache_requests). 0.0 means that ++ everything is cached and 1.0 means that nothing is ++ expected to be in the engine cache. ++ --optimizer-extra-pruning-depth=# ++ If the optimizer needs to enumerate join prefix of this ++ size or larger, then it will try aggressively prune away ++ the search space. ++ --optimizer-index-block-copy-cost=# ++ Cost of copying a key block from the cache to intern ++ storage as part of an index scan. ++ --optimizer-key-compare-cost=# ++ Cost of checking a key against the end key condition. ++ --optimizer-key-copy-cost=# ++ Cost of finding the next key in the engine and copying it ++ to the SQL layer. ++ --optimizer-key-lookup-cost=# ++ Cost for finding a key based on a key value ++ --optimizer-key-next-find-cost=# ++ Cost of finding the next key and rowid when using ++ filters. ++ --optimizer-max-sel-arg-weight=# ++ The maximum weight of the SEL_ARG graph. Set to 0 for no ++ limit ++ --optimizer-max-sel-args=# ++ The maximum number of SEL_ARG objects created when ++ optimizing a range. If more objects would be needed, the ++ range will not be used by the optimizer. ++ --optimizer-prune-level=# ++ Controls the heuristic(s) applied during query ++ optimization to prune less-promising partial plans from ++ the optimizer search space. Meaning: 0 - do not apply any ++ heuristic, thus perform exhaustive search: 1 - prune ++ plans based on cost and number of retrieved rows eq_ref: ++ 2 - prune also if we find an eq_ref chain ++ --optimizer-row-copy-cost=# ++ Cost of copying a row from the engine or the join cache ++ to the SQL layer. ++ --optimizer-row-lookup-cost=# ++ Cost of finding a row based on a rowid or a clustered ++ key. ++ --optimizer-row-next-find-cost=# ++ Cost of finding the next row when scanning the table. ++ --optimizer-rowid-compare-cost=# ++ Cost of comparing two rowid's ++ --optimizer-rowid-copy-cost=# ++ Cost of copying a rowid ++ --optimizer-scan-setup-cost=# ++ Extra cost added to TABLE and INDEX scans to get ++ optimizer to prefer index lookups. ++ --optimizer-search-depth=# ++ Maximum depth of search performed by the query optimizer. ++ Values larger than the number of relations in a query ++ result in better query plans, but take longer to compile ++ a query. Values smaller than the number of tables in a ++ relation result in faster optimization, but may produce ++ very bad query plans. If set to 0, the system will ++ automatically pick a reasonable value. ++ --optimizer-selectivity-sampling-limit=# ++ Controls number of record samples to check condition ++ selectivity ++ --optimizer-switch=name ++ Fine-tune the optimizer behavior. Takes a comma-separated ++ list of option=value pairs, where value is on, off, or ++ default, and options are: index_merge, index_merge_union, ++ index_merge_sort_union, index_merge_intersection, ++ index_merge_sort_intersection, index_condition_pushdown, ++ derived_merge, derived_with_keys, firstmatch, loosescan, ++ materialization, in_to_exists, semijoin, ++ partial_match_rowid_merge, partial_match_table_scan, ++ subquery_cache, mrr, mrr_cost_based, mrr_sort_keys, ++ outer_join_with_cache, semijoin_with_cache, ++ join_cache_incremental, join_cache_hashed, join_cache_bka, ++ optimize_join_buffer_size, table_elimination, ++ extended_keys, exists_to_in, orderby_uses_equalities, ++ condition_pushdown_for_derived, split_materialized, ++ condition_pushdown_for_subquery, rowid_filter, ++ condition_pushdown_from_having, not_null_range_scan, ++ hash_join_cardinality, cset_narrowing, sargable_casefold ++ --optimizer-trace=name ++ Controls tracing of the Optimizer: ++ optimizer_trace=option=val[,option=val...], where option ++ is one of {enabled} and val is one of {on, off, default} ++ --optimizer-trace-max-mem-size=# ++ Maximum allowed size of an optimizer trace ++ --optimizer-use-condition-selectivity=# ++ Controls selectivity of which conditions the optimizer ++ takes into account to calculate cardinality of a partial ++ join when it searches for the best execution plan ++ Meaning: 1 - use selectivity of index backed range ++ conditions to calculate the cardinality of a partial join ++ if the last joined table is accessed by full table scan ++ or an index scan, 2 - use selectivity of index backed ++ range conditions to calculate the cardinality of a ++ partial join in any case, 3 - additionally always use ++ selectivity of range conditions that are not backed by ++ any index to calculate the cardinality of a partial join, ++ 4 - use histograms to calculate selectivity of range ++ conditions that are not backed by any index to calculate ++ the cardinality of a partial join.5 - additionally use ++ selectivity of certain non-range predicates calculated on ++ record samples ++ --optimizer-where-cost=# ++ Cost of checking the row against the WHERE clause. ++ Increasing this will have the optimizer to prefer plans ++ with less row combinations. ++ --partition[=name] Enable or disable partition plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --performance-schema ++ Enable the performance schema. ++ --performance-schema-accounts-size=# ++ Maximum number of instrumented user@host accounts. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-consumer-events-stages-current ++ Default startup value for the events_stages_current ++ consumer. ++ --performance-schema-consumer-events-stages-history ++ Default startup value for the events_stages_history ++ consumer. ++ --performance-schema-consumer-events-stages-history-long ++ Default startup value for the events_stages_history_long ++ consumer. ++ --performance-schema-consumer-events-statements-current ++ Default startup value for the events_statements_current ++ consumer. ++ --performance-schema-consumer-events-statements-history ++ Default startup value for the events_statements_history ++ consumer. ++ --performance-schema-consumer-events-statements-history-long ++ Default startup value for the ++ events_statements_history_long consumer. ++ --performance-schema-consumer-events-transactions-current ++ Default startup value for the events_transactions_current ++ consumer. ++ --performance-schema-consumer-events-transactions-history ++ Default startup value for the events_transactions_history ++ consumer. ++ --performance-schema-consumer-events-transactions-history-long ++ Default startup value for the ++ events_transactions_history_long consumer. ++ --performance-schema-consumer-events-waits-current ++ Default startup value for the events_waits_current ++ consumer. ++ --performance-schema-consumer-events-waits-history ++ Default startup value for the events_waits_history ++ consumer. ++ --performance-schema-consumer-events-waits-history-long ++ Default startup value for the events_waits_history_long ++ consumer. ++ --performance-schema-consumer-global-instrumentation ++ Default startup value for the global_instrumentation ++ consumer. ++ (Defaults to on; use --skip-performance-schema-consumer-global-instrumentation to disable.) ++ --performance-schema-consumer-statements-digest ++ Default startup value for the statements_digest consumer. ++ (Defaults to on; use --skip-performance-schema-consumer-statements-digest to disable.) ++ --performance-schema-consumer-thread-instrumentation ++ Default startup value for the thread_instrumentation ++ consumer. ++ (Defaults to on; use --skip-performance-schema-consumer-thread-instrumentation to disable.) ++ --performance-schema-digests-size=# ++ Size of the statement digest. Use 0 to disable, -1 for ++ automated sizing. ++ --performance-schema-events-stages-history-long-size=# ++ Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-events-stages-history-size=# ++ Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-events-statements-history-long-size=# ++ Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-events-statements-history-size=# ++ Number of rows per thread in EVENTS_STATEMENTS_HISTORY. ++ Use 0 to disable, -1 for automated sizing. ++ --performance-schema-events-transactions-history-long-size=# ++ Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-events-transactions-history-size=# ++ Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. ++ Use 0 to disable, -1 for automated sizing. ++ --performance-schema-events-waits-history-long-size=# ++ Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-events-waits-history-size=# ++ Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-hosts-size=# ++ Maximum number of instrumented hosts. Use 0 to disable, ++ -1 for automated sizing. ++ --performance-schema-instrument[=name] ++ Default startup value for a performance schema ++ instrument. ++ --performance-schema-max-cond-classes=# ++ Maximum number of condition instruments. ++ --performance-schema-max-cond-instances=# ++ Maximum number of instrumented condition objects. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-max-digest-length=# ++ Maximum length considered for digest text, when stored in ++ performance_schema tables. ++ --performance-schema-max-file-classes=# ++ Maximum number of file instruments. ++ --performance-schema-max-file-handles=# ++ Maximum number of opened instrumented files. ++ --performance-schema-max-file-instances=# ++ Maximum number of instrumented files. Use 0 to disable, ++ -1 for automated sizing. ++ --performance-schema-max-index-stat=# ++ Maximum number of index statistics for instrumented ++ tables. Use 0 to disable, -1 for automated scaling. ++ --performance-schema-max-memory-classes=# ++ Maximum number of memory pool instruments. ++ --performance-schema-max-metadata-locks=# ++ Maximum number of metadata locks. Use 0 to disable, -1 ++ for automated scaling. ++ --performance-schema-max-mutex-classes=# ++ Maximum number of mutex instruments. ++ --performance-schema-max-mutex-instances=# ++ Maximum number of instrumented MUTEX objects. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-max-prepared-statements-instances=# ++ Maximum number of instrumented prepared statements. Use 0 ++ to disable, -1 for automated scaling. ++ --performance-schema-max-program-instances=# ++ Maximum number of instrumented programs. Use 0 to ++ disable, -1 for automated scaling. ++ --performance-schema-max-rwlock-classes=# ++ Maximum number of rwlock instruments. ++ --performance-schema-max-rwlock-instances=# ++ Maximum number of instrumented RWLOCK objects. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-max-socket-classes=# ++ Maximum number of socket instruments. ++ --performance-schema-max-socket-instances=# ++ Maximum number of opened instrumented sockets. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-max-sql-text-length=# ++ Maximum length of displayed sql text. ++ --performance-schema-max-stage-classes=# ++ Maximum number of stage instruments. ++ --performance-schema-max-statement-classes=# ++ Maximum number of statement instruments. ++ --performance-schema-max-statement-stack=# ++ Number of rows per thread in EVENTS_STATEMENTS_CURRENT. ++ --performance-schema-max-table-handles=# ++ Maximum number of opened instrumented tables. Use 0 to ++ disable, -1 for automated sizing. ++ --performance-schema-max-table-instances=# ++ Maximum number of instrumented tables. Use 0 to disable, ++ -1 for automated sizing. ++ --performance-schema-max-table-lock-stat=# ++ Maximum number of lock statistics for instrumented ++ tables. Use 0 to disable, -1 for automated scaling. ++ --performance-schema-max-thread-classes=# ++ Maximum number of thread instruments. ++ --performance-schema-max-thread-instances=# ++ Maximum number of instrumented threads. Use 0 to disable, ++ -1 for automated sizing. ++ --performance-schema-session-connect-attrs-size=# ++ Size of session attribute string buffer per thread. Use 0 ++ to disable, -1 for automated sizing. ++ --performance-schema-setup-actors-size=# ++ Maximum number of rows in SETUP_ACTORS. ++ --performance-schema-setup-objects-size=# ++ Maximum number of rows in SETUP_OBJECTS. ++ --performance-schema-users-size=# ++ Maximum number of instrumented users. Use 0 to disable, ++ -1 for automated sizing. ++ --pid-file=name Pid file used by safe_mysqld ++ --plugin-dir=name Directory for plugins ++ --plugin-load=name Semicolon-separated list of plugins to load, where each ++ plugin is specified as ether a plugin_name=library_file ++ pair or only a library_file. If the latter case, all ++ plugins from a given library_file will be loaded. ++ --plugin-load-add=name ++ Optional semicolon-separated list of plugins to load. ++ This option adds to the list specified by --plugin-load ++ in an incremental way. It can be specified many times, ++ adding more plugins every time. ++ --plugin-maturity=name ++ The lowest desirable plugin maturity. Plugins less mature ++ than that will not be installed or loaded. One of: ++ unknown, experimental, alpha, beta, gamma, stable ++ -P, --port=# Port number to use for connection or 0 to default to, ++ my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default ++ (3306), whatever comes first ++ --port-open-timeout=# ++ Maximum time in seconds to wait for the port to become ++ free. (Default: No wait). ++ --preload-buffer-size=# ++ The size of the buffer that is allocated when preloading ++ indexes ++ --profiling-history-size=# ++ Number of statements about which profiling information is ++ maintained. If set to 0, no profiles are stored. See SHOW ++ PROFILES. ++ --progress-report-time=# ++ Seconds between sending progress reports to the client ++ for time-consuming statements. Set to 0 to disable ++ progress reporting. ++ --proxy-protocol-networks=name ++ Enable proxy protocol for these source networks. The ++ syntax is a comma separated list of IPv4 and IPv6 ++ networks. If the network doesn't contain mask, it is ++ considered to be a single host. "*" represents all ++ networks and must the only directive on the line. String ++ "localhost" represents non-TCP local connections (Unix ++ domain socket, Windows named pipe or shared memory). ++ --query-alloc-block-size=# ++ Allocation block size for query parsing and execution ++ --query-cache-limit=# ++ Don't cache results that are bigger than this ++ --query-cache-min-res-unit=# ++ The minimum size for blocks allocated by the query cache ++ --query-cache-size=# ++ The memory allocated to store results from old queries ++ --query-cache-strip-comments ++ Strip all comments from a query before storing it in the ++ query cache ++ --query-cache-type=name ++ OFF = Don't cache or retrieve results. ON = Cache all ++ results except SELECT SQL_NO_CACHE ... queries. DEMAND = ++ Cache only SELECT SQL_CACHE ... queries ++ --query-cache-wlock-invalidate ++ Invalidate queries in query cache on LOCK for write ++ --query-prealloc-size=# ++ Persistent buffer for query parsing and execution ++ --range-alloc-block-size=# ++ Allocation block size for storing ranges during ++ optimization ++ --read-binlog-speed-limit=# ++ Maximum speed(KB/s) to read binlog from master (0 = no ++ limit) ++ --read-buffer-size=# ++ Each thread that does a sequential scan allocates a ++ buffer of this size for each table it scans. If you do ++ many sequential scans, you may want to increase this ++ value ++ --read-only Make all non-temporary tables read-only, with the ++ exception for replication (slave) threads and users with ++ the 'READ ONLY ADMIN' privilege ++ --read-rnd-buffer-size=# ++ When reading rows in sorted order after a sort, the rows ++ are read through this buffer to avoid a disk seeks ++ --redirect-url=name URL of another server to redirect clients to. Empty ++ string means no redirection ++ --relay-log=name The location and name to use for relay logs. ++ --relay-log-index=name ++ The location and name to use for the file that keeps a ++ list of the last relay logs ++ --relay-log-info-file=name ++ The location and name of the file that remembers where ++ the SQL replication thread is in the relay logs. ++ --relay-log-purge if disabled - do not purge relay logs. if enabled - purge ++ them as soon as they are no more needed. ++ (Defaults to on; use --skip-relay-log-purge to disable.) ++ --relay-log-recovery ++ Enables automatic relay log recovery right after the ++ database startup, which means that the IO Thread starts ++ re-fetching from the master right after the last ++ transaction processed. ++ --relay-log-space-limit=# ++ Maximum space to use for all relay logs ++ --replicate-annotate-row-events ++ Tells the slave to write annotate rows events received ++ from the master to its own binary log. Ignored if ++ log_slave_updates is not set ++ (Defaults to on; use --skip-replicate-annotate-row-events to disable.) ++ --replicate-do-db=name ++ Tells the slave thread to restrict replication to the ++ specified database. To specify more than one database, ++ use the directive multiple times, once for each database. ++ Note that this will only work if you do not use ++ cross-database queries such as UPDATE some_db.some_table ++ SET foo='bar' while having selected a different or no ++ database. If you need cross database updates to work, ++ make sure you have 3.23.28 or later, and use ++ replicate-wild-do-table=db_name.%. ++ --replicate-do-table=name ++ Tells the slave thread to restrict replication to the ++ specified table. To specify more than one table, use the ++ directive multiple times, once for each table. This will ++ work for cross-database updates, in contrast to ++ replicate-do-db. ++ --replicate-events-marked-for-skip=name ++ Whether the slave should replicate events that were ++ created with @@skip_replication=1 on the master. Default ++ REPLICATE (no events are skipped). Other values are ++ FILTER_ON_SLAVE (events will be sent by the master but ++ ignored by the slave) and FILTER_ON_MASTER (events marked ++ with @@skip_replication=1 will be filtered on the master ++ and never be sent to the slave). ++ --replicate-ignore-db=name ++ Tells the slave thread to not replicate to the specified ++ database. To specify more than one database to ignore, ++ use the directive multiple times, once for each database. ++ This option will not work if you use cross database ++ updates. If you need cross database updates to work, make ++ sure you have 3.23.28 or later, and use ++ replicate-wild-ignore-table=db_name.%. ++ --replicate-ignore-table=name ++ Tells the slave thread to not replicate to the specified ++ table. To specify more than one table to ignore, use the ++ directive multiple times, once for each table. This will ++ work for cross-database updates, in contrast to ++ replicate-ignore-db. ++ --replicate-rewrite-db=name ++ Updates to a database with a different name than the ++ original. Example: ++ replicate-rewrite-db=master_db_name->slave_db_name. ++ --replicate-same-server-id ++ In replication, if set to 1, do not skip events having ++ our server id. Default value is 0 (to break infinite ++ loops in circular replication). Can't be set to 1 if ++ --log-slave-updates is used. ++ --replicate-wild-do-table=name ++ Tells the slave thread to restrict replication to the ++ tables that match the specified wildcard pattern. To ++ specify more than one table, use the directive multiple ++ times, once for each table. This will work for ++ cross-database updates. Example: ++ replicate-wild-do-table=foo%.bar% will replicate only ++ updates to tables in all databases that start with foo ++ and whose table names start with bar. ++ --replicate-wild-ignore-table=name ++ Tells the slave thread to not replicate to the tables ++ that match the given wildcard pattern. To specify more ++ than one table to ignore, use the directive multiple ++ times, once for each table. This will work for ++ cross-database updates. Example: ++ replicate-wild-ignore-table=foo%.bar% will not do updates ++ to tables in databases that start with foo and whose ++ table names start with bar. ++ --report-host=name Hostname or IP of the slave to be reported to the master ++ during slave registration. Will appear in the output of ++ SHOW SLAVE HOSTS. Leave unset if you do not want the ++ slave to register itself with the master. Note that it is ++ not sufficient for the master to simply read the IP of ++ the slave off the socket once the slave connects. Due to ++ NAT and other routing issues, that IP may not be valid ++ for connecting to the slave from the master or other ++ hosts ++ --report-password=name ++ The account password of the slave to be reported to the ++ master during slave registration ++ --report-port=# Port for connecting to slave reported to the master ++ during slave registration. Set it only if the slave is ++ listening on a non-default port or if you have a special ++ tunnel from the master or other clients to the slave. If ++ not sure, leave this option unset ++ --report-user=name The account user name of the slave to be reported to the ++ master during slave registration ++ --require-secure-transport ++ When this option is enabled, connections attempted using ++ insecure transport will be rejected. Secure transports ++ are SSL/TLS, Unix sockets or named pipes. ++ --rowid-merge-buff-size=# ++ The size of the buffers used [NOT] IN evaluation via ++ partial matching ++ --rpl-semi-sync-master-enabled ++ Enable semi-synchronous replication master (disabled by ++ default). ++ --rpl-semi-sync-master-timeout=# ++ The timeout value (in ms) for semi-synchronous ++ replication in the master ++ --rpl-semi-sync-master-trace-level=# ++ The tracing level for semi-sync replication. ++ --rpl-semi-sync-master-wait-no-slave ++ Wait until timeout when no semi-synchronous replication ++ slave is available. ++ (Defaults to on; use --skip-rpl-semi-sync-master-wait-no-slave to disable.) ++ --rpl-semi-sync-master-wait-point=name ++ Should transaction wait for semi-sync ack after having ++ synced binlog, or after having committed in storage ++ engine.. One of: AFTER_SYNC, AFTER_COMMIT ++ --rpl-semi-sync-slave-delay-master ++ Only write master info file when ack is needed. ++ --rpl-semi-sync-slave-enabled ++ Enable semi-synchronous replication slave (disabled by ++ default). ++ --rpl-semi-sync-slave-kill-conn-timeout[=#] ++ Timeout for the mysql connection used to kill the slave ++ io_thread's connection on master. This timeout comes into ++ play when stop slave is executed. ++ --rpl-semi-sync-slave-trace-level=# ++ The tracing level for semi-sync replication. ++ --safe-mode Skip some optimize stages (for testing). Deprecated. ++ --safe-user-create Don't allow new user creation by the user who has no ++ write privileges to the mysql.user table. ++ --secure-auth Disallow authentication for accounts that have old ++ (pre-4.1) passwords ++ (Defaults to on; use --skip-secure-auth to disable.) ++ --secure-file-priv=name ++ Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to ++ files within specified directory ++ --secure-timestamp=name ++ Restricts direct setting of a session timestamp. Possible ++ levels are: YES - timestamp cannot deviate from the ++ system clock, REPLICATION - replication thread can adjust ++ timestamp to match the master's, SUPER - a user with this ++ privilege and a replication thread can adjust timestamp, ++ NO - historical behavior, anyone can modify session ++ timestamp ++ --sequence[=name] Enable or disable SEQUENCE plugin. One of: ON, OFF, FORCE ++ (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --server-id=# Uniquely identifies the server instance in the community ++ of replication partners ++ --session-track-schema ++ Track changes to the default schema. ++ (Defaults to on; use --skip-session-track-schema to disable.) ++ --session-track-state-change ++ Track changes to the session state. ++ --session-track-system-variables=name ++ Track changes in registered system variables. ++ --session-track-transaction-info=name ++ Track changes to the transaction attributes. OFF to ++ disable; STATE to track just transaction state (Is there ++ an active transaction? Does it have any data? etc.); ++ CHARACTERISTICS to track transaction state and report all ++ statements needed to start a transaction with the same ++ characteristics (isolation level, read only/read ++ write,snapshot - but not any work done / data modified ++ within the transaction). ++ --show-slave-auth-info ++ Show user and password in SHOW SLAVE HOSTS on this ++ master. ++ --silent-startup Don't print [Note] to the error log during startup. ++ --skip-grant-tables Start without grant tables. This gives all users FULL ++ ACCESS to all tables. ++ --skip-host-cache Don't cache host names. ++ --skip-name-resolve Don't resolve hostnames. All hostnames are IP's or ++ 'localhost'. ++ --skip-networking Don't allow connection with TCP/IP ++ --skip-show-database ++ Don't allow 'SHOW DATABASE' commands ++ --skip-slave-start If set, slave is not autostarted. ++ --slave-compressed-protocol ++ Use compression on master/slave protocol ++ --slave-connections-needed-for-purge=# ++ Minimum number of connected slaves required for automatic ++ binary log purge with max_binlog_total_size, ++ binlog_expire_logs_seconds or binlog_expire_logs_days. ++ --slave-ddl-exec-mode=name ++ How replication events should be executed. Legal values ++ are STRICT and IDEMPOTENT (default). In IDEMPOTENT mode, ++ replication will not stop for DDL operations that are ++ idempotent. This means that CREATE TABLE is treated as ++ CREATE TABLE OR REPLACE and DROP TABLE is treated as DROP ++ TABLE IF EXISTS. ++ --slave-domain-parallel-threads=# ++ Maximum number of parallel threads to use on slave for ++ events in a single replication domain. When using ++ multiple domains, this can be used to limit a single ++ domain from grabbing all threads and thus stalling other ++ domains. The default of 0 means to allow a domain to grab ++ as many threads as it wants, up to the value of ++ slave_parallel_threads. ++ --slave-exec-mode=name ++ How replication events should be executed. Legal values ++ are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, ++ replication will not stop for operations that are ++ idempotent. For example, in row based replication ++ attempts to delete rows that doesn't exist will be ++ ignored. In STRICT mode, replication will stop on any ++ unexpected difference between the master and the slave. ++ --slave-load-tmpdir=name ++ The location where the slave should put its temporary ++ files when replicating a LOAD DATA INFILE command ++ --slave-max-allowed-packet=# ++ The maximum packet length to sent successfully from the ++ master to slave. ++ --slave-max-statement-time=# ++ A query that has taken more than slave_max_statement_time ++ seconds to run on the slave will be aborted. The argument ++ will be treated as a decimal value with microsecond ++ precision. A value of 0 (default) means no timeout ++ --slave-net-timeout=# ++ Number of seconds to wait for more data from any ++ master/slave connection before aborting the read ++ --slave-parallel-max-queued=# ++ Limit on how much memory SQL threads should use per ++ parallel replication thread when reading ahead in the ++ relay log looking for opportunities for parallel ++ replication. Only used when --slave-parallel-threads > 0. ++ --slave-parallel-mode=name ++ Controls what transactions are applied in parallel when ++ using --slave-parallel-threads. Possible values: ++ "optimistic" tries to apply most transactional DML in ++ parallel, and handles any conflicts with rollback and ++ retry. "conservative" limits parallelism in an effort to ++ avoid any conflicts. "aggressive" tries to maximise the ++ parallelism, possibly at the cost of increased conflict ++ rate. "minimal" only parallelizes the commit steps of ++ transactions. "none" disables parallel apply completely. ++ --slave-parallel-threads=# ++ If non-zero, number of threads to spawn to apply in ++ parallel events on the slave that were group-committed on ++ the master or were logged with GTID in different ++ replication domains. Note that these threads are in ++ addition to the IO and SQL threads, which are always ++ created by a replication slave ++ --slave-parallel-workers=# ++ Alias for slave_parallel_threads ++ --slave-run-triggers-for-rbr=name ++ Modes for how triggers in row-base replication on slave ++ side will be executed. Legal values are NO (default), ++ YES, LOGGING and ENFORCE. NO means that trigger for RBR ++ will not be running on slave. YES and LOGGING means that ++ triggers will be running on slave, if there was not ++ triggers running on the master for the statement. LOGGING ++ also means results of that the executed triggers work ++ will be written to the binlog. ENFORCE means that ++ triggers will always be run on the slave, even if there ++ are triggers on the master. ENFORCE implies LOGGING. ++ --slave-skip-errors=name ++ Tells the slave thread to continue replication when a ++ query event returns an error from the provided list ++ --slave-sql-verify-checksum ++ Force checksum verification of replication events after ++ reading them from relay log. Note: Events are always ++ checksum-verified by slave on receiving them from the ++ network before writing them to the relay log ++ (Defaults to on; use --skip-slave-sql-verify-checksum to disable.) ++ --slave-transaction-retries=# ++ Number of times the slave SQL thread will retry a ++ transaction in case it failed with a deadlock, elapsed ++ lock wait timeout or listed in ++ slave_transaction_retry_errors, before giving up and ++ stopping ++ --slave-transaction-retry-errors=name ++ Tells the slave thread to retry transaction for ++ replication when a query event returns an error from the ++ provided list. Deadlock error, elapsed lock wait timeout, ++ net read error, net read timeout, net write error, net ++ write timeout, connect error and 2 types of lost ++ connection error are automatically added to this list ++ --slave-transaction-retry-interval=# ++ Interval of the slave SQL thread will retry a transaction ++ in case it failed with a deadlock or elapsed lock wait ++ timeout or listed in slave_transaction_retry_errors ++ --slave-type-conversions=name ++ Set of slave type conversions that are enabled. If the ++ variable is empty, no conversions are allowed and it is ++ expected that the types match exactly. Any combination ++ of: ALL_LOSSY, ALL_NON_LOSSY ++ Use 'ALL' to set all combinations. ++ --slow-launch-time=# ++ If creating the thread takes longer than this value (in ++ seconds), the Slow_launch_threads counter will be ++ incremented ++ --slow-query-log Alias for log_slow_query. Log slow queries to a table or ++ log file. Defaults logging to a file 'hostname'-slow.log ++ or a table mysql.slow_log if --log-output=TABLE is used. ++ Must be enabled to activate other slow log options. ++ --slow-query-log-file=name ++ Alias for log_slow_query_file. Log slow queries to given ++ log file. Defaults logging to 'hostname'-slow.log. Must ++ be enabled to activate other slow log options ++ --socket=name Socket file to use for connection ++ --sort-buffer-size=# ++ Each thread that needs to do a sort allocates a buffer of ++ this size ++ --sql-mode=name Sets the sql mode. Any combination of: REAL_AS_FLOAT, ++ PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ++ IGNORE_BAD_TABLE_OPTIONS, ONLY_FULL_GROUP_BY, ++ NO_UNSIGNED_SUBTRACTION, NO_DIR_IN_CREATE, POSTGRESQL, ++ ORACLE, MSSQL, DB2, MAXDB, NO_KEY_OPTIONS, ++ NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, MYSQL323, MYSQL40, ++ ANSI, NO_AUTO_VALUE_ON_ZERO, NO_BACKSLASH_ESCAPES, ++ STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, ++ NO_ZERO_DATE, ALLOW_INVALID_DATES, ++ ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL, ++ NO_AUTO_CREATE_USER, HIGH_NOT_PRECEDENCE, ++ NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH, ++ EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT, ++ TIME_ROUND_FRACTIONAL ++ Use 'ALL' to set all combinations. ++ --sql-safe-updates If set to 1, UPDATEs and DELETEs need either a key in the ++ WHERE clause, or a LIMIT clause, or else they will ++ aborted. Prevents the common mistake of accidentally ++ deleting or updating every row in a table. ++ --ssl Enable SSL for connection (automatically enabled if an ++ ssl option is used). ++ (Defaults to on; use --skip-ssl to disable.) ++ --ssl-ca=name CA file in PEM format (check OpenSSL docs, implies --ssl) ++ --ssl-capath=name CA directory (check OpenSSL docs, implies --ssl) ++ --ssl-cert=name X509 cert in PEM format (implies --ssl) ++ --ssl-cipher=name SSL cipher to use (implies --ssl) ++ --ssl-crl=name CRL file in PEM format (check OpenSSL docs, implies ++ --ssl) ++ --ssl-crlpath=name CRL directory (check OpenSSL docs, implies --ssl) ++ --ssl-key=name X509 key in PEM format (implies --ssl) ++ --stack-trace Print a symbolic stack trace on failure ++ (Defaults to on; use --skip-stack-trace to disable.) ++ --standard-compliant-cte ++ Allow only CTEs compliant to SQL standard ++ (Defaults to on; use --skip-standard-compliant-cte to disable.) ++ --stored-program-cache=# ++ The soft upper limit for number of cached stored routines ++ for one connection. ++ --strict-password-validation ++ When password validation plugins are enabled, reject ++ passwords that cannot be validated (passwords specified ++ as a hash) ++ (Defaults to on; use --skip-strict-password-validation to disable.) ++ -s, --symbolic-links ++ Enable symbolic link support. ++ (Defaults to on; use --skip-symbolic-links to disable.) ++ --sync-binlog=# Synchronously flush binary log to disk after every #th ++ event. Use 0 (default) to disable synchronous flushing ++ --sync-frm Sync .frm files to disk on creation ++ (Defaults to on; use --skip-sync-frm to disable.) ++ --sync-master-info=# ++ Synchronously flush master info to disk after every #th ++ event. Use 0 to disable synchronous flushing ++ --sync-relay-log=# Synchronously flush relay log to disk after every #th ++ event. Use 0 to disable synchronous flushing ++ --sync-relay-log-info=# ++ Synchronously flush relay log info to disk after every ++ #th transaction. Use 0 to disable synchronous flushing ++ --sysdate-is-now Non-default option to alias SYSDATE() to NOW() to make it ++ safe-replicable. Since 5.0, SYSDATE() returns a `dynamic' ++ value different for different invocations, even within ++ the same statement. ++ --system-versioning-alter-history=name ++ Versioning ALTER TABLE mode. ERROR: Fail ALTER with ++ error; KEEP: Keep historical system rows and subject them ++ to ALTER ++ --system-versioning-insert-history ++ Allows direct inserts into ROW_START and ROW_END columns ++ if secure_timestamp allows changing @@timestamp ++ --table-cache=# Deprecated; use --table-open-cache instead. ++ --table-definition-cache=# ++ The number of cached table definitions ++ --table-open-cache=# ++ The number of cached open tables ++ --table-open-cache-instances=# ++ Maximum number of table cache instances ++ --tc-heuristic-recover=name ++ Decision to use in heuristic recover process. One of: OFF, ++ COMMIT, ROLLBACK ++ --tcp-keepalive-interval=# ++ The interval, in seconds, between when successive ++ keep-alive packets are sent if no acknowledgement is ++ received.If set to 0, system dependent default is used. ++ (Automatically configured unless set explicitly) ++ --tcp-keepalive-probes=# ++ The number of unacknowledged probes to send before ++ considering the connection dead and notifying the ++ application layer.If set to 0, system dependent default ++ is used. (Automatically configured unless set explicitly) ++ --tcp-keepalive-time=# ++ Timeout, in seconds, with no activity until the first TCP ++ keep-alive packet is sent.If set to 0, system dependent ++ default is used. (Automatically configured unless set ++ explicitly) ++ --tcp-nodelay Set option TCP_NODELAY (disable Nagle's algorithm) on ++ socket ++ (Defaults to on; use --skip-tcp-nodelay to disable.) ++ --temp-pool Using this option will cause most temporary files created ++ to use a small set of names, rather than a unique name ++ for each new file. Deprecated. ++ --thread-cache-size=# ++ How many threads we should keep in a cache for reuse. ++ These are freed after 5 minutes of idle time ++ --thread-handling=name ++ Define threads usage for handling queries. One of: ++ one-thread-per-connection, no-threads, pool-of-threads ++ --thread-pool-dedicated-listener ++ If set to 1,listener thread will not pick up queries ++ --thread-pool-exact-stats ++ If set to 1, provides better statistics in ++ information_schema threadpool tables ++ --thread-pool-groups[=name] ++ Enable or disable THREAD_POOL_GROUPS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --thread-pool-idle-timeout=# ++ Timeout in seconds for an idle thread in the thread ++ pool.Worker thread will be shut down after timeout ++ --thread-pool-max-threads=# ++ Maximum allowed number of worker threads in the thread ++ pool ++ --thread-pool-oversubscribe=# ++ How many additional active worker threads in a group are ++ allowed. ++ --thread-pool-prio-kickup-timer=# ++ The number of milliseconds before a dequeued low-priority ++ statement is moved to the high-priority queue ++ --thread-pool-priority=name ++ Threadpool priority. High priority connections usually ++ start executing earlier than low priority.If priority set ++ to 'auto', the the actual priority(low or high) is ++ determined based on whether or not connection is inside ++ transaction. ++ --thread-pool-queues[=name] ++ Enable or disable THREAD_POOL_QUEUES plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --thread-pool-size=# ++ Number of thread groups in the pool. This parameter is ++ roughly equivalent to maximum number of concurrently ++ executing threads (threads in a waiting state do not ++ count as executing). ++ --thread-pool-stall-limit=# ++ Maximum query execution time in milliseconds,before an ++ executing non-yielding thread is considered stalled.If a ++ worker thread is stalled, additional worker thread may be ++ created to handle remaining clients. ++ --thread-pool-stats[=name] ++ Enable or disable THREAD_POOL_STATS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --thread-pool-waits[=name] ++ Enable or disable THREAD_POOL_WAITS plugin. One of: ON, ++ OFF, FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --thread-stack=# The stack size for each thread ++ --tls-version=name TLS protocol version for secure connections.. Any ++ combination of: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3 ++ Use 'ALL' to set all combinations. ++ --tmp-disk-table-size=# ++ Max size for data for an internal temporary on-disk ++ MyISAM or Aria table. ++ --tmp-memory-table-size=# ++ If an internal in-memory temporary table exceeds this ++ size, MariaDB will automatically convert it to an on-disk ++ MyISAM or Aria table. Same as tmp_table_size. ++ --tmp-table-size=# Alias for tmp_memory_table_size. If an internal in-memory ++ temporary table exceeds this size, MariaDB will ++ automatically convert it to an on-disk MyISAM or Aria ++ table. ++ -t, --tmpdir=name Path for temporary files. Several paths may be specified, ++ separated by a colon (:), in this case they are used in a ++ round-robin fashion ++ --transaction-alloc-block-size=# ++ Allocation block size for transactions to be stored in ++ binary log ++ --transaction-isolation=name ++ Default transaction isolation level. One of: ++ READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, ++ SERIALIZABLE ++ --transaction-prealloc-size=# ++ Persistent buffer for transactions to be stored in binary ++ log ++ --transaction-read-only ++ Default transaction access mode. True if transactions are ++ read-only. ++ --unix-socket[=name] ++ Enable or disable unix_socket plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --updatable-views-with-limit=name ++ YES = Don't issue an error message (warning only) if a ++ VIEW without presence of a key of the underlying table is ++ used in queries with a LIMIT clause for updating. NO = ++ Prohibit update of a VIEW, which does not contain a key ++ of the underlying table and the query uses a LIMIT clause ++ (usually get from GUI tools) ++ --use-stat-tables=name ++ Specifies how to use system statistics tables. One of: ++ NEVER, COMPLEMENTARY, PREFERABLY, ++ COMPLEMENTARY_FOR_QUERIES, PREFERABLY_FOR_QUERIES ++ -u, --user=name Run mysqld daemon as user. ++ --user-variables[=name] ++ Enable or disable user_variables plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --userstat Enables statistics gathering for USER_STATISTICS, ++ CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS ++ tables in the INFORMATION_SCHEMA ++ -v, --verbose Used with --help option for detailed help. ++ -V, --version[=name] ++ Output version information and exit. ++ --wait-timeout=# The number of seconds the server waits for activity on a ++ connection before closing it ++ --wsrep-OSU-method[=name] ++ Method for Online Schema Upgrade. One of: TOI, RSU ++ --wsrep-SR-store=name ++ Storage for streaming replication fragments. One of: none, ++ table ++ --wsrep-allowlist=name ++ Allowed IP addresses split by comma delimiter ++ --wsrep-auto-increment-control ++ To automatically control the assignment of autoincrement ++ variables ++ (Defaults to on; use --skip-wsrep-auto-increment-control to disable.) ++ --wsrep-certification-rules=name ++ Certification rules to use in the cluster. Possible ++ values are: "strict": stricter rules that could result in ++ more certification failures. "optimized": relaxed rules ++ that allow more concurrency and cause less certification ++ failures. ++ --wsrep-certify-nonPK ++ Certify tables with no primary key ++ (Defaults to on; use --skip-wsrep-certify-nonPK to disable.) ++ --wsrep-cluster-address=name ++ Address to initially connect to cluster ++ --wsrep-cluster-name=name ++ Name for the cluster ++ --wsrep-convert-LOCK-to-trx ++ To convert locking sessions into transactions ++ --wsrep-data-home-dir=name ++ home directory for wsrep provider ++ --wsrep-dbug-option=name ++ DBUG options to provider library ++ --wsrep-debug=name WSREP debug level logging. One of: NONE, SERVER, ++ TRANSACTION, STREAMING, CLIENT ++ --wsrep-desync To desynchronize the node from the cluster ++ --wsrep-dirty-reads Allow reads even when the node is not in the primary ++ component. ++ --wsrep-drupal-282555-workaround ++ Enable a workaround to handle the cases where inserting a ++ DEFAULT value into an auto-increment column could fail ++ with duplicate key error ++ --wsrep-forced-binlog-format=name ++ binlog format to take effect over user's choice. One of: ++ MIXED, STATEMENT, ROW, NONE ++ --wsrep-gtid-domain-id=# ++ When wsrep_gtid_mode is set, this value is used as ++ gtid_domain_id for galera transactions and also copied to ++ the joiner nodes during state transfer. It is ignored, ++ otherwise. ++ --wsrep-gtid-mode Automatically update the (joiner) node's ++ wsrep_gtid_domain_id value with that of donor's (received ++ during state transfer) and use it in place of ++ gtid_domain_id for all galera transactions. When OFF ++ (default), wsrep_gtid_domain_id is simply ignored ++ (backward compatibility). ++ --wsrep-ignore-apply-errors=# ++ Ignore replication errors ++ --wsrep-load-data-splitting ++ To commit LOAD DATA transaction after every 10K rows ++ inserted (deprecated) ++ --wsrep-log-conflicts ++ To log multi-master conflicts ++ --wsrep-max-ws-rows=# ++ Max number of rows in write set ++ --wsrep-max-ws-size=# ++ Max write set size (bytes) ++ --wsrep-mode=name Set of WSREP features that are enabled.. Any combination ++ of: STRICT_REPLICATION, BINLOG_ROW_FORMAT_ONLY, ++ REQUIRED_PRIMARY_KEY, REPLICATE_MYISAM, REPLICATE_ARIA, ++ DISALLOW_LOCAL_GTID, BF_ABORT_MARIABACKUP ++ Use 'ALL' to set all combinations. ++ --wsrep-mysql-replication-bundle=# ++ mysql replication group commit ++ --wsrep-new-cluster Bootstrap a cluster. It works by overriding the current ++ value of wsrep_cluster_address. It is recommended not to ++ add this option to the config file as this will trigger ++ bootstrap on every server start. ++ --wsrep-node-address=name ++ Specifies the node's network address, in the format ip ++ address[:port]. Used in situations where autoguessing is ++ not reliable. As of MariaDB 10.1.8, supports IPv6. ++ --wsrep-node-incoming-address=name ++ Client connection address ++ --wsrep-node-name=name ++ Name of this node. This name can be used in ++ wsrep_sst_donor as a preferred donor. Note that multiple ++ nodes in a cluster can have the same name. ++ --wsrep-notify-cmd=name ++ --wsrep-on To enable wsrep replication ++ --wsrep-provider=name ++ Path to replication provider library ++ --wsrep-provider[=name] ++ Enable or disable wsrep_provider plugin. One of: ON, OFF, ++ FORCE (don't start if the plugin fails to load), ++ FORCE_PLUS_PERMANENT (like FORCE, but the plugin can not ++ be uninstalled). ++ --wsrep-provider-options=name ++ Semicolon (;) separated list of wsrep options (see ++ wsrep_provider_options documentation). ++ --wsrep-recover Recover database state after crash and exit ++ --wsrep-reject-queries[=name] ++ Variable to set to reject queries. One of: NONE, ALL, ++ ALL_KILL ++ --wsrep-restart-slave ++ Should MariaDB slave be restarted automatically, when ++ node joins back to cluster ++ --wsrep-retry-autocommit=# ++ Max number of times to retry a failed autocommit ++ statement ++ --wsrep-slave-FK-checks ++ Should slave thread do foreign key constraint checks ++ (Defaults to on; use --skip-wsrep-slave-FK-checks to disable.) ++ --wsrep-slave-UK-checks ++ Should slave thread do secondary index uniqueness checks ++ --wsrep-slave-threads=# ++ Number of slave appliers to launch ++ --wsrep-sst-auth=name ++ Authentication for SST connection ++ --wsrep-sst-donor=name ++ preferred donor node for the SST ++ --wsrep-sst-donor-rejects-queries ++ Reject client queries when donating state snapshot ++ transfer ++ --wsrep-sst-method=name ++ State snapshot transfer method ++ --wsrep-sst-receive-address=name ++ Address where node is waiting for SST contact ++ --wsrep-start-position=name ++ global transaction position to start from ++ --wsrep-status-file=name ++ wsrep status output filename ++ --wsrep-sync-wait[=#] ++ Ensure "synchronous" read view before executing an ++ operation of the type specified by bitmask: 1 - ++ READ(includes SELECT, SHOW and BEGIN/START TRANSACTION); ++ 2 - UPDATE and DELETE; 4 - INSERT and REPLACE ++ --wsrep-trx-fragment-size=# ++ Size of transaction fragments for streaming replication ++ (measured in units of 'wsrep_trx_fragment_unit') ++ --wsrep-trx-fragment-unit=name ++ Unit for streaming replication transaction fragments' ++ size: bytes, rows, statements ++ ++Variables (--variable-name=value) ++and boolean options {FALSE|TRUE} Value (after reading options) ++------------------------------------------------------------ ------------- ++allow-suspicious-udfs FALSE ++alter-algorithm DEFAULT ++analyze-sample-percentage 100 ++aria-block-size 8192 ++aria-checkpoint-interval 0 ++aria-checkpoint-log-activity 1048576 ++aria-encrypt-tables FALSE ++aria-force-start-after-recovery-failures 0 ++aria-group-commit none ++aria-group-commit-interval 0 ++aria-log-dir-path /var/lib/mysql/ ++aria-log-file-size 1073741824 ++aria-log-purge-type immediate ++aria-max-sort-file-size 9223372036853727232 ++aria-page-checksum TRUE ++aria-pagecache-age-threshold 300 ++aria-pagecache-buffer-size 134217728 ++aria-pagecache-division-limit 100 ++aria-pagecache-file-hash-size 512 ++aria-recover-options ++aria-repair-threads 1 ++aria-sort-buffer-size 268434432 ++aria-stats-method nulls_unequal ++aria-sync-log-dir NEWFILE ++auto-increment-increment 1 ++auto-increment-offset 1 ++autocommit TRUE ++automatic-sp-privileges TRUE ++back-log 80 ++basedir /usr ++big-tables FALSE ++bind-address 127.0.0.1 ++binlog-alter-two-phase FALSE ++binlog-annotate-row-events TRUE ++binlog-cache-size 32768 ++binlog-checksum CRC32 ++binlog-commit-wait-count 0 ++binlog-commit-wait-usec 100000 ++binlog-direct-non-transactional-updates FALSE ++binlog-expire-logs-seconds 864000 ++binlog-file-cache-size 16384 ++binlog-format MIXED ++binlog-gtid-index TRUE ++binlog-gtid-index-page-size 4096 ++binlog-gtid-index-span-min 65536 ++binlog-legacy-event-pos FALSE ++binlog-optimize-thread-scheduling TRUE ++binlog-row-event-max-size 8192 ++binlog-row-image FULL ++binlog-row-metadata NO_LOG ++binlog-space-limit 0 ++binlog-stmt-cache-size 32768 ++block-encryption-mode aes-128-ecb ++bulk-insert-buffer-size 8388608 ++character-set-client-handshake TRUE ++character-set-collations utf8mb4=uca1400_ai_ci ++character-set-filesystem binary ++character-set-server utf8mb4 ++character-sets-dir /usr/share/mariadb/charsets/ ++chroot (No default value) ++collation-server utf8mb4_general_ci ++column-compression-threshold 100 ++column-compression-zlib-level 6 ++column-compression-zlib-strategy DEFAULT_STRATEGY ++column-compression-zlib-wrap FALSE ++completion-type NO_CHAIN ++concurrent-insert AUTO ++connect-timeout 10 ++console FALSE ++core-file FALSE ++datadir /var/lib/mysql/ ++deadlock-search-depth-long 15 ++deadlock-search-depth-short 4 ++deadlock-timeout-long 50000000 ++deadlock-timeout-short 10000 ++debug ++debug-abort-slave-event-count 0 ++debug-disconnect-slave-event-count 0 ++debug-gdb FALSE ++debug-max-binlog-dump-events 0 ++debug-no-sync FALSE ++debug-sporadic-binlog-dump-fail FALSE ++default-password-lifetime 0 ++default-regex-flags ++default-storage-engine InnoDB ++default-time-zone (No default value) ++default-tmp-storage-engine (No default value) ++default-week-format 0 ++delay-key-write ON ++delayed-insert-limit 100 ++delayed-insert-timeout 300 ++delayed-queue-size 1000 ++des-key-file (No default value) ++disconnect-on-expired-password FALSE ++div-precision-increment 4 ++encrypt-binlog FALSE ++encrypt-tmp-disk-tables FALSE ++encrypt-tmp-files FALSE ++enforce-storage-engine (No default value) ++eq-range-index-dive-limit 200 ++event-scheduler OFF ++expensive-subquery-limit 100 ++expire-logs-days 10 ++explicit-defaults-for-timestamp TRUE ++external-locking FALSE ++extra-max-connections 1 ++extra-port 0 ++feedback ON ++feedback-http-proxy (No default value) ++feedback-send-retry-wait 60 ++feedback-send-timeout 60 ++feedback-url https://feedback.mariadb.org/rest/v1/post ++feedback-user-info ++flashback FALSE ++flush FALSE ++flush-time 0 ++ft-boolean-syntax + -><()~*:""&| ++ft-max-word-len 84 ++ft-min-word-len 4 ++ft-query-expansion-limit 20 ++ft-stopword-file (No default value) ++gdb FALSE ++general-log FALSE ++general-log-file HOSTNAME.log ++getopt-prefix-matching TRUE ++group-concat-max-len 1048576 ++gtid-cleanup-batch-size 64 ++gtid-domain-id 0 ++gtid-ignore-duplicates FALSE ++gtid-pos-auto-engines ++gtid-strict-mode FALSE ++help TRUE ++histogram-size 254 ++histogram-type JSON_HB ++host-cache-size 279 ++idle-readonly-transaction-timeout 0 ++idle-transaction-timeout 0 ++idle-write-transaction-timeout 0 ++ignore-builtin-innodb FALSE ++ignore-db-dirs ++in-predicate-conversion-threshold 1000 ++init-connect ++init-file (No default value) ++init-rpl-role MASTER ++init-slave ++innodb ON ++innodb-adaptive-flushing TRUE ++innodb-adaptive-flushing-lwm 10 ++innodb-adaptive-hash-index FALSE ++innodb-adaptive-hash-index-parts 8 ++innodb-autoextend-increment 64 ++innodb-autoinc-lock-mode 1 ++innodb-buf-dump-status-frequency 0 ++innodb-buffer-page ON ++innodb-buffer-page-lru ON ++innodb-buffer-pool-chunk-size 0 ++innodb-buffer-pool-dump-at-shutdown TRUE ++innodb-buffer-pool-dump-now FALSE ++innodb-buffer-pool-dump-pct 25 ++innodb-buffer-pool-filename ib_buffer_pool ++innodb-buffer-pool-load-abort FALSE ++innodb-buffer-pool-load-at-startup TRUE ++innodb-buffer-pool-load-now FALSE ++innodb-buffer-pool-size 134217728 ++innodb-buffer-pool-stats ON ++innodb-checksum-algorithm full_crc32 ++innodb-cmp ON ++innodb-cmp-per-index ON ++innodb-cmp-per-index-enabled FALSE ++innodb-cmp-per-index-reset ON ++innodb-cmp-reset ON ++innodb-cmpmem ON ++innodb-cmpmem-reset ON ++innodb-compression-algorithm zlib ++innodb-compression-default FALSE ++innodb-compression-failure-threshold-pct 5 ++innodb-compression-level 6 ++innodb-compression-pad-pct-max 50 ++innodb-data-file-buffering FALSE ++innodb-data-file-path ibdata1:12M:autoextend ++innodb-data-file-write-through FALSE ++innodb-data-home-dir (No default value) ++innodb-deadlock-detect TRUE ++innodb-deadlock-report full ++innodb-default-encryption-key-id 1 ++innodb-default-row-format dynamic ++innodb-disable-sort-file-cache FALSE ++innodb-doublewrite ON ++innodb-encrypt-log FALSE ++innodb-encrypt-tables OFF ++innodb-encrypt-temporary-tables FALSE ++innodb-encryption-rotate-key-age 1 ++innodb-encryption-rotation-iops 100 ++innodb-encryption-threads 0 ++innodb-fast-shutdown 1 ++innodb-fatal-semaphore-wait-threshold 600 ++innodb-file-per-table TRUE ++innodb-fill-factor 100 ++innodb-flush-log-at-timeout 1 ++innodb-flush-log-at-trx-commit 1 ++innodb-flush-method O_DIRECT ++innodb-flush-neighbors 1 ++innodb-flush-sync TRUE ++innodb-flushing-avg-loops 30 ++innodb-force-primary-key FALSE ++innodb-force-recovery 0 ++innodb-ft-aux-table (No default value) ++innodb-ft-being-deleted ON ++innodb-ft-cache-size 8000000 ++innodb-ft-config ON ++innodb-ft-default-stopword ON ++innodb-ft-deleted ON ++innodb-ft-enable-diag-print FALSE ++innodb-ft-enable-stopword TRUE ++innodb-ft-index-cache ON ++innodb-ft-index-table ON ++innodb-ft-max-token-size 84 ++innodb-ft-min-token-size 3 ++innodb-ft-num-word-optimize 2000 ++innodb-ft-result-cache-limit 2000000000 ++innodb-ft-server-stopword-table (No default value) ++innodb-ft-sort-pll-degree 2 ++innodb-ft-total-cache-size 640000000 ++innodb-ft-user-stopword-table (No default value) ++innodb-immediate-scrub-data-uncompressed FALSE ++innodb-instant-alter-column-allowed add_drop_reorder ++innodb-io-capacity 200 ++innodb-io-capacity-max 18446744073709551615 ++innodb-lock-wait-timeout 50 ++innodb-lock-waits ON ++innodb-locks ON ++innodb-log-buffer-size 16777216 ++innodb-log-file-buffering FALSE ++innodb-log-file-size 100663296 ++innodb-log-file-write-through FALSE ++innodb-log-group-home-dir (No default value) ++innodb-log-spin-wait-delay 0 ++innodb-lru-flush-size 32 ++innodb-lru-scan-depth 1536 ++innodb-max-dirty-pages-pct 90 ++innodb-max-dirty-pages-pct-lwm 0 ++innodb-max-purge-lag 0 ++innodb-max-purge-lag-delay 0 ++innodb-max-purge-lag-wait 4294967295 ++innodb-max-undo-log-size 10485760 ++innodb-metrics ON ++innodb-monitor-disable (No default value) ++innodb-monitor-enable (No default value) ++innodb-monitor-reset (No default value) ++innodb-monitor-reset-all (No default value) ++innodb-numa-interleave FALSE ++innodb-old-blocks-pct 37 ++innodb-old-blocks-time 1000 ++innodb-online-alter-log-max-size 134217728 ++innodb-open-files 0 ++innodb-optimize-fulltext-only FALSE ++innodb-page-size 16384 ++innodb-prefix-index-cluster-optimization TRUE ++innodb-print-all-deadlocks FALSE ++innodb-purge-batch-size 1000 ++innodb-purge-rseg-truncate-frequency 128 ++innodb-purge-threads 4 ++innodb-random-read-ahead FALSE ++innodb-read-ahead-threshold 56 ++innodb-read-io-threads 4 ++innodb-read-only FALSE ++innodb-read-only-compressed FALSE ++innodb-rollback-on-timeout FALSE ++innodb-snapshot-isolation FALSE ++innodb-sort-buffer-size 1048576 ++innodb-spin-wait-delay 4 ++innodb-stats-auto-recalc TRUE ++innodb-stats-include-delete-marked FALSE ++innodb-stats-method nulls_equal ++innodb-stats-modified-counter 0 ++innodb-stats-on-metadata FALSE ++innodb-stats-persistent TRUE ++innodb-stats-persistent-sample-pages 20 ++innodb-stats-traditional TRUE ++innodb-stats-transient-sample-pages 8 ++innodb-status-file FALSE ++innodb-status-output FALSE ++innodb-status-output-locks FALSE ++innodb-strict-mode TRUE ++innodb-sync-spin-loops 30 ++innodb-sys-columns ON ++innodb-sys-fields ON ++innodb-sys-foreign ON ++innodb-sys-foreign-cols ON ++innodb-sys-indexes ON ++innodb-sys-tables ON ++innodb-sys-tablespaces ON ++innodb-sys-tablestats ON ++innodb-sys-virtual ON ++innodb-table-locks TRUE ++innodb-tablespaces-encryption ON ++innodb-temp-data-file-path ibtmp1:12M:autoextend ++innodb-tmpdir (No default value) ++innodb-truncate-temporary-tablespace-now FALSE ++innodb-trx ON ++innodb-undo-directory (No default value) ++innodb-undo-log-truncate FALSE ++innodb-undo-tablespaces 3 ++innodb-use-atomic-writes TRUE ++innodb-use-native-aio TRUE ++innodb-write-io-threads 4 ++interactive-timeout 28800 ++join-buffer-size 262144 ++join-buffer-space-limit 2097152 ++join-cache-level 2 ++keep-files-on-create FALSE ++key-buffer-size 134217728 ++key-cache-age-threshold 300 ++key-cache-block-size 1024 ++key-cache-division-limit 100 ++key-cache-file-hash-size 512 ++key-cache-segments 0 ++large-files-support TRUE ++large-pages FALSE ++lc-messages en_US ++lc-messages-dir (No default value) ++lc-time-names en_US ++local-infile TRUE ++lock-wait-timeout 86400 ++log-basename HOSTNAME ++log-bin (No default value) ++log-bin-compress FALSE ++log-bin-compress-min-len 256 ++log-bin-index (No default value) ++log-bin-trust-function-creators FALSE ++log-ddl-recovery ddl_recovery.log ++log-disabled-statements sp ++log-error ++log-isam myisam.log ++log-output FILE ++log-queries-not-using-indexes FALSE ++log-short-format FALSE ++log-slave-updates FALSE ++log-slow-admin-statements TRUE ++log-slow-disabled-statements sp ++log-slow-filter admin,filesort,filesort_on_disk,filesort_priority_queue,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk ++log-slow-max-warnings 10 ++log-slow-min-examined-row-limit 0 ++log-slow-query FALSE ++log-slow-query-file HOSTNAME-slow.log ++log-slow-query-time 10 ++log-slow-rate-limit 1 ++log-slow-slave-statements TRUE ++log-slow-verbosity ++log-tc tc.log ++log-tc-size 24576 ++log-warnings 2 ++long-query-time 10 ++low-priority-updates FALSE ++lower-case-file-system FALSE ++lower-case-table-names 0 ++master-info-file master.info ++master-retry-count 100000 ++master-verify-checksum FALSE ++max-allowed-packet 16777216 ++max-binlog-cache-size 18446744073709547520 ++max-binlog-size 1073741824 ++max-binlog-stmt-cache-size 18446744073709547520 ++max-binlog-total-size 0 ++max-connect-errors 100 ++max-connections 151 ++max-delayed-threads 20 ++max-digest-length 1024 ++max-error-count 64 ++max-heap-table-size 16777216 ++max-join-size 18446744073709551615 ++max-length-for-sort-data 1024 ++max-password-errors 4294967295 ++max-prepared-stmt-count 16382 ++max-recursive-iterations 1000 ++max-relay-log-size 1073741824 ++max-rowid-filter-size 131072 ++max-seeks-for-key 4294967295 ++max-session-mem-used 9223372036854775807 ++max-sort-length 1024 ++max-sp-recursion-depth 0 ++max-statement-time 0 ++max-user-connections 0 ++max-write-lock-count 4294967295 ++memlock FALSE ++metadata-locks-cache-size 1024 ++metadata-locks-hash-instances 8 ++min-examined-row-limit 0 ++mrr-buffer-size 262144 ++myisam-block-size 1024 ++myisam-data-pointer-size 6 ++myisam-max-sort-file-size 18446744073709551615 ++myisam-mmap-size 9223372036853727232 ++myisam-recover-options BACKUP,QUICK ++myisam-repair-threads 1 ++myisam-sort-buffer-size 134216704 ++myisam-stats-method NULLS_UNEQUAL ++myisam-use-mmap FALSE ++mysql56-temporal-format TRUE ++net-buffer-length 16384 ++net-read-timeout 30 ++net-retry-count 10 ++net-write-timeout 60 ++note-verbosity basic,explain ++old FALSE ++old-mode UTF8_IS_UTF8MB3 ++old-passwords FALSE ++old-style-user-limits FALSE ++open-files-limit 32000 ++optimizer-adjust-secondary-key-costs 0 ++optimizer-disk-read-cost 10.24 ++optimizer-disk-read-ratio 0.02 ++optimizer-extra-pruning-depth 8 ++optimizer-index-block-copy-cost 0.0356 ++optimizer-key-compare-cost 0.011361 ++optimizer-key-copy-cost 0.015685 ++optimizer-key-lookup-cost 0.435777 ++optimizer-key-next-find-cost 0.082347 ++optimizer-max-sel-arg-weight 32000 ++optimizer-max-sel-args 16000 ++optimizer-prune-level 2 ++optimizer-row-copy-cost 0.060866 ++optimizer-row-lookup-cost 0.130839 ++optimizer-row-next-find-cost 0.045916 ++optimizer-rowid-compare-cost 0.002653 ++optimizer-rowid-copy-cost 0.002653 ++optimizer-scan-setup-cost 10 ++optimizer-search-depth 62 ++optimizer-selectivity-sampling-limit 100 ++optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on ++optimizer-trace ++optimizer-trace-max-mem-size 1048576 ++optimizer-use-condition-selectivity 4 ++optimizer-where-cost 0.032 ++partition ON ++performance-schema FALSE ++performance-schema-accounts-size -1 ++performance-schema-consumer-events-stages-current FALSE ++performance-schema-consumer-events-stages-history FALSE ++performance-schema-consumer-events-stages-history-long FALSE ++performance-schema-consumer-events-statements-current FALSE ++performance-schema-consumer-events-statements-history FALSE ++performance-schema-consumer-events-statements-history-long FALSE ++performance-schema-consumer-events-transactions-current FALSE ++performance-schema-consumer-events-transactions-history FALSE ++performance-schema-consumer-events-transactions-history-long FALSE ++performance-schema-consumer-events-waits-current FALSE ++performance-schema-consumer-events-waits-history FALSE ++performance-schema-consumer-events-waits-history-long FALSE ++performance-schema-consumer-global-instrumentation TRUE ++performance-schema-consumer-statements-digest TRUE ++performance-schema-consumer-thread-instrumentation TRUE ++performance-schema-digests-size -1 ++performance-schema-events-stages-history-long-size -1 ++performance-schema-events-stages-history-size -1 ++performance-schema-events-statements-history-long-size -1 ++performance-schema-events-statements-history-size -1 ++performance-schema-events-transactions-history-long-size -1 ++performance-schema-events-transactions-history-size -1 ++performance-schema-events-waits-history-long-size -1 ++performance-schema-events-waits-history-size -1 ++performance-schema-hosts-size -1 ++performance-schema-instrument ++performance-schema-max-cond-classes 90 ++performance-schema-max-cond-instances -1 ++performance-schema-max-digest-length 1024 ++performance-schema-max-file-classes 80 ++performance-schema-max-file-handles 32768 ++performance-schema-max-file-instances -1 ++performance-schema-max-index-stat -1 ++performance-schema-max-memory-classes 320 ++performance-schema-max-metadata-locks -1 ++performance-schema-max-mutex-classes 210 ++performance-schema-max-mutex-instances -1 ++performance-schema-max-prepared-statements-instances -1 ++performance-schema-max-program-instances -1 ++performance-schema-max-rwlock-classes 50 ++performance-schema-max-rwlock-instances -1 ++performance-schema-max-socket-classes 10 ++performance-schema-max-socket-instances -1 ++performance-schema-max-sql-text-length 1024 ++performance-schema-max-stage-classes 160 ++performance-schema-max-statement-classes 222 ++performance-schema-max-statement-stack 10 ++performance-schema-max-table-handles -1 ++performance-schema-max-table-instances -1 ++performance-schema-max-table-lock-stat -1 ++performance-schema-max-thread-classes 50 ++performance-schema-max-thread-instances -1 ++performance-schema-session-connect-attrs-size -1 ++performance-schema-setup-actors-size -1 ++performance-schema-setup-objects-size -1 ++performance-schema-users-size -1 ++pid-file /run/mysqld/mysqld.pid ++plugin-dir /usr/lib/mysql/plugin/ ++plugin-maturity gamma ++port 3306 ++port-open-timeout 0 ++preload-buffer-size 32768 ++profiling-history-size 15 ++progress-report-time 5 ++protocol-version 10 ++proxy-protocol-networks ++query-alloc-block-size 16384 ++query-cache-limit 1048576 ++query-cache-min-res-unit 4096 ++query-cache-size 1048576 ++query-cache-strip-comments FALSE ++query-cache-type OFF ++query-cache-wlock-invalidate FALSE ++query-prealloc-size 24576 ++range-alloc-block-size 4096 ++read-binlog-speed-limit 0 ++read-buffer-size 131072 ++read-only FALSE ++read-rnd-buffer-size 262144 ++redirect-url ++relay-log (No default value) ++relay-log-index (No default value) ++relay-log-info-file relay-log.info ++relay-log-purge TRUE ++relay-log-recovery FALSE ++relay-log-space-limit 0 ++replicate-annotate-row-events TRUE ++replicate-events-marked-for-skip REPLICATE ++replicate-same-server-id FALSE ++report-host (No default value) ++report-password (No default value) ++report-port 0 ++report-user (No default value) ++require-secure-transport FALSE ++rowid-merge-buff-size 8388608 ++rpl-semi-sync-master-enabled FALSE ++rpl-semi-sync-master-timeout 10000 ++rpl-semi-sync-master-trace-level 32 ++rpl-semi-sync-master-wait-no-slave TRUE ++rpl-semi-sync-master-wait-point AFTER_COMMIT ++rpl-semi-sync-slave-delay-master FALSE ++rpl-semi-sync-slave-enabled FALSE ++rpl-semi-sync-slave-kill-conn-timeout 5 ++rpl-semi-sync-slave-trace-level 32 ++safe-user-create FALSE ++secure-auth TRUE ++secure-file-priv (No default value) ++secure-timestamp NO ++sequence ON ++server-id 1 ++session-track-schema TRUE ++session-track-state-change FALSE ++session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone ++session-track-transaction-info OFF ++show-slave-auth-info FALSE ++silent-startup FALSE ++skip-grant-tables FALSE ++skip-name-resolve FALSE ++skip-networking FALSE ++skip-show-database FALSE ++skip-slave-start FALSE ++slave-compressed-protocol FALSE ++slave-connections-needed-for-purge 1 ++slave-ddl-exec-mode IDEMPOTENT ++slave-domain-parallel-threads 0 ++slave-exec-mode STRICT ++slave-load-tmpdir /tmp ++slave-max-allowed-packet 1073741824 ++slave-max-statement-time 0 ++slave-net-timeout 60 ++slave-parallel-max-queued 131072 ++slave-parallel-mode conservative ++slave-parallel-threads 0 ++slave-parallel-workers 0 ++slave-run-triggers-for-rbr NO ++slave-skip-errors OFF ++slave-sql-verify-checksum TRUE ++slave-transaction-retries 10 ++slave-transaction-retry-errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701 ++slave-transaction-retry-interval 0 ++slave-type-conversions ++slow-launch-time 2 ++slow-query-log FALSE ++slow-query-log-file HOSTNAME-slow.log ++socket /run/mysqld/mysqld.sock ++sort-buffer-size 2097152 ++sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION ++sql-safe-updates FALSE ++ssl TRUE ++ssl-ca (No default value) ++ssl-capath (No default value) ++ssl-cert (No default value) ++ssl-cipher (No default value) ++ssl-crl (No default value) ++ssl-crlpath (No default value) ++ssl-key (No default value) ++stack-trace TRUE ++standard-compliant-cte TRUE ++stored-program-cache 256 ++strict-password-validation TRUE ++symbolic-links TRUE ++sync-binlog 0 ++sync-frm TRUE ++sync-master-info 10000 ++sync-relay-log 10000 ++sync-relay-log-info 10000 ++sysdate-is-now FALSE ++system-time-zone UTC ++system-versioning-alter-history ERROR ++system-versioning-insert-history FALSE ++table-cache 2000 ++table-definition-cache 400 ++table-open-cache 2000 ++table-open-cache-instances 8 ++tc-heuristic-recover OFF ++tcp-keepalive-interval 0 ++tcp-keepalive-probes 0 ++tcp-keepalive-time 0 ++tcp-nodelay TRUE ++temp-pool FALSE ++thread-cache-size 151 ++thread-handling one-thread-per-connection ++thread-pool-dedicated-listener FALSE ++thread-pool-exact-stats FALSE ++thread-pool-groups ON ++thread-pool-idle-timeout 60 ++thread-pool-max-threads 65536 ++thread-pool-oversubscribe 3 ++thread-pool-prio-kickup-timer 1000 ++thread-pool-priority auto ++thread-pool-queues ON ++thread-pool-size 2 ++thread-pool-stall-limit 500 ++thread-pool-stats ON ++thread-pool-waits ON ++thread-stack 299008 ++tls-version TLSv1.2,TLSv1.3 ++tmp-disk-table-size 18446744073709551615 ++tmp-memory-table-size 16777216 ++tmp-table-size 16777216 ++tmpdir /tmp ++transaction-alloc-block-size 8192 ++transaction-isolation REPEATABLE-READ ++transaction-prealloc-size 4096 ++transaction-read-only FALSE ++unix-socket ON ++updatable-views-with-limit YES ++use-stat-tables PREFERABLY_FOR_QUERIES ++user-variables ON ++userstat FALSE ++verbose TRUE ++version VERSION ++version-comment Debian RELEASE ++version-compile-machine ARCH ++version-compile-os debian-linux-gnu ++version-malloc-library system ++version-source-revision - ++version-ssl-library SSL-VERSION ++wait-timeout 28800 ++wsrep-OSU-method TOI ++wsrep-SR-store table ++wsrep-allowlist ++wsrep-auto-increment-control TRUE ++wsrep-certification-rules strict ++wsrep-certify-nonPK TRUE ++wsrep-cluster-address ++wsrep-cluster-name my_wsrep_cluster ++wsrep-convert-LOCK-to-trx FALSE ++wsrep-data-home-dir /var/lib/mysql/ ++wsrep-dbug-option ++wsrep-debug NONE ++wsrep-desync FALSE ++wsrep-dirty-reads FALSE ++wsrep-drupal-282555-workaround FALSE ++wsrep-forced-binlog-format NONE ++wsrep-gtid-domain-id 0 ++wsrep-gtid-mode FALSE ++wsrep-ignore-apply-errors 7 ++wsrep-load-data-splitting FALSE ++wsrep-log-conflicts FALSE ++wsrep-max-ws-rows 0 ++wsrep-max-ws-size 2147483647 ++wsrep-mode ++wsrep-mysql-replication-bundle 0 ++wsrep-new-cluster FALSE ++wsrep-node-address ++wsrep-node-incoming-address AUTO ++wsrep-node-name HOSTNAME ++wsrep-notify-cmd ++wsrep-on FALSE ++wsrep-patch-version wsrep_26.22 ++wsrep-provider none ++wsrep-provider ON ++wsrep-provider-options ++wsrep-recover FALSE ++wsrep-reject-queries NONE ++wsrep-restart-slave FALSE ++wsrep-retry-autocommit 1 ++wsrep-slave-FK-checks TRUE ++wsrep-slave-UK-checks FALSE ++wsrep-slave-threads 1 ++wsrep-sst-auth (No default value) ++wsrep-sst-donor ++wsrep-sst-donor-rejects-queries FALSE ++wsrep-sst-method rsync ++wsrep-sst-receive-address AUTO ++wsrep-start-position 00000000-0000-0000-0000-000000000000:-1 ++wsrep-status-file ++wsrep-sync-wait 0 ++wsrep-trx-fragment-size 0 ++wsrep-trx-fragment-unit bytes ++ ++To see what variables a running server is using, type ++'SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES' instead of 'mysqld --verbose --help' or 'mariadbd --verbose --help'. diff --cc debian/tests/upstream index dc55c74ad,000000000..5c39949a3 mode 100644,000000..100644 --- a/debian/tests/upstream +++ b/debian/tests/upstream @@@ -1,71 -1,0 +1,66 @@@ +#!/bin/sh +# autopkgtest check: Build and run the upstream test suite. +# (C) 2012 Canonical Ltd. +# Author: Daniel Kessel + +# running the mysql testsuite as described in: +# https://bugs.launchpad.net/ubuntu/+source/mysql-5.5/+bug/959683 + +echo "Running test 'testsuite'" +set -e + - SKIP_TEST_LST="/tmp/skip-test.lst" ++MTR_SKIP_TEST_LIST=$(mktemp) +ARCH=$(dpkg --print-architecture) + +WORKDIR=$(mktemp -d) - trap 'rm -rf $WORKDIR $SKIP_TEST_LST' 0 INT QUIT ABRT PIPE TERM ++trap 'rm -rf $WORKDIR $MTR_SKIP_TEST_LIST' 0 INT QUIT ABRT PIPE TERM +cd "$WORKDIR" + +mkdir var +mkdir tmp + +echo "using vardir: $WORKDIR/var" +echo "using tmpdir: $WORKDIR/tmp" + +echo "Setting up skip-tests-list" + - # Use unstable-tests list as base to skip all tests considered unstable - # or create an empty file if that upstream file does not exists on this branch - cp /usr/share/mariadb/mariadb-test/unstable-tests $SKIP_TEST_LST || touch $SKIP_TEST_LST - - # Also use the arch specific skiplists if exist - if [ -f /usr/share/mariadb/mariadb-test/unstable-tests.$ARCH ] ++# Use the arch specific skiplists if exist, otherwise list is empty ++if [ -f "/usr/share/mariadb/mariadb-test/unstable-tests.$ARCH" ] +then - cat /usr/share/mariadb/mariadb-test/unstable-tests.$ARCH >> $SKIP_TEST_LST ++ cat "/usr/share/mariadb/mariadb-test/unstable-tests.$ARCH" >> "$MTR_SKIP_TEST_LIST" +fi + +# Skip tests that cannot run properly on ci.debian.net / autopkgtests.ubuntu.com - cat >> $SKIP_TEST_LST << EOF ++cat >> "$MTR_SKIP_TEST_LIST" << EOF +binlog.binlog_server_start_options : Requires writable /usr +main.ctype_uca : Requires writable /usr +rpl.rpl_gtid_mode : Requires starting server as root ref http://bugs.mysql.com/bug.php?id=70517 +EOF + +# Skip tests that cannot run properly on Gitlab-CI - if [ ! -z "$GITLAB_CI" ] ++if [ -n "$GITLAB_CI" ] +then - cat >> $SKIP_TEST_LST << EOF ++ cat >> "$MTR_SKIP_TEST_LIST" << EOF +main.mysqld--help : For unknown reason table-cache is 4000 instead of default 421 +EOF +fi + - if [ "$ARCH" = "s390x" ] - then - echo "main.func_regexp_pcre : recursion fails on s390x https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1723947" >> $SKIP_TEST_LST - elif [ "$ARCH" = "armhf" ] || [ "$ARCH" = "i386" ] - then - echo "main.failed_auth_unixsocket : Test returns wrong exit code on armhf and i386 (but only in debci) https://jira.mariadb.org/browse/MDEV-23933" >> $SKIP_TEST_LST - fi - +# Store skipped test list in artifacts so it can be viewed while debugging +# failed autopkgtest runs - cp -v $SKIP_TEST_LST $AUTOPKGTEST_ARTIFACTS ++cp -v "$MTR_SKIP_TEST_LIST" "$AUTOPKGTEST_ARTIFACTS" + +cd /usr/share/mariadb/mariadb-test - echo "starting mariadb-test-run.pl..." - eatmydata perl -I. ./mariadb-test-run.pl --suite=main \ ++echo "starting mysql-test-tun.pl..." ++export MTR_PRINT_CORE=detailed ++# The $MTR_ARGUMENTS_APPEND is intentionally used to pass in extra arguments ++# shellcheck disable=SC2086 ++eatmydata perl -I. ./mysql-test-run.pl \ ++ --force --testcase-timeout=120 --suite-timeout=540 --retry=3 \ ++ --verbose-restart --max-save-core=1 --max-save-datadir=1 \ ++ --parallel=auto --skip-rpl --suite=main \ ++ --skip-test-list="$MTR_SKIP_TEST_LIST" \ + --vardir="$WORKDIR/var" --tmpdir="$WORKDIR/tmp" \ - --parallel=auto --skip-rpl \ - --force --skip-test-list=$SKIP_TEST_LST \ - --xml-report=$AUTOPKGTEST_ARTIFACTS/mysql-test-run-junit.xml $@ 2>&1 ++ --xml-report="$AUTOPKGTEST_ARTIFACTS/mysql-test-run-junit.xml" \ ++ $MTR_ARGUMENTS_APPEND \ ++ "$@" 2>&1 +echo "run: OK" diff --cc debian/unstable-tests.alpha index 000000000,000000000..722ed455e new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.alpha @@@ -1,0 -1,0 +1,2 @@@ ++main.alter_table_mdev539_maria : MDEV-23922 ++repair_symlink-5543 : MDEV-23920 diff --cc debian/unstable-tests.amd64 index 000000000,000000000..d28f1eb16 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.amd64 @@@ -1,0 -1,0 +1,3 @@@ ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.arm64 index 000000000,000000000..b6230a86e new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.arm64 @@@ -1,0 -1,0 +1,4 @@@ ++binlog.flashback-largebinlog : MDEV-32352 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.armel index 000000000,000000000..88d06b441 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.armel @@@ -1,0 -1,0 +1,5 @@@ ++main.partition_key_cache : MDEV-23427 ++main.table_value_constr : MDEV-33520 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.armhf index 000000000,000000000..11bf83371 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.armhf @@@ -1,0 -1,0 +1,21 @@@ ++# MDEV-33381: The full test suite (including --big-test) has numerous failures ++# on armhf and a Raspberry Pi enthusiast is needed to debug them ++federated.federatedx_versioning : MDEV-33381 ++index_intersect_innodb : MDEV-23921 ++main.index_intersect : MDEV-23921 ++main.join_cache_notasan : MDEV-34084 ++main.table_value_constr : MDEV-33520 ++main.xml : MDEV-21968 ++maria.maria-purge : MDEV-31349 ++mariabackup.encrypted_page_corruption : Not reported upstream yet ++period.versioning : MDEV-33381 ++spider.basic_sql : MDEV-33381 ++spider.spider_fixes_part : MDEV-33381 ++spider/bg.basic_sql : MDEV-33381 ++spider/bg.spider_fixes_part : MDEV-33381 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 ++versioning.autoinc : MDEV-33381 ++versioning.online : MDEV-33381 ++versioning.partition : MDEV-33381 ++versioning.trx_id : MDEV-33381 diff --cc debian/unstable-tests.hppa index 000000000,000000000..d273b15eb new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.hppa @@@ -1,0 -1,0 +1,19 @@@ ++index_intersect_innodb : MDEV-23921 ++main.analyze_engine_stats : MDEV-32375 ++main.analyze_stmt_orderby : MDEV-32375 ++main.analyze_stmt_slow_query_log : MDEV-12237 ++main.cte_recursive : MDEV-32375 ++main.derived_split_innodb : MDEV-32375 ++main.explain_json_format_partitions : MDEV-32375 ++main.func_json_notembedded : MDEV-27955 / MDEV-30518 / https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1006529 (timeout) ++main.index_intersect : MDEV-23921 ++main.index_intersect : MDEV-23921 ++main.index_intersect_innodb : MDEV-23921 ++main.join_cache_notasan : MDEV-31893 (fixed but perhaps not for hppa) ++main.join_cache_notasan : MDEV-34084 ++main.rowid_filter_innodb : MDEV-32375 ++main.table_value_constr : MDEV-33520 ++maria.maria-purge : MDEV-31349 ++repair_symlink-5543 : MDEV-23920 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.hurd index 000000000,000000000..dbc096bee new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.hurd @@@ -1,0 -1,0 +1,1 @@@ ++# MDEV-8535: auth_socket does not build on hurd-i368 diff --cc debian/unstable-tests.hurd-i386 index 000000000,000000000..32dbff60e new file mode 120000 --- /dev/null +++ b/debian/unstable-tests.hurd-i386 @@@ -1,0 -1,0 +1,1 @@@ ++unstable-tests.hurd diff --cc debian/unstable-tests.m68k index 000000000,000000000..1d55cfdbf new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.m68k @@@ -1,0 -1,0 +1,3 @@@ ++# The m68k build on Debian runs in a qemu builder and has ++# DEB_BUILD_OPTIONS="nobench nocheck" defined, so *all* tests are skipped ++# intentionally (Bug#972057) diff --cc debian/unstable-tests.powerpc index 000000000,000000000..4438338f9 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.powerpc @@@ -1,0 -1,0 +1,5 @@@ ++main.func_json_notembedded : MDEV-30518 / MDEV-27955 ++main.table_value_constr : MDEV-33520 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.ppc64 index 000000000,000000000..a78b633ee new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.ppc64 @@@ -1,0 -1,0 +1,6 @@@ ++main.func_json_notembedded : MDEV-30518 / MDEV-27955 ++main.index_merge_innodb : MDEV-30728 ++main.mysql_upgrade : https://bugs.debian.org/1053486 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.ppc64el index 000000000,000000000..2bf1d6994 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.ppc64el @@@ -1,0 -1,0 +1,6 @@@ ++main.index_merge_innodb : MDEV-30728 ++main.innodb_ext_key : MDEV-30728 ++maria.maria-purge : MDEV-31349 ++spider.spider_fixes_part : MDEV-30929 - sporadic, not just ppc64el ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.riscv64 index 000000000,000000000..1cdbf93d3 new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.riscv64 @@@ -1,0 -1,0 +1,4 @@@ ++maria.maria-purge : MDEV-31349 ++rpl.parallel_backup_slave_binlog_off : MDEV-30676 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.s390x index 000000000,000000000..0090e77cd new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.s390x @@@ -1,0 -1,0 +1,5 @@@ ++innodb.row_size_error_log_warnings_3 : MDEV-30918 ++main.func_json_notembedded : MDEV-30518 / MDEV-27955 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/unstable-tests.sh4 index 000000000,000000000..1d55cfdbf new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.sh4 @@@ -1,0 -1,0 +1,3 @@@ ++# The m68k build on Debian runs in a qemu builder and has ++# DEB_BUILD_OPTIONS="nobench nocheck" defined, so *all* tests are skipped ++# intentionally (Bug#972057) diff --cc debian/unstable-tests.sparc64 index 000000000,000000000..e397067da new file mode 100644 --- /dev/null +++ b/debian/unstable-tests.sparc64 @@@ -1,0 -1,0 +1,19 @@@ ++main.ctype_binary : https://bugs.debian.org/1053485 ++main.ctype_latin1 : https://bugs.debian.org/1053485 ++main.features : MDEV-27954 ++main.func_json_notembedded : MDEV-27955 / MDEV-30518 ++main.func_like : MDEV-27954 ++main.func_math : MDEV-27954 ++main.func_str : MDEV-27954 ++main.group_by : MDEV-27954 ++main.group_by_null : MDEV-27954 ++main.index_merge_innodb : MDEV-30728 ++main.long_unique_bugs : MDEV-30928 ++main.partition_order : MDEV-27954 ++main.repair_symlink-5543 : MDEV-23920 ++main.type_datetime : MDEV-27954 ++main.xa_prepared_binlog_off : Likely also MDEV-30728 ++main.xml : MDEV-27954 ++maria.maria-purge : MDEV-31349 ++type_test.type_test_double : MDEV-22243, but wasn't actually fixed yet ++unit.conc_connection : CONC-640: unit.conc_connection fails on test_conc21 diff --cc debian/upstream/metadata index 000000000,000000000..184baa427 new file mode 100644 --- /dev/null +++ b/debian/upstream/metadata @@@ -1,0 -1,0 +1,6 @@@ ++Bug-Database: https://jira.mariadb.org ++Bug-Submit: https://jira.mariadb.org ++Donation: https://mariadb.org/donate/ ++Repository: git://github.com/MariaDB/server.git ++Repository-Browse: https://github.com/MariaDB/server ++Security-Contact: security@mariadb.org diff --cc debian/upstream/signing-key.asc index 000000000,000000000..708d2063a new file mode 100644 --- /dev/null +++ b/debian/upstream/signing-key.asc @@@ -1,0 -1,0 +1,51 @@@ ++-----BEGIN PGP PUBLIC KEY BLOCK----- ++ ++mQINBFb8EKsBEADwGmleOSVThrbCyCVUdCreMTKpmD5p5aPz/0jc66050MAb71Hv ++TVcfuMqHYO8O66qXLpEdqZpuk4D+rw1oKyC+d8uPD2PSHRqBXnR0Qf+LVTZvtO92 ++3R7pYnC2x6V6iVGpKQYFP8cwh2B1qgIa+9y/N8cQIqfD+0ghyiUjjTYek3YFBnqa ++L/2h2V0Mt0DkBrDK80LqEY10PAFDfJjINAW9XNHZzi2KqUx5w1z8rItokXV6fYE5 ++ItyGMR6WVajJg5D4VCiZd0ymuQP2bGkrRbl6FH5vofVSkahKMJeHs2lbvMvNyS3c ++n8vxoBvbbcwSAV1gvB1uzXXxv0kdkFZjhU1Tss4+Dak8qeEmIrC5qYycLxIdVEhT ++Z8N8+P7Dll+QGOZKu9+OzhQ+byzpLFhUHKys53eXo/HrfWtw3DdP21yyb5P3QcgF ++scxfZHzZtFNUL6XaVnauZM2lqquUW+lMNdKKGCBJ6co4QxjocsxfISyarcFj6ZR0 ++5Hf6VU3Y7AyuFZdL0SQWPv9BSu/swBOimrSiiVHbtE49Nx1x/d1wn1peYl07WRUv ++C10eF36ZoqEuSGmDz59mWlwB3daIYAsAAiBwgcmN7aSB8XD4ZPUVSEZvwSm/IwuS ++Rkpde+kIhTLjyv5bRGqU2P/Mi56dB4VFmMJaF26CiRXatxhXOAIAF9dXCwARAQAB ++tC1NYXJpYURCIFNpZ25pbmcgS2V5IDxzaWduaW5nLWtleUBtYXJpYWRiLm9yZz6J ++AjgEEwEIACIFAlb8EKsCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEPFl ++byTHTNHYJZ0P/2Z2RURRkSTHLKZ/GqSvPReReeB7AI+ZrDapkpG/26xp1Yw1isCO ++y99pvQ7hjTFhdZQ7xSRUiT/e27wJxR7s4G/ck5VOVjuJzGnByNLmwMjdN1ONIO9P ++hQAs2iF3uoIbVTxzXof2F8C0WSbKgEWbtqlCWlaapDpN8jKAWdsQsNMdXcdpJ2os ++WiacQRxLREBGjVRkAiqdjYkegQ4BZ0GtPULKjZWCUNkaat51b7O7V19nSy/T7MM7 ++n+kqYQLMIHCF8LGd3QQsNppRnolWVRzXMdtR2+9iI21qv6gtHcMiAg6QcKA7halL ++kCdIS2nWR8g7nZeZjq5XhckeNGrGX/3w/m/lwczYjMUer+qs2ww5expZJ7qhtSta ++lE3EtL/l7zE4RlknqwDZ0IXtxCNPu2UovCzZmdZm8UWfMSKk/3VgL8HgzYRr8fo0 ++yj0XkckJ7snXvuhoviW2tjm46PyHPWRKgW4iEzUrB+hiXpy3ikt4rLRg/iMqKjyf ++mvcE/VdmFVtsfbfRVvlaWiIWCndRTVBkAaTu8DwrGyugQsbjEcK+4E25/SaKIJIw ++qfxpyBVhru21ypgEMAw1Y8KC7KntB7jzpFotE4wpv1jZKUZuy71ofr7g3/2O+7nW ++LrR1mncbuT6yXo316r56dfKzOxQJBnYFwTjXfa65yBArjQBUCPNYOKr0uQINBFb8 ++EKsBEADDfCMsu2U1CdJhr4xp6z4J89/tMnpCQASC8DQhtZ6bWG/ksyKt2DnDQ050 ++XBEng+7epzHWA2UgT0liY05zZmFs1X7QeZr16B7JANq6fnHOdZB0ThS7JEYbProk ++MxcqAFLAZJCpZT534GpzW7qHwzjV+d13IziCHdi6+DD5eavYzBqY8QzjlOXbmIlY ++7dJUCwXTECUfirc6kH86CS8fXZTke4QYZ55VnrOomB4QGqP371kwBETnhlhi74+p ++vi3jW05Z5x1tVMwuugyzzkseZp1VYmJq5SHNFZ/pnAQLE9gUDTb6UWcPBwQh9Sw+ ++7ahSK74lJKYm3wktyvZhzAxbNyzs1M56yeFP6uFwJTBfNByyMAa6TGUhNkxlLcYj ++xKbVmoAnKCVM8t41TlLv/a0ki8iQxqvphVLufksR9IpN6d3F15j6GeyVtxBEv04i ++v4vbuKthWytb+gjX4bI8CAo9jGHevmtdiw/SbeKx2YBM1MF6eua37rFMooOBj4X7 ++VfQCyS+crNsOQn8nJGahYbzUDCCgnX+pqN9iZvXisMS79wVyD5DyISFDvT/5jY7I ++XxPibxr10P/8lfW1d72uxyI2UiZKZpyHCt4k47yMq4KQGLGuhxJ6q6O3bi2aXRuz ++8bLqTBLca9dmx9wZFvRh6jS/SKEg7eFcY0xbb6RVIv1UwGDYfQARAQABiQIfBBgB ++CAAJBQJW/BCrAhsMAAoJEPFlbyTHTNHYEBIQAJhFTh1u34Q+5bnfiM2dAdCr6T6w ++4Y1v9ePiIYdSImeseJS2yRglpLcMjW0uEA9KXiRtC/Nm/ClnqYJzCKeIaweHqH6d ++IgJKaXZFt1Uaia7X9tDDwqALGu97irUrrV1Kh9IkM0J29Vid5amakrdS4mwt2uEI ++SSnCi7pfVoEro+S7tYQ9iH6APVIwqWvcaty3cANdwKWfUQZ6a9IQ08xqzaMhMp2V ++zhVrWkq3B0j2aRoZR7BNLH2I7Z0giIM8ARjZs99aTRL+SfMEQ3sUxNLb3KWP/n1l ++SFbrk4HGzqUBBfczESlNc0970C6znK0H0HD11/3BTkMuPqww+Tzex4dpMQllMEKZ ++3wEyd9v6ba+nj/P1FHSEy/VN6IXzd82s1lYOonKTdmXAIROcHnb0QUzwsd/mhB3j ++KhEDOV2ZcBTD3yHv8m7C9G9y4hV+7yQlnPlSg3DjBp3SS5r+sOObCIy2Ad32upoX ++kilWa9g7GZSuhY9kyKqeEba1lgXXaQykEeqx0pexkWavNnb9JaPrAZHDjUGcXrRE ++mjEyXyElRoD4CrWXySe46jCuNhVVlkLGo7osefynXa/+PNjQjURtx8en7M9A1FkQ ++uRAxE8KIZgZzYxkGl5o5POSFCA4JUoRPDcrl/sI3fuq2dIOE/BJ2r8dV+LddiR+i ++ukhXRwJXH8RVVEUS ++=ihRo ++-----END PGP PUBLIC KEY BLOCK----- diff --cc debian/watch index 000000000,000000000..90a412745 new file mode 100644 --- /dev/null +++ b/debian/watch @@@ -1,0 -1,0 +1,17 @@@ ++version=4 ++opts=\ ++pgpsigurlmangle=s/$/.asc/,\ ++uversionmangle=s/-(rc|beta)/$1/,pasv \ ++https://archive.mariadb.org/mariadb-11.4.([\d\.]*(?:-beta|-rc)?)/source/ mariadb-([\d\.]*(?:-beta|-rc)?).tar.gz ++ ++# String "-11.4." needs to be in path as MariaDB releases several series in ++# parallel (e.g 11.4, 10.11, 10.4, 10.3 etc) and uscan should check for updates only ++# in the 11.4-series. ++ ++# Automated signature checking with pgpsigurlmangle has been available ++# only since devscripts version 2.13.3 ++ ++# Specifically use archive.mariadb.org because it supports https and the main ++# page has a file listing suitable for scanning new releases. ++# The archive.mariadb.org service is under MariaDB Foundation control and is ++# the official source for new releases.